summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindex.cgi385
1 files changed, 191 insertions, 194 deletions
diff --git a/index.cgi b/index.cgi
index 102aaa4..9cc79e1 100755
--- a/index.cgi
+++ b/index.cgi
@@ -5,7 +5,7 @@ use strict;
use warnings;
use POSIX 'strftime', 'ceil', 'floor';
use Socket 'inet_pton', 'inet_ntop', 'AF_INET', 'AF_INET6';
-use TUWF ':html', 'html_escape';
+use TUWF ':html5', 'html_escape', 'mkclass';
my @syntax = sort map /([^\/]+)\.vim$/?$1:(),
@@ -98,16 +98,12 @@ TUWF::post '/' => sub {
TUWF::get '/' => sub {
- htmlHeader('mypastes');
- htmlUploadForm();
- htmlFooter();
+ template(['mypastes'], \&html_upload_form);
};
TUWF::get qr{/copy/$code_re} => sub {
- htmlHeader('mypastes');
- htmlUploadForm(tuwf->capture(0));
- htmlFooter();
+ template(['mypastes'], sub { html_upload_form(tuwf->capture(0)) });
};
@@ -129,35 +125,37 @@ TUWF::post '/mypastes' => sub {
}
my $cnt = ceil(tuwf->dbRow('SELECT count(*) AS cnt FROM pastes WHERE passcode = ?', $p)->{cnt} / 100);
- htmlHeader('mypastes', 'newpaste');
- Tr;
- td class => 'ff', ' ';
- td class => 'top';
- b 'Listing all your pastes:';
- table class => 'mypastelist';
- for(@$pl) {
- use utf8;
- Tr;
- td class => 'mpldate', strftime '%F %T', gmtime $_->{date};
- td class => 'mplcode'; a href => "/$_->{code}", substr($_->{code}, 0, 5).(length $_->{code} > 5 ? '…':''); end;
- td class => 'mplsyn', $_->{syntax};
- td class => 'mplsize', sprintf '%.1fk', $_->{size}/1024;
- td class => 'mplprev', $_->{preview};
- end;
- }
- end;
- if($f->{p} > 1 || $cnt > 1) {
- form method => 'POST', action => '/mypastes', class => 'pagination';
- input type => 'hidden', name => 'pc', value => $p;
- b 'Page: ';
- input type => 'submit', name => 'p', value => $_ for (1..($f->{p} - 1));
- txt " $f->{p} ";
- input type => 'submit', name => 'p', value => $_ for(($f->{p}+1)..$cnt);
- end;
- }
- end;
- end 'tr';
- htmlFooter();
+ template(['mypastes', 'newpaste'], sub {
+ Tr sub {
+ Td class => 'ff', ' ';
+ Td class => 'top', sub {
+ B 'Listing all your pastes:';
+ Table class => 'mypastelist', sub {
+ for(@$pl) {
+ use utf8;
+ Tr sub {
+ Td class => 'mpldate', strftime '%F %T', gmtime $_->{date};
+ Td class => 'mplcode', sub {
+ A href => "/$_->{code}", substr($_->{code}, 0, 5).(length $_->{code} > 5 ? '…':'');
+ };
+ Td class => 'mplsyn', $_->{syntax};
+ Td class => 'mplsize', sprintf '%.1fk', $_->{size}/1024;
+ Td class => 'mplprev', $_->{preview};
+ };
+ }
+ };
+ if($f->{p} > 1 || $cnt > 1) {
+ Form method => 'POST', action => '/mypastes', class => 'pagination', sub {
+ Input type => 'hidden', name => 'pc', value => $p;
+ B 'Page: ';
+ Input type => 'submit', name => 'p', value => $_ for (1..($f->{p} - 1));
+ txt " $f->{p} ";
+ Input type => 'submit', name => 'p', value => $_ for(($f->{p}+1)..$cnt);
+ };
+ }
+ };
+ };
+ });
};
@@ -177,25 +175,25 @@ TUWF::get qr{/$code_re} => sub {
my $cnt = ($r->{raw} =~ y/\n/\n/);
$cnt += 1 if $r->{raw} !~ /\n$/;
- htmlHeader(\$code, 'mypastes', 'newpaste');
- Tr;
- td class => 'numbers';
- if(!$r->{wrap}) {
- pre;
- for (1..$cnt) {
- a name => "r$_", href => "#r$_", $_;
- lit "\n";
- }
- end;
- }
- end;
- td class => 'top code';
- pre $r->{wrap} ? (class => 'allowwrap') : ();
- lit get_html($r);
- end;
- end;
- end 'tr';
- htmlFooter();
+ template([\$code, 'mypastes', 'newpaste'], sub {
+ Tr sub {
+ Td class => 'numbers', sub {
+ if(!$r->{wrap}) {
+ Pre sub {
+ for (1..$cnt) {
+ A name => "r$_", href => "#r$_", $_;
+ lit "\n";
+ }
+ };
+ }
+ };
+ Td class => 'top code', sub {
+ Pre mkclass(allowwrap => $r->{wrap}), sub {
+ lit get_html($r);
+ };
+ };
+ };
+ });
};
@@ -250,47 +248,46 @@ sub get_html {
}
-sub htmlHeader {
- my @links = @_;
- html lang => 'en';
- head;
- title 'Blicky.net pastebin';
- Link rel => 'stylesheet', type => 'text/css', href => '/style.css';
- meta name => 'robots', content => 'noindex, nofollow', undef;
- end;
- body;
- div id => 'leftdiv', '';
- div id => 'toplinks';
- for(@links) {
- txt ' ';
- if(ref($_)) {
- a href => '#', onclick => "return unpaste('/$$_')", 'unpaste';
- txt ' ';
- a href => "/$$_.txt", 'raw';
- txt ' ';
- a href => "/copy/$$_", 'copy';
- } else {
- /newpaste/ && a href => '/', 'new paste';
- /mypastes/ && a href => '#', onclick => 'return mypastes()', 'my pastes';
- }
- }
- end;
- table;
- Tr; td colspan => 2, class => 'header';
- h1 'Blicky.net pastebin';
- end; end;
-}
-
-
-sub htmlFooter {
- end 'table';
- script type => 'text/javascript', src => '/script.js', '';
- end 'body';
- end 'html';
+sub template {
+ my($links, $content) = @_;
+ Html lang => 'en', sub {
+ Head sub {
+ Title 'Blicky.net pastebin';
+ Link rel => 'stylesheet', type => 'text/css', href => '/style.css';
+ Meta name => 'robots', content => 'noindex, nofollow', undef;
+ };
+ Body sub {
+ Div id => 'leftdiv', '';
+ Div id => 'toplinks', sub {
+ for(@$links) {
+ txt ' ';
+ if(ref($_)) {
+ A href => '#', onclick => "return unpaste('/$$_')", 'unpaste';
+ txt ' ';
+ A href => "/$$_.txt", 'raw';
+ txt ' ';
+ A href => "/copy/$$_", 'copy';
+ } else {
+ /newpaste/ && A href => '/', 'new paste';
+ /mypastes/ && A href => '#', onclick => 'return mypastes()', 'my pastes';
+ }
+ }
+ };
+ Table sub {
+ Tr sub {
+ Td colspan => 2, class => 'header', sub {
+ H1 'Blicky.net pastebin';
+ };
+ };
+ $content->();
+ };
+ Script type => 'text/javascript', src => '/script.js', '';
+ };
+ };
}
-sub htmlUploadForm {
+sub html_upload_form {
my $copy = shift;
my $r = $copy
@@ -299,94 +296,94 @@ sub htmlUploadForm {
return if !ref $r;
use utf8;
- Tr;
- td class => 'ff', '';
- td class => 'top';
- form enctype => 'multipart/form-data', 'accept-charset' => 'utf-8', method => 'post', action => '/';
-
- fieldset;
- legend '▾ Contents';
- textarea name => 'f', id => 'f', $r->{raw};
- br;
- input type => 'submit', value => 'Submit', id => 'submit';
- txt '-or- ';
- input type => 'file', name => 'u', id => 'u';
- i ' (UTF-8, max. ~1MiB)';
- end;
-
- fieldset;
- legend '▾ Options';
- a href => '#', id => 'formatsave', 'save as default';
- input type => 'checkbox', class => 'check', id => 'w', name => 'w', value => 1, $r->{wrap} ? (checked => 'checked') : ();
- label for => 'w', ' allow line wrapping';
- br;
- input type => 'checkbox', class => 'check', id => 'c', name => 'c', value => 1, $r->{parse_urls} ? (checked => 'checked') : ();
- label for => 'c', ' make URLs clickable';
- br;
- i 'Syntax highlighting: ';
- input type => 'text', name => 's', id => 's', size => 10, value => $r->{syntax};
- i;
- txt ' Popular: ';
- b class => 'syntax';
- for (@{ tuwf->dbAll('SELECT syntax FROM syntaxes ORDER BY cnt DESC LIMIT 7') }) {
- a href => '#', onclick => 'return setsyn(this)', $_->{syntax};
- txt ' ';
- }
- end;
- txt '| ';
- a href => '#', onclick => 'return showall()', 'Show all »';
- end 'i';
- div id => 'syntax', style => 'display: none';
- for (@syntax) {
- a href => '#', onclick => 'return setsyn(this)', $_;
- txt ' ';
- }
- end;
- end 'fieldset';
-
- fieldset;
- legend '▾ Passcode';
- label for => 'p', 'Passcode: ';
- input type => 'password', name => 'p', id => 'p', size => 10;
- input type => 'checkbox', class => 'check', id => 'ps', name => 'ps', value => 1;
- label for => 'ps', ' save on my computer';
- br;
- i;
- txt '(Optional, necessary for listing and/or removing your pastes.)';
- br;
- b 'Important:';
- txt ' make sure your passcode is not something other people are likely to use.'
- .' For example, use "nickname-asdf" instead of "asdf".';
- end;
- end 'fieldset';
- end 'form';
-
- fieldset;
- legend '▾ Info';
- ul;
- li "Pastes don't expire.";
- li 'All pastes are private, that is, nobody can find your paste unless they know the URL or the passcode.';
- li;
- txt 'If you absolutely need to have a paste removed from this site, and you lost your passcode, send a mail to ';
- a href => 'mailto:ayo@blicky.net', 'ayo@blicky.net';
- txt '.';
- end;
- li;
- txt 'Want to paste stuff from the commandline? We have a ';
- a href => '/bpaste.sh', 'script';
- txt ' for that.';
- end;
- li 'Code highlighting is provided by vim.';
- li;
- txt 'This website is ';
- a href => 'https://g.blicky.net/bpaste.git', 'open source';
- txt '.';
- end;
- end;
- end 'fieldset';
-
- end 'td';
- end 'tr';
+ Tr sub {
+ Td class => 'ff', '';
+ Td class => 'top', sub {
+ Form enctype => 'multipart/form-data', 'accept-charset' => 'utf-8', method => 'post', action => '/', sub {
+
+ Fieldset sub {
+ Legend '▾ Contents';
+ Textarea name => 'f', id => 'f', $r->{raw};
+ Br;
+ Input type => 'submit', value => 'Submit', id => 'submit';
+ txt '-or- ';
+ Input type => 'file', name => 'u', id => 'u';
+ I ' (UTF-8, max. ~1MiB)';
+ };
+
+ Fieldset sub {
+ Legend '▾ Options';
+ A href => '#', id => 'formatsave', 'save as default';
+ Input type => 'checkbox', class => 'check', id => 'w', name => 'w', value => 1, $r->{wrap} ? (checked => 'checked') : ();
+ Label for => 'w', ' allow line wrapping';
+ Br;
+ Input type => 'checkbox', class => 'check', id => 'c', name => 'c', value => 1, $r->{parse_urls} ? (checked => 'checked') : ();
+ Label for => 'c', ' make URLs clickable';
+ Br;
+ I 'Syntax highlighting: ';
+ Input type => 'text', name => 's', id => 's', size => 10, value => $r->{syntax};
+ I sub {;
+ txt ' Popular: ';
+ B class => 'syntax', sub {
+ for (@{ tuwf->dbAll('SELECT syntax FROM syntaxes ORDER BY cnt DESC LIMIT 7') }) {
+ A href => '#', onclick => 'return setsyn(this)', $_->{syntax};
+ txt ' ';
+ }
+ };
+ txt '| ';
+ A href => '#', onclick => 'return showall()', 'Show all »';
+ };
+ Div id => 'syntax', style => 'display: none', sub {
+ for (@syntax) {
+ A href => '#', onclick => 'return setsyn(this)', $_;
+ txt ' ';
+ }
+ };
+ };
+
+ Fieldset sub {
+ Legend '▾ Passcode';
+ Label for => 'p', 'Passcode: ';
+ Input type => 'password', name => 'p', id => 'p', size => 10;
+ Input type => 'checkbox', class => 'check', id => 'ps', name => 'ps', value => 1;
+ Label for => 'ps', ' save on my computer';
+ Br;
+ I sub {
+ txt '(Optional, necessary for listing and/or removing your pastes.)';
+ Br;
+ B 'Important:';
+ txt ' make sure your passcode is not something other people are likely to use.'
+ .' For example, use "nickname-asdf" instead of "asdf".';
+ };
+ };
+ };
+
+ Fieldset sub {
+ Legend '▾ Info';
+ Ul sub {
+ Li "Pastes don't expire.";
+ Li 'All pastes are private, that is, nobody can find your paste unless they know the URL or the passcode.';
+ Li sub {
+ txt 'If you absolutely need to have a paste removed from this site, and you lost your passcode, send a mail to ';
+ A href => 'mailto:ayo@blicky.net', 'ayo@blicky.net';
+ txt '.';
+ };
+ Li sub {
+ txt 'Want to paste stuff from the commandline? We have a ';
+ A href => '/bpaste.sh', 'script';
+ txt ' for that.';
+ };
+ Li 'Code highlighting is provided by vim.';
+ Li sub {
+ txt 'This website is ';
+ A href => 'https://g.blicky.net/bpaste.git', 'open source';
+ txt '.';
+ };
+ };
+ };
+
+ };
+ };
}
@@ -445,19 +442,19 @@ sub getpaste {
sub msg {
my($msg, $back) = @_;
tuwf->resInit;
- htmlHeader('mypastes', 'newpaste');
- Tr;
- td class => 'numbers', '';
- td class => 'top';
- br;
- lit html_escape $msg;
- if($back) {
- br;
- a href => 'javascript:history.go(-1)', 'Back to the form';
- }
- end;
- end 'tr';
- htmlFooter;
+ template(['mypastes', 'newpaste'], sub {
+ Tr sub {
+ Td class => 'numbers', '';
+ Td class => 'top', sub {
+ Br;
+ lit html_escape $msg;
+ if($back) {
+ Br;
+ A href => 'javascript:history.go(-1)', 'Back to the form';
+ }
+ };
+ };
+ });
return 1;
}