a lot of changes, hoo boy.
made the expiry check interval configurable (expire_every in config.yml) fixed a bug where an expired paste could still be viewed for a short period after expiring in some situations consolidated the paste fetching and parameter validation functions somewhat fixed some bugs with expiry handling hopefully haven't broken anything, changes are untested
This commit is contained in:
parent
986ea029ee
commit
e73864fcea
270
config.yml
270
config.yml
|
@ -7,6 +7,9 @@ locale: "en_GB"
|
|||
logger: "console"
|
||||
log: "debug"
|
||||
|
||||
# Time in seconds between each paste expiry check
|
||||
expire_every: 600
|
||||
|
||||
template: "template_toolkit"
|
||||
engines:
|
||||
template:
|
||||
|
@ -24,144 +27,145 @@ plugins:
|
|||
options:
|
||||
sqlite_unicode: 1
|
||||
|
||||
# Comment out for production
|
||||
show_errors: 1
|
||||
# Uncomment for debugging
|
||||
#show_errors: 1
|
||||
|
||||
# Sets the expiration for posts
|
||||
# Options can be any combination of weeks, days, hours, minutes, seconds
|
||||
expiration:
|
||||
weeks: 2
|
||||
weeks: 2
|
||||
|
||||
|
||||
# Languages supported by Pygments
|
||||
# TODO: perhaps swap this out with something in App::WerePaste::Util::PygmentsBridge so we can dynamically load supported languages
|
||||
languages:
|
||||
- Programming languages:
|
||||
- ActionScript:
|
||||
- Ada:
|
||||
- ANTLR:
|
||||
- AppleScript:
|
||||
- Assembly: nasm
|
||||
- Asymptote:
|
||||
- Awk:
|
||||
- Bash:
|
||||
- Befunge:
|
||||
- Boo:
|
||||
- BrainFuck:
|
||||
- C:
|
||||
- C++:
|
||||
- C#:
|
||||
- Clojure:
|
||||
- CoffeeScript:
|
||||
- ColdFusion: cfm
|
||||
- Common Lisp:
|
||||
- Coq:
|
||||
- Cryptol:
|
||||
- Cython:
|
||||
- D:
|
||||
- Dart:
|
||||
- Delphi:
|
||||
- Dylan:
|
||||
- Erlang:
|
||||
- Factor:
|
||||
- Fancy:
|
||||
- Fortran:
|
||||
- F#:
|
||||
- GAP:
|
||||
- Gherkin:
|
||||
- GL shaders:
|
||||
- Groovy:
|
||||
- Haskell:
|
||||
- IDL:
|
||||
- Io:
|
||||
- Java:
|
||||
- JavaScript:
|
||||
- Lasso:
|
||||
- LLVM:
|
||||
- Logtalk:
|
||||
- Lua:
|
||||
- Matlab:
|
||||
- MiniD:
|
||||
- Modelica:
|
||||
- Modula-2:
|
||||
- MuPad:
|
||||
- Nemerle:
|
||||
- Nimrod:
|
||||
- Objective-C:
|
||||
- Objective-J:
|
||||
- Octave:
|
||||
- OCaml:
|
||||
- PHP:
|
||||
- Perl:
|
||||
- PovRay:
|
||||
- PostScript:
|
||||
- PowerShell:
|
||||
- Prolog:
|
||||
- Python:
|
||||
- REBOL:
|
||||
- Red:
|
||||
- Redcode:
|
||||
- Ruby:
|
||||
- Rust:
|
||||
- R:
|
||||
- S:
|
||||
- S-Plus:
|
||||
- Scala:
|
||||
- Scheme:
|
||||
- Scilab:
|
||||
- Smalltalk:
|
||||
- SNOBOL:
|
||||
- Tcl:
|
||||
- Vala:
|
||||
- Verilog:
|
||||
- VHDL:
|
||||
- Visual Basic.NET: vbnet
|
||||
- Visual FoxPro: foxpro
|
||||
- XQuery:
|
||||
- Zephir:
|
||||
- Template Languages:
|
||||
- Cheetah:
|
||||
- Django:
|
||||
- ERB:
|
||||
- Genshi:
|
||||
- Jinja:
|
||||
- JSP:
|
||||
- Mako:
|
||||
- Myghty:
|
||||
- Smarty:
|
||||
- Tea:
|
||||
- Configuration Markup:
|
||||
- ApacheConf:
|
||||
- INI-style: ini
|
||||
- Lighttpd:
|
||||
- Nginx:
|
||||
- Other Markups:
|
||||
- BBCode:
|
||||
- CMake:
|
||||
- CSS:
|
||||
- Debian control file: control
|
||||
- Diff:
|
||||
- DTD:
|
||||
- Gettext Catalogs: pot
|
||||
- Gnuplot:
|
||||
- Groff:
|
||||
- HTML:
|
||||
- HTTP Session: http
|
||||
- IRC log (irssi-format): irc
|
||||
- Makefile:
|
||||
- MoinMoin/Trac wiki markup: moin
|
||||
- MySQL:
|
||||
- POV-Ray Scenes: pov
|
||||
- Ragel:
|
||||
- Redcode:
|
||||
- ReST:
|
||||
- SQL:
|
||||
- PostgreSQL: psql
|
||||
- SQLite:
|
||||
- Squid Configuration: squid
|
||||
- TeX:
|
||||
- tcsh:
|
||||
- VimScript: vim
|
||||
- Windows Batch Script: bat
|
||||
- XML:
|
||||
- XSLT:
|
||||
- YAML:
|
||||
- Programming languages:
|
||||
- ActionScript:
|
||||
- Ada:
|
||||
- ANTLR:
|
||||
- AppleScript:
|
||||
- Assembly: nasm
|
||||
- Asymptote:
|
||||
- Awk:
|
||||
- Bash:
|
||||
- Befunge:
|
||||
- Boo:
|
||||
- BrainFuck:
|
||||
- C:
|
||||
- C++:
|
||||
- C#:
|
||||
- Clojure:
|
||||
- CoffeeScript:
|
||||
- ColdFusion: cfm
|
||||
- Common Lisp:
|
||||
- Coq:
|
||||
- Cryptol:
|
||||
- Cython:
|
||||
- D:
|
||||
- Dart:
|
||||
- Delphi:
|
||||
- Dylan:
|
||||
- Erlang:
|
||||
- Factor:
|
||||
- Fancy:
|
||||
- Fortran:
|
||||
- F#:
|
||||
- GAP:
|
||||
- Gherkin:
|
||||
- GL shaders:
|
||||
- Groovy:
|
||||
- Haskell:
|
||||
- IDL:
|
||||
- Io:
|
||||
- Java:
|
||||
- JavaScript:
|
||||
- Lasso:
|
||||
- LLVM:
|
||||
- Logtalk:
|
||||
- Lua:
|
||||
- Matlab:
|
||||
- MiniD:
|
||||
- Modelica:
|
||||
- Modula-2:
|
||||
- MuPad:
|
||||
- Nemerle:
|
||||
- Nimrod:
|
||||
- Objective-C:
|
||||
- Objective-J:
|
||||
- Octave:
|
||||
- OCaml:
|
||||
- PHP:
|
||||
- Perl:
|
||||
- PovRay:
|
||||
- PostScript:
|
||||
- PowerShell:
|
||||
- Prolog:
|
||||
- Python:
|
||||
- REBOL:
|
||||
- Red:
|
||||
- Redcode:
|
||||
- Ruby:
|
||||
- Rust:
|
||||
- R:
|
||||
- S:
|
||||
- S-Plus:
|
||||
- Scala:
|
||||
- Scheme:
|
||||
- Scilab:
|
||||
- Smalltalk:
|
||||
- SNOBOL:
|
||||
- Tcl:
|
||||
- Vala:
|
||||
- Verilog:
|
||||
- VHDL:
|
||||
- Visual Basic.NET: vbnet
|
||||
- Visual FoxPro: foxpro
|
||||
- XQuery:
|
||||
- Zephir:
|
||||
- Template Languages:
|
||||
- Cheetah:
|
||||
- Django:
|
||||
- ERB:
|
||||
- Genshi:
|
||||
- Jinja:
|
||||
- JSP:
|
||||
- Mako:
|
||||
- Myghty:
|
||||
- Smarty:
|
||||
- Tea:
|
||||
- Configuration Markup:
|
||||
- ApacheConf:
|
||||
- INI-style: ini
|
||||
- Lighttpd:
|
||||
- Nginx:
|
||||
- Other Markups:
|
||||
- BBCode:
|
||||
- CMake:
|
||||
- CSS:
|
||||
- Debian control file: control
|
||||
- Diff:
|
||||
- DTD:
|
||||
- Gettext Catalogs: pot
|
||||
- Gnuplot:
|
||||
- Groff:
|
||||
- HTML:
|
||||
- HTTP Session: http
|
||||
- IRC log (irssi-format): irc
|
||||
- Makefile:
|
||||
- MoinMoin/Trac wiki markup: moin
|
||||
- MySQL:
|
||||
- POV-Ray Scenes: pov
|
||||
- Ragel:
|
||||
- Redcode:
|
||||
- ReST:
|
||||
- SQL:
|
||||
- PostgreSQL: psql
|
||||
- SQLite:
|
||||
- Squid Configuration: squid
|
||||
- TeX:
|
||||
- tcsh:
|
||||
- VimScript: vim
|
||||
- Windows Batch Script: bat
|
||||
- XML:
|
||||
- XSLT:
|
||||
- YAML:
|
||||
|
|
|
@ -12,7 +12,7 @@ use Data::UUID;
|
|||
my $lastexpunge = 0;
|
||||
|
||||
sub DeploySchema {
|
||||
# need to find a way to handle this that doesn't shit errors everywhere
|
||||
# TODO: figure out how to ensure schema is deployed without producing "table already exists" errors when it is already deployed
|
||||
eval {schema->deploy};
|
||||
}
|
||||
sub DateTimeToQueryable {
|
||||
|
@ -22,39 +22,47 @@ sub DateTimeToQueryable {
|
|||
}
|
||||
sub ExpirationToDate {
|
||||
my $expire = shift;
|
||||
$expire = $expire ? { split ':', $expire } : undef;
|
||||
$expire = $expire ? { split ':', $expire } : config->{default_expire};
|
||||
return undef if $expire and $expire->{never};
|
||||
return DateTimeToQueryable(%{ $expire || config->{default_expire} });
|
||||
return DateTimeToQueryable(%{ $expire });
|
||||
}
|
||||
sub GetUUID {
|
||||
my $uuid = Data::UUID->new->create_str;
|
||||
$uuid =~ s/\-//g;
|
||||
return lc $uuid;
|
||||
}
|
||||
sub CheckExpired {
|
||||
return unless time > ($lastexpunge+900); #expunge once every 15 mins
|
||||
sub CheckExpiry {
|
||||
return unless time > ($lastexpunge+config->{expire_every});
|
||||
$lastexpunge = time;
|
||||
schema->resultset('Paste')->search({ expiration => { '<' => DateTimeToQueryable() }})->delete_all;
|
||||
schema->resultset('Paste')->search({expiration => { '<' => DateTimeToQueryable() }})->delete_all;
|
||||
}
|
||||
sub ValidateParams {
|
||||
my $params = shift;
|
||||
if($params->{id}) {
|
||||
return undef unless lc($params->{id}) =~ /^[a-f0-9]*$/;
|
||||
return 1;
|
||||
}
|
||||
return undef unless $params->{code};
|
||||
#TODO: Allow all 'word' characters rather than just a-zA-Z0-9, expanded grammar
|
||||
## Presently this is limited so people can't do anything nasty.
|
||||
return undef unless $params->{title} =~ /^[a-zA-Z0-9\.\-_ @\(\)]{0,255}$/;
|
||||
return undef unless $params->{lang} =~ /^[a-z0-9\.\-\+# ]{0,40}$/;
|
||||
return undef unless $params->{expiration} =~ /^([a-z]+:[0-9]+)(:[a-z]+:[0-9]+)*$/ or not $params->{expiration};
|
||||
return 1;
|
||||
}
|
||||
sub GetPaste {
|
||||
my $id = shift;
|
||||
return schema->resultset('Paste')->single({ id => $id }) or return undef;
|
||||
my $id = shift; $id = lc $id;
|
||||
return undef unless $id =~ /^[a-f0-9]*$/;
|
||||
#This got a bit messy, required because otherwise there are scenarios where an expired paste may still be viewed
|
||||
return schema->resultset('Paste')->single({
|
||||
-and => [
|
||||
{ id => $id },
|
||||
-or => [
|
||||
{ expiration => { '>=' => DateTimeToQueryable() }},
|
||||
{ expiration => undef }
|
||||
]
|
||||
]}) or return undef;
|
||||
}
|
||||
sub SubmitPaste {
|
||||
my $params = shift;
|
||||
my ($lang,$html) = PygmentsHighlight(lang => $params->{lang}, code => $params->{code});
|
||||
#TODO: maybe figure out a nicer way of doing this, presently the UUID namespace changes with every app start
|
||||
my $id = GetUUID();
|
||||
my $result = schema->resultset('Paste')->create({
|
||||
id => $id,
|
||||
|
@ -66,31 +74,26 @@ sub SubmitPaste {
|
|||
}) or return undef;
|
||||
return $id;
|
||||
}
|
||||
sub ValidateAndGet {
|
||||
my $params = shift;
|
||||
ValidateParams($params) or return undef;
|
||||
return GetPaste(lc $params->{id}) or return undef;
|
||||
}
|
||||
|
||||
# Startup
|
||||
DeploySchema();
|
||||
# Hooks
|
||||
hook 'before' => sub { CheckExpired(); };
|
||||
hook 'before' => sub { CheckExpiry(); };
|
||||
# Routes
|
||||
#get
|
||||
get '/' => sub { template 'index.tt'; };
|
||||
get '/:id' => sub { my $paste=ValidateAndGet(scalar params('route')) or pass; template 'show.tt', { paste => $paste };};
|
||||
get '/:id/copy' => sub { my $paste=ValidateAndGet(scalar params('route')) or pass; template 'index.tt', { paste => $paste }; };
|
||||
get '/:id/raw' => sub { my $paste=ValidateAndGet(scalar params('route')) or pass; content_type 'text/plain'; return $paste->code; };
|
||||
get '/:id' => sub { my $paste=GetPaste(scalar params 'route') or pass; template 'show.tt', { paste => $paste }; };
|
||||
get '/:id/copy' => sub { my $paste=GetPaste(scalar params 'route') or pass; template 'index.tt', { paste => $paste }; };
|
||||
get '/:id/raw' => sub { my $paste=GetPaste(scalar params 'route') or pass; content_type 'text/plain'; return $paste->code; };
|
||||
#post
|
||||
post '/' => sub {
|
||||
my $p = params('body');
|
||||
ValidateParams($p) or return send_error('Submitted paste is not valid. Check your post title and language, and try again.',400);
|
||||
my $p = params 'body';
|
||||
ValidateParams($p) or return send_error('Submitted paste is not valid. Check your post title and language, and try again.', 400);
|
||||
my $id = SubmitPaste($p) or return redirect '/503.html';
|
||||
return redirect "/$id";
|
||||
};
|
||||
#default
|
||||
any qr/.*/ => sub { return send_error('Page gone',404); };
|
||||
any qr/.*/ => sub { return send_error('What you seek cannot be found here.', 404); };
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
|
Loading…
Reference in New Issue