First commit
This commit is contained in:
commit
7a3a80c791
|
@ -0,0 +1,9 @@
|
|||
*~
|
||||
*.swp
|
||||
blib
|
||||
Makefile
|
||||
Makefile.old
|
||||
.build
|
||||
*.db
|
||||
_Inline
|
||||
data/pastes.db
|
|
@ -0,0 +1,13 @@
|
|||
App::WerePaste
|
||||
--------------
|
||||
|
||||
Perl-based pastebin software, largely a rewrite of Dancebin, using Pygments via Inline::Python for syntax highlighting.
|
||||
|
||||
Requirements:
|
||||
|
||||
- Dancer2
|
||||
- Dancer2::Plugin::DBIC
|
||||
- Data::UUID
|
||||
- Try::Tiny
|
||||
- Inline::Python
|
||||
- pip module Pygments
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../lib";
|
||||
|
||||
use App::WerePaste;
|
||||
|
||||
App::WerePaste->start;
|
|
@ -0,0 +1,167 @@
|
|||
appname: "WerePaste"
|
||||
layout: "main"
|
||||
charset: "UTF-8"
|
||||
tz: "Europe/London"
|
||||
locale: "en_GB"
|
||||
|
||||
logger: "console"
|
||||
log: "debug"
|
||||
|
||||
template: "template_toolkit"
|
||||
engines:
|
||||
template:
|
||||
template_toolkit:
|
||||
encoding: 'utf8'
|
||||
start_tag: '[%'
|
||||
end_tag: '%]'
|
||||
|
||||
|
||||
plugins:
|
||||
DBIC:
|
||||
default:
|
||||
schema_class: 'App::WerePaste::Schema'
|
||||
dsn: dbi:SQLite:dbname=data/pastes.db
|
||||
options:
|
||||
sqlite_unicode: 1
|
||||
|
||||
# Comment out for production
|
||||
show_errors: 1
|
||||
|
||||
# Sets the expiration for posts
|
||||
# Options can be any combination of weeks, days, hours, minutes, seconds
|
||||
expiration:
|
||||
weeks: 2
|
||||
|
||||
|
||||
# Languages supported by Pygments
|
||||
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:
|
|
@ -0,0 +1,9 @@
|
|||
CREATE TABLE posts (
|
||||
id TEXT PRIMARY KEY NOT NULL,
|
||||
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, /* Created timestamp */
|
||||
expiration TIMESTAMP, /* Created timestamp */
|
||||
language TEXT NOT NULL, /* Language (if detected) */
|
||||
title TEXT, /* Title/Filename */
|
||||
code BLOB NOT NULL, /* Code */
|
||||
html BLOB /* HTML version of Code */
|
||||
);
|
|
@ -0,0 +1,96 @@
|
|||
package App::WerePaste;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use App::WerePaste::Util::PygmentsBridge qw/:all/;
|
||||
use Dancer2;
|
||||
use Dancer2::Plugin::DBIC qw/schema/;
|
||||
use DateTime;
|
||||
use Data::UUID;
|
||||
|
||||
my $lastexpunge = 0;
|
||||
|
||||
sub DeploySchema {
|
||||
# need to find a way to handle this that doesn't shit errors everywhere
|
||||
eval {schema->deploy};
|
||||
}
|
||||
sub DateTimeToQueryable {
|
||||
my $dt = DateTime->now(time_zone => config->{tz});
|
||||
$dt->add(@_) if scalar @_;
|
||||
return schema->storage->datetime_parser->format_datetime($dt);
|
||||
}
|
||||
sub ExpirationToDate {
|
||||
my $expire = shift;
|
||||
$expire = $expire ? { split ':', $expire } : undef;
|
||||
return undef if $expire and $expire->{never};
|
||||
return DateTimeToQueryable(%{ $expire || config->{default_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
|
||||
$lastexpunge = time;
|
||||
schema->resultset('Paste')->search({ expiration => [undef, { '<' => 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};
|
||||
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;
|
||||
}
|
||||
sub SubmitPaste {
|
||||
my $params = shift;
|
||||
my ($lang,$html) = PygmentsHighlight(lang => $params->{lang}, code => $params->{code});
|
||||
my $id = GetUUID();
|
||||
my $result = schema->resultset('Paste')->create({
|
||||
id => $id,
|
||||
title => $params->{title},
|
||||
language => $lang,
|
||||
expiration => ExpirationToDate($params->{expiration}),
|
||||
code => $params->{code},
|
||||
html => $html,
|
||||
}) 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(); };
|
||||
# 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; };
|
||||
#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 $id = SubmitPaste($p) or return redirect '/503.html';
|
||||
return redirect "/$id";
|
||||
};
|
||||
#default
|
||||
any qr/.*/ => sub { return send_error('Page gone',404); };
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -0,0 +1,11 @@
|
|||
package App::WerePaste::Schema;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Schema';
|
||||
|
||||
__PACKAGE__->load_namespaces;
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -0,0 +1,28 @@
|
|||
package App::WerePaste::Schema::Result::Paste;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->table("pastes");
|
||||
__PACKAGE__->add_columns(
|
||||
'id', { data_type => 'text', is_nullable => 0 },
|
||||
'ts', { data_type => 'timestamp', default_value => \"current_timestamp", is_nullable => 0 },
|
||||
'expiration', { data_type => 'timestamp', is_nullable => 1 },
|
||||
'language', { data_type => 'text', is_nullable => 0 },
|
||||
'title', { data_type => 'text', is_nullable => 1 },
|
||||
'code', { data_type => 'blob', is_nullable => 0 },
|
||||
'html', { data_type => 'blob', is_nullable => 1 },
|
||||
);
|
||||
__PACKAGE__->set_primary_key('id');
|
||||
|
||||
use Dancer2;
|
||||
__PACKAGE__->load_components(qw/InflateColumn::DateTime/);
|
||||
__PACKAGE__->add_columns(
|
||||
'+ts' => { timezone => config->{tz}, locale => config->{locale} },
|
||||
'+expiration' => { timezone => config->{tz}, locale => config->{locale}, formatter => 'DateTime::Formatter::MySQL' }
|
||||
);
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -0,0 +1,52 @@
|
|||
package App::WerePaste::Util::PygmentsBridge;
|
||||
|
||||
use strict;
|
||||
use Exporter;
|
||||
use vars qw/$VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS/;
|
||||
|
||||
use Carp;
|
||||
|
||||
use Encode qw/decode_utf8/;
|
||||
use Try::Tiny;
|
||||
|
||||
use Inline Python => <<'END_INLINE_PYTHON';
|
||||
from pygments import highlight
|
||||
from pygments.lexers import guess_lexer, get_lexer_by_name
|
||||
from pygments.formatters import HtmlFormatter
|
||||
|
||||
def py_highlight(c,l):
|
||||
return highlight(c,l,HtmlFormatter(linenos=True,anchorlinenos=True,lineanchors="L",linenospecial=10,linespans="L",encoding="utf-8"))
|
||||
|
||||
def py_guesslexer(c):
|
||||
return guess_lexer(c,encoding="utf-8")
|
||||
|
||||
def py_getlexer(l):
|
||||
return get_lexer_by_name(l,encoding="utf-8")
|
||||
|
||||
def py_getnamefromlexer(l):
|
||||
return l.name
|
||||
|
||||
END_INLINE_PYTHON
|
||||
|
||||
$VERSION = 1.0.0;
|
||||
@ISA = qw/Exporter/;
|
||||
@EXPORT = qw//;
|
||||
@EXPORT_OK = qw/PygmentsHighlight/;
|
||||
%EXPORT_TAGS = (all => [@EXPORT_OK]);
|
||||
|
||||
sub PygmentsHighlight {
|
||||
my (%params) = @_;
|
||||
return unless $params{code};
|
||||
my $lexer;
|
||||
try {
|
||||
$lexer = py_getlexer($params{lang}) if $params{lang};
|
||||
} catch {};
|
||||
try {
|
||||
$lexer = py_guesslexer($params{code}) unless $lexer;
|
||||
} catch {};
|
||||
$lexer = py_getlexer('text') unless $lexer;
|
||||
return (py_getnamefromlexer($lexer),decode_utf8(py_highlight($params{code},$lexer)));
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -0,0 +1,26 @@
|
|||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/* Solarized Dark
|
||||
|
||||
For use with Jekyll and Pygments
|
||||
|
||||
http://ethanschoonover.com/solarized
|
||||
|
||||
SOLARIZED HEX ROLE
|
||||
--------- -------- ------------------------------------------
|
||||
base03 #002b36 background
|
||||
base01 #586e75 comments / secondary content
|
||||
base1 #93a1a1 body text / default code / primary content
|
||||
orange #cb4b16 constants
|
||||
red #dc322f regex, special keywords
|
||||
blue #268bd2 reserved keywords
|
||||
cyan #2aa198 strings, numbers
|
||||
green #859900 operators, other keywords
|
||||
*/
|
||||
|
||||
.paste { background-color: #002b36; color: #93a1a1 }
|
||||
.paste .c { color: #586e75 } /* Comment */
|
||||
.paste .err { color: #93a1a1 } /* Error */
|
||||
.paste .g { color: #93a1a1 } /* Generic */
|
||||
.paste .k { color: #859900 } /* Keyword */
|
||||
.paste .l { color: #93a1a1 } /* Literal */
|
||||
.paste .n { color: #93a1a1 } /* Name */
|
||||
.paste .o { color: #859900 } /* Operator */
|
||||
.paste .x { color: #cb4b16 } /* Other */
|
||||
.paste .p { color: #93a1a1 } /* Punctuation */
|
||||
.paste .cm { color: #586e75 } /* Comment.Multiline */
|
||||
.paste .cp { color: #859900 } /* Comment.Preproc */
|
||||
.paste .c1 { color: #586e75 } /* Comment.Single */
|
||||
.paste .cs { color: #859900 } /* Comment.Special */
|
||||
.paste .gd { color: #2aa198 } /* Generic.Deleted */
|
||||
.paste .ge { color: #93a1a1; font-style: italic } /* Generic.Emph */
|
||||
.paste .gr { color: #dc322f } /* Generic.Error */
|
||||
.paste .gh { color: #cb4b16 } /* Generic.Heading */
|
||||
.paste .gi { color: #859900 } /* Generic.Inserted */
|
||||
.paste .go { color: #93a1a1 } /* Generic.Output */
|
||||
.paste .gp { color: #93a1a1 } /* Generic.Prompt */
|
||||
.paste .gs { color: #93a1a1; font-weight: bold } /* Generic.Strong */
|
||||
.paste .gu { color: #cb4b16 } /* Generic.Subheading */
|
||||
.paste .gt { color: #93a1a1 } /* Generic.Traceback */
|
||||
.paste .kc { color: #cb4b16 } /* Keyword.Constant */
|
||||
.paste .kd { color: #268bd2 } /* Keyword.Declaration */
|
||||
.paste .kn { color: #859900 } /* Keyword.Namespace */
|
||||
.paste .kp { color: #859900 } /* Keyword.Pseudo */
|
||||
.paste .kr { color: #268bd2 } /* Keyword.Reserved */
|
||||
.paste .kt { color: #dc322f } /* Keyword.Type */
|
||||
.paste .ld { color: #93a1a1 } /* Literal.Date */
|
||||
.paste .m { color: #2aa198 } /* Literal.Number */
|
||||
.paste .s { color: #2aa198 } /* Literal.String */
|
||||
.paste .na { color: #93a1a1 } /* Name.Attribute */
|
||||
.paste .nb { color: #B58900 } /* Name.Builtin */
|
||||
.paste .nc { color: #268bd2 } /* Name.Class */
|
||||
.paste .no { color: #cb4b16 } /* Name.Constant */
|
||||
.paste .nd { color: #268bd2 } /* Name.Decorator */
|
||||
.paste .ni { color: #cb4b16 } /* Name.Entity */
|
||||
.paste .ne { color: #cb4b16 } /* Name.Exception */
|
||||
.paste .nf { color: #268bd2 } /* Name.Function */
|
||||
.paste .nl { color: #93a1a1 } /* Name.Label */
|
||||
.paste .nn { color: #93a1a1 } /* Name.Namespace */
|
||||
.paste .nx { color: #93a1a1 } /* Name.Other */
|
||||
.paste .py { color: #93a1a1 } /* Name.Property */
|
||||
.paste .nt { color: #268bd2 } /* Name.Tag */
|
||||
.paste .nv { color: #268bd2 } /* Name.Variable */
|
||||
.paste .ow { color: #859900 } /* Operator.Word */
|
||||
.paste .w { color: #93a1a1 } /* Text.Whitespace */
|
||||
.paste .mf { color: #2aa198 } /* Literal.Number.Float */
|
||||
.paste .mh { color: #2aa198 } /* Literal.Number.Hex */
|
||||
.paste .mi { color: #2aa198 } /* Literal.Number.Integer */
|
||||
.paste .mo { color: #2aa198 } /* Literal.Number.Oct */
|
||||
.paste .sb { color: #586e75 } /* Literal.String.Backtick */
|
||||
.paste .sc { color: #2aa198 } /* Literal.String.Char */
|
||||
.paste .sd { color: #93a1a1 } /* Literal.String.Doc */
|
||||
.paste .s2 { color: #2aa198 } /* Literal.String.Double */
|
||||
.paste .se { color: #cb4b16 } /* Literal.String.Escape */
|
||||
.paste .sh { color: #93a1a1 } /* Literal.String.Heredoc */
|
||||
.paste .si { color: #2aa198 } /* Literal.String.Interpol */
|
||||
.paste .sx { color: #2aa198 } /* Literal.String.Other */
|
||||
.paste .sr { color: #dc322f } /* Literal.String.Regex */
|
||||
.paste .s1 { color: #2aa198 } /* Literal.String.Single */
|
||||
.paste .ss { color: #2aa198 } /* Literal.String.Symbol */
|
||||
.paste .bp { color: #268bd2 } /* Name.Builtin.Pseudo */
|
||||
.paste .vc { color: #268bd2 } /* Name.Variable.Class */
|
||||
.paste .vg { color: #268bd2 } /* Name.Variable.Global */
|
||||
.paste .vi { color: #268bd2 } /* Name.Variable.Instance */
|
||||
.paste .il { color: #2aa198 } /* Literal.Number.Integer.Long */
|
|
@ -0,0 +1,62 @@
|
|||
@charset "UTF-8";
|
||||
|
||||
body {
|
||||
font-family: 'lucida console', monospace;
|
||||
font-size: 11px;
|
||||
background:#002b36;
|
||||
color: #586e75;
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-size: 12px;
|
||||
font-family: 'lucida console', monospace;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-top: 1px solid #335e69;
|
||||
border-bottom: 1px solid #335e69;
|
||||
background:#113c47;
|
||||
color: #93a1a1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
a, a:hover, a:visited, a:focus {
|
||||
text-decoration: none;
|
||||
color: #ccf;
|
||||
}
|
||||
.highlighttable {
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
}
|
||||
td {
|
||||
border: 2px solid #335e69;
|
||||
padding: 2px 0;
|
||||
}
|
||||
td.code {
|
||||
width: 100%;
|
||||
border-right: none;
|
||||
border-left: 1px solid #335e69;
|
||||
}
|
||||
td.linenos {
|
||||
border-left: none;
|
||||
border-right: 1px solid #335e69;
|
||||
}
|
||||
td.linenos > .linenodiv > pre > a {
|
||||
display: inline-block;
|
||||
padding-top: 2px;
|
||||
}
|
||||
.highlight > pre > span {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding-top: 2px;
|
||||
}
|
||||
.highlight > pre > span:hover {
|
||||
background-color: #113c47;
|
||||
}
|
||||
.selected {
|
||||
background-color: #335e69;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env sh
|
||||
[ -z "$APP" ] && exit 1
|
||||
cd /home/sites/$APP
|
||||
pkill -F /home/sites/$APP.pid 2>/dev/null
|
||||
plackup -s Starman -D -p 12080 ./bin/app.pl --pid /home/sites/$APP.pid
|
|
@ -0,0 +1,30 @@
|
|||
<form action="/" method="POST">
|
||||
<input type="text" name="title" placeholder="Title (optional)" value="[% paste.title %]" size="40" maxlength="255" />
|
||||
<select class="language" name="lang" style="float: right">
|
||||
<option value="" [% 'selected' UNLESS paste.language %]>Language: Auto</option>
|
||||
<option value="text" [% 'selected' IF paste.language == 'text' %]>Text</option>
|
||||
[% FOR group = settings.languages %]
|
||||
<optgroup label="[% group.keys.0 %]">
|
||||
[% FOR lang = group.values.0 %]
|
||||
[% val = (lang.values.0 || lang.keys.0) | lower %]
|
||||
<option value="[% val | lower %]" [% 'selected' IF paste.language == "${val}" %]>[% lang.keys.0 %]</option>
|
||||
[% END %]
|
||||
</optgroup>
|
||||
[% END %]
|
||||
</select>
|
||||
<br />
|
||||
<textarea name="code" rows="32">[% paste.code %]</textarea>
|
||||
<br />
|
||||
<div style='float: right'>
|
||||
<select class="expiration" name="expiration">
|
||||
<option value="hours:1" >Expire 1 hour from now</option>
|
||||
<option value="hours:6" >Expire 6 hours from now</option>
|
||||
<option value="days:1" >Expire 1 day from now</option>
|
||||
<option value="weeks:1" >Expire 1 week from now</option>
|
||||
<option value="months:1">Expire 1 month from now</option>
|
||||
<option value="years:1" >Expire 1 year from now</option>
|
||||
<option value="never:1" selected>Never expire</option>
|
||||
</select>
|
||||
<button type="submit">Save</button>
|
||||
</div>
|
||||
</form>
|
|
@ -0,0 +1,19 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>[% IF paste %][% paste.title || paste.id %] - [% END %]paste.were.space</title>
|
||||
<link rel="stylesheet" href="/reset.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="/style.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="/solarized256.css" type="text/css"/>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id='nav'>
|
||||
<a href="/">new paste</a>[% IF paste %] | <a href="/[% paste.id %]/copy">duplicate paste</a> | <a href="/[% paste.id %]/raw">raw paste data</a>[% END %] | v4: <span id='addr'></span> | v6: <span id='addr6'></span><br />
|
||||
<span id='blurb'><a href="https://github.com/MaffC/WerePaste">App::WerePaste</a>. Abuse of this service will result in the innocent losing out.</span>
|
||||
</div>
|
||||
<br />
|
||||
[% content %]
|
||||
<script type='text/javascript'>var x4=x6=null;function ip(v){var x=new XMLHttpRequest();x.onreadystatechange=rt;x.open('GET','http://ip'+v+'.maff.scot/',true);x.send(null);v==6? x6=x : x4=x;};function rt(){if(x4!=null&&x4.status===200){document.getElementById('addr').textContent=x4.responseText;};if(x6!=null&&x6.status===200){document.getElementById('addr6').textContent=x6.responseText;}};ip(4);ip(6);</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
<h1>[% paste.title %]</h1>
|
||||
<span id='dates'>Pasted at <b>[% paste.ts.hms %], [% paste.ts.dmy %]</b>
|
||||
[% IF paste.expiration %] | Expires at <b>[% paste.expiration.hms %], [% paste.expiration.dmy %]</b>[% END %] | Language: [% paste.language %]</span>
|
||||
<br />
|
||||
<br />
|
||||
<div class="paste">
|
||||
[% IF paste.html %]
|
||||
[% paste.html %]
|
||||
[% ELSE %]
|
||||
<pre>[% paste.code %]</pre>
|
||||
[% END %]
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function highlight_line() {
|
||||
var lnum = window.location.hash.match(/L-\d+/);
|
||||
if(!lnum) { return; }
|
||||
$('.linenos a').removeClass('selected');
|
||||
$('.highlight span').removeClass('selected');
|
||||
$('.linenos a[href="#'+lnum+'"]').addClass('selected');
|
||||
$('.highlight span[id="'+lnum+'"]').addClass('selected');
|
||||
}
|
||||
$(document).ready(function() {
|
||||
window.onhashchange = highlight_line;
|
||||
if(location.hash.indexOf("#L")===0){highlight_line();}
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue