package LDV::Comments; use strict; use warnings; use utf8; use Mojo::Base 'Mojolicious::Controller'; use Mojo::URL; sub _gen_id { my ($self) = @_; my $url = $self->req->param('pageid') || $self->req->headers->referrer; my $maxlen = 64; return unless $url; my $id = Mojo::URL->new($url)->path; $id =~ s{^/+}{}o; $id =~ s{/+$}{}o; $id =~ y{/.}{-}s; $id =~ s<\.[a-z0-9]{2,4}$><>io; $id = substr($id, -$maxlen, $maxlen); $self->app->log->debug("comments id: $id -- $url"); return $id; } sub _comments_load { my ($self) = @_; my $id = $self->_gen_id or die("can't get id\n"); my $path = $self->app->home->rel_file("data/comments/$id.json"); return [] unless -f $path; open my $FH, '<', $path or die("open (r): $path -- $!\n"); local $/ = undef; my $data = <$FH>; close $FH; return $self->app->json->decode($data); } sub _comments_save { my ($self, $data) = @_; my $id = $self->_gen_id or die("can't get id\n"); my $path = $self->app->home->rel_file("data/comments/$id.json"); open my $FH, '>', $path or die("open (w): $path -- $!\n"); print $FH $self->app->json->encode($data); close $FH; return 1; } sub add { my ($self) = @_; eval { my $text = $self->req->param('text') or die("empty comment\n"); my $comments = $self->_comments_load(); my $comment = { text => $text, time => time(), user => $self->session('username') || 'anonymous', }; push @{ $comments }, $comment; $self->_comments_save($comments); $self->render(text => 'OK'); } or do { chomp $@; $self->app->log->error($@); $@ = 'internal error' if $@ =~ m{line \d+}o; $self->res->code(400); $self->render(text => $@); }; $self->rendered(); } sub get { my ($self) = @_; eval { my $comments = $self->_comments_load(); die("can't load comments\n") unless ref($comments) eq 'ARRAY'; if (my $count = scalar @{ $comments }) { $self->app->log->debug("loaded $count comments"); $self->stash({comments => $comments}); $self->render(template => 'comments/list'); } else { $self->render(template => 'comments/none'); }; } or do { chomp $@; $self->app->log->error($@); $@ = 'internal error' if $@ =~ m{line \d+}o; $self->res->code(400); $self->render(text => $@); }; $self->rendered(); } 1;