From c1490cd15cf473e449ef3a08061959bf8efc3388 Mon Sep 17 00:00:00 2001 From: Ryan Voots Date: Sat, 18 Jun 2016 14:48:42 -0400 Subject: [PATCH] Eval supported, uses memcached --- app.pl | 99 +++++++++++++++++++++++++++++++++++---- pastes.db | Bin 3072 -> 8192 bytes templates/editor.html.tt | 92 ++++++++++++++++-------------------- templates/page.html.tt | 24 ++++++++++ 4 files changed, 155 insertions(+), 60 deletions(-) create mode 100755 templates/page.html.tt diff --git a/app.pl b/app.pl index d9af3d3..677f371 100755 --- a/app.pl +++ b/app.pl @@ -9,6 +9,10 @@ use DBI; use Mojolicious::Lite; use Mojolicious::Plugin::TtRenderer; +use Cache::Memcached::Fast; +use POE::Filter::Reference; +use IO::Compress::Gzip; +use IO::Uncompress::Gunzip; plugin 'tt_renderer' => { template_options => { @@ -21,6 +25,26 @@ plugin 'tt_renderer' => { app->renderer->default_handler( 'tt' ); app->renderer->paths( [ './tmpl' ] ); +my $memd = new Cache::Memcached::Fast({ + servers => [ { address => 'localhost:11211', weight => 2.5 }, ], + namespace => 'pastebin:', + connect_timeout => 0.2, + io_timeout => 0.5, + close_on_error => 1, + compress_threshold => 1_000, + compress_ratio => 0.9, + compress_methods => [ \&IO::Compress::Gzip::gzip, + \&IO::Uncompress::Gunzip::gunzip ], + max_failures => 3, + failure_timeout => 2, + ketama_points => 150, + nowait => 1, + hash_namespace => 1, + serialize_methods => [ \&Storable::freeze, \&Storable::thaw ], + utf8 => 1, + max_size => 512 * 1024, +}); + my $dbh = DBI->connect("dbi:SQLite:dbname=pastes.db", "", "", {RaiseError => 1}); # hardcode some channels first my %channels = ( @@ -28,10 +52,43 @@ my %channels = ( "freenode#perl" => "#perl (freenode)", ); +sub insert_pastebin { + my ($paste, $who, $what, $where) = @_; + + $dbh->do("INSERT INTO posts (paste, who, 'where', what, 'when') VALUES (?, ?, ?, ?, ?)", {}, $paste, $who, $where, $what, time()); + my $id = $dbh->last_insert_id('', '', 'posts', 'id'); + + return $id; +} + +sub get_eval { + my ($paste_id, $code) = @_; + + if (my $cached = $memd->get($paste_id)) { + return $cached; + } else { + my $filter = POE::Filter::Reference->new(); + my $socket = IO::Socket::INET->new( PeerAddr => 'localhost', PeerPort => '14400' ) + or die "error: cannot connect to eval server"; + + my $refs = $filter->put( [ { code => "perl $code" } ] ); + + print $socket $refs->[0]; + my $output = do {local $/; <$socket>}; + close $socket; + my $result = $filter->get( [ $output ] ); + + $memd->set($paste_id, $result->[0]->[0]); + + return $result->[0]->[0]; + } +} + + get '/' => sub { my $c = shift; - $c->stash({pastedata => q{}, channels => \%channels, viewing => 0}); - $c->render("editor"); + $c->stash({pastedata => q{}, channels => \%channels, viewing => 0, page_tmpl => 'editor.html.tt'}); + $c->render("page"); }; get '/pastebin' => sub {$_[0]->redirect_to('/')}; get '/paste' => sub {$_[0]->redirect_to('/')}; @@ -40,33 +97,59 @@ get '/paste' => sub {$_[0]->redirect_to('/')}; post '/paste' => sub { my $c = shift; - my @args = map {($c->param($_))} qw/paste user chan desc/; + my @args = map {($c->param($_))} qw/paste name desc chan/; - $dbh->do("INSERT INTO posts (paste, who, 'where', what, 'when') VALUES (?, ?, ?, ?, ?)", {}, @args, time()); - my $id = $dbh->last_insert_id('', '', 'posts', 'id'); + my $id = insert_pastebin(@args); $c->redirect_to('/pastebin/'.$id); #$c->render(text => "post accepted! $id"); }; +get '/edit/:pasteid' => sub { + my $c = shift; + my $pasteid = $c->param('pasteid'); + + my $row = $dbh->selectrow_hashref("SELECT * FROM posts WHERE id = ? LIMIT 1", {}, $pasteid); + + if ($row->{when}) { + $c->stash({pastedata => $row->{paste}, channels => \%channels, viewing => 0}); + $c->stash({page_tmpl => 'editor.html.tt'}); + + $c->render('page'); + } else { +# 404 + } +}; + get '/pastebin/:pasteid' => sub { my $c = shift; my $pasteid = $c->param('pasteid'); my $row = $dbh->selectrow_hashref("SELECT * FROM posts WHERE id = ? LIMIT 1", {}, $pasteid); - print Dumper($row); - if ($row->{when}) { $c->stash({pastedata => $row->{paste}, channels => \%channels, viewing => 1}); $c->stash($row); + $c->stash({page_tmpl => 'editor.html.tt'}); - $c->render('editor'); + $c->render('page'); } else { # 404 } }; +get '/eval/:pasteid' => sub { + my ($c) = @_; + my $pasteid = $c->param('pasteid'); + + my $row = $dbh->selectrow_hashref("SELECT * FROM posts WHERE id = ? LIMIT 1", {}, $pasteid); + my $code = $row->{paste} // ''; + + my $output = get_eval($pasteid, $code); + + $c->render(json => {evalout => $output}); +}; + app->start; diff --git a/pastes.db b/pastes.db index 5d3f1eed1df6be2e9b8ec50dac43cdf1bfb80523..fa175eb7a204c25cac8c51faf4a8051942bcd16d 100644 GIT binary patch literal 8192 zcmeHMO>7&-6(+fIWP7WmO`E!H;(EM%_Wp3WBqdpqxLH#aMNzxd4@FT@B9c}paV^oN zNQ$Jx$kZB15fnZ2(rXJ8C{Un>^jIK33p8kZZF}gUXwh2_LC$S+3S9KfE-6xqSQ$C> zM?-RVzM1#FdGlsx-^_4zWueqG$^B}5ztALOt|6D(?V2XU<#KuPcNu@(B~)09FJ)v>D>QHhXX3A8zO`5F*z*_9 z?>)cr{LJ$c&-Xpw_QYIq)cnE2>z7?0+gG0y)VqOe~-xk|vk-)l76L^6)4S16P1!cMi)Ao$enmx`6r?q2hL-83uJqUo)f_3~1c=%k1>d~;*x zo!pBr54&D=jf@O6%|^3S+1=RI8|*iRT_dy%!43B7$6)>+?ALnWPwcfG_%Zv{9{3LX zQV$f^uk^qy`{f>(WM4c6i9fPm>VXg0FZRHX*cW=B#6I5x%k0Q8nENaHg&z0?%l1Hp zz1jmy?3Eti*vrQt{u_3<2Y!0vISTlfhfX*T9o#JJmo~QJciBrlX`UTA2D5))nI8BZ z>p2FopR;ZU;Mfgcr?J`1eB#3IMY{07g$Mp0JaEO$TyxuN3=X?{X~7Rk72=vu*lq|I zVY(?H-qq})IZ=#2A`Ek?0P)v?A}LggCnGKmPNF7&9h{Ks=txt7p$?IXy9)tIT2O`3 zYm^b`q9X0^7Z z_D8BN+olGOkB-nLb-z%vLpjWAutlRLENKs5o`y?UwsW0D!Mxap0~)(OYg{Lk!+a-j z6HzVQ7sf|54GvJta0nOZ%`(dk6N&uV_?QX{1SL-M-I`KSML-#h>;VJ|DCD1#!0?Y_ z4Qg6o_%s@F7x0!;3*FTKx|=MB>S;o!`glC7WBDZ+mPHHKJ^P1{u{{BY)C;yxAfsr` za2#5v8L8X1tO(@7JmD?De`iWj?o8nt19iAug~OuJF+~|26V+NB$BoOG*?Gut7PK^C zzEvonSkBNvspC4jR5!^+se-Gfa12)q)v_55N0(N09Kvl4S`j{^zN+$Jj>G5ffeepi zXvol%p&&y=hU#e}W!RHpM}~(o)MPMasLN26Atq{#8m`>~RzT)6Ey-9-PU_KJDP?3O zW4e{LBqN=dRw&|?)0~8#iAu%_YDh-RO0GT5&qQ@2W6P%_{&d#N=h8Z_@K&aRa`{#| zijuRH^yEr(&1z*PlbN$f^C%qGrMQvChVy8EG;2)jD_OK<)kOVl1q)NAgv7>-9!Tm| zW^y``+9_7<@2XE9=t$r)_WQr8cpWn(3vr?SZ0TCpUY z|IeZDve~Xk@p$^-q|5x%`;AmR~!NQj6KvdVV9n5z9!k zi_$8N6I!&H%5Dyz#pjDpZ5EJWExEp1-Azs<(IAACY#MEk&rj>cVmiB$&1dLmteP!8 zME}^d+0ESAU|J+@qk%>$nMo$|*y-$wzMM_z^qSpWORnW8k!nOP(3iHd!Mup-i&TDEMh1J{qRTDbjv=-z zJl00UQQ`63pi1B|YWX!Zs12(U-3dZets%W-vyn#GG;6SRK3{e;?`#)Qk9KP; zfBUu*Eg$1cnXGmq6nTxBCw}IA=d{*;t)UH;z;XC26K-tOdUX~aaJGQLSd!%Q0cH*v1O<_ zL|BnXU@KiU#4E99FcX`HJ*%UpaQ6~mcF9HEvEHFXxjHAG-*4M{k**yIHxD&y4q2_0 z1QJm9b`oc8KC6Lcjy{B4z0pZaScq|GdAAk22H|-#n#$4chWiy24&86XdqeEB!@2hTN6RQH6*zL8L-CUMCXL;_lKnlB`tOGxE5HKJBEzeBO=(y&2Ke z{E0IJTCh=k`dzyJzmA7^%-@-hm_J{f|MmRq)h(-)yduYtB`x zMNS>?#{cJ7_~x)HI)G;0ESIZ;b+4?GVb>wmwf7Q)v*pP~wO%gbA%Ja8rzYgX4=r)9 z4F}ou^y7&e!>*~pyaW33^w-~teDkvFJ)LU43EG<~Y-zb$H*pKGC29dd5d$h{n$HJE zSft1hkU^FqCj%#gD#JY)yfQqIL6RXXPv61=laZ@%Q+q;H@vAtu4(K6;W)(YO21z+l z25d$JrF%i1Et;nnw8m}}H#7n~QGmlGkqQC0m4!$iwjc-Cyo1m#?l!f^E92RU?DLIW twQnliJJNtt-|UD7P(g(!AazI-JKy$N9jqcL2lr^Ha`!fRW{?Np{}*#o*aH9n delta 56 zcmZp0Xpop7%__^lz`#6F!JbieW5NPvK3*VKhRK - - - - - - - - - - - - - - Editor - - - +[% END %] +[% BLOCK page_header %] +
+ [% IF viewing %] +
+ Who: [% who %] +
+
+ When: [% when %] +
+
+ What: [% what %] +
+ [% ELSE %] +
+ + +
+
+ + +
+
+ + +
+ [% END %] +
+[% END %] + +[% BLOCK body %]
-
- [% IF viewing %] -
- Who: [% who %] -
-
- When: [% when %] -
-
- What: [% what %] -
- [% ELSE %] -
- - -
-
- - -
-
- - -
- [% END %] -
+ [% PROCESS page_header %]
@@ -114,6 +104,4 @@ }); - - - +[% END %] diff --git a/templates/page.html.tt b/templates/page.html.tt new file mode 100755 index 0000000..ede1cf8 --- /dev/null +++ b/templates/page.html.tt @@ -0,0 +1,24 @@ + +[% PROCESS "$page_tmpl" %] + + + + + + + + + + + + + + Perlbot Pastebin + [% PROCESS body_style %] + + + +[% PROCESS body %] + + +