package CMTD::Helpers; use strict; use warnings; use utf8; use Mojo::Base 'Mojolicious::Plugin'; use Mojo::Util qw(b64_encode md5_sum); use Mojo::URL; sub register { my ($self, $app) = @_; $app->helper(allow_cors => sub { my ($c) = @_; $c->res->headers->add('Access-Control-Allow-Origin' => '*'); return; }); $app->helper(referrer => sub { my ($c) = @_; my $url = $c->req->headers->referrer || $c->req->param('url'); return unless $url; my $u = Mojo::URL->new($url); my $site = $u->host; my $path = $u->path; $path =~ s{^/+}{}o; $path =~ s{/+$}{}o; $path =~ y{/.}{-}s; $path =~ s<\.[a-z0-9]{2,4}$><>io; my $md5 = md5_sum($path); return {site => $site, hash => $md5, path => $path}; }); $app->helper(maintenance => sub { my ($c) = @_; eval { my $table = 'captcha'; my $tries = $c->app->config->{captcha}->{tries}; my $limit = $c->app->config->{captcha}->{limit}; $c->app->db->delete($table, {tries => {'>=' => $tries}}); my $count = $c->app->db->select($table, 'count(id)')->list; if ($count < $limit) { $c->app->db->begin; foreach my $n ($count + 1 .. $limit) { $c->app->log->info("generating captcha's: $n of $limit"); my ($code, $data) = $c->app->captcha->create; next unless $code and $data; my $b64 = 'data:image/jpeg;base64,' . b64_encode($data, ''); $c->app->db->insert($table, { code => $code, data => $b64 }); } $c->app->db->commit; } 1; } or do { chomp $@; $c->app->log->error($@); }; }); $app->helper(client_reply => sub { my ($c, $code, $msg) = @_; $c->res->code($code); $c->render(text => "$msg\n"); $c->rendered; return; }); $app->helper(site_by_name => sub { my ($c, $site) = @_; return $c->app->db->select('sites', '*', {site => $site})->hash; }); $app->helper(pid_by_hash => sub { my ($c, $sid, $hash) = @_; return $c->app->db->select('pages', 'id', {sid => $sid, hash => $hash})->list; }); $app->helper(comments_by_pid => sub { my ($c, $pid) = @_; return $c->app->db->select('comments', '*', {pid => $pid}, 'seq')->hashes; }); $app->helper(captcha_by_id => sub { my ($c, $cid) = @_; return $c->app->db->select('captcha', '*', {cid => $cid})->hash; }); $app->helper(captcha_solve => sub { my ($c, $id, $input) = @_; my $cap = $c->app->db->select('captcha', '*', {cid => $id})->hash; return "no captcha with this id" unless $cap and ref($cap) eq 'HASH'; if ($cap->{code} ne $input) { if ($cap->{tries} + 1 >= $app->config->{tries}) { $app->db->delete('captcha', {id => $cap->{id}}); } else { $app->db->update('captcha', \'tries = tries + 1', {id => $cap->{id}}); } return "captcha code mismatch"; } }); $app->helper(get_captcha => sub { my ($c) = @_; my $table = 'captcha'; my @sort = qw(shown tries); $app->db->begin; my ($cid, $data) = $app->db->select($table, ['id', 'data'], undef, \@sort)->list; $app->db->update($table, {shown => time()}, {id => $cid}); $app->db->commit; return ($cid, $data); }); $app->helper(add_page => sub { my ($c, $sid, $page) = @_; $c->app->db->insert('pages', { sid => $sid, hash => $page->{hash}, path => $page->{path}, }); }); $app->helper(add_comment => sub { my ($c, $pid, $cm) = @_; my $table = 'comments'; $c->app->db->begin; my $seq = $c->app->db->select($table, 'max(seq)', {pid => $pid})->list; $c->app->db->insert($table, { pid => $pid, seq => $seq, date => time(), name => $cm->{name}, reply => $cm->{reply}, email => $cm->{email}, text => b64_encode($cm->{text}), }); $c->app->db->commit; }); } 1;