diff options
Diffstat (limited to 'lib/VNDB/Handler')
-rw-r--r-- | lib/VNDB/Handler/Discussions.pm | 57 | ||||
-rw-r--r-- | lib/VNDB/Handler/Misc.pm | 117 | ||||
-rw-r--r-- | lib/VNDB/Handler/Producers.pm | 69 | ||||
-rw-r--r-- | lib/VNDB/Handler/Releases.pm | 108 | ||||
-rw-r--r-- | lib/VNDB/Handler/Tags.pm | 193 | ||||
-rw-r--r-- | lib/VNDB/Handler/ULists.pm | 100 | ||||
-rw-r--r-- | lib/VNDB/Handler/Users.pm | 102 | ||||
-rw-r--r-- | lib/VNDB/Handler/VNBrowse.pm | 30 | ||||
-rw-r--r-- | lib/VNDB/Handler/VNEdit.pm | 119 | ||||
-rw-r--r-- | lib/VNDB/Handler/VNPage.pm | 42 |
10 files changed, 465 insertions, 472 deletions
diff --git a/lib/VNDB/Handler/Discussions.pm b/lib/VNDB/Handler/Discussions.pm index 0b5daa6c..6f6cb385 100644 --- a/lib/VNDB/Handler/Discussions.pm +++ b/lib/VNDB/Handler/Discussions.pm @@ -3,15 +3,15 @@ package VNDB::Handler::Discussions; use strict; use warnings; -use YAWF ':html', 'xml_escape'; +use TUWF ':html', 'xml_escape'; use POSIX 'ceil'; use VNDB::Func; -YAWF::register( +TUWF::register( qr{t([1-9]\d*)(?:/([1-9]\d*))?} => \&thread, qr{t([1-9]\d*)\.([1-9]\d*)} => \&redirect, - qr{t/(db|an|ge|[vpu])([1-9]\d*)?} => \&board, + qr{t/(all|db|an|ge|[vpu])([1-9]\d*)?} => \&board, qr{t([1-9]\d*)/reply} => \&edit, qr{t([1-9]\d*)\.([1-9]\d*)/edit} => \&edit, qr{t/(db|an|ge|[vpu])([1-9]\d*)?/new} => \&edit, @@ -24,10 +24,10 @@ sub thread { $page ||= 1; my $t = $self->dbThreadGet(id => $tid, what => 'boardtitles')->[0]; - return 404 if !$t->{id} || $t->{hidden} && !$self->authCan('boardmod'); + return $self->resNotFound if !$t->{id} || $t->{hidden} && !$self->authCan('boardmod'); my $p = $self->dbPostGet(tid => $tid, results => 25, page => $page, what => 'user'); - return 404 if !$p->[0]; + return $self->resNotFound if !$p->[0]; $self->htmlHeader(title => $t->{title}, noindex => 1); div class => 'mainbox'; @@ -46,7 +46,7 @@ sub thread { end; } end; - end; + end 'div'; $self->htmlBrowseNavigate("/t$tid/", $page, [ $t->{count}, 25 ], 't', 1); div class => 'mainbox thread'; @@ -82,7 +82,7 @@ sub thread { end; } end; - end; + end 'div'; $self->htmlBrowseNavigate("/t$tid/", $page, [ $t->{count}, 25 ], 'b', 1); if($t->{locked}) { @@ -105,7 +105,7 @@ sub thread { input type => 'submit', value => mt('_thread_quickreply_full'), class => 'submit', name => 'fullreply'; end; end; - end; + end 'form'; } elsif(!$self->authCan('board')) { div class => 'mainbox'; h1 mt '_thread_noreply_title'; @@ -135,7 +135,7 @@ sub edit { # in case we start a new thread, parse boards my $board = ''; if($tid !~ /^\d+$/) { - return 404 if $tid =~ /(db|an|ge)/ && $num || $tid =~ /[vpu]/ && !$num; + return $self->resNotFound if $tid =~ /(db|an|ge)/ && $num || $tid =~ /[vpu]/ && !$num; $board = $tid.($num||''); $tid = 0; $num = 0; @@ -143,10 +143,10 @@ sub edit { # get thread and post, if any my $t = $tid && $self->dbThreadGet(id => $tid, what => 'boards')->[0]; - return 404 if $tid && !$t->{id}; + return $self->resNotFound if $tid && !$t->{id}; my $p = $num && $self->dbPostGet(tid => $tid, num => $num, what => 'user')->[0]; - return 404 if $num && !$p->{num}; + return $self->resNotFound if $num && !$p->{num}; # are we allowed to perform this action? return $self->htmlDenied if !$self->authCan('board') @@ -159,16 +159,16 @@ sub edit { return if !$self->authCheckCode; $frm = $self->formValidate( !$tid || $num == 1 ? ( - { name => 'title', maxlength => 50 }, - { name => 'boards', maxlength => 50 }, + { post => 'title', maxlength => 50 }, + { post => 'boards', maxlength => 50 }, ) : (), $self->authCan('boardmod') ? ( - { name => 'locked', required => 0 }, - { name => 'hidden', required => 0 }, - { name => 'nolastmod', required => 0 }, + { post => 'locked', required => 0 }, + { post => 'hidden', required => 0 }, + { post => 'nolastmod', required => 0 }, ) : (), - { name => 'msg', maxlenght => 5000 }, - { name => 'fullreply', required => 0 }, + { post => 'msg', maxlength => 32768 }, + { post => 'fullreply', required => 0 }, ); $frm->{_err} = 1 if $frm->{fullreply}; @@ -270,23 +270,23 @@ sub edit { sub board { my($self, $type, $iid) = @_; $iid ||= ''; - return 404 if $type =~ /(db|an|ge)/ && $iid; + return $self->resNotFound if $type =~ /(db|an|ge|all)/ && $iid; my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' }, + { get => 'p', required => 0, default => 1, template => 'int' }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; my $obj = !$iid ? undef : $type eq 'u' ? $self->dbUserGet(uid => $iid, what => 'hide_list')->[0] : $type eq 'p' ? $self->dbProducerGet(id => $iid)->[0] : $self->dbVNGet(id => $iid)->[0]; - return 404 if $iid && !$obj; + return $self->resNotFound if $iid && !$obj; my $ititle = $obj && ($obj->{title}||$obj->{name}||$obj->{username}); - my $title = !$obj ? mt("_dboard_$type") : mt '_disboard_item_title', $ititle; + my $title = !$obj ? mt($type eq 'all' ? '_disboard_item_all' : "_dboard_$type") : mt '_disboard_item_title', $ititle; my($list, $np) = $self->dbThreadGet( - type => $type, + $type ne 'all' ? (type => $type) : (), $iid ? (iid => $iid) : (), results => 50, page => $f->{p}, @@ -302,7 +302,7 @@ sub board { p; a href => '/t', mt '_disboard_rootlink'; txt ' > '; - a href => "/t/$type", mt "_dboard_$type"; + a href => "/t/$type", mt $type eq 'all' ? '_disboard_item_all' : "_dboard_$type"; if($iid) { txt ' > '; a style => 'font-weight: bold', href => "/t/$type$iid", "$type$iid"; @@ -316,10 +316,10 @@ sub board { br; br; a href => "/t/$type$iid/new", mt '_disboard_createyourown'; } else { - a href => '/t/'.($iid ? $type.$iid : $type ne 'ge' ? 'db' : $type).'/new', mt '_disboard_startnew'; + a href => '/t/'.($iid ? $type.$iid : $type ne 'ge' ? 'db' : $type).'/new', mt '_disboard_startnew' if $type ne 'all'; } end; - end; + end 'div'; _threadlist($self, $list, $f, $np, "/t/$type$iid", $type.$iid) if @$list; @@ -334,6 +334,7 @@ sub index { div class => 'mainbox'; h1 mt '_disindex_title'; p class => 'browseopts'; + a href => '/t/all', mt '_disboard_item_all'; a href => '/t/'.$_, mt "_dboard_$_" for (@{$self->{discussion_boards}}); end; @@ -400,7 +401,7 @@ sub _threadlist { lit $self->{l10n}->date($o->{ldate}); end; end; - end; + end 'tr'; } ); } diff --git a/lib/VNDB/Handler/Misc.pm b/lib/VNDB/Handler/Misc.pm index 5df5ab10..062e3ae4 100644 --- a/lib/VNDB/Handler/Misc.pm +++ b/lib/VNDB/Handler/Misc.pm @@ -4,18 +4,17 @@ package VNDB::Handler::Misc; use strict; use warnings; -use YAWF ':html', ':xml', 'xml_escape'; +use TUWF ':html', ':xml', 'xml_escape', 'uri_escape'; use VNDB::Func; use POSIX 'strftime'; -YAWF::register( +TUWF::register( qr{}, \&homepage, qr{(?:([upvr])([1-9]\d*)/)?hist}, \&history, qr{d([1-9]\d*)}, \&docpage, qr{setlang}, \&setlang, qr{nospam}, \&nospam, - qr{we-dont-like-ie}, \&iemessage, qr{xml/prefs\.xml}, \&prefs, qr{opensearch\.xml}, \&opensearch, @@ -23,7 +22,7 @@ YAWF::register( qr{u([1-9]\d*)/tags}, sub { $_[0]->resRedirect("/g/links?u=$_[1]", 'perm') }, qr{(.*[^/]+)/+}, sub { $_[0]->resRedirect("/$_[1]", 'perm') }, qr{([pv])}, sub { $_[0]->resRedirect("/$_[1]/all", 'perm') }, - qr{v/search}, sub { $_[0]->resRedirect("/v/all?q=".uri_escape($_[0]->reqParam('q')||''), 'perm') }, + qr{v/search}, sub { $_[0]->resRedirect("/v/all?q=".uri_escape($_[0]->reqGet('q')||''), 'perm') }, qr{notes}, sub { $_[0]->resRedirect('/d8', 'perm') }, qr{faq}, sub { $_[0]->resRedirect('/d6', 'perm') }, qr{v([1-9]\d*)/(?:stats|scr)}, @@ -61,7 +60,7 @@ sub homepage { end; } end; - end; + end 'div'; table class => 'mainbox threelayout'; Tr; @@ -83,7 +82,7 @@ sub homepage { end; } end; - end; + end 'td'; # Announcements td; @@ -101,12 +100,12 @@ sub homepage { lit bb2html $post->{msg}, 150; end; } - end; + end 'td'; # Recent posts td; h1; - a href => '/t', mt '_home_recentposts'; txt ' '; + a href => '/t/all', mt '_home_recentposts'; txt ' '; a href => '/feeds/posts.atom'; cssicon 'feed', mt '_atom_feed'; end; end; my $posts = $self->dbThreadGet(what => 'lastpost boardtitles', results => 10, sort => 'lastpost', reverse => 1, notusers => 1); @@ -121,9 +120,9 @@ sub homepage { end; } end; - end; + end 'td'; - end; + end 'tr'; Tr; # Random visual novels @@ -139,14 +138,14 @@ sub homepage { end; } end; - end; + end 'td'; # Upcoming releases td; h1; - a href => strftime('/r?fil=date_after-%Y%m%d;o=a;s=released', gmtime), mt '_home_upcoming'; + a href => '/r?fil=released-0;o=a;s=released', mt '_home_upcoming'; end; - my $upcoming = $self->filFetchDB(release => undef, undef, {results => 10, unreleased => 1, what => 'platforms'}); + my $upcoming = $self->filFetchDB(release => undef, undef, {results => 10, released => 0, what => 'platforms'}); ul; for (@$upcoming) { li; @@ -159,14 +158,14 @@ sub homepage { end; } end; - end; + end 'td'; # Just released td; h1; - a href => strftime('/r?fil=date_before-%Y%m%d;o=d;s=released', gmtime), mt '_home_justreleased'; + a href => '/r?fil=released-1;o=d;s=released', mt '_home_justreleased'; end; - my $justrel = $self->filFetchDB(release => undef, undef, {results => 10, sort => 'released', reverse => 1, unreleased => 0, what => 'platforms'}); + my $justrel = $self->filFetchDB(release => undef, undef, {results => 10, sort => 'released', reverse => 1, released => 1, what => 'platforms'}); ul; for (@$justrel) { li; @@ -179,10 +178,10 @@ sub homepage { end; } end; - end; + end 'td'; - end; # /tr - end; # /table + end 'tr'; + end 'table'; $self->htmlFooter; } @@ -194,14 +193,14 @@ sub history { $id ||= 0; my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'm', required => 0, default => !$type, enum => [ 0, 1 ] }, - { name => 'h', required => 0, default => 0, enum => [ -1..1 ] }, - { name => 't', required => 0, default => '', enum => [ 'v', 'r', 'p' ] }, - { name => 'e', required => 0, default => 0, enum => [ -1..1 ] }, - { name => 'r', required => 0, default => 0, enum => [ 0, 1 ] }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'm', required => 0, default => !$type, enum => [ 0, 1 ] }, + { get => 'h', required => 0, default => 0, enum => [ -1..1 ] }, + { get => 't', required => 0, default => '', enum => [ 'v', 'r', 'p' ] }, + { get => 'e', required => 0, default => 0, enum => [ -1..1 ] }, + { get => 'r', required => 0, default => 0, enum => [ 0, 1 ] }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; # get item object and title my $obj = $type eq 'u' ? $self->dbUserGet(uid => $id, what => 'hide_list')->[0] : @@ -209,7 +208,7 @@ sub history { $type eq 'r' ? $self->dbReleaseGet(id => $id)->[0] : $type eq 'v' ? $self->dbVNGet(id => $id)->[0] : undef; my $title = mt $type ? ('_hist_title_item', $obj->{title} || $obj->{name} || $obj->{username}) : '_hist_title'; - return 404 if $type && !$obj->{id}; + return $self->resNotFound if $type && !$obj->{id}; # get the edit history my($list, $np) = $self->dbRevisionGet( @@ -274,7 +273,7 @@ sub history { a $f->{r} ? (class => 'optselected') : (), href => $u->(r => 1), mt '_hist_filter_increl'; end; } - end; + end 'div'; $self->htmlBrowseHist($list, $f, $np, $u->()); $self->htmlFooter; @@ -287,7 +286,7 @@ sub docpage { my $l = '.'.$self->{l10n}->language_tag(); my $f = sprintf('%s/data/docs/%d', $VNDB::ROOT, $did); my $F; - open($F, '<:utf8', $f.$l) or open($F, '<:utf8', $f) or return 404; + open($F, '<:utf8', $f.$l) or open($F, '<:utf8', $f) or return $self->resNotFound; my @c = <$F>; close $F; @@ -343,8 +342,8 @@ sub docpage { sub setlang { my $self = shift; - my $lang = $self->formValidate({name => 'lang', required => 1, enum => [ VNDB::L10N::languages ]}); - return 404 if $lang->{_err}; + my $lang = $self->formValidate({get => 'lang', required => 1, enum => [ VNDB::L10N::languages ]}); + return $self->resNotFound if $lang->{_err}; $lang = $lang->{lang}; my $browser = VNDB::L10N->get_handle()->language_tag(); @@ -354,9 +353,7 @@ sub setlang { if($lang ne $self->{l10n}->language_tag()) { $self->authInfo->{id} ? $self->authPref(l10n => $lang eq $browser ? undef : $lang) - : $self->resHeader('Set-Cookie', sprintf 'l10n=%s; expires=%s; path=/; domain=%s', - $lang, $lang eq $browser ? 'Sat, 01-Jan-2000 00:00:00 GMT' : 'Sat, 01-Jan-2030 00:00:00 GMT', - $self->{cookie_domain}); + : $self->resCookie(l10n => $lang eq $browser ? undef : $lang, expires => time()+31536000); } } @@ -377,57 +374,15 @@ sub nospam { } -sub iemessage { - my $self = shift; - - if($self->reqParam('i-still-want-access')) { - (my $ref = $self->reqHeader('Referer') || '/') =~ s/^\Q$self->{url}//; - $ref = '/' if $ref eq '/we-dont-like-ie'; - $self->resRedirect($ref, 'temp'); - $self->resHeader('Set-Cookie', "ie-sucks=1; path=/; domain=$self->{cookie_domain}"); - return; - } - - html; - head; - title 'Your browser sucks'; - style type => 'text/css', - q|body { background: black }| - .q|div { position: absolute; left: 50%; top: 50%; width: 500px; margin-left: -250px; height: 180px; margin-top: -90px; background-color: #012; border: 1px solid #258; text-align: center; }| - .q|p { color: #ddd; margin: 10px; font: 9pt "Tahoma"; }| - .q|h1 { color: #258; font-size: 14pt; font-family: "Futura", "Century New Gothic", "Arial", Serif; font-weight: normal; margin: 10px 0 0 0; } | - .q|a { color: #fff }|; - end; - body; - div; - h1 'Oops, we were too lazy to support your browser!'; - p; - lit qq|We decided to stop supporting Internet Explorer 6 and 7, as it's a royal pain in | - .qq|the ass to make our site look good in a browser that doesn't want to cooperate with us.<br />| - .qq|You can try one of the following free alternatives: | - .qq|<a href="http://www.mozilla.com/firefox/">Firefox</a>, | - .qq|<a href="http://www.opera.com/">Opera</a>, | - .qq|<a href="http://www.apple.com/safari/">Safari</a>, or | - .qq|<a href="http://www.google.com/chrome">Chrome</a>.<br /><br />| - .qq|If you're really stubborn about using Internet Explorer, upgrading to version 8 will also work.<br /><br />| - .qq|...and if you're mad, you can also choose to ignore this warning and | - .qq|<a href="/we-dont-like-ie?i-still-want-access=1">open the site anyway</a>.|; - end; - end; - end; - end; -} - - sub prefs { my $self = shift; return if !$self->authCheckCode; - return 404 if !$self->authInfo->{id}; + return $self->resNotFound if !$self->authInfo->{id}; my $f = $self->formValidate( - { name => 'key', enum => [qw|filter_vn filter_release|] }, - { name => 'value', required => 0, maxlength => 2000 }, + { get => 'key', enum => [qw|filter_vn filter_release|] }, + { get => 'value', required => 0, maxlength => 2000 }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; $self->authPref($f->{key}, $f->{value}); # doesn't really matter what we return, as long as it's XML @@ -452,7 +407,7 @@ sub opensearch { tag 'Url', type => 'application/opensearchdescription+xml', rel => 'self', template => $self->{url}.'/opensearch.xml', undef; tag 'Query', role => 'example', searchTerms => 'Tsukihime', undef; tag 'moz:SearchForm', $self->{url}.'/v/all'; - end; + end 'OpenSearchDescription'; } diff --git a/lib/VNDB/Handler/Producers.pm b/lib/VNDB/Handler/Producers.pm index f7a46c2d..5030c1a3 100644 --- a/lib/VNDB/Handler/Producers.pm +++ b/lib/VNDB/Handler/Producers.pm @@ -3,11 +3,11 @@ package VNDB::Handler::Producers; use strict; use warnings; -use YAWF ':html', ':xml', 'xml_escape'; +use TUWF ':html', ':xml', 'xml_escape', 'html_escape'; use VNDB::Func; -YAWF::register( +TUWF::register( qr{p([1-9]\d*)/rg} => \&rg, qr{p([1-9]\d*)(?:\.([1-9]\d*))?} => \&page, qr{p(?:([1-9]\d*)(?:\.([1-9]\d*))?/edit|/new)} @@ -21,7 +21,7 @@ sub rg { my($self, $pid) = @_; my $p = $self->dbProducerGet(id => $pid, what => 'relgraph')->[0]; - return 404 if !$p->{id} || !$p->{rgraph}; + return $self->resNotFound if !$p->{id} || !$p->{rgraph}; my $title = mt '_prodrg_title', $p->{name}; return if $self->htmlRGHeader($title, 'p', $p); @@ -40,6 +40,7 @@ sub rg { $self->htmlFooter; } + sub page { my($self, $pid, $rev) = @_; @@ -48,7 +49,7 @@ sub page { what => 'extended relations'.($rev ? ' changes' : ''), $rev ? ( rev => $rev ) : () )->[0]; - return 404 if !$p->{id}; + return $self->resNotFound if !$p->{id}; $self->htmlHeader(title => $p->{name}, noindex => $rev); $self->htmlMainTabs(p => $p); @@ -82,34 +83,34 @@ sub page { h2 class => 'alttitle', $p->{original} if $p->{original}; p class => 'center'; txt mt '_prodpage_langtype', mt("_lang_$p->{lang}"), mt "_ptype_$p->{type}"; - txt "\n".mt '_prodpage_aliases', $p->{alias} if $p->{alias}; + lit '<br />'.html_escape mt '_prodpage_aliases', $p->{alias} if $p->{alias}; my @links = ( $p->{website} ? [ 'homepage', $p->{website} ] : (), $p->{l_wp} ? [ 'wikipedia', "http://en.wikipedia.org/wiki/$p->{l_wp}" ] : (), ); - txt "\n" if @links; + br if @links; for(@links) { a href => $_->[1], mt "_prodpage_$_->[0]"; txt ' - ' if $_ ne $links[$#links]; } - end; + end 'p'; if(@{$p->{relations}}) { my %rel; push @{$rel{$_->{relation}}}, $_ for (sort { $a->{name} cmp $b->{name} } @{$p->{relations}}); p class => 'center'; - txt "\n"; + br; for my $r (sort { $self->{prod_relations}{$a}[0] <=> $self->{prod_relations}{$b}[0] } keys %rel) { txt mt("_prodrel_$r").': '; for (@{$rel{$r}}) { a href => "/p$_->{id}", title => $_->{original}||$_->{name}, shorten $_->{name}, 40; txt ', ' if $_ ne $rel{$r}[$#{$rel{$r}}]; } - txt "\n"; + br; } - end; + end 'p'; } if($p->{desc}) { @@ -117,7 +118,7 @@ sub page { lit bb2html $p->{desc}; end; } - end; + end 'div'; _releases($self, $p); @@ -186,11 +187,11 @@ sub _releases { txt ' '; } end; - end; + end 'tr'; } } - end; - end; + end 'table'; + end 'div'; } @@ -200,7 +201,7 @@ sub edit { my($self, $pid, $rev) = @_; my $p = $pid && $self->dbProducerGet(id => $pid, what => 'changes extended relations', $rev ? (rev => $rev) : ())->[0]; - return 404 if $pid && !$p->{id}; + return $self->resNotFound if $pid && !$p->{id}; $rev = undef if !$p || $p->{cid} == $p->{latest}; return $self->htmlDenied if !$self->authCan('edit') @@ -216,18 +217,18 @@ sub edit { if($self->reqMethod eq 'POST') { return if !$self->authCheckCode; $frm = $self->formValidate( - { name => 'type', enum => $self->{producer_types} }, - { name => 'name', maxlength => 200 }, - { name => 'original', required => 0, maxlength => 200, default => '' }, - { name => 'alias', required => 0, maxlength => 500, default => '' }, - { name => 'lang', enum => $self->{languages} }, - { name => 'website', required => 0, maxlength => 250, default => '', template => 'url' }, - { name => 'l_wp', required => 0, maxlength => 150, default => '' }, - { name => 'desc', required => 0, maxlength => 5000, default => '' }, - { name => 'prodrelations', required => 0, maxlength => 5000, default => '' }, - { name => 'editsum', required => 0, maxlength => 5000 }, - { name => 'ihid', required => 0 }, - { name => 'ilock', required => 0 }, + { post => 'type', enum => $self->{producer_types} }, + { post => 'name', maxlength => 200 }, + { post => 'original', required => 0, maxlength => 200, default => '' }, + { post => 'alias', required => 0, maxlength => 500, default => '' }, + { post => 'lang', enum => $self->{languages} }, + { post => 'website', required => 0, maxlength => 250, default => '', template => 'url' }, + { post => 'l_wp', required => 0, maxlength => 150, default => '' }, + { post => 'desc', required => 0, maxlength => 5000, default => '' }, + { post => 'prodrelations', required => 0, maxlength => 5000, default => '' }, + { post => 'editsum', required => 0, maxlength => 5000 }, + { post => 'ihid', required => 0 }, + { post => 'ilock', required => 0 }, ); push @{$frm->{_err}}, 'badeditsum' if !$frm->{editsum} || lc($frm->{editsum}) eq lc($frm->{desc}); if(!$frm->{_err}) { @@ -306,7 +307,7 @@ sub edit { a href => '#', mt '_pedit_rel_addbut'; end; end; - end; + end 'table'; }], ]); $self->htmlFooter; @@ -344,10 +345,10 @@ sub list { my($self, $char) = @_; my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'q', required => 0, default => '' }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'q', required => 0, default => '' }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; my($list, $np) = $self->dbProducerGet( $char ne 'all' ? ( char => $char ) : (), @@ -391,7 +392,7 @@ sub list { } } clearfloat; - end; + end 'div'; $self->htmlBrowseNavigate($pageurl, $f->{p}, $np, 'b'); $self->htmlFooter; } @@ -401,8 +402,8 @@ sub list { sub pxml { my $self = shift; - my $q = $self->formValidate({ name => 'q', maxlength => 500 }); - return 404 if $q->{_err}; + my $q = $self->formValidate({ get => 'q', maxlength => 500 }); + return $self->resNotFound if $q->{_err}; $q = $q->{q}; my($list, $np) = $self->dbProducerGet( diff --git a/lib/VNDB/Handler/Releases.pm b/lib/VNDB/Handler/Releases.pm index 4b5a3374..a3ecbd42 100644 --- a/lib/VNDB/Handler/Releases.pm +++ b/lib/VNDB/Handler/Releases.pm @@ -3,11 +3,11 @@ package VNDB::Handler::Releases; use strict; use warnings; -use YAWF ':html'; +use TUWF ':html', 'uri_escape'; use VNDB::Func; -YAWF::register( +TUWF::register( qr{r([1-9]\d*)(?:\.([1-9]\d*))?} => \&page, qr{(v)([1-9]\d*)/add} => \&edit, qr{r} => \&browse, @@ -24,7 +24,7 @@ sub page { what => 'vn extended producers platforms media'.($rev ? ' changes' : ''), $rev ? (rev => $rev) : (), )->[0]; - return 404 if !$r->{id}; + return $self->resNotFound if !$r->{id}; $self->htmlHeader(title => $r->{title}, noindex => $rev); $self->htmlMainTabs('r', $r); @@ -250,10 +250,10 @@ sub _infotable { option value => -1, mt '_relinfo_user_del' if $rl; end; end; - end; + end 'tr'; } - end; + end 'table'; } @@ -272,11 +272,11 @@ sub edit { } my $r = $rid && $self->dbReleaseGet(id => $rid, what => 'vn extended producers platforms media changes', $rev ? (rev => $rev) : ())->[0]; - return 404 if $rid && !$r->{id}; + return $self->resNotFound if $rid && !$r->{id}; $rev = undef if !$r || $r->{cid} == $r->{latest}; my $v = $vid && $self->dbVNGet(id => $vid)->[0]; - return 404 if $vid && !$v->{id}; + return $self->resNotFound if $vid && !$v->{id}; return $self->htmlDenied if !$self->authCan('edit') || $rid && ($r->{locked} && !$self->authCan('lock') || $r->{hidden} && !$self->authCan('del')); @@ -298,31 +298,31 @@ sub edit { if($self->reqMethod eq 'POST') { return if !$self->authCheckCode; $frm = $self->formValidate( - { name => 'type', enum => $self->{release_types} }, - { name => 'patch', required => 0, default => 0 }, - { name => 'freeware', required => 0, default => 0 }, - { name => 'doujin', required => 0, default => 0 }, - { name => 'title', maxlength => 250 }, - { name => 'original', required => 0, default => '', maxlength => 250 }, - { name => 'gtin', required => 0, default => '0', + { post => 'type', enum => $self->{release_types} }, + { post => 'patch', required => 0, default => 0 }, + { post => 'freeware', required => 0, default => 0 }, + { post => 'doujin', required => 0, default => 0 }, + { post => 'title', maxlength => 250 }, + { post => 'original', required => 0, default => '', maxlength => 250 }, + { post => 'gtin', required => 0, default => '0', func => [ \>intype, 'Not a valid JAN/UPC/EAN code' ] }, - { name => 'catalog', required => 0, default => '', maxlength => 50 }, - { name => 'languages', multi => 1, enum => $self->{languages} }, - { name => 'website', required => 0, default => '', maxlength => 250, template => 'url' }, - { name => 'released', required => 0, default => 0, template => 'int' }, - { name => 'minage' , required => 0, default => -1, enum => $self->{age_ratings} }, - { name => 'notes', required => 0, default => '', maxlength => 10240 }, - { name => 'platforms', required => 0, default => '', multi => 1, enum => $self->{platforms} }, - { name => 'media', required => 0, default => '' }, - { name => 'resolution',required => 0, default => 0, enum => [ 0..$#{$self->{resolutions}} ] }, - { name => 'voiced', required => 0, default => 0, enum => $self->{voiced} }, - { name => 'ani_story', required => 0, default => 0, enum => $self->{animated} }, - { name => 'ani_ero', required => 0, default => 0, enum => $self->{animated} }, - { name => 'producers', required => 0, default => '' }, - { name => 'vn', maxlength => 5000 }, - { name => 'editsum', required => 0, maxlength => 5000 }, - { name => 'ihid', required => 0 }, - { name => 'ilock', required => 0 }, + { post => 'catalog', required => 0, default => '', maxlength => 50 }, + { post => 'languages', multi => 1, enum => $self->{languages} }, + { post => 'website', required => 0, default => '', maxlength => 250, template => 'url' }, + { post => 'released', required => 0, default => 0, template => 'int' }, + { post => 'minage' , required => 0, default => -1, enum => $self->{age_ratings} }, + { post => 'notes', required => 0, default => '', maxlength => 10240 }, + { post => 'platforms', required => 0, default => '', multi => 1, enum => $self->{platforms} }, + { post => 'media', required => 0, default => '' }, + { post => 'resolution',required => 0, default => 0, enum => [ 0..$#{$self->{resolutions}} ] }, + { post => 'voiced', required => 0, default => 0, enum => $self->{voiced} }, + { post => 'ani_story', required => 0, default => 0, enum => $self->{animated} }, + { post => 'ani_ero', required => 0, default => 0, enum => $self->{animated} }, + { post => 'producers', required => 0, default => '' }, + { post => 'vn', maxlength => 5000 }, + { post => 'editsum', required => 0, maxlength => 5000 }, + { post => 'ihid', required => 0 }, + { post => 'ilock', required => 0 }, ); push @{$frm->{_err}}, 'badeditsum' if !$frm->{editsum} || lc($frm->{editsum}) eq lc($frm->{notes}); @@ -456,7 +456,7 @@ sub _form { option value => 3, mt '_redit_form_prod_both'; end; end; td class => 'tc_add'; a id => 'producer_add', href => '#', mt '_redit_form_prod_addbut'; end; - end; end; + end; end 'table'; }], ], @@ -480,14 +480,14 @@ sub browse { my $self = shift; my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'o', required => 0, default => 'a', enum => ['a', 'd'] }, - { name => 'q', required => 0, default => '', maxlength => 500 }, - { name => 's', required => 0, default => 'title', enum => [qw|released minage title|] }, - { name => 'fil',required => 0, default => '' }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'o', required => 0, default => 'a', enum => ['a', 'd'] }, + { get => 'q', required => 0, default => '', maxlength => 500 }, + { get => 's', required => 0, default => 'title', enum => [qw|released minage title|] }, + { get => 'fil',required => 0 }, ); - return 404 if $f->{_err}; - $f->{fil} = $self->authPref('filter_release') if !grep $_ eq 'fil', $self->reqParam(); + return $self->resNotFound if $f->{_err}; + $f->{fil} //= $self->authPref('filter_release'); my %compat = _fil_compat($self); my($list, $np) = !$f->{q} && !$f->{fil} && !keys %compat ? ([], 0) : $self->filFetchDB(release => $f->{fil}, \%compat, { @@ -505,11 +505,11 @@ sub browse { h1 mt '_rbrowse_title'; $self->htmlSearchBox('r', $f->{q}); a id => 'filselect', href => '#r'; - lit '<i>▸</i> '.mt('_rbrowse_filters').'<i></i>'; + lit '<i>▸</i> '.mt('_js_fil_filters').'<i></i>'; end; input type => 'hidden', class => 'hidden', name => 'fil', id => 'fil', value => $f->{fil}; end; - end; + end 'form'; my $uri = sprintf '/r?q=%s;fil=%s', uri_escape($f->{q}), $f->{fil}; $self->htmlBrowse( @@ -541,7 +541,7 @@ sub browse { a href => "/r$l->{id}", title => $l->{original}||$l->{title}, shorten $l->{title}, 90; b class => 'grayedout', ' (patch)' if $l->{patch}; end; - end; + end 'tr'; }, ) if @$list; if(($f->{q} || $f->{fil}) && !@$list) { @@ -561,18 +561,18 @@ sub _fil_compat { my $self = shift; my %c; my $f = $self->formValidate( - { name => 'ln', required => 0, multi => 1, default => '', enum => $self->{languages} }, - { name => 'pl', required => 0, multi => 1, default => '', enum => $self->{platforms} }, - { name => 'me', required => 0, multi => 1, default => '', enum => [ keys %{$self->{media}} ] }, - { name => 'tp', required => 0, default => '', enum => [ '', @{$self->{release_types}} ] }, - { name => 'pa', required => 0, default => 0, enum => [ 0..2 ] }, - { name => 'fw', required => 0, default => 0, enum => [ 0..2 ] }, - { name => 'do', required => 0, default => 0, enum => [ 0..2 ] }, - { name => 'ma_m', required => 0, default => 0, enum => [ 0, 1 ] }, - { name => 'ma_a', required => 0, default => 0, enum => $self->{age_ratings} }, - { name => 'mi', required => 0, default => 0, template => 'int' }, - { name => 'ma', required => 0, default => 99999999, template => 'int' }, - { name => 're', required => 0, multi => 1, default => 0, enum => [ 1..$#{$self->{resolutions}} ] }, + { get => 'ln', required => 0, multi => 1, default => '', enum => $self->{languages} }, + { get => 'pl', required => 0, multi => 1, default => '', enum => $self->{platforms} }, + { get => 'me', required => 0, multi => 1, default => '', enum => [ keys %{$self->{media}} ] }, + { get => 'tp', required => 0, default => '', enum => [ '', @{$self->{release_types}} ] }, + { get => 'pa', required => 0, default => 0, enum => [ 0..2 ] }, + { get => 'fw', required => 0, default => 0, enum => [ 0..2 ] }, + { get => 'do', required => 0, default => 0, enum => [ 0..2 ] }, + { get => 'ma_m', required => 0, default => 0, enum => [ 0, 1 ] }, + { get => 'ma_a', required => 0, default => 0, enum => $self->{age_ratings} }, + { get => 'mi', required => 0, default => 0, template => 'int' }, + { get => 'ma', required => 0, default => 99999999, template => 'int' }, + { get => 're', required => 0, multi => 1, default => 0, enum => [ 1..$#{$self->{resolutions}} ] }, ); return () if $f->{_err}; $c{minage} = [ grep $_ >= 0 && ($f->{ma_m} ? $f->{ma_a} >= $_ : $f->{ma_a} <= $_), @{$self->{age_ratings}} ] if $f->{ma_a} || $f->{ma_m}; diff --git a/lib/VNDB/Handler/Tags.pm b/lib/VNDB/Handler/Tags.pm index ad736027..6a4cb760 100644 --- a/lib/VNDB/Handler/Tags.pm +++ b/lib/VNDB/Handler/Tags.pm @@ -4,11 +4,11 @@ package VNDB::Handler::Tags; use strict; use warnings; -use YAWF ':html', ':xml'; +use TUWF ':html', ':xml', 'xml_escape'; use VNDB::Func; -YAWF::register( +TUWF::register( qr{g([1-9]\d*)}, \&tagpage, qr{g([1-9]\d*)/(edit)}, \&tagedit, qr{g([1-9]\d*)/(add)}, \&tagedit, @@ -27,16 +27,16 @@ sub tagpage { my($self, $tag) = @_; my $t = $self->dbTagGet(id => $tag, what => 'parents(0) childs(2) aliases')->[0]; - return 404 if !$t; + return $self->resNotFound if !$t; my $f = $self->formValidate( - { name => 's', required => 0, default => 'tagscore', enum => [ qw|title rel pop tagscore rating| ] }, - { name => 'o', required => 0, default => 'd', enum => [ 'a','d' ] }, - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'm', required => 0, default => -1, enum => [qw|0 1 2|] }, + { get => 's', required => 0, default => 'tagscore', enum => [ qw|title rel pop tagscore rating| ] }, + { get => 'o', required => 0, default => 'd', enum => [ 'a','d' ] }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'm', required => 0, default => -1, enum => [qw|0 1 2|] }, ); - return 404 if $f->{_err}; - my $tagspoil = $self->reqCookie($self->{cookie_prefix}.'tagspoil'); + return $self->resNotFound if $f->{_err}; + my $tagspoil = $self->reqCookie('tagspoil'); $f->{m} = $tagspoil =~ /^[0-2]$/ ? $tagspoil : 0 if $f->{m} == -1; my($list, $np) = $t->{meta} || $t->{state} != 2 ? ([],0) : $self->filFetchDB(vn => undef, undef, { @@ -69,7 +69,7 @@ sub tagpage { p mt '_tagp_pending_msg'; end; } - end; + end 'div'; } div class => 'mainbox'; @@ -84,9 +84,10 @@ sub tagpage { txt ' > '; a href => "/g$_->{id}", $_->{name}; } - txt " > $t->{name}\n"; + txt " > $t->{name}"; + br; } - end; + end 'p'; if($t->{description}) { p class => 'description'; @@ -95,11 +96,12 @@ sub tagpage { } if(@{$t->{aliases}}) { p class => 'center'; - b mt('_tagp_aliases')."\n"; - txt "$_\n" for (@{$t->{aliases}}); + b mt('_tagp_aliases'); + br; + lit xml_escape($_).'<br />' for (@{$t->{aliases}}); end; } - end; + end 'div'; _childtags($self, $t) if @{$t->{childs}}; @@ -112,9 +114,11 @@ sub tagpage { a href => "/g$t->{id}?m=1", $f->{m} == 1 ? (class => 'optselected') : (), onclick => "setCookie('tagspoil', 1);return true;", mt '_tagp_spoil1'; a href => "/g$t->{id}?m=2", $f->{m} == 2 ? (class => 'optselected') : (), onclick => "setCookie('tagspoil', 2);return true;", mt '_tagp_spoil2'; end; - p "\n\n".mt '_tagp_novn' if !@$list; - p "\n".mt '_tagp_cached'; - end; + if(!@$list) { + p; br; br; txt mt '_tagp_novn'; end; + } + p; br; txt mt '_tagp_cached'; end; + end 'div'; $self->htmlBrowseVN($list, $f, $np, "/g$t->{id}?m=$f->{m}", 1) if @$list; } @@ -164,12 +168,12 @@ sub _childtags { end; } end; - end; + end 'li'; } - end; + end 'ul'; clearfloat; br; - end; + end 'div'; } @@ -179,7 +183,7 @@ sub tagedit { my($frm, $par); if($act && $act eq 'add') { $par = $self->dbTagGet(id => $tag)->[0]; - return 404 if !$par; + return $self->resNotFound if !$par; $frm->{parents} = $par->{name}; $tag = undef; } @@ -187,18 +191,18 @@ sub tagedit { return $self->htmlDenied if !$self->authCan('tag') || $tag && !$self->authCan('tagmod'); my $t = $tag && $self->dbTagGet(id => $tag, what => 'parents(1) aliases addedby')->[0]; - return 404 if $tag && !$t; + return $self->resNotFound if $tag && !$t; if($self->reqMethod eq 'POST') { return if !$self->authCheckCode; $frm = $self->formValidate( - { name => 'name', required => 1, maxlength => 250, regex => [ qr/^[^,]+$/, 'A comma is not allowed in tag names' ] }, - { name => 'state', required => 0, default => 0, enum => [ 0..2 ] }, - { name => 'meta', required => 0, default => 0 }, - { name => 'alias', required => 0, maxlength => 1024, default => '', regex => [ qr/^[^,]+$/s, 'No comma allowed in aliases' ] }, - { name => 'description', required => 0, maxlength => 10240, default => '' }, - { name => 'parents', required => !$self->authCan('tagmod'), default => '' }, - { name => 'merge', required => 0, default => '' }, + { post => 'name', required => 1, maxlength => 250, regex => [ qr/^[^,]+$/, 'A comma is not allowed in tag names' ] }, + { post => 'state', required => 0, default => 0, enum => [ 0..2 ] }, + { post => 'meta', required => 0, default => 0 }, + { post => 'alias', required => 0, maxlength => 1024, default => '', regex => [ qr/^[^,]+$/s, 'No comma allowed in aliases' ] }, + { post => 'description', required => 0, maxlength => 10240, default => '' }, + { post => 'parents', required => !$self->authCan('tagmod'), default => '' }, + { post => 'merge', required => 0, default => '' }, ); my @aliases = split /[\t\s]*\n[\t\s]*/, $frm->{alias}; my @parents = split /[\t\s]*,[\t\s]*/, $frm->{parents}; @@ -289,13 +293,13 @@ sub taglist { my $self = shift; my $f = $self->formValidate( - { name => 's', required => 0, default => 'name', enum => ['added', 'name'] }, - { name => 'o', required => 0, default => 'a', enum => ['a', 'd'] }, - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 't', required => 0, default => -1, enum => [ -1..2 ] }, - { name => 'q', required => 0, default => '' }, + { get => 's', required => 0, default => 'name', enum => ['added', 'name'] }, + { get => 'o', required => 0, default => 'a', enum => ['a', 'd'] }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 't', required => 0, default => -1, enum => [ -1..2 ] }, + { get => 'q', required => 0, default => '' }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; my($t, $np) = $self->dbTagGet( sort => $f->{s}, reverse => $f->{o} eq 'd', @@ -321,7 +325,7 @@ sub taglist { if(!@$t) { p mt '_tagb_noresults'; } - end; + end 'div'; if(@$t) { $self->htmlBrowse( class => 'taglist', @@ -345,7 +349,7 @@ sub taglist { b class => 'grayedout', ' '.mt '_tagb_note_del' if $l->{state} == 1; } end; - end; + end 'tr'; } ); } @@ -357,14 +361,14 @@ sub taglinks { my $self = shift; my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'o', required => 0, default => 'd', enum => ['a', 'd'] }, - { name => 's', required => 0, default => 'date', enum => [qw|date tag|] }, - { name => 'v', required => 0, default => 0, template => 'int' }, - { name => 'u', required => 0, default => 0, template => 'int' }, - { name => 't', required => 0, default => 0, template => 'int' }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'o', required => 0, default => 'd', enum => ['a', 'd'] }, + { get => 's', required => 0, default => 'date', enum => [qw|date tag|] }, + { get => 'v', required => 0, default => 0, template => 'int' }, + { get => 'u', required => 0, default => 0, template => 'int' }, + { get => 't', required => 0, default => 0, template => 'int' }, ); - return 404 if $f->{_err} || $f->{p} > 100; + return $self->resNotFound if $f->{_err} || $f->{p} > 100; my($list, $np) = $self->dbTagLinks( what => 'details', @@ -420,10 +424,10 @@ sub taglinks { a href => "/v$o->{id}", $o->{title}; end; } - end; + end 'ul'; } p mt '_taglink_fil_add' unless $f->{v} && $f->{u} && $f->{t}; - end; + end 'div'; $self->htmlBrowse( class => 'taglinks', @@ -450,7 +454,7 @@ sub taglinks { a href => $url->(u=>$l->{uid}), class => 'setfil', '> ' if !$f->{u}; a href => "/u$l->{uid}", $l->{username}; end; - td class => 'tc3'; + td class => 'tc3'.($l->{ignore}?' ignored':''); tagscore $l->{vote}; end; td class => 'tc4'; @@ -473,23 +477,61 @@ sub vntagmod { my($self, $vid) = @_; my $v = $self->dbVNGet(id => $vid)->[0]; - return 404 if !$v || $v->{hidden}; + return $self->resNotFound if !$v || $v->{hidden}; return $self->htmlDenied if !$self->authCan('tag'); + my $tags = $self->dbTagStats(vid => $vid, results => 9999); + my $my = $self->dbTagLinks(vid => $vid, uid => $self->authInfo->{id}); + if($self->reqMethod eq 'POST') { return if !$self->authCheckCode; my $frm = $self->formValidate( - { name => 'taglinks', required => 0, default => '', maxlength => 10240, regex => [ qr/^[1-9][0-9]*,-?[1-3],-?[0-2]( [1-9][0-9]*,-?[1-3],-?[0-2])*$/, 'meh' ] } + { post => 'taglinks', required => 0, default => '', maxlength => 10240, regex => [ qr/^[1-9][0-9]*,-?[1-3],-?[0-2]( [1-9][0-9]*,-?[1-3],-?[0-2])*$/, 'meh' ] }, + { post => 'overrule', required => 0, multi => 1, template => 'int' }, ); - return 404 if $frm->{_err}; - $self->dbTagLinkEdit($self->authInfo->{id}, $vid, [ map [ split /,/ ], split / /, $frm->{taglinks}]); - } + return $self->resNotFound if $frm->{_err}; + + # convert some data in a more convenient structure for faster lookup + my %tags = map +($_->{id} => $_), @$tags; + my %old = map +($_->{tag} => $_), @$my; + my %new = map { my($tag, $vote, $spoiler) = split /,/; ($tag => [ $vote, $spoiler ]) } split / /, $frm->{taglinks}; + my %over = !$self->authCan('tagmod') || !$frm->{overrule}[0] ? () : (map $new{$_} ? ($_ => 1) : (), @{$frm->{overrule}}); + + # hashes which need to be filled, indicating what should be changed to the DB + my %delete; # tag => 1 + my %update; # tag => [ vote, spoiler ] (ignore flag is untouched) + my %insert; # tag => [ vote, spoiler, ignore ] + my %overrule; # tag => 0/1 + + for my $t (keys %old, keys %new) { + my $prev_over = $old{$t} && !$old{$t}{ignore} && $tags{$t}{overruled}; + + # overrule checkbox has changed? make sure to (de-)overrule the tag votes + $overrule{$t} = $over{$t}?1:0 if (!$prev_over && $over{$t}) || ($prev_over && !$over{$t}); + + # tag deleted? + if($old{$t} && !$new{$t}) { + $delete{$t} = 1; + next; + } - my $my = $self->dbTagLinks(vid => $vid, uid => $self->authInfo->{id}); - my $tags = $self->dbTagStats(vid => $vid, results => 9999); + # and insert or update the vote + if(!$old{$t} && $new{$t}) { + # determine whether this vote is going to be ignored or not + my $ign = $tags{$t}{overruled} && !$prev_over && !$over{$t}; + $insert{$t} = [ $new{$t}[0], $new{$t}[1], $ign ]; + } elsif($old{$t}{vote} != $new{$t}[0] || (defined $old{$t}{spoiler} ? $old{$t}{spoiler} : -1) != $new{$t}[1]) { + $update{$t} = [ $new{$t}[0], $new{$t}[1] ]; + } + } + $self->dbTagLinkEdit($self->authInfo->{id}, $vid, \%insert, \%update, \%delete, \%overrule); + + # need to re-fetch the tags and tag links, as these have been modified + $tags = $self->dbTagStats(vid => $vid, results => 9999); + $my = $self->dbTagLinks(vid => $vid, uid => $self->authInfo->{id}); + } - my $frm; my $title = mt '_tagv_title', $v->{title}; $self->htmlHeader(title => $title, noindex => 1); @@ -504,26 +546,27 @@ sub vntagmod { li mt '_tagv_msg_cache'; end; end; - end; - $self->htmlForm({ frm => $frm, action => "/v$vid/tagmod", nosubmit => 1 }, tagmod => [ mt('_tagv_frm_title'), + end 'div'; + $self->htmlForm({ action => "/v$vid/tagmod", nosubmit => 1 }, tagmod => [ mt('_tagv_frm_title'), [ hidden => short => 'taglinks', value => '' ], [ static => nolabel => 1, content => sub { table class => 'tgl'; thead; Tr; td ''; - td colspan => 2, class => 'tc_you', mt '_tagv_col_you'; + td colspan => $self->authCan('tagmod') ? 3 : 2, class => 'tc_you', mt '_tagv_col_you'; td colspan => 3, class => 'tc_others', mt '_tagv_col_others'; end; Tr; td class => 'tc_tagname', mt '_tagv_col_tag'; td class => 'tc_myvote', mt '_tagv_col_rating'; + td class => 'tc_myover', 'O' if $self->authCan('tagmod'); td class => 'tc_myspoil', mt '_tagv_col_spoiler'; td class => 'tc_allvote', mt '_tagv_col_rating'; td class => 'tc_allspoil', mt '_tagv_col_spoiler'; td class => 'tc_allwho', ''; end; - end; + end 'thead'; tfoot; Tr; td colspan => 6; input type => 'submit', class => 'submit', value => mt('_tagv_save'), style => 'float: right'; @@ -534,17 +577,25 @@ sub vntagmod { lit mt '_tagv_addmsg'; end; end; - end; end; + end; end 'tfoot'; tbody id => 'tagtable'; for my $t (sort { $a->{name} cmp $b->{name} } @$tags) { my $m = (grep $_->{tag} == $t->{id}, @$my)[0] || {}; Tr id => "tgl_$t->{id}"; td class => 'tc_tagname'; a href => "/g$t->{id}", $t->{name}; end; td class => 'tc_myvote', $m->{vote}||0; + if($self->authCan('tagmod')) { + td class => 'tc_myover'; + input type => 'checkbox', name => 'overrule', value => $t->{id}, + $m->{vote} && !$m->{ignore} && $t->{overruled} ? (checked => 'checked') : () + if $t->{cnt} > 1; + end; + } td class => 'tc_myspoil', defined $m->{spoiler} ? $m->{spoiler} : -1; td class => 'tc_allvote'; - tagscore !$m->{vote} ? $t->{rating} : $t->{cnt} == 1 ? 0 : ($t->{rating}*$t->{cnt} - $m->{vote}) / ($t->{cnt}-1); - i ' ('.($t->{cnt} - ($m->{vote} ? 1 : 0)).')'; + tagscore $t->{rating}; + i $t->{overruled} ? (class => 'grayedout') : (), " ($t->{cnt})"; + b class => 'standout', style => 'font-weight: bold', ' !' if $t->{overruled}; end; td class => 'tc_allspoil', sprintf '%.2f', $t->{spoiler}; td class => 'tc_allwho'; @@ -552,8 +603,8 @@ sub vntagmod { end; end; } - end; - end; + end 'tbody'; + end 'table'; } ], ]); $self->htmlFooter; @@ -623,7 +674,7 @@ sub tagindex { end; } li; - txt "\n"; + br; a href => '/g/list?t=0;o=d;s=added', mt '_tagidx_queue_link'; txt ' - '; a href => '/g/list?t=1;o=d;s=added', mt '_tagidx_denied'; @@ -631,8 +682,8 @@ sub tagindex { end; end; - end; # /tr - end; # /table + end 'tr'; + end 'table'; $self->htmlFooter; } @@ -671,10 +722,10 @@ sub tagxml { my $self = shift; my $f = $self->formValidate( - { name => 'q', required => 0, maxlength => 500 }, - { name => 'id', required => 0, multi => 1, template => 'int' }, + { get => 'q', required => 0, maxlength => 500 }, + { get => 'id', required => 0, multi => 1, template => 'int' }, ); - return 404 if $f->{_err} || (!$f->{q} && !$f->{id} && !$f->{id}[0]); + return $self->resNotFound if $f->{_err} || (!$f->{q} && !$f->{id} && !$f->{id}[0]); my($list, $np) = $self->dbTagGet( !$f->{q} ? () : $f->{q} =~ /^g([1-9]\d*)/ ? (id => $1) : $f->{q} =~ /^name:(.+)$/ ? (name => $1) : (search => $f->{q}), diff --git a/lib/VNDB/Handler/ULists.pm b/lib/VNDB/Handler/ULists.pm index 764d515b..94007a73 100644 --- a/lib/VNDB/Handler/ULists.pm +++ b/lib/VNDB/Handler/ULists.pm @@ -3,11 +3,11 @@ package VNDB::Handler::ULists; use strict; use warnings; -use YAWF ':html', ':xml'; +use TUWF ':html', ':xml'; use VNDB::Func; -YAWF::register( +TUWF::register( qr{v([1-9]\d*)/vote}, \&vnvote, qr{v([1-9]\d*)/wish}, \&vnwish, qr{v([1-9]\d*)/list}, \&vnlist_e, @@ -27,9 +27,9 @@ sub vnvote { return if !$self->authCheckCode; my $f = $self->formValidate( - { name => 'v', enum => [ -1, 1..10 ] } + { get => 'v', enum => [ -1, 1..10 ] } ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; $self->dbVoteDel($uid, $id) if $f->{v} == -1; $self->dbVoteAdd($id, $uid, $f->{v}) if $f->{v} > 0; @@ -46,9 +46,9 @@ sub vnwish { return if !$self->authCheckCode; my $f = $self->formValidate( - { name => 's', enum => [ -1, @{$self->{wishlist_status}} ] } + { get => 's', enum => [ -1, @{$self->{wishlist_status}} ] } ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; $self->dbWishListDel($uid, $id) if $f->{s} == -1; $self->dbWishListAdd($id, $uid, $f->{s}) if $f->{s} != -1; @@ -65,9 +65,9 @@ sub vnlist_e { return if !$self->authCheckCode; my $f = $self->formValidate( - { name => 'e', enum => [ -1, @{$self->{vnlist_status}} ] } + { get => 'e', enum => [ -1, @{$self->{vnlist_status}} ] } ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; $self->dbVNListDel($uid, $id) if $f->{e} == -1; $self->dbVNListAdd($uid, $id, $f->{e}) if $f->{e} != -1; @@ -82,9 +82,9 @@ sub rlist_e { my $rid = $id; if(!$rid) { my $f = $self->formValidate( - { name => 'id', required => 1, template => 'int' } + { get => 'id', required => 1, template => 'int' } ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; $rid = $f->{id}; } @@ -93,9 +93,9 @@ sub rlist_e { return if !$self->authCheckCode; my $f = $self->formValidate( - { name => 'e', required => 1, enum => [ -1, @{$self->{rlist_status}} ] } + { get => 'e', required => 1, enum => [ -1, @{$self->{rlist_status}} ] } ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; $self->dbRListDel($uid, $rid) if $f->{e} == -1; $self->dbRListAdd($uid, $rid, $f->{e}) if $f->{e} >= 0; @@ -116,24 +116,24 @@ sub votelist { my($self, $type, $id) = @_; my $obj = $type eq 'v' ? $self->dbVNGet(id => $id)->[0] : $self->dbUserGet(uid => $id, what => 'hide_list')->[0]; - return 404 if !$obj->{id}; + return $self->resNotFound if !$obj->{id}; my $own = $type eq 'u' && $self->authInfo->{id} && $self->authInfo->{id} == $id; - return 404 if $type eq 'u' && !$own && !(!$obj->{hide_list} || $self->authCan('usermod')); + return $self->resNotFound if $type eq 'u' && !$own && !(!$obj->{hide_list} || $self->authCan('usermod')); my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'o', required => 0, default => 'd', enum => ['a', 'd'] }, - { name => 's', required => 0, default => 'date', enum => [qw|date title vote|] }, - { name => 'c', required => 0, default => 'all', enum => [ 'all', 'a'..'z', 0 ] }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'o', required => 0, default => 'd', enum => ['a', 'd'] }, + { get => 's', required => 0, default => 'date', enum => [qw|date title vote|] }, + { get => 'c', required => 0, default => 'all', enum => [ 'all', 'a'..'z', 0 ] }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; if($own && $self->reqMethod eq 'POST') { return if !$self->authCheckCode; my $frm = $self->formValidate( - { name => 'vid', required => 1, multi => 1, template => 'int' }, - { name => 'batchedit', required => 1, enum => [ -2, -1, 1..10 ] }, + { post => 'vid', required => 1, multi => 1, template => 'int' }, + { post => 'batchedit', required => 1, enum => [ -2, -1, 1..10 ] }, ); my @vid = grep $_ && $_ > 0, @{$frm->{vid}}; if(!$frm->{_err} && @vid && $frm->{batchedit} > -2) { @@ -210,7 +210,7 @@ sub votelist { option value => -1, 'revoke'; end; end; - end; + end 'tr'; }) : (), ); end if $own; @@ -223,21 +223,21 @@ sub wishlist { my $own = $self->authInfo->{id} && $self->authInfo->{id} == $uid; my $u = $self->dbUserGet(uid => $uid, what => 'hide_list')->[0]; - return 404 if !$u || !$own && !(!$u->{hide_list} || $self->authCan('usermod')); + return $self->resNotFound if !$u || !$own && !(!$u->{hide_list} || $self->authCan('usermod')); my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'o', required => 0, default => 'd', enum => [ 'a', 'd' ] }, - { name => 's', required => 0, default => 'wstat', enum => [qw|title added wstat|] }, - { name => 'f', required => 0, default => -1, enum => [ -1, @{$self->{wishlist_status}} ] }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'o', required => 0, default => 'd', enum => [ 'a', 'd' ] }, + { get => 's', required => 0, default => 'wstat', enum => [qw|title added wstat|] }, + { get => 'f', required => 0, default => -1, enum => [ -1, @{$self->{wishlist_status}} ] }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; if($own && $self->reqMethod eq 'POST') { return if !$self->authCheckCode; my $frm = $self->formValidate( - { name => 'sel', required => 0, default => 0, multi => 1, template => 'int' }, - { name => 'batchedit', required => 1, enum => [ -1, @{$self->{wishlist_status}} ] }, + { post => 'sel', required => 0, default => 0, multi => 1, template => 'int' }, + { post => 'batchedit', required => 1, enum => [ -1, @{$self->{wishlist_status}} ] }, ); if(!$frm->{_err} && @{$frm->{sel}} && $frm->{sel}[0]) { $self->dbWishListDel($uid, $frm->{sel}) if $frm->{batchedit} == -1; @@ -269,7 +269,7 @@ sub wishlist { $_ == -1 ? mt '_wishlist_prio_all' : mt "_wish_$_" for (-1, @{$self->{wishlist_status}}); end; - end; + end 'div'; if($own) { my $code = $self->authGetCode("/u$uid/wish"); @@ -315,7 +315,7 @@ sub wishlist { end; }) : (), ); - end if $own; + end 'form' if $own; $self->htmlFooter; } @@ -325,26 +325,26 @@ sub vnlist { my $own = $self->authInfo->{id} && $self->authInfo->{id} == $uid; my $u = $self->dbUserGet(uid => $uid, what => 'hide_list')->[0]; - return 404 if !$u || !$own && !(!$u->{hide_list} || $self->authCan('usermod')); + return $self->resNotFound if !$u || !$own && !(!$u->{hide_list} || $self->authCan('usermod')); my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'o', required => 0, default => 'a', enum => [ 'a', 'd' ] }, - { name => 's', required => 0, default => 'title', enum => [ 'title', 'vote' ] }, - { name => 'c', required => 0, default => 'all', enum => [ 'all', 'a'..'z', 0 ] }, - { name => 'v', required => 0, default => 0, enum => [ -1..1 ] }, - { name => 't', required => 0, default => -1, enum => [ -1, @{$self->{vnlist_status}} ] }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'o', required => 0, default => 'a', enum => [ 'a', 'd' ] }, + { get => 's', required => 0, default => 'title', enum => [ 'title', 'vote' ] }, + { get => 'c', required => 0, default => 'all', enum => [ 'all', 'a'..'z', 0 ] }, + { get => 'v', required => 0, default => 0, enum => [ -1..1 ] }, + { get => 't', required => 0, default => -1, enum => [ -1, @{$self->{vnlist_status}} ] }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; if($own && $self->reqMethod eq 'POST') { return if !$self->authCheckCode; my $frm = $self->formValidate( - { name => 'vid', required => 0, default => 0, multi => 1, template => 'int' }, - { name => 'rid', required => 0, default => 0, multi => 1, template => 'int' }, - { name => 'not', required => 0, default => '', maxlength => 2000 }, - { name => 'vns', required => 1, enum => [ -2, -1, @{$self->{vnlist_status}}, 999 ] }, - { name => 'rel', required => 1, enum => [ -2, -1, @{$self->{rlist_status}} ] }, + { post => 'vid', required => 0, default => 0, multi => 1, template => 'int' }, + { post => 'rid', required => 0, default => 0, multi => 1, template => 'int' }, + { post => 'not', required => 0, default => '', maxlength => 2000 }, + { post => 'vns', required => 1, enum => [ -2, -1, @{$self->{vnlist_status}}, 999 ] }, + { post => 'rel', required => 1, enum => [ -2, -1, @{$self->{rlist_status}} ] }, ); my @vid = grep $_ > 0, @{$frm->{vid}}; my @rid = grep $_ > 0, @{$frm->{rid}}; @@ -404,7 +404,7 @@ sub vnlist { a href => $url->(t => -1), -1 == $f->{t} ? (class => 'optselected') : (), mt '_rlist_all'; a href => $url->(t => $_), $_ == $f->{t} ? (class => 'optselected') : (), mt '_vnlist_status_'.$_ for @{$self->{vnlist_status}}; end; - end; + end 'div'; _vnlist_browse($self, $own, $list, $np, $f, $url, $uid); $self->htmlFooter; @@ -458,7 +458,7 @@ sub _vnlist_browse { lit $txt; end; td class => 'tc8', $i->{vote} || '-'; - end; + end 'tr'; for (@{$i->{rels}}) { Tr class => "collapse relhid collapse_vid$i->{vid}".($n%2 ? '':' odd'); @@ -476,7 +476,7 @@ sub _vnlist_browse { end; td class => 'tc6', $_->{status} ? mt '_rlist_status_'.$_->{status} : ''; td class => 'tc7_8', colspan => 2, ''; - end; + end 'tr'; } }, @@ -505,11 +505,11 @@ sub _vnlist_browse { input type => 'submit', value => mt '_rlist_update'; end; td class => 'tc7_8', colspan => 2, mt '_rlist_releasenote'; - end; + end 'tr'; }) : (), ); - end if $own; + end 'form' if $own; } 1; diff --git a/lib/VNDB/Handler/Users.pm b/lib/VNDB/Handler/Users.pm index 044c72b2..75ddb547 100644 --- a/lib/VNDB/Handler/Users.pm +++ b/lib/VNDB/Handler/Users.pm @@ -3,12 +3,12 @@ package VNDB::Handler::Users; use strict; use warnings; -use YAWF ':html', 'xml_escape'; +use TUWF ':html', 'xml_escape'; use VNDB::Func; use POSIX 'floor'; -YAWF::register( +TUWF::register( qr{u([1-9]\d*)} => \&userpage, qr{u/login} => \&login, qr{u([1-9]\d*)/logout} => \&logout, @@ -28,7 +28,7 @@ sub userpage { my($self, $uid) = @_; my $u = $self->dbUserGet(uid => $uid, what => 'stats hide_list')->[0]; - return 404 if !$u->{id}; + return $self->resNotFound if !$u->{id}; my $votes = $u->{c_votes} && $self->dbVoteStats(uid => $uid); @@ -113,8 +113,8 @@ sub userpage { } end; end; - end; - end; + end 'table'; + end 'div'; if(!$u->{hide_list} && $votes) { div class => 'mainbox'; @@ -142,8 +142,8 @@ sub login { my $frm; if($self->reqMethod eq 'POST') { $frm = $self->formValidate( - { name => 'usrname', required => 1, minlength => 2, maxlength => 15 }, - { name => 'usrpass', required => 1, minlength => 4, maxlength => 64, template => 'asciiprint' }, + { post => 'usrname', required => 1, minlength => 2, maxlength => 15 }, + { post => 'usrpass', required => 1, minlength => 4, maxlength => 64, template => 'asciiprint' }, ); (my $ref = $self->reqHeader('Referer')||'/') =~ s/^\Q$self->{url}//; @@ -166,7 +166,7 @@ sub login { sub logout { my $self = shift; my $uid = shift; - return 404 if !$self->authInfo->{id} || $self->authInfo->{id} != $uid; + return $self->resNotFound if !$self->authInfo->{id} || $self->authInfo->{id} != $uid; $self->authLogout; } @@ -180,7 +180,7 @@ sub newpass { if($self->reqMethod eq 'POST') { return if !$self->authCheckCode; $frm = $self->formValidate( - { name => 'mail', required => 1, template => 'mail' }, + { post => 'mail', required => 1, template => 'mail' }, ); if(!$frm->{_err}) { $u = $self->dbUserGet(mail => $frm->{mail})->[0]; @@ -238,12 +238,12 @@ sub register { if($self->reqMethod eq 'POST') { return if !$self->authCheckCode; $frm = $self->formValidate( - { name => 'usrname', template => 'pname', minlength => 2, maxlength => 15 }, - { name => 'mail', template => 'mail' }, - { name => 'usrpass', minlength => 4, maxlength => 64, template => 'asciiprint' }, - { name => 'usrpass2', minlength => 4, maxlength => 64, template => 'asciiprint' }, - { name => 'type', regex => [ qr/^[1-3]$/ ] }, - { name => 'answer', template => 'int' }, + { post => 'usrname', template => 'pname', minlength => 2, maxlength => 15 }, + { post => 'mail', template => 'mail' }, + { post => 'usrpass', minlength => 4, maxlength => 64, template => 'asciiprint' }, + { post => 'usrpass2', minlength => 4, maxlength => 64, template => 'asciiprint' }, + { post => 'type', regex => [ qr/^[1-3]$/ ] }, + { post => 'answer', template => 'int' }, ); my $num = $self->{stats}{[qw|vn releases producers|]->[ $frm->{type} - 1 ]}; push @{$frm->{_err}}, 'notanswer' if !$frm->{_err} && ($frm->{answer} > $num || $frm->{answer} < $num*0.995); @@ -292,7 +292,7 @@ sub edit { # fetch user info (cached if uid == loggedin uid) my $u = $self->authInfo->{id} == $uid ? $self->authInfo : $self->dbUserGet(uid => $uid, what => 'extended prefs')->[0]; - return 404 if !$u->{id}; + return $self->resNotFound if !$u->{id}; # check POST data my $frm; @@ -300,17 +300,17 @@ sub edit { return if !$self->authCheckCode; $frm = $self->formValidate( $self->authCan('usermod') ? ( - { name => 'usrname', template => 'pname', minlength => 2, maxlength => 15 }, - { name => 'rank', enum => [ 1..$#{$self->{user_ranks}} ] }, - { name => 'ign_votes', required => 0, default => 0 }, + { post => 'usrname', template => 'pname', minlength => 2, maxlength => 15 }, + { post => 'rank', enum => [ 1..$#{$self->{user_ranks}} ] }, + { post => 'ign_votes', required => 0, default => 0 }, ) : (), - { name => 'mail', template => 'mail' }, - { name => 'usrpass', required => 0, minlength => 4, maxlength => 64, template => 'asciiprint' }, - { name => 'usrpass2', required => 0, minlength => 4, maxlength => 64, template => 'asciiprint' }, - { name => 'hide_list', required => 0, default => 0, enum => [0,1] }, - { name => 'show_nsfw', required => 0, default => 0, enum => [0,1] }, - { name => 'skin', required => 0, default => '', enum => [ '', keys %{$self->{skins}} ] }, - { name => 'customcss', required => 0, maxlength => 2000, default => '' }, + { post => 'mail', template => 'mail' }, + { post => 'usrpass', required => 0, minlength => 4, maxlength => 64, template => 'asciiprint' }, + { post => 'usrpass2', required => 0, minlength => 4, maxlength => 64, template => 'asciiprint' }, + { post => 'hide_list', required => 0, default => 0, enum => [0,1] }, + { post => 'show_nsfw', required => 0, default => 0, enum => [0,1] }, + { post => 'skin', required => 0, default => '', enum => [ '', keys %{$self->{skins}} ] }, + { post => 'customcss', required => 0, maxlength => 2000, default => '' }, ); push @{$frm->{_err}}, 'passmatch' if ($frm->{usrpass} || $frm->{usrpass2}) && (!$frm->{usrpass} || !$frm->{usrpass2} || $frm->{usrpass} ne $frm->{usrpass2}); @@ -338,7 +338,7 @@ sub edit { # create the page $self->htmlHeader(title => mt('_usere_title'), noindex => 1); $self->htmlMainTabs('u', $u, 'edit'); - if($self->reqParam('d')) { + if($self->reqGet('d')) { div class => 'mainbox'; h1 mt '_usere_saved_title'; div class => 'notice'; @@ -379,10 +379,10 @@ sub posts { # fetch user info (cached if uid == loggedin uid) my $u = $self->authInfo->{id} && $self->authInfo->{id} == $uid ? $self->authInfo : $self->dbUserGet(uid => $uid, what => 'hide_list')->[0]; - return 404 if !$u->{id}; + return $self->resNotFound if !$u->{id}; my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' } + { get => 'p', required => 0, default => 1, template => 'int' } ); my($posts, $np) = $self->dbPostGet(uid => $uid, hide => 1, what => 'thread', page => $f->{p}, sort => 'date', reverse => 1); @@ -436,7 +436,7 @@ sub delete { if(!$act) { my $code = $self->authGetCode("/u$uid/del/o"); my $u = $self->dbUserGet(uid => $uid, what => 'hide_list')->[0]; - return 404 if !$u->{id}; + return $self->resNotFound if !$u->{id}; $self->htmlHeader(title => 'Delete user', noindex => 1); $self->htmlMainTabs('u', $u, 'del'); div class => 'mainbox'; @@ -473,12 +473,12 @@ sub list { my($self, $char) = @_; my $f = $self->formValidate( - { name => 's', required => 0, default => 'username', enum => [ qw|username registered votes changes tags| ] }, - { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] }, - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'q', required => 0, default => '', maxlength => 50 }, + { get => 's', required => 0, default => 'username', enum => [ qw|username registered votes changes tags| ] }, + { get => 'o', required => 0, default => 'a', enum => [ 'a','d' ] }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'q', required => 0, default => '', maxlength => 50 }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; $self->htmlHeader(noindex => 1, title => mt '_ulist_title'); @@ -534,7 +534,7 @@ sub list { td class => 'tc5'; lit !$l->{c_tags} ? 0 : qq|<a href="/g/links?u=$l->{id}">$l->{c_tags}</a>|; end; - end; + end 'tr'; }, ); $self->htmlFooter; @@ -548,21 +548,20 @@ sub notifies { return $self->htmlDenied if !$u->{id} || $uid != $u->{id}; my $f = $self->formValidate( - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'r', required => 0, default => 0, enum => [0,1] }, - + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'r', required => 0, default => 0, enum => [0,1] }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; # changing the notification settings my $saved; - if($self->reqMethod() eq 'POST' && $self->reqParam('set')) { + if($self->reqMethod() eq 'POST' && $self->reqPost('set')) { return if !$self->authCheckCode; my $frm = $self->formValidate( - { name => 'notify_nodbedit', required => 0, default => 1, enum => [0,1] }, - { name => 'notify_announce', required => 0, default => 0, enum => [0,1] } + { post => 'notify_nodbedit', required => 0, default => 1, enum => [0,1] }, + { post => 'notify_announce', required => 0, default => 0, enum => [0,1] } ); - return 404 if $frm->{_err}; + return $self->resNotFound if $frm->{_err}; $self->authPref($_, $frm->{$_}) for ('notify_nodbedit', 'notify_announce'); $saved = 1; @@ -570,11 +569,11 @@ sub notifies { } elsif($self->reqMethod() eq 'POST') { return if !$self->authCheckCode; my $frm = $self->formValidate( - { name => 'notifysel', multi => 1, required => 0, template => 'int' }, - { name => 'markread', required => 0 }, - { name => 'remove', required => 0 } + { post => 'notifysel', multi => 1, required => 0, template => 'int' }, + { post => 'markread', required => 0 }, + { post => 'remove', required => 0 } ); - return 404 if $frm->{_err}; + return $self->resNotFound if $frm->{_err}; my @ids = grep $_, @{$frm->{notifysel}}; $self->dbNotifyMarkRead(@ids) if @ids && $frm->{markread}; $self->dbNotifyRemove(@ids) if @ids && $frm->{remove}; @@ -587,6 +586,7 @@ sub notifies { results => 25, what => 'titles', read => $f->{r} == 1 ? undef : 0, + reverse => $f->{r} == 1, ); $self->htmlHeader(title => mt('_usern_title'), noindex => 1); @@ -634,7 +634,7 @@ sub notifies { : 'item_edit'), sprintf('<i>%s</i>', xml_escape $l->{c_title}), sprintf('<i>%s</i>', xml_escape $l->{username}); end; - end; + end 'tr'; }, footer => sub { Tr; @@ -664,7 +664,7 @@ sub notifies { input type => 'submit', name => 'set', value => mt '_usern_set_submit'; end; end; - end; + end 'form'; $self->htmlFooter; } @@ -673,7 +673,7 @@ sub readnotify { my($self, $uid, $nid) = @_; return $self->htmlDenied if !$self->authInfo->{id} || $uid != $self->authInfo->{id}; my $n = $self->dbNotifyGet(uid => $uid, id => $nid)->[0]; - return 404 if !$n->{iid}; + return $self->resNotFound if !$n->{iid}; $self->dbNotifyMarkRead($n->{id}) if !$n->{read}; # NOTE: for t+.+ IDs, this will create a double redirect, which is rather awkward... $self->resRedirect("/$n->{ltype}$n->{iid}".($n->{subid}?".$n->{subid}":''), 'perm'); diff --git a/lib/VNDB/Handler/VNBrowse.pm b/lib/VNDB/Handler/VNBrowse.pm index 8a63b79b..97dc4e69 100644 --- a/lib/VNDB/Handler/VNBrowse.pm +++ b/lib/VNDB/Handler/VNBrowse.pm @@ -3,11 +3,11 @@ package VNDB::Handler::VNBrowse; use strict; use warnings; -use YAWF ':html'; +use TUWF ':html', 'uri_escape'; use VNDB::Func; -YAWF::register( +TUWF::register( qr{v/([a-z0]|all)} => \&list, ); @@ -16,16 +16,16 @@ sub list { my($self, $char) = @_; my $f = $self->formValidate( - { name => 's', required => 0, default => 'tagscore', enum => [ qw|title rel pop tagscore rating| ] }, - { name => 'o', required => 0, enum => [ 'a','d' ] }, - { name => 'p', required => 0, default => 1, template => 'int' }, - { name => 'q', required => 0, default => '' }, - { name => 'sq', required => 0, default => '' }, - { name => 'fil',required => 0, default => '' }, + { get => 's', required => 0, default => 'tagscore', enum => [ qw|title rel pop tagscore rating| ] }, + { get => 'o', required => 0, enum => [ 'a','d' ] }, + { get => 'p', required => 0, default => 1, template => 'int' }, + { get => 'q', required => 0, default => '' }, + { get => 'sq', required => 0, default => '' }, + { get => 'fil',required => 0 }, ); - return 404 if $f->{_err}; + return $self->resNotFound if $f->{_err}; $f->{q} ||= $f->{sq}; - $f->{fil} = $self->authPref('filter_vn') if !grep $_ eq 'fil', $self->reqParam(); + $f->{fil} //= $self->authPref('filter_vn'); my %compat = _fil_compat($self); return $self->resRedirect('/'.$1.$2.(!$3 ? '' : $1 eq 'd' ? '#'.$3 : '.'.$3), 'temp') @@ -60,11 +60,11 @@ sub list { end; a id => 'filselect', href => '#v'; - lit '<i>▸</i> '.mt('_rbrowse_filters').'<i></i>'; # TODO: it's not *r*browse + lit '<i>▸</i> '.mt('_js_fil_filters').'<i></i>'; end; input type => 'hidden', class => 'hidden', name => 'fil', id => 'fil', value => $f->{fil}; end; - end; # /form + end 'form'; $self->htmlBrowseVN($list, $f, $np, "/v/$char?q=$quri;fil=$f->{fil}", $f->{fil} =~ /tag_inc-/); $self->htmlFooter(prefs => ['filter_vn']); @@ -75,9 +75,9 @@ sub _fil_compat { my $self = shift; my %c; my $f = $self->formValidate( - { name => 'ln', required => 0, multi => 1, enum => $self->{languages}, default => '' }, - { name => 'pl', required => 0, multi => 1, enum => $self->{platforms}, default => '' }, - { name => 'sp', required => 0, default => $self->reqCookie($self->{cookie_prefix}.'tagspoil') =~ /^([0-2])$/ ? $1 : 0, enum => [0..2] }, + { get => 'ln', required => 0, multi => 1, enum => $self->{languages}, default => '' }, + { get => 'pl', required => 0, multi => 1, enum => $self->{platforms}, default => '' }, + { get => 'sp', required => 0, default => $self->reqCookie('tagspoil') =~ /^([0-2])$/ ? $1 : 0, enum => [0..2] }, ); return () if $f->{_err}; $c{lang} //= $f->{ln} if $f->{ln}[0]; diff --git a/lib/VNDB/Handler/VNEdit.pm b/lib/VNDB/Handler/VNEdit.pm index b93c544d..82f7e169 100644 --- a/lib/VNDB/Handler/VNEdit.pm +++ b/lib/VNDB/Handler/VNEdit.pm @@ -3,11 +3,11 @@ package VNDB::Handler::VNEdit; use strict; use warnings; -use YAWF ':html', ':xml'; +use TUWF ':html', ':xml'; use VNDB::Func; -YAWF::register( +TUWF::register( qr{v(?:([1-9]\d*)(?:\.([1-9]\d*))?/edit|/new)} => \&edit, qr{xml/vn\.xml} => \&vnxml, @@ -19,7 +19,7 @@ sub edit { my($self, $vid, $rev) = @_; my $v = $vid && $self->dbVNGet(id => $vid, what => 'extended screenshots relations anime changes', $rev ? (rev => $rev) : ())->[0]; - return 404 if $vid && !$v->{id}; + return $self->resNotFound if $vid && !$v->{id}; $rev = undef if !$vid || $v->{cid} == $v->{latest}; return $self->htmlDenied if !$self->authCan('edit') @@ -38,23 +38,23 @@ sub edit { if($self->reqMethod eq 'POST') { return if !$self->authCheckCode; $frm = $self->formValidate( - { name => 'title', maxlength => 250 }, - { name => 'original', required => 0, maxlength => 250, default => '' }, - { name => 'alias', required => 0, maxlength => 500, default => '' }, - { name => 'desc', required => 0, default => '', maxlength => 10240 }, - { name => 'length', required => 0, default => 0, enum => $self->{vn_lengths} }, - { name => 'l_wp', required => 0, default => '', maxlength => 150 }, - { name => 'l_encubed', required => 0, default => '', maxlength => 100 }, - { name => 'l_renai', required => 0, default => '', maxlength => 100 }, - { name => 'l_vnn', required => 0, default => $b4{l_vnn}||0, template => 'int' }, - { name => 'anime', required => 0, default => '' }, - { name => 'previmage', required => 0, default => 0, template => 'int' }, - { name => 'img_nsfw', required => 0, default => 0 }, - { name => 'vnrelations', required => 0, default => '', maxlength => 5000 }, - { name => 'screenshots', required => 0, default => '', maxlength => 1000 }, - { name => 'editsum', required => 0, maxlength => 5000 }, - { name => 'ihid', required => 0 }, - { name => 'ilock', required => 0 }, + { post => 'title', maxlength => 250 }, + { post => 'original', required => 0, maxlength => 250, default => '' }, + { post => 'alias', required => 0, maxlength => 500, default => '' }, + { post => 'desc', required => 0, default => '', maxlength => 10240 }, + { post => 'length', required => 0, default => 0, enum => $self->{vn_lengths} }, + { post => 'l_wp', required => 0, default => '', maxlength => 150 }, + { post => 'l_encubed', required => 0, default => '', maxlength => 100 }, + { post => 'l_renai', required => 0, default => '', maxlength => 100 }, + { post => 'l_vnn', required => 0, default => $b4{l_vnn}||0, template => 'int' }, + { post => 'anime', required => 0, default => '' }, + { post => 'previmage', required => 0, default => 0, template => 'int' }, + { post => 'img_nsfw', required => 0, default => 0 }, + { post => 'vnrelations', required => 0, default => '', maxlength => 5000 }, + { post => 'screenshots', required => 0, default => '', maxlength => 1000 }, + { post => 'editsum', required => 0, maxlength => 5000 }, + { post => 'ihid', required => 0 }, + { post => 'ilock', required => 0 }, ); push @{$frm->{_err}}, 'badeditsum' if !$frm->{editsum} || lc($frm->{editsum}) eq lc($frm->{desc}); @@ -86,7 +86,7 @@ sub edit { # nothing changed? just redirect return $self->resRedirect("/v$vid", 'post') - if $vid && !$self->reqUploadFileName('img') && $image == $v->{image} + if $vid && !$self->reqPost('img') && $image == $v->{image} && !grep $frm->{$_} ne $b4{$_}, keys %b4; # perform the edit/add @@ -123,31 +123,19 @@ sub edit { sub _uploadimage { my($self, $v, $frm) = @_; - return $v ? $frm->{previmage} : 0 if $frm->{_err} || !$self->reqUploadFileName('img'); + return $v ? $frm->{previmage} : 0 if $frm->{_err} || !$self->reqPost('img'); - # save to temporary location - my $tmp = sprintf '%s/static/cv/00/tmp.%d.jpg', $VNDB::ROOT, $$*int(rand(1000)+1); - $self->reqSaveUpload('img', $tmp); + # perform some elementary checks + my $imgdata = $self->reqUploadRaw('img'); + $frm->{_err} = [ 'noimage' ] if $imgdata !~ /^(\xff\xd8|\x89\x50)/; # JPG or PNG headers + $frm->{_err} = [ 'toolarge' ] if length($imgdata) > 512*1024; + return undef if $frm->{_err}; - # perform some checks - my $l; - open(my $T, '<:raw:bytes', $tmp) || die $1; - read $T, $l, 2; - close($T); - - $frm->{_err} = [ 'noimage' ] if $l ne pack('H*', 'ffd8') && $l ne pack('H*', '8950'); - $frm->{_err} = [ 'toolarge' ] if -s $tmp > 512*1024; - - if($frm->{_err}) { - unlink $tmp; - return undef; - } - - # get image ID and move it to the correct location + # get image ID and save it, to be processed by Multi my $imgid = $self->dbVNImageId; - my $new = sprintf '%s/static/cv/%02d/%d.jpg', $VNDB::ROOT, $imgid%100, $imgid; - rename $tmp, $new or die $!; - chmod 0666, $new; + my $fn = sprintf '%s/static/cv/%02d/%d.jpg', $VNDB::ROOT, $imgid%100, $imgid; + $self->reqSaveUpload('img', $fn); + chmod 0666, $fn; return -1*$imgid; } @@ -187,14 +175,15 @@ sub _form { h2 mt '_vnedit_image_upload'; input type => 'file', class => 'text', name => 'img', id => 'img'; - p mt('_vnedit_image_upload_msg')."\n\n\n"; + p mt('_vnedit_image_upload_msg'); + br; br; br; h2 mt '_vnedit_image_nsfw'; input type => 'checkbox', class => 'checkbox', id => 'img_nsfw', name => 'img_nsfw', $frm->{img_nsfw} ? (checked => 'checked') : (); label class => 'checkbox', for => 'img_nsfw', mt '_vnedit_image_nsfw_check'; p mt '_vnedit_image_nsfw_msg'; - end; + end 'div'; }], ], @@ -229,7 +218,7 @@ sub _form { a href => '#', mt '_vnedit_rel_addbut'; end; end; - end; + end 'table'; }], ], @@ -292,8 +281,8 @@ sub _updreverse { sub vnxml { my $self = shift; - my $q = $self->formValidate({ name => 'q', maxlength => 500 }); - return 404 if $q->{_err}; + my $q = $self->formValidate({ get => 'q', maxlength => 500 }); + return $self->resNotFound if $q->{_err}; $q = $q->{q}; my($list, $np) = $self->dbVNGet( @@ -321,9 +310,9 @@ sub scrxml { # fetch information about screenshots if($self->reqMethod ne 'POST') { my $ids = $self->formValidate( - { name => 'id', required => 1, template => 'int', multi => 1 } + { get => 'id', required => 1, template => 'int', multi => 1 } ); - return 404 if $ids->{_err}; + return $self->resNotFound if $ids->{_err}; my $r = $self->dbScreenshotGet($ids->{id}); xml; @@ -334,28 +323,22 @@ sub scrxml { } # upload new screenshot - my $num = $self->formValidate({name => 'upload', template => 'int'}); - return 404 if $num->{_err}; - my $tmp = sprintf '%s/static/sf/00/tmp.%d.jpg', $VNDB::ROOT, $$*int(rand(1000)+1); - $self->reqSaveUpload("scr_upl_file_$num->{upload}", $tmp); + my $num = $self->formValidate({get => 'upload', template => 'int'}); + return $self->resNotFound if $num->{_err}; + my $param = "scr_upl_file_$num->{upload}"; + # check for simple errors my $id = 0; - $id = -2 if !-s $tmp; - if(!$id) { - my $l; - open(my $T, '<:raw:bytes', $tmp) || die $1; - read $T, $l, 2; - close($T); - $id = -1 if $l ne pack('H*', 'ffd8') && $l ne pack('H*', '8950'); - } + my $imgdata = $self->reqUploadRaw($param); + $id = -2 if !$imgdata; + $id = -1 if !$id && $imgdata !~ /^(\xff\xd8|\x89\x50)/; # JPG or PNG headers - if($id) { - unlink $tmp; - } else { + # no error? save and let Multi process it + if(!$id) { $id = $self->dbScreenshotAdd; - my $new = sprintf '%s/static/sf/%02d/%d.jpg', $VNDB::ROOT, $id%100, $id; - rename $tmp, $new or die $!; - chmod 0666, $new; + my $fn = sprintf '%s/static/sf/%02d/%d.jpg', $VNDB::ROOT, $id%100, $id; + $self->reqSaveUpload($param, $fn); + chmod 0666, $fn; } xml; diff --git a/lib/VNDB/Handler/VNPage.pm b/lib/VNDB/Handler/VNPage.pm index 5e024424..ee121c9b 100644 --- a/lib/VNDB/Handler/VNPage.pm +++ b/lib/VNDB/Handler/VNPage.pm @@ -3,11 +3,11 @@ package VNDB::Handler::VNPage; use strict; use warnings; -use YAWF ':html', 'xml_escape'; +use TUWF ':html', 'xml_escape'; use VNDB::Func; -YAWF::register( +TUWF::register( qr{v/rand} => \&rand, qr{v([1-9]\d*)/rg} => \&rg, qr{v([1-9]\d*)(?:\.([1-9]\d*))?} => \&page, @@ -24,7 +24,7 @@ sub rg { my($self, $vid) = @_; my $v = $self->dbVNGet(id => $vid, what => 'relgraph')->[0]; - return 404 if !$v->{id} || !$v->{rgraph}; + return $self->resNotFound if !$v->{id} || !$v->{rgraph}; my $title = mt '_vnrg_title', $v->{title}; return if $self->htmlRGHeader($title, 'v', $v); @@ -50,7 +50,7 @@ sub page { what => 'extended anime relations screenshots rating ranking'.($rev ? ' changes' : ''), $rev ? (rev => $rev) : (), )->[0]; - return 404 if !$v->{id}; + return $self->resNotFound if !$v->{id}; my $r = $self->dbReleaseGet(vid => $vid, what => 'producers platforms'); @@ -80,13 +80,15 @@ sub page { end; if($v->{img_nsfw}) { p id => 'nsfw_show', $self->authPref('show_nsfw') ? (style => 'display: none') : (); - txt mt('_vnpage_imgnsfw_msg')."\n\n"; + txt mt('_vnpage_imgnsfw_msg'); + br; br; a href => '#', mt '_vnpage_imgnsfw_show'; - txt "\n\n".mt '_vnpage_imgnsfw_note'; + br; br; + txt mt '_vnpage_imgnsfw_note'; end; } } - end; + end 'div'; # /vnimg # general info table; @@ -145,8 +147,8 @@ sub page { end; end; - end; - end; + end 'table'; + end 'div'; clearfloat; # tags @@ -170,7 +172,7 @@ sub page { } end; } - end; + end 'div'; # /mainbox _releases($self, $v, $r); _stats($self, $v); @@ -268,10 +270,10 @@ sub _producers { a href => "/p$_->{id}", title => $_->{original}||$_->{name}, shorten $_->{name}, 30; txt ' & ' if $_ != $p[$#p]; } - txt "\n"; + br; } end; - end; + end 'tr'; } } @@ -300,7 +302,7 @@ sub _relations { } end; end; - end; + end 'tr'; } @@ -331,11 +333,11 @@ sub _anime { end; acronym title => $_->{title_kanji}||$_->{title_romaji}, shorten $_->{title_romaji}, 50; b ' ('.(defined $_->{type} ? mt("_animetype_$_->{type}").', ' : '').$_->{year}.')'; - txt "\n"; + br; } } end; - end; + end 'tr'; } @@ -379,7 +381,7 @@ sub _useroptions { end; } end; - end; + end 'tr'; } @@ -446,11 +448,11 @@ sub _releases { txt ' '; } end; - end; + end 'tr'; } } - end; - end; + end 'table'; + end 'div'; } @@ -489,7 +491,7 @@ sub _screenshots { } end; } - end; + end 'div'; } |