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 5d3f1ee..fa175eb 100644 Binary files a/pastes.db and b/pastes.db differ diff --git a/templates/editor.html.tt b/templates/editor.html.tt index 7e4fb4c..e2f054b 100755 --- a/templates/editor.html.tt +++ b/templates/editor.html.tt @@ -1,19 +1,5 @@ - - - - - - - - - - - - - - - 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 %] + + +