summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2008-10-26 13:23:15 +0100
committerYorhel <git@yorhel.nl>2008-10-26 13:23:15 +0100
commit45802c119b3f3a36ffae3296b37d51dd3a454f29 (patch)
treedde77096c1d248596c0c1d9b25f546db881ffd11
parent3fb8a1ca280184cbe9b9873b2c736cab446414ac (diff)
Removing all files we're not going to use with the rewrite
...this is basically everything we're going to rewrite
-rw-r--r--.gitignore1
-rw-r--r--data/tpl/defs.pl562
-rw-r--r--data/tpl/docs4
-rw-r--r--data/tpl/error10
-rw-r--r--data/tpl/hist102
-rw-r--r--data/tpl/home66
-rw-r--r--data/tpl/main161
-rw-r--r--data/tpl/pbrowse45
-rw-r--r--data/tpl/pedit44
-rw-r--r--data/tpl/ppage55
-rw-r--r--data/tpl/redit69
-rw-r--r--data/tpl/rlist90
-rw-r--r--data/tpl/rpage68
-rw-r--r--data/tpl/tedit33
-rw-r--r--data/tpl/tindex49
-rw-r--r--data/tpl/ttag60
-rw-r--r--data/tpl/tthread81
-rw-r--r--data/tpl/useredit36
-rw-r--r--data/tpl/userlist50
-rw-r--r--data/tpl/userlogin14
-rw-r--r--data/tpl/userpage13
-rw-r--r--data/tpl/userpass21
-rw-r--r--data/tpl/userreg38
-rw-r--r--data/tpl/vnbrowse108
-rw-r--r--data/tpl/vnedit120
-rw-r--r--data/tpl/vnlist63
-rw-r--r--data/tpl/vnpage204
-rw-r--r--data/tpl/vnpage_rel59
-rw-r--r--data/tpl/vnpage_rg11
-rw-r--r--data/tpl/vnpage_scr37
-rw-r--r--data/tpl/vnpage_stats39
-rw-r--r--data/tpl/wlist55
-rw-r--r--lib/VNDB.pm247
-rw-r--r--lib/VNDB/Discussions.pm193
-rw-r--r--lib/VNDB/HomePages.pm306
-rw-r--r--lib/VNDB/Producers.pm176
-rw-r--r--lib/VNDB/Releases.pm188
-rw-r--r--lib/VNDB/Users.pm238
-rw-r--r--lib/VNDB/Util/Auth.pm133
-rw-r--r--lib/VNDB/Util/DB.pm1582
-rw-r--r--lib/VNDB/Util/Request.pm46
-rw-r--r--lib/VNDB/Util/Response.pm220
-rw-r--r--lib/VNDB/Util/Template.pm235
-rw-r--r--lib/VNDB/Util/Tools.pm172
-rw-r--r--lib/VNDB/VN.pm419
-rw-r--r--lib/VNDB/VNLists.pm230
-rw-r--r--lib/global.pl687
-rw-r--r--static/files/blank.css0
-rw-r--r--static/files/def.js479
-rw-r--r--static/files/dyna.js815
-rw-r--r--static/files/footer.gifbin91 -> 0 bytes
-rw-r--r--static/files/graph.pngbin601 -> 0 bytes
-rw-r--r--static/files/headerbg.jpgbin6068 -> 0 bytes
-rw-r--r--static/files/headerbot.pngbin2343 -> 0 bytes
-rw-r--r--static/files/icons.pngbin3208 -> 0 bytes
-rw-r--r--static/files/rss.pngbin735 -> 0 bytes
-rw-r--r--static/files/select.pngbin1165 -> 0 bytes
-rw-r--r--static/files/sidebarbg.jpgbin3035 -> 0 bytes
-rw-r--r--static/files/sidebarbot.jpgbin1642 -> 0 bytes
-rw-r--r--static/files/sidebg.jpgbin553 -> 0 bytes
-rw-r--r--static/files/style.css923
-rw-r--r--static/files/uicons.pngbin4404 -> 0 bytes
-rw-r--r--static/files/warning.pngbin2348 -> 0 bytes
-rw-r--r--util/fcgi.pl124
64 files changed, 0 insertions, 9781 deletions
diff --git a/.gitignore b/.gitignore
index 47fa605d..4ce94ab6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,5 @@
/data/config.pl
/data/log/
-/data/tplcompiled.pm
/static/cv/
/static/rg/
/static/sf/
diff --git a/data/tpl/defs.pl b/data/tpl/defs.pl
deleted file mode 100644
index 9135adb1..00000000
--- a/data/tpl/defs.pl
+++ /dev/null
@@ -1,562 +0,0 @@
-[[!
-
-use Time::CTime ();
-use Algorithm::Diff 'sdiff';
-use POSIX ('ceil', 'floor');
-
-my %p; # $X->{page} global page data
-my %d; # $X->{page}->{$p} local page data
-
-# redefine _hchar - usually a bad idea, but who cares
-sub _hchar {local$_=shift||return'';s/&/&amp;/g;s/</&lt;/g;s/>/&gt;/g;s/"/&quot;/g;s/\r?\n/ <br \/>\n/g;return$_;}
-
-sub formatdate {return _hchar(Time::CTime::strftime($_[0],gmtime($_[1]||0)))||'';}
-sub txt {local$_=shift||return'';s/&/&amp;/g;s/</&lt;/g;s/>/&gt;/g;return$_;}
-sub art2str {my$r='';$r.=($r?' & ':'').$_->{name}foreach (@{$_[0]->{artists}});return $_[1]?$r:_hchar($r);}
-sub calctime {my$r=shift;return'0:00:00'if!$r;my$x=sprintf'%d:%02d:%02d',int($r/3600),int(($r%3600)/60),($r%3600)%60;return $x;}
-sub shorten {local$_=shift||return'';return length>$_[0]?substr($_,0,$_[0]-3).'...':$_};
-
-# Date string format: yyyy-mm-dd
-# y = 0 -> Unknown
-# y = 9999 -> TBA (To Be Announced)
-# m = 99 -> Month + day unknown, year known
-# d = 99 -> Day unknown, month + year known
-sub datestr {
- my $d = sprintf '%08d', $_[0]||0;
- my $b = $d > Time::CTime::strftime("%Y%m%d", gmtime());
- my @d = map int, $1, $2, $3 if $d =~ /^([0-9]{4})([0-9]{2})([0-9]{2})$/;
- return 'unknown' if $d[0] == 0;
- my $r = sprintf $d[1] == 99 ? '%04d' : $d[2] == 99 ? '%04d-%02d' : '%04d-%02d-%02d', @d;
- $r = 'TBA' if $d[0] == 9999;
- $r =~ s/^[0-9]{4}-// if $_[1];
- return ($b&&!$_[1]?'<b class="future">':'').$r.($b?'</b>':'');
-}
-sub mediastr {
- return join(', ', map {
- $_->{medium} =~ /^(cd|dvd|gdr|blr)$/
- ? sprintf('%d %s%s', $_->{qty}, $VNDB::MED->{$_->{medium}}, $_->{qty}>1?'s':'')
- : $VNDB::MED->{$_->{medium}}
- } @{$_[0]});
-}
-sub sortbut { # url, col
- my $r=' '; my $u = _hchar($_[0]);
- $u .= $u =~ /\?/ ? ';' : '?';
- for ('a', 'd') {
- my $chr = $_ eq 'd' ? "\x{25BE}" : "\x{25B4}";
- $r .= $d{order}[0] eq $_[1] && $d{order}[1] eq $_ ? $chr :
- sprintf '<a href="%ss=%s;o=%s">%s</a>', $u, $_[1], $_, $chr;
- }
- return $r;
-}
-sub pagebut { # url
- my @br; my $ng = $_[0] =~ /\?/ ? ';' : '?';
- push @br, sprintf '<a href="%s">&lt;- previous</a>', $_[0].($d{page}-2 ? $ng.'p='.($d{page}-1) : '') if $d{page} > 1;
- push @br, sprintf '<a href="%s">next -&gt;</a>', $_[0].$ng.'p='.($d{page}+1) if $d{npage};
- return $#br >= 0 ? ('<p class="browse">( '.join(' | ', @br).' )</p>') : '';
-}
-sub wraplong { # text, margin
- local $_ = $_[0];
- my $m = $_[1]/2;
- s/([^\s\r\n]{$m})([^\s\r\n])/$1 $2/g;
- return $_;
-}
-sub age {
- my $a = time-$_[0];
- return sprintf '%d %s%s',
- $a > 60*60*24*365*2 ? ( $a/60/60/24/365, 'years' ) :
- $a > 60*60*24*(365/12)*2 ? ( $a/60/60/24/(365/12), 'months' ) :
- $a > 60*60*24*7*2 ? ( $a/60/60/24/7, 'weeks' ) :
- $a > 60*60*24*2 ? ( $a/60/60/24, 'days' ) :
- $a > 60*60*2 ? ( $a/60/60, 'hours' ) :
- $a > 60*2 ? ( $a/60, 'min' ) :
- ( $a, 'sec' ),
- $_[1]?'':' ago';
-}
-sub userstr { # [ uid, username ] or a hashref containing those keys
- my($id,$n) = ref($_[0])eq'HASH'?($_[0]{uid}||$_[0]{requester}, $_[0]{username}):@_;
- return !$id ? '[deleted]' : '<a href="/u'.$id.'">'.$n.'</a>';
-}
-
-
-sub wordsplit { # split a string into an array of words, but make sure to not split HTML tags
-# return [ split //, $_[0] ];
- my @a;
- my $in='';
- for (split /\s+/, $_[0]) {
- my $gt = () = />/g;
- my $lt = () = /</g;
- if($in && $gt > $lt) {
- push @a, $in.$_;
- $in='';
- } elsif($lt > $gt || $in) {
- $in .= $_.' ';
- } else {
- push @a, $_;
- };
- }
- push @a, $in if $in;
- return \@a;
-}
-
-sub cdiff { # obj1, obj2, @items->[ short, name, serialise, diff, [parsed_x, parsed_y] ]
- my($x, $y, @items, @c) = @_;
- # serialise = 0 -> integer, 1 -> string, CODEref -> code
-
- my $type = defined $$y{minage} ? 'r' : defined $$y{length} ? 'v' : 'p';
- my $pre = '<div id="revbrowse">'.
- ($$y{next} ? qq|<a href="/$type$$y{id}.$$y{next}" id="revnext">later revision -&gt;</a>| : '').
- ($x ? qq|<a href="/$type$$y{id}.$$x{rev}" id="revprev">&lt;- earlier revision</a>| : '').
- qq|<a href="/$type$$y{id}" id="revmain">$type$$y{id}</a>&nbsp;</div>|;
-
- if(!$x) { # just show info about the revision if there is no previous edit
- return $pre.qq|<div id="tmc"><b>Revision $$y{rev}</b> (<a href="/$type$$y{id}/edit?rev=$$y{rev}">edit</a>)<br />By |.userstr($y).q| on |.
- formatdate('%Y-%m-%d at %R', $$y{added}).'<br /><b>Edit summary:</b><br /><br />'.
- summary($$y{comments}, 0, '[no summary]').'</div>';
- }
- for (@items) {
- $_->[4] = !$_->[2] ? $x->{$_->[0]}||'0' : !ref($_->[2]) ? _hchar(wraplong($x->{$_->[0]}||'[empty]',60)) : &{$_->[2]}($x->{$_->[0]})||'[empty]';
- $_->[5] = !$_->[2] ? $y->{$_->[0]}||'0' : !ref($_->[2]) ? _hchar(wraplong($y->{$_->[0]}||'[empty]',60)) : &{$_->[2]}($y->{$_->[0]})||'[empty]';
- push(@c, $_) if $_->[4] ne $_->[5];
- if($_->[3] && $_->[4] ne $_->[5]) {
- my($rx,$ry,$ch) = ('','','u');
- for (sdiff(wordsplit($_->[4]), wordsplit($_->[5]))) {
- if($ch ne $_->[0]) {
- if($ch ne 'u') {
- $rx .= '</b>';
- $ry .= '</b>';
- }
- $rx .= '<b class="diff_del">' if $_->[0] eq '-' || $_->[0] eq 'c';
- $ry .= '<b class="diff_add">' if $_->[0] eq '+' || $_->[0] eq 'c';
- }
- $ch = $_->[0];
- $rx .= $_->[1].' ' if $ch ne '+';
- $ry .= $_->[2].' ' if $ch ne '-';
- }
- $_->[4] = $rx;
- $_->[5] = $ry;
- }
- }
- return $pre.'<table id="tmc"><thead><tr><td class="tc1">&nbsp;</td>'.
- qq|<td class="tc2"><b>Revision $$x{rev}</b> (<a href="/$type$$y{id}/edit?rev=$$x{rev}">edit</a>)<br />By |.userstr($x).' on '.formatdate('%Y-%m-%d at %R', $$x{added}).'</td>'.
- qq|<td class="tc3"><b>Revision $$y{rev}</b> (<a href="/$type$$y{id}/edit?rev=$$y{rev}">edit</a>)<br />By |.userstr($y).' on '.formatdate('%Y-%m-%d at %R', $$y{added}).'</td>'.
- '</tr><tr></tr><tr><td>&nbsp;</td><td colspan="2"><b>Edit summary of revision '.$$y{rev}.'</b><br /><br />'.summary($$y{comments}, 0, '[no summary]').'<br /><br /></td></tr></thead>'.
- join('',map{
- '<tr><td class="tc1">'.$_->[1].'</td><td class="tc2">'.$_->[4].'</td><td class="tc3">'.$_->[5].'</td></tr>'
- } @c).'</table>';
-}
-
-
-sub summary { # cmd, len, def
- return $_[2]||'' if !$_[0];
- my $res = '';
- my $len = 0;
- my $as = 0;
- my $raw = 0;
- (my $txt = $_[0]) =~ s/\r?\n/\n /g;
- for (split / /, $txt) {
- next if !defined $_ || $_ eq '';
- my $l = length;
- s/\&/&amp;/g;
- s/>/&gt;/g;
- s/</&lt;/g;
- if(!$raw && s/^\[raw\]//) {
- $l -= 5;
- $raw++;
- }
- if(!$raw) {
- $l -= 9 while(s/\[spoiler\]/<b class="spoiler">/i);
- $l -= 10 while(s/\[\/spoiler\]/<\/b>/i);
- while(s/\[url=((https?:\/\/|\/)[^\]>]+)\]/<a href="$1" rel="nofollow">/i) {
- $l -= length($1)+6;
- $as++;
- }
- if(!$as && s/(http|https):\/\/(.+[0-9a-zA-Z=\/])/<a href="$1:\/\/$2" rel="nofollow">link<\/a>/) {
- $l = 4;
- } elsif(!$as) {
- s/^(.*[^\w]|)([tdvpr][1-9][0-9]*)\.([1-9][0-9]*)([^\w].*|)$/$1<a href="\/$2.$3">$2.$3<\/a>$4/ ||
- s/^(.*[^\w]|)([tduvpr][1-9][0-9]*)([^\w].*|)$/$1<a href="\/$2">$2<\/a>$3/;
- }
- while(s/\[\/url\]/<\/a>/i) {
- $l -= 6;
- $as--;
- }
- }
- if(s/\[\/raw\]//) {
- $l -= 6;
- $raw=0;
- }
- $len += $l + 1;
- last if $_[1] && $len > $_[1];
- $res .= "$_ ";
- }
- $res =~ y/\n/ / if $_[1];
- $res =~ s/\n/<br \/>/g if !$_[1];
- $res =~ s/ +$//;
- $res .= '</a>' x $as if $as;
- $res .= '...' if $_[1] && $len > $_[1];
- return $res;
-}
-
-
-sub ttabs { # [vrpu], obj, sel
- my($t, $o, $s) = @_;
- $s||='';
- my @act = (
- !$s?'%s':'<a href="/%s">%1$s</a>',
- $$o{locked} ?
- '<b>locked for editing</b>' : (),
- $p{Authlock} && $t ne 'u' ?
- sprintf('<a href="/%%s/lock">%s</a>', $$o{locked} ? 'unlock' : 'lock') : (),
- $p{Authdel} && $t ne 'u' ? (
- sprintf('<a href="/%%s/hide"%s>%s</a>', $t eq 'v' ? ' id="vhide"' : '', $$o{hidden} ? 'unhide' : 'hide') ) : (),
- $t eq 'u' && $p{Authusermod} ? (
- '<a href="/%s/del" id="userdel">del</a>' ) : (),
- ($t eq 'u' && $p{Authusermod}) || ($t ne 'u' && (!$$o{locked} && !$$o{hidden}) || ($p{Authedit} && $p{Authlock})) ?
- ($s eq 'edit' ? 'edit' : '<a href="'.($p{Authedit}?'/%s/edit':'/u/register?n=1').'" '.($t eq 'v' || $t eq 'r' ? 'class="dropdown" rel="nofollow editDD"':'').'>edit</a>') : (),
-
- $t eq 'u' ? (
- $o->{flags} & $VNDB::UFLAGS->{list} ? ( $s eq 'list' ? 'list' : '<a href="/%s/list">list</a>', ) : (),
- $o->{flags} & $VNDB::UFLAGS->{list} ? ( $s eq 'wish' ? 'wishlist' : '<a href="/%s/wish">wishlist</a>', ) : (),
- ) : (),
-
- $t ne 'r' ? (
- $s eq 'disc' ? 'discussions' : '<a href="/t/%s">discussions</a>', ) : (),
-
- $p{Authhist} ?
- ($s eq 'hist' ? 'history' : '<a href="/%s/hist">history</a>') : (),
- );
- return '<p class="mod">&lt; '.join(' - ', map { sprintf $_, $t.$$o{id} } @act).' &gt;</p>'.(
- !$p{Authedit} ? qq|
-<div id="editDD" class="dropdown">
- <ul>
- <li><b>Not logged in</b></li>
- <li><a href="/u/login">Login</a></li>
- <li><a href="/u/register">Register</a></li>
- </ul>
-</div>
- | : $t eq 'v' ? qq|
-<div id="editDD" class="dropdown">
- <ul>
- <li><a href="/v$$o{id}/edit" rel="nofollow">Edit all</a></li>
- <li><a href="/v$$o{id}/edit?fh=info" rel="nofollow">General info</a></li>
- <li><a href="/v$$o{id}/edit?fh=cat" rel="nofollow">Categories</a></li>
- <li><a href="/v$$o{id}/edit?fh=rel" rel="nofollow">Relations</a></li>
- <li><a href="/v$$o{id}/edit?fh=img" rel="nofollow">Image</a></li>
- <li><a href="/v$$o{id}/edit?fh=scr" rel="nofollow">Screenshots</a></li>
- <li><a href="/v$$o{id}/add" rel="nofollow">Add release</a></li>
- </ul>
-</div>| : $t eq 'r' ? qq|
-<div id="editDD" class="dropdown">
- <ul>
- <li><a href="/r$$o{id}/edit" rel="nofollow">Edit all</a></li>
- <li><a href="/r$$o{id}/edit?fh=info" rel="nofollow">General info</a></li>
- <li><a href="/r$$o{id}/edit?fh=pnm" rel="nofollow">Platforms &amp; media</a></li>
- <li><a href="/r$$o{id}/edit?fh=prod" rel="nofollow">Producers</a></li>
- <li><a href="/r$$o{id}/edit?fh=rel" rel="nofollow">Relations</a></li>
- </ul>
-</div>| : ''
- );
-}
-
-
-# Uwaaaa~ ugly function!
-sub rlist_dd {
- my $r = shift;
- return
- qq|<div class="dropdown rlistdd" id="rlistDD$$r{id}"><ul><li><b>Release status</b></li>|.
- join('', map {
- $r->{rlist} && $_ == $r->{rlist}{rstat} ? qq|<li><b><acronym class="uicons r$_">&nbsp;</acronym>&nbsp;$$VNDB::RSTAT[$_]</b></li>|
- : qq|<li><a href="/r$$r{id}/list?r=$_"><acronym class="uicons r$_">&nbsp;</acronym>&nbsp;$$VNDB::RSTAT[$_]</a></li>|
- } 0..$#$VNDB::RSTAT).
- qq|</ul><ul><li><b>Play status</b></li>|.
- join('', map {
- $r->{rlist} && $_ == $r->{rlist}{vstat} ? qq|<li><b><acronym class="uicons v$_">&nbsp;</acronym>&nbsp;$$VNDB::VSTAT[$_]</b></li>|
- : qq|<li><a href="/r$$r{id}/list?v=$_"><acronym class="uicons v$_">&nbsp;</acronym>&nbsp;$$VNDB::VSTAT[$_]</a></li>|
- } 0..$#$VNDB::VSTAT).
- qq|</ul><ul class="full">|.
- ($r->{rlist} ? qq|<li class="center"><a href="/r$$r{id}/list?d=1">remove from my list</a></li>|
- : qq|<li class="center"><b>not in your list</b></li>|).
- qq|</ul></div>|;
-}
-
-
-my %pagetitles = (
- faq => 'Frequently Asked Questions',
- userlogin => 'Login',
- userreg => 'Register a new account',
- userpass => 'Forgot your password?',
- home => 'Visual Novel Database',
- pbrowse => 'Browse producers',
- userlist => 'Browse users',
- tindex => 'Discussion board index',
- ttag => sub {
- return ($p{ttag}{obj} ? 'Related discussions for ' : '').$p{ttag}{title} },
- tthread => sub {
- return $p{tthread}{t}{title} },
- tedit => sub {
- return $p{tedit}{p} ? 'Edit post' :
- $p{tedit}{t} ? 'Reply to thread' : 'Start a new thread' },
- userpage => sub {
- return 'User: '.$p{userpage}{user}{username} },
- vnlist => 'My visual novel list (old)',
- wlist => sub {
- return $p{wlist}{user}{username} eq $p{AuthUsername} ? 'My wishlist' : ($p{wlist}{user}{username}.'\'s wishlist'); },
- rlist => sub {
- return $p{rlist}{user}{username} eq $p{AuthUsername} ? 'My visual novel list' : ($p{rlist}{user}{username}.'\'s visual novel list'); },
- useredit => sub {
- return !$p{useredit}{adm} ? 'My account' : 'Edit '.$p{useredit}{form}{username}.'\'s account'; },
- ppage => sub {
- return $p{ppage}{prod}{name} },
- pedit => sub {
- return $p{pedit}{id} ? sprintf('Edit %s', $p{pedit}{form}{name}) : 'Add a new producer'; },
- vnedit => sub {
- return $p{vnedit}{id} ? sprintf('Edit %s', $p{vnedit}{form}{title}) : 'Add a new visual novel'; },
- redit => sub {
- return $p{redit}{id} ? sprintf('Edit %s', $p{redit}{rel}{title}) : sprintf('Add release to %s', $p{redit}{vn}{title}); },
- vnpage => sub { return $p{vnpage}{vn}{title}; },
- vnrg => sub { return 'Relations for '.$p{vnrg}{vn}{title} },
- vnstats => sub { return 'User statistics for '.$p{vnstats}{vn}{title} },
- vnbrowse => sub {
- return $p{vnbrowse}{chr} eq 'search' ? 'Visual novel search' :
- $p{vnbrowse}{chr} eq 'mod' ? 'Visual Novels awaiting moderation' :
- $p{vnbrowse}{chr} eq 'all' ? 'Browse all visual novels' :
- $p{vnbrowse}{chr} eq '0' ? 'Browse by char: Other' :
- sprintf 'Browse by char: %s', uc $p{vnbrowse}{chr}; },
- rpage => sub {
- return $p{rpage}{rel}{romaji} || $p{rpage}{rel}{title} },
- hist => sub {
- return !$p{hist}{id} || !$p{hist}{type} ? 'Recent changes' :
- $p{hist}{type} eq 'u' ? 'Recent changes by '.$p{hist}{title} : 'Edit history of '.$p{hist}{title}; },
- docs => sub { $p{docs}{title} },
- error => sub {
- $p{error}{err} eq 'notfound' ? '404 Page Not Found' : 'Error Parsing Form' },
-);
-sub gettitle{$p{$_}&&($p{PageTitle}=ref($pagetitles{$_}) eq 'CODE' ? &{$pagetitles{$_}} : $pagetitles{$_}) for (keys%pagetitles);}
-
-
-#
-# F O R M E R R O R H A N D L I N G
-#
-my %formerr_names = (
- # this list is rather incomplete...
- mail => 'Email',
- username => 'Username',
- userpass => 'Password',
- pass1 => 'Password',
- pass2 => 'Password (second)',
- title => 'Title',
- desc => 'Description',
- rel => 'Relation',
- romaji => 'Romanized title',
- lang => 'Language',
- web => 'Website',
- released => 'Release date',
- platforms => 'Platforms',
- media => 'Media',
- name => 'Name',
- vn => 'Visual novel relations',
- l_vnn => 'Visual-novels.net link',
- comm => 'Edit summary',
- msg => 'Message',
-);
-my @formerr_msgs = (
- sub { return sprintf 'Field "%s" is required.', @_ },
- sub { return sprintf '%s should have at least %d characters.', @_ },
- sub { return sprintf '%s is too large! Only %d characters allowed.', @_ },
- sub { return
- $_[1] eq 'mail' ? 'Invalid email address' :
- $_[1] eq 'url' ? 'Invalid URL' :
- $_[1] eq 'pname' ? sprintf('%s can only contain alfanumeric characters!', $_[0]) :
- $_[1] eq 'asciiprint' ? sprintf('Only ASCII characters are allowed at %s', $_[0]) :
- $_[1] eq 'int' ? sprintf('%s should be a number!', $_[0]) :
- $_[1] eq 'gtin' ? 'Not a valid JAN, UPC or EAN code!' : '';
- },
- sub { return sprintf '%s: invalid item selected', @_ },
- sub { return 'Invalid unicode, are you sure your browser works fine?' },
-);
-my %formerr_exeptions = (
- loginerr => 'Invalid username or password',
- badpass => 'Passwords do not match',
- usrexists => 'Username already exists, please choose an other one',
- mailexists => 'There already is a user with that email address, please request a new password if you forgot it',
- nomail => 'No user found with that email address',
- nojpeg => 'Image is not in JPEG or PNG format!',
- toolarge => 'Image is too large (in filesize), try to compress it a little',
- wrongtag => 'Wrong tag selected!',
-);
-sub formerr {
- my @err = ref $_[0] eq 'ARRAY' ? @{$_[0]} : ();
- return '' if $#err < 0;
- my @msgs;
- my $ret = '<span class="warning">
- Error:<ul>';
- $ret .= sprintf " <li>%s</li>\n",
- /^([a-z0-9_]+)-([0-9]+)(?:-(.+))?$/ ? &{$formerr_msgs[$2-1]}($formerr_names{$1}||$1, $3||'') : $formerr_exeptions{$_}
- foreach (@err);
- $ret .= "</ul>\n</span>\n";
-}
-
-#
-# F O R M C R E A T I N G
-#
-
-# args = [
-# {
-# type => $type,
-# %options
-# }, ...
-# ], $formobj
-#
-# $type $formobj %options ( required, [ optional ] )
-# error X ( )
-# startform ( action, [ upload ] )
-# endform ( )
-# input X ( short, name, [ class, default ] )
-# pass ( short, name )
-# upload ( short, name, [ class ] )
-# hidden X ( short, [ value ] )
-# textarea X ( short, name, [ rows, cols, class ] )
-# select X ( short, name, options, [ class ] ) # options = arrayref of hashes with keys: short, name
-# as X ( name )
-# trans X ( )
-# submit ( [ text, short ] )
-# sub ( title )
-# check X ( short, name, [ value ] )
-# static ( text, raw [ name, class ] )
-# date X ( short, name )
-#
-sub cform {
- my $obj = shift;
- my $frm = shift;
- my $ret = '';
- my $csub = '';
- for (@$obj) {
- $_->{class} ||= '';
- $_->{class} .= ' sf_'.$csub if $csub && $_->{class} !~ /nohid/;
- $_->{class} .= ' formhid' if $csub && $frm->{_hid} && !$frm->{_hid}{$csub} && $_->{class} !~ /nohid/;
- $_->{name} = '<i>*</i> '.$_->{name} if $_->{r};
-
- # error
- if($_->{type} eq 'error') {
- $ret .= formerr($frm->{_err});
- # startform
- } elsif($_->{type} eq 'startform') {
- $ret .= sprintf qq|<form action="/nospam?%s" method="post" accept-charset="utf-8"%s>\n|,
- $_->{action}, $_->{upload} ? ' enctype="multipart/form-data"' : '';
- $ret .= sprintf qq| <input type="hidden" class="hidden" name="fh" id="_hid" value="%s" />\n|,
- $frm->{_hid} ? _hchar(join(',', keys %{$frm->{_hid}})) : '' if $_->{fh};
- $ret .= qq|<p class="formnotice">Items denoted by a red asterisk (<i>*</i>) are required.</p>\n|
- if scalar grep { $_->{r} } @$obj;
- $ret .= "<ul>\n";
- # endform
- } elsif($_->{type} eq 'endform') {
- $ret .= qq|</ul></form>\n|;
- # input
- } elsif($_->{type} eq 'input') {
- $ret .= sprintf qq|<li%s>\n <label for="%s">%s</label>\n %s<input type="text" class="text" name="%2\$s" id="%2\$s" value="%s" />%s\n</li>\n|,
- $_->{class} ? ' class="'.$_->{class}.'"' : '', $_->{short}, $_->{name}, $_->{pre} ? '<i>'.$_->{pre}.'</i>' : '',
- _hchar($frm->{$_->{short}}?$frm->{$_->{short}}:$_->{default}), $_->{post} ? '<i>'.$_->{post}.'</i>' : '';
- # pass
- } elsif($_->{type} eq 'pass') {
- $ret .= sprintf qq|<li%s>\n <label for="%s">%s</label>\n <input type="password" class="text" name="%2\$s" id="%2\$s" />\n</li>\n|,
- $_->{class} ? ' class="'.$_->{class}.'"' : '', $_->{short}, $_->{name};
- # upload
- } elsif($_->{type} eq 'upload') {
- $ret .= sprintf qq|<li%s>\n <label for="%s">%s</label>\n <input type="file" class="text" name="%2\$s" id="%2\$s" />\n</li>\n|,
- $_->{class} ? ' class="'.$_->{class}.'"' : '', $_->{short}, $_->{name};
- # hidden
- } elsif($_->{type} eq 'hidden') {
- $ret .= sprintf qq| <input type="hidden" class="hidden" name="%s" id="%1\$s" value="%s" />\n|,
- $_->{short}, _hchar($_->{value} || $frm->{$_->{short}});
- # textarea
- } elsif($_->{type} eq 'textarea') {
- $ret .= sprintf qq|<li%s>\n <label for="%s">%s</label>\n <textarea name="%2\$s" id="%2\$s" rows="%s" cols="%s">%s</textarea>\n</li>\n|,
- $_->{class} ? ' class="'.$_->{class}.'"' : '', $_->{short}, $_->{name}, $_->{rows}||15, $_->{cols}||70, txt($frm->{$_->{short}});
- # select
- } elsif($_->{type} eq 'select') {
- $ret .= sprintf qq|<li%s>\n <label for="%s">%s</label>\n <select name="%2\$s" id="%2\$s">\n%s</select>\n</li>\n|,
- $_->{class} ? ' class="'.$_->{class}.'"' : '', $_->{short}, $_->{name}, eval {
- my $r='';
- for my $s (@{$_->{options}}) {
- $r .= sprintf qq| <option value="%s"%s>%s</option>\n|,
- $s->{short}, defined $frm->{$_->{short}} && $frm->{$_->{short}} eq $s->{short} ? ' selected="selected"' : '', $s->{name};
- }
- return $r;
- };
- # jssel
- } elsif($_->{type} eq 'jssel') {
- (my $oname = $_->{name}) =~ s/^<i>\*<\/i>//;
- $ret .= sprintf
- qq|<li%s>\n|
- .qq| <label for="%s_select">%s</label>\n|
- .qq| <select name="%s_select" id="%s_select" multiple="multiple" size="5" class="multiple">\n|
- .qq| <option value="0_new" style="font-style: italic">Add %s...</option>\n|
- .qq| </select>\n|
- .qq| <div id="%s_conts">\n|
- .qq| Loading...\n|
- .qq| </div>\n|
- .qq| <input type="hidden" name="%s" id="%s" class="hidden" value="%s" />\n|
- .qq|</li>\n|,
- $_->{class} ? ' class="'.$_->{class}.'"' : '',
- $_->{sh}, $_->{name}, $_->{sh}, $_->{sh}, $oname, $_->{sh}, $_->{short}, $_->{short}, _hchar($frm->{$_->{short}});
- # submit
- } elsif($_->{type} eq 'submit') {
- $ret .= sprintf qq|<li class="nolabel">\n <br /><input type="submit" class="submit" value="%s"%s />\n </li>\n|,
- $_->{text} || 'Verstuur', $_->{short} ? sprintf(' name="%s" id="%1$s"', $_->{short}) : '';
- # sub
- } elsif($_->{type} eq 'sub') {
- $ret .= sprintf qq|<li class="subform">\n <a href="#" class="s_%s">%s %s</a>\n</li>\n|,
- $_->{short}, $frm->{_hid} && !$frm->{_hid}{$_->{short}} ? '&#9656;' : '&#9662;', $_->{title};
- $csub = $_->{short};
- # check
- } elsif($_->{type} eq 'check') {
- $ret .= sprintf qq|<li class="nolabel%s">\n <input type="checkbox" name="%s" id="%2\$s" value="%s"%s />\n <label for="%2\$s" class="checkbox">%s</label>\n</li>\n|,
- $_->{class} ? ' '.$_->{class} : '',
- $_->{short}, $_->{value} || 'true', $frm->{$_->{short}} ? ' checked="checked"' : '', $_->{name};
- # static
- } elsif($_->{type} eq 'static') {
- $ret .= $_->{name}
- ? sprintf qq|<li%s>\n <label>%s</label>\n <p>%s</p>\n</li>|, $_->{class} ? ' class="'.$_->{class}.'"' : '', $_->{name}, $_->{text}
- : $_->{raw}
- ? sprintf qq|<li%s>\n %s\n</li>|, $_->{class} ? ' class="'.$_->{class}.'"' : '', $_->{text}
- : sprintf qq|<li class="nolabel%s">\n %s\n</li>|, $_->{class} ? ' '.$_->{class} : '', $_->{text};
- # date
- } elsif($_->{type} eq 'date') {
- $ret .= sprintf qq|<li class="date%s">\n <label for="%s">%s</label>\n|,
- $_->{class} ? ' '.$_->{class} : '', $_->{short}, $_->{name};
- $ret .= sprintf qq| <select name="%s" id="%s">\n%s</select>\n|,
- $_->{short}, $_->{short}, eval {
- my $r='';
- for my $s (0, 1980..((localtime())[5]+1905), 9999) {
- $r .= sprintf qq| <option value="%s"%s>%s</option>\n|,
- $s, $frm->{$_->{short}} && ($frm->{$_->{short}}[0]||0) == $s ? ' selected="selected"' : '',
- !$s ? '-year-' : $s < 9999 ? $s : 'TBA';
- }
- return $r;
- };
- $ret .= sprintf qq| <select name="%s" id="%s_m">\n%s</select>\n|,
- $_->{short}, $_->{short}, eval {
- my $r='';
- for my $s (0..12) {
- $r .= sprintf qq| <option value="%s"%s>%s</option>\n|,
- $s, $frm->{$_->{short}} && ($frm->{$_->{short}}[1]||0) == $s ? ' selected="selected"' : '',
- $s ? $Time::CTime::MonthOfYear[$s-1] : '-month-';
- }
- return $r;
- };
- $ret .= sprintf qq| <select name="%s" id="%s_d">\n%s</select>\n</li>\n|,
- $_->{short}, $_->{short}, eval {
- my $r='';
- for my $s (0..31) {
- $r .= sprintf qq| <option value="%s"%s>%s</option>\n|,
- $s, $frm->{$_->{short}} && ($frm->{$_->{short}}[2]||0) == $s ? ' selected="selected"' : '',
- $s ? $s : '-day-';
- }
- return $r;
- };
- }
- }
- return $ret;
-}
-
-]]
diff --git a/data/tpl/docs b/data/tpl/docs
deleted file mode 100644
index 6aeefe81..00000000
--- a/data/tpl/docs
+++ /dev/null
@@ -1,4 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-<div id="dpage">
-[[= $d{content} ]]
-</div>
diff --git a/data/tpl/error b/data/tpl/error
deleted file mode 100644
index 995293d1..00000000
--- a/data/tpl/error
+++ /dev/null
@@ -1,10 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-[[ if($d{err} eq 'notfound') { ]]
- The page you were looking for could not be found!
-
-[[ } elsif($d{err} eq 'formerr') { ]]
-<span class="warning">
- <b>Error:</b> The form could not be sent, please make sure you have Javascript
- enabled in your browser!
-</span>
-[[ } ]]
diff --git a/data/tpl/hist b/data/tpl/hist
deleted file mode 100644
index fd8863b4..00000000
--- a/data/tpl/hist
+++ /dev/null
@@ -1,102 +0,0 @@
-[[= $d{type} ? ttabs($d{type}, $d{obj}, 'hist') : '' ]]-
-<h2 class="rss">[[: $p{PageTitle} ]]</h2>
-[[ if($d{type} eq 'u' && $#{$d{hist}} < 0) { ]]
-<p>
- You haven't made any changes yet.
-</p>
-[[ } ]]
-<br /><br />
-
-[[
- my $url = !$d{type} ? '/hist' : '/'.$d{type}.$d{id}.'/hist';
- my $furl = $url.'?e='.$d{sele}.';t=';
- my $eurl = $url.'?t='.$d{selt}.';e=';
- my $purl = !$d{type}?$eurl.$d{sele}:$d{type} eq 'v' && $d{seli} ? $url.'?i=1' : $url;
- my $rurl = $url.'/rss.xml'.(!$d{type}?'?t='.$d{selt}.';e='.$d{sele}:$d{type} eq 'v' && $d{seli} ? '?i=1' : '');
- local $_ = $d{selt};
- my @fil = (
- /a/ ? 'all items' : '<a href="%sa">all items</a>',
- /v/ ? 'visual novels' : '<a href="%sv">visual novels</a>',
- /r/ ? 'releases' : '<a href="%sr">releases</a>',
- /p/ ? 'producers' : '<a href="%sp">producers</a>',
- );
- local $_ = $d{sele};
- my @edi = (
- /0/ ? 'all changes' : '<a href="%s0">all changes</a>',
- /2/ ? 'edits only' : '<a href="%s2">edits only</a>',
- /1/ ? 'newly created pages only' : '<a href="%s1">newly created pages only</a>',
- );
- local $_ = $d{seli};
- my @inc = (
- /0/ ? 'exclude' : '<a href="'.$url.'">exclude</a>',
- /1/ ? 'include' : '<a href="'.$url.'?i=1">include</a>',
- );
-]]
-
-[[ if(!$d{type}) { ]]-
-<p class="browse">
- [[= join(' | ', map { sprintf $_, $furl } @fil) ]]<br />
- [[= join(' | ', map { sprintf $_, $eurl } @edi) ]]<br /><br /><br />
-</p>
-[[ } if($d{type} eq 'v') { ]]-
-<p class="browse">
- ([[= join(' | ', @inc) ]]) edits of releases.
-</p>
-[[ } ]]
-
-[[ if($d{act} eq 'r') { ]]
-<span class="msg">
- Performed the mass-revert, please see the following list for details.
-</span>
-[[ } elsif($d{act} eq 'd') { ]]
-<span class="msg">
- The following edits have been completely deleted.
-</span>
-[[ } ]]-
-
-
-<a class="rss" href="[[= $rurl ]]">RSS</a>
-[[= pagebut($purl) ]]
-[[ if(0 and $p{Authmod} || $p{Authdel}) { ]]
-<form method="post" action="[[= $purl ]]" class="tblf">
-[[ } ]]
-<table id="thi">
- <thead><tr>
- <td class="tc1" colspan="2">Rev.</td>
- <td class="tc2">Date</td>
- [[ if($d{type} ne 'u' || $d{act}) { ]]-
- <td class="tc3">User</td>[[ } ]]-
- [[ if(!$d{type} || $d{type} eq 'u' || $d{act}) { ]]-
- <td class="tc4">Page</td>[[ } ]]-
- [[ if($d{type} && !$d{act}) { ]]-
- <td class="tc5">Summary</td>[[ } ]]-
- [[ if($d{act} eq 'r') { ]]-
- <td class="tc5">Action</td>[[ } ]]-
- [[ if(0 and $p{Authmod}) { ]]-
- <td class="tc6"><input type="checkbox" id="checkall" name="sel" value="all" /></td>[[ } ]]-
- </tr></thead>
-
- [[ for (@{$d{hist}}) { my $t = (qw|v r p|)[$_->{type}]; ]]-
- <tr>
- <td class="tc1_1"><a href="/[[= $t.$_->{iid}.'.'.$_->{rev} ]]">[[= $_->{rev} == 1 ? "<b>$t$_->{iid}</b>" : $t.$_->{iid} ]]</a></td>
- <td class="tc1_2"><a href="/[[= $t.$_->{iid}.'.'.$_->{rev} ]]">.[[= $_->{rev} == 1 ? '<b>'.$_->{rev}.'</b>' : $_->{rev} ]]</a></td>
- <td class="tc2">[[= formatdate('%Y-%m-%d %R', $_->{added}, 'dh') ]]</td>
- [[ if($d{type} ne 'u' || $d{act}) { ]]-
- <td class="tc3">[[= userstr $_ ]]</td>[[ } ]]-
- [[ if(!$d{type} || $d{type} eq 'u' || $d{act}) { ]]-
- <td class="tc4"><a href="/[[= $t.$_->{iid} ]].[[= $_->{rev} ]]" title="[[: $_->{ioriginal}||$_->{ititle} ]]">[[: shorten $_->{ititle}, 30 ]]</a></td>[[ } ]]-
- [[ if($d{type} && !$d{act}) { ]]-
- <td class="tc5">[[= summary($_->{comments}, $d{type} eq 'u' ? 40 : 60)||'[empty]' ]]</td>[[ } ]]-
- [[ if($d{act} eq 'r') { ]]-
- <td class="tc5">[[: $_->{_status} ]]</td>[[ } ]]-
- [[ if(0 and $p{Authmod} && !$d{act}) { ]]-
- <td class="tc6"><input type="checkbox" name="sel" value="[[= $_->{id} ]]" /></td>[[ } ]]-
- </tr>
- [[ } ]]
-
-</table>
-[[ if(0 and $p{Authmod}) { ]]<input type="submit" class="right" name="post" value="Mass revert" />[[ } ]]
-[[ if(0 and $p{Authdel}) { ]]<input type="submit" class="right" name="post" value="Mass delete" id="massdel" />[[ } ]]
-[[ if(0 and $p{Authmod} || $p{Authdel}) { ]]</form>[[ } ]]
-[[= pagebut($purl) ]]
-
diff --git a/data/tpl/home b/data/tpl/home
deleted file mode 100644
index 3b36246d..00000000
--- a/data/tpl/home
+++ /dev/null
@@ -1,66 +0,0 @@
-<h2>Welcome to VNDB - The Visual Novel Database!</h2>
-<p class="desc">
- <br />
- VNDB.org strives to be a comprehensive database for information about visual novels and
- eroge.<br />
- This website is built as a wiki, meaning that anyone can freely add and contribute information
- to the database, allowing us to create the largest, most accurate and most up-to-date visual novel
- database on the web.<br />
- Registered users are also able to keep track of a personal list of games they want to play or have finished
- and they can vote on all visual novels.<br /><br />
-
- Feel free to <a href="/v">browse around</a>, <a href="/u/register">register an account</a>
- or to participate in the discussions about visual novels or VNDB on our <a href="/t">discussion board</a>.
-</p>
-
-[[ if($d{an}{title}) { ]]-
-<h3 class="home">[[: $d{an}{title} ]]-
- <p class="actions">[[= age $d{anpost}{date} ]]</p></h3>
-<p class="desc">
- [[= summary $d{anpost}{msg}, 200 ]]
- <br />
- <a href="/t[[= $d{an}{id} ]]">Read more...</a> - <a href="/t/an">news archive</a>.
-</p>
-[[ } ]]-
-
-<ul class="home">
- <li><b>Recent changes</b></li>
- [[ for (@{$d{recentedits}}) { my $t = (qw|v r p|)[$_->{type}]; ]]-
- <li>[[= $t ]]:<a href="/[[= $t.$_->{iid}.'.'.$_->{rev} ]]" title="[[: $_->{ioriginal}||$_->{ititle} ]]">[[: shorten $_->{ititle}, 30 ]]</a></li>
- [[ } ]]-
-</ul>
-
-<ul class="home">
- <li><b>Recent posts</b></li>
- [[ for (@{$d{recentposts}}) { ]]-
- <li><a href="/t[[= $_->{id}.'.'.$_->{count} ]]" title="[[: $_->{original}||$_->{title} ]]">[[: shorten $_->{title}, 25 ]]</a> <i>[[= age $_->{ldate}, 1 ]]</i></li>
- [[ } ]]-
-</ul>
-
-<ul class="home">
- <li><b>Upcoming releases</b></li>
- [[ for (@{$d{upcomingrel}}) { ]]-
- <li>[[= datestr $_->{released}, 1 ]]- <a href="/r[[= $_->{id} ]]" title="[[: $_->{original}||$_->{title} ]]">[[: shorten $_->{title}, 25 ]]</a></i></li>
- [[ } ]]-
-</ul>
-
-<ul class="home break">
- <li><b>Recently added visual novels</b></li>
- [[ for (@{$d{recentvns}}) { ]]-
- <li><a href="/v[[= $_->{iid} ]]" title="[[: $_->{ioriginal}||$_->{ititle} ]]">[[: shorten $_->{ititle}, 30 ]]</a></li>
- [[ } ]]-
-</ul>
-
-<ul class="home">
- <li><b>Random visual novels</b></li>
- [[ for (@{$d{randomvns}}) { ]]-
- <li><a href="/v[[= $_->{id} ]]" title="[[: $_->{original}||$_->{title} ]]">[[: shorten $_->{title}, 30 ]]</a></li>
-[[ } ]]-
-</ul>
-
-<ul class="home">
- <li><b>Just released</b></li>
- [[ for (@{$d{justrel}}) { ]]-
- <li>[[= datestr $_->{released}, 1 ]]- <a href="/r[[= $_->{id} ]]" title="[[: $_->{original}||$_->{title} ]]">[[: shorten $_->{title}, 25 ]]</a></i></li>
- [[ } ]]-
-</ul>
diff --git a/data/tpl/main b/data/tpl/main
deleted file mode 100644
index a9c4a69d..00000000
--- a/data/tpl/main
+++ /dev/null
@@ -1,161 +0,0 @@
-[[+ defs.pl ]]
-[[ %p = %{$X->{page}}; gettitle(); ]]
-
-<!DOCTYPE html
- PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-
-<head>
- <title>[[: $p{PageTitle} ]]- :: VNDB</title>
- <link href="[[: $p{st} ]]/files/style.css?[[= $VNDB::VERSION ]]" rel="stylesheet" type="text/css" media="screen" />
- <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
-[[ if($p{redit} || $p{vnedit}) { ]]-
- <script src="[[: $p{st} ]]/files/dyna.js?[[= $VNDB::VERSION ]]" type="text/javascript"></script>
-[[ } ]]-
- <script src="[[: $p{st} ]]/files/def.js?[[= $VNDB::VERSION ]]" type="text/javascript"></script>
-[[ if(0 && $p{devshit}) { ]]-
- <link rel="icon" href="/favicon.gif" type="image/gif" />
- <meta name="robots" content="noindex, nofollow" />
-[[ } elsif(
- grep($p{$_}, qw| userlist userpage userlogin userreg userpass vnlist rlist wlist hist |)
- || ($p{ttag} && $p{ttag}{iid})
- || ($p{vnpage} && $p{vnpage}{page} eq 'stats')
- || grep { $p{$_} && $p{$_}{change} } qw|vnpage ppage rpage|
- ) { ]]-
- <meta name="robots" content="noindex, follow" />
-[[ }]]-
-
-[[if($p{hist}){ ]]
- <link rel="alternate" type="application/rss+xml" title="Recent changes" href="
- [[= (!$p{hist}{type}?'/hist':'/'.$p{hist}{type}.$p{hist}{id}.'/hist').'/rss.xml'.(!$p{hist}{type}?'?t='.$p{hist}{selt}.';e='.$p{hist}{sele}:$p{hist}{type} eq 'v' && $p{hist}{seli} ? '?i=1':'') ]]" />
-[[ } ]]-
-</head>
-
-<body>
-<div id="header">
- <form id="search" method="get" action="/v/search">
- <fieldset>
- <legend>Search</legend>
- <input id="searchfield" type="text" name="sq" value="search" style="color: #999" />
- <input id="searchsubmit" type="submit" value="Search" />
- </fieldset>
- </form>
- <h1><a href="http://vndb.org/">vndb.org</a> / #vndb @ irc.synirc.net <a href="/">
- [[ if($p{devshit}) { ]]<b style="color: red">The VNDB.org Testing Grounds</b>[[ } else { ]]<b>The Visual Novel Database</b>[[ } ]]</a></h1>
-</div>
-
-
-<div id="page">
-
-<div id="content">
-[[ # = noindex-tag (see above) ]]
-[[ if($p{home}) { %d = %{$p{home}}; ]] [[+ home ]][[ } ]]
-[[ if($p{userlogin}) { %d = %{$p{userlogin}}; ]] [[+ userlogin ]][[ } ]]
-[[ if($p{userreg}) { %d = %{$p{userreg}}; ]] [[+ userreg ]][[ } ]]
-[[ if($p{userpass}) { %d = %{$p{userpass}}; ]] [[+ userpass ]][[ } ]]
-[[ if($p{useredit}) { %d = %{$p{useredit}}; ]] [[+ useredit ]][[ } ]]
-[[ if($p{userlist}) { %d = %{$p{userlist}}; ]] [[+ userlist ]][[ }# ]]
-[[ if($p{userpage}) { %d = %{$p{userpage}}; ]] [[+ userpage ]][[ }# ]]
-[[ if($p{vnpage}) { %d = %{$p{vnpage}}; ]] [[+ vnpage ]][[ } ]]
-[[ if($p{vnedit}) { %d = %{$p{vnedit}}; ]] [[+ vnedit ]][[ } ]]
-[[ if($p{redit}) { %d = %{$p{redit}}; ]] [[+ redit ]][[ } ]]
-[[ if($p{vnbrowse}) { %d = %{$p{vnbrowse}}; ]] [[+ vnbrowse ]][[ } ]]
-[[ if($p{pbrowse}) { %d = %{$p{pbrowse}}; ]] [[+ pbrowse ]][[ } ]]
-[[ if($p{pedit}) { %d = %{$p{pedit}}; ]] [[+ pedit ]][[ } ]]
-[[ if($p{ppage}) { %d = %{$p{ppage}}; ]] [[+ ppage ]][[ } ]]
-[[ if($p{vnlist}) { %d = %{$p{vnlist}}; ]] [[+ vnlist ]][[ }# ]]
-[[ if($p{rlist}) { %d = %{$p{rlist}}; ]] [[+ rlist ]][[ }# ]]
-[[ if($p{wlist}) { %d = %{$p{wlist}}; ]] [[+ wlist ]][[ }# ]]
-[[ if($p{hist}) { %d = %{$p{hist}}; ]] [[+ hist ]][[ }# ]]
-[[ if($p{rpage}) { %d = %{$p{rpage}}; ]] [[+ rpage ]][[ } ]]
-[[ if($p{docs}) { %d = %{$p{docs}}; ]] [[+ docs ]][[ } ]]
-[[ if($p{tindex}) { %d = %{$p{tindex}}; ]] [[+ tindex ]][[ } ]]
-[[ if($p{ttag}) { %d = %{$p{ttag}}; ]] [[+ ttag ]][[ }# ]]
-[[ if($p{tthread}) { %d = %{$p{tthread}}; ]] [[+ tthread ]][[ } ]]
-[[ if($p{tedit}) { %d = %{$p{tedit}}; ]] [[+ tedit ]][[ } ]]
-[[ if($p{error}) { %d = %{$p{error}}; ]] [[+ error ]][[ } ]]
-</div>
-
-
-<div id="side"><div><div>
-
- <h2>Menu</h2>
- <ul>
- <li><a href="/">Home</a></li>
- <li><a href="/v">Browse</a> | <a href="/v/search">Search</a></li>
- <li><a href="/p">Producers</a></li>
- <li><a href="/u/list">Users</a></li>
- <li><a href="/hist">Recent changes</a></li>
- <li><a href="/t">Discussion board</a></li>
- <li><a href="/d6">FAQ</a></li>
- </ul>
-
--[[ if(!$p{AuthLoggedin}) { ]]-
- <h2>Login</h2>
- <form method="post" action="/nospam?/u/login" id="loginform">
- <fieldset>
- <legend>Login</legend>
- <input type="text" id="usrname" name="username" />
- <input type="password" id="usrpass" name="userpass" />
- <input type="submit" value="Login" />
- </fieldset>
- </form>
- <p>
- <a href="/u/register">register</a> or <a href="/u/newpass">forgot password?</a>
- </p>
-[[ } else { ]]-
- <h2>User menu</h2>
- <ul>
- <li><a href="/u[[= $p{AuthId} ]]">[[: $p{AuthUsername} ]]</a> ([[: $p{AuthRankname} ]])</li>
- <li><a href="/u[[= $p{AuthId} ]]/edit">My profile</a></li>
- <li><a href="/u[[= $p{AuthId} ]]/list">My visual novel list</a></li>
- [[ if($p{AuthOldList}) { ]]-
- <li><a href="/u[[= $p{AuthId} ]]/vlist">My visual novel list (old)</a></li>[[ } ]]-
- <li><a href="/u[[= $p{AuthId} ]]/wish">My wishlist</a></li>
- <li><a href="/t/u[[= $p{AuthId} ]]">My messages</a></li>
- <li><a href="/u[[= $p{AuthId} ]]/hist">My recent changes</a></li>
- [[ if($p{Authedit}) { ]]-
- <li>&nbsp;</li>
- <li><a href="/v/new">Add visual novel</a></li>
- <li><a href="/p/add">Add producer</a></li>
- [[ } ]]
- <li>&nbsp;</li>
- <li><a href="/u/logout">Logout</a></li>
- </ul>
-[[ } ]]-
-
--[[ #</div></div><div><div> ]]
- <h2>Statistics</h2>
- <ul>
- <li><b>[[= $p{Statvn}||0 ]]</b> visual novels</li>
- <li><b>[[= $p{Statproducers}||0 ]]</b> producers</li>
- <li><b>[[= $p{Statreleases}||0 ]]</b> releases</li>
- <li><b>[[= $p{Statusers}||0 ]]</b> users</li>
- </ul>
-[[ if(0) { ]] <h2>Most popular</h2>
- <ul>[[ for (@{$p{popular}}) { ]]-
- <li><a href="/v[[: $_->{id} ]]" title="[[: $_->{title} ]]">[[: length($_->{title})>30 ? (substr($_->{title}, 0, 27).'...') : $_->{title} ]]</a></li>[[ } ]]-
- <li class="more"><a href="/v/all?s=votes&amp;o=d">More...</a></li>
- </ul>[[ } ]]-
-</div></div></div>
-
-</div>
-
-<div id="footer">
- <p>
- vndb v[[: $VNDB::VERSION ]]- |
- <a href="/d7">about us</a> |
- <a href="mailto:contact@vndb.org">contact@vndb.org</a> (english only) |
- designed by <a href="http://www.freecsstemplates.org/">free css templates</a>.
- </p>
-</div>
-
--[[ if(0 && $p{devshit}) { ]]-
- <pre id="debug">SQL Queries used:<br />
-[[= $p{devshit} ]]
-</pre>
-[[ } ]]-
-
-</body>
-</html>
diff --git a/data/tpl/pbrowse b/data/tpl/pbrowse
deleted file mode 100644
index 8d2604c3..00000000
--- a/data/tpl/pbrowse
+++ /dev/null
@@ -1,45 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-<p class="chr">
- -[[= $d{chr} ne 'all' ? '<a href="/p/all">all</a>' : 'all' ]]- |
- [[ for('a'..'z', 0) { ]]-
- -[[ if($d{chr} eq $_) { ]][[= $_?$_:'#' ]][[ } else { ]]<a href="/p/[[= $_ ]]">[[= $_?$_:'#' ]]</a>[[ } ]]
- [[ } ]]-
- <form id="psearch" method="get" action="/p" accept-charset="UTF-8">
- <fieldset>
- <input type="text" name="q" id="q" value="[[: $d{query} ]]" class="text"
- /><input type="submit" value="Search!" />
- </fieldset>
- </form>
-</p>
-
--[[ if($#{$d{prods}} < 0) { ]]
-<p>
- No results again, life sucks... :'(
-</p>
-[[ } else {
- my $url = sprintf '/p/%s', $d{chr};
- $url .= '?q='.$d{query} if $d{query};
-]]
-[[= pagebut($url) ]]
-<table id="tpd">
- <thead><tr>
- <td class="tc1">Name</td>
- <td class="tc2">Type</td>
- <td class="tc3">Website</td>
- </tr></thead>
-[[ for (@{$d{prods}}) { ]]-
- <tr>
- <td class="tc1">
- <acronym class="icons lang -[[= $_->{lang} ]]" title="[[: $VNDB::LANG->{$_->{lang}} ]]">&nbsp;</acronym><a
- href="/p[[= $_->{id} ]]" title="[[: $_->{original}||$_->{name} ]]">[[: $_->{name} ]]</a></td>
- <td class="tc2">[[: $VNDB::PROT->{$_->{type}} ]]</td>
- <td class="tc3">
- [[ if($_->{website}) { ]]
- <a href="[[: $_->{website} ]]">[[: shorten $_->{website}, 50 ]]
- [[ } else { ]]---[[ } ]]
- </td>
- </tr>
-[[ } ]]-
-</table>
-[[= pagebut($url) ]]
-[[ } ]]
diff --git a/data/tpl/pedit b/data/tpl/pedit
deleted file mode 100644
index 56c06b92..00000000
--- a/data/tpl/pedit
+++ /dev/null
@@ -1,44 +0,0 @@
-[[= $d{id} ? ttabs('p', $d{prod}, 'edit') : '' ]]
-<h2>[[: $p{PageTitle} ]]</h2>
--[[ if(!$d{id}) { ]]
- <span class="msg">
- Please search the database before adding a new producer in order to prevent duplicate entries.
- </span>
-[[ } else { ]]
- <span class="msg">
- Please check the <a href="/t/p[[= $d{id} ]]">discussion board</a> <b>before</b> making
- any changes!
- </span>
-[[ } if($d{id} && $d{prod}{cid} != $d{prod}{latest}) { ]]
- <span class="warning">
- You are editing an old revision of this producer. If you save it, all changes made after
- -[[= formatdate('%Y-%m-%d %R', $d{prod}{added}) ]]- will be removed!
- </span>
-[[ } ]]
-
--[[= cform([
- { type => 'error' },
- { type => 'startform', action => $d{id} ? '/p'.$d{id}.'/edit' : '/p/add' },
-
- { type => 'sub', title => 'General info', short => 'info' },
- { type => 'select', name => 'Type', short => 'type', r=>1, options => [ map {
- { short => $_, name => $VNDB::PROT->{$_} } } sort keys %$VNDB::PROT ] },
- { type => 'input', name => 'Name (romaji)', short => 'name', r=>1 },
- { type => 'input', name => 'Original name', short => 'original' },
- { type => 'static', text => q|
- The original name of the producer, leave blank if it is already in the Latin alphabet.<br /><br />| },
-
- { type => 'select', name => 'Primary language', short => 'lang', r=>1, options => [ map {
- ({ short => $_, name => sprintf '%s (%s)', $_, $VNDB::LANG->{$_} }) } sort keys %{$VNDB::LANG} ] },
-
- { type => 'input', name => 'Website', short => 'website' },
- { type => 'textarea', name => 'Description', short => 'desc', rows => 7, cols => 60 },
-
- { type => 'sub', title => 'Edit summary', short => 'com' },
- { type => 'textarea', name => 'Edit summary', short => 'comm', rows => 3, cols => 60 },
- { type => 'static', text => 'Please explain your modifications and cite all sources.' },
-
- { type => 'submit', text => $d{id} ? 'Edit' : 'Add' },
- { type => 'endform' },
-
-], $d{form}) ]]
diff --git a/data/tpl/ppage b/data/tpl/ppage
deleted file mode 100644
index e0a1fa08..00000000
--- a/data/tpl/ppage
+++ /dev/null
@@ -1,55 +0,0 @@
-[[= ttabs('p', $d{prod}) ]]
-<h2>[[: $p{PageTitle} ]]</h2>
-[[ if($d{prod}{original}) { ]]<h3 class="alttitle">[[: $d{prod}{original} ]]</h3>[[ } ]]
-
-[[ if($d{prod}{hidden}) { ]]-
- <span class="warning">
- This item has been deleted from the database. File a request on the
- <a href="/t/p[[= $d{prod}{id} ]]">discussion board</a> to undelete this page.
- </span>
-[[ } ]]
-[[ if(!$d{prod}{hidden} || $p{Authdel}) { ]]-
-
-
-
-[[ if($d{change}) { ]]
-[[= cdiff($d{prev}, $d{prod},
- [ type => 'Type', sub { $VNDB::PROT->{$_[0]} } ],
- [ name => 'Name (romaji)', 1 ],
- [ original => 'Original name', 1 ],
- [ lang => 'Language', sub { $VNDB::LANG->{$_[0]} } ],
- [ website => 'Website', 1 ],
- [ desc => 'Description', 1, 1 ],
- ) ]]
-[[ } ]]
-
-<dl>
- <dt>Type</dt><dd>[[: $VNDB::PROT->{$d{prod}{type}} ]]</dd>
- <dt>Primary lang.</dt><dd>[[: $VNDB::LANG->{$d{prod}{lang}} ]]</dd>
-[[ if($d{prod}{website}) { ]]-
- <dt>Links</dt><dd><a href="[[: $d{prod}{website} ]]">Official homepage</a></dd>[[ } ]]-
-</dl>
-
--[[ if($d{prod}{desc}) { ]]
-<p>[[= summary($d{prod}{desc}) ]]<br /><br /></p>
-[[ } ]]
-
-
-<h3>Visual novel relations</h3>
-[[ if($#{$d{vn}} < 0) { ]]-
-<p>
- We have currently no visual novels related to this producer.
-</p>
-[[ } else { ]]-
-<ul>
- [[ for (@{$d{vn}}) { ]]-
- <li><a href="/v[[= $_->{id} ]]">[[: $_->{title} ]]</a>
- [[ if($_->{date} ne "0000-00-00") { ]]- ([[= datestr($_->{date}) ]])[[ } ]]
- </li>
- [[ } ]]-
-</ul>
-[[ } ]]
-
-
-
-[[ } ]]
diff --git a/data/tpl/redit b/data/tpl/redit
deleted file mode 100644
index 32d618e3..00000000
--- a/data/tpl/redit
+++ /dev/null
@@ -1,69 +0,0 @@
-[[= $d{id} ? ttabs('r', $d{rel}, 'edit') : ttabs('v', $d{vn}, 'edit') ]]-
-<h2>[[: $p{PageTitle} ]]</h2>
-
-[[ if($d{id}) { ]]
- <span class="msg">
- Please check the <a href="/t/v[[= $d{rel}{vn}[0]{vid} ]]">discussion board</a> <b>before</b> making
- any changes!
- </span>
-[[ } if($d{id} && $d{rel}{cid} != $d{rel}{latest}) { ]]
- <span class="warning">
- You are editing an old revision of this producer. If you save it, all changes made after
- -[[= formatdate('%Y-%m-%d %R', $d{rel}{added}) ]]- will be removed!
- </span>
-[[ } ]]
-
-[[= cform( [
- { type => 'error' },
- { type => 'startform', action => $d{id} ? sprintf('/r%d/edit', $d{rel}{id}) : '/v'.$d{vn}{id}.'/add', fh => 1 },
-
- { type => 'sub', title => 'General info', short => 'info' },
- { type => 'select', name => 'Type', short => 'type', r=>1, options => [ map {
- ({ short => $_, name => $VNDB::RTYP->[$_] }) } 0..$#{$VNDB::RTYP} ] },
-
- { type => 'input', name => 'Title (romaji)', short => 'title', r=>1 },
- { type => 'input', name => 'Original title', short => 'original' },
- { type => 'static', text => q|
- The original title of this release, leave blank if it already is in the Latin alphabet.<br /><br />| },
-
- { type => 'select', name => 'Language', short => 'language', r=>1, options => [ map {
- ({ short => $_, name => sprintf '%s (%s)', $_, $VNDB::LANG->{$_} }) } sort keys %{$VNDB::LANG} ] },
-
- { type => 'input', name => 'JAN/UPC/EAN', short => 'gtin' },
- { type => 'input', name => 'Official website', short => 'website' },
- { type => 'date', name => 'Release date', short => 'released' },
- { type => 'static', text => 'Leave month or day blank if they are unknown<br /><br />' },
- { type => 'select', name => 'Age rating', short => 'minage', options => [ map
- { { name => $VNDB::VRAGES->{$_}, short => $_ } } sort { $a <=> $b } keys %$VNDB::VRAGES ] },
- { type => 'textarea', name => 'Notes', short => 'notes', rows => 3, cols => 50 },
- { type => 'static', text => 'Miscellaneous notes/comments, information that does not fit in the above fields. E.g.: Censored/uncensored or for which releases this patch applies. Max. 250 characters.' },
-
- { type => 'sub', title => 'Platforms & Media', short => 'pnm' },
- { type => 'static', raw => 1, text => '<label>Platforms</label><ul class="platforms">'.join('', map { my $p = $_;
- '<li><input type="checkbox" name="platforms" value="'.$_.'" id="'.$_.'" '.
- (($d{form}{platforms} && grep { $p eq $_ } @{$d{form}{platforms}}) ? 'checked="checked" ':'').'/>'.
- '<label for="'.$_.'"><acronym class="icons '.$_.'" title="'.$VNDB::PLAT->{$_}.'">&nbsp;</acronym>'.$VNDB::PLAT->{$_}.'</label></li>'
- } sort { $VNDB::PLAT->{$a} cmp $VNDB::PLAT->{$b} } keys %$VNDB::PLAT).'</ul>' },
-
- { type => 'static', text => '<br />' },
- { type => 'jssel', name => 'Media', sh => 'md', short => 'media' },
-
- { type => 'sub', title => 'Producers', short => 'prod' },
- { type => 'jssel', name => 'Producers', sh => 'pd', short => 'producers' },
-
- { type => 'sub', title => 'Visual novel relations', short => 'rel'},
- { type => 'jssel', name => 'Relations', sh => 'vn', short => 'vn', r=>1 },
- { type => 'static', text => q|
- Although a release usually contains only one visual novel, it is also possible
- for one release to include several games. Use this field to specify which
- visual novels are included in this release.| },
-
-
- { type => 'sub', title => 'Edit summary', short => 'com' },
- { type => 'textarea', name => 'Edit summary', short => 'comm', rows => 3, cols => 60 },
- { type => 'static', text => 'Please explain your modifications and cite all sources.' },
-
- { type => 'submit', text => $d{id} ? 'Edit' : 'Add' },
- { type => 'endform' },
-
-], $d{form}) ]]
diff --git a/data/tpl/rlist b/data/tpl/rlist
deleted file mode 100644
index f76eb65d..00000000
--- a/data/tpl/rlist
+++ /dev/null
@@ -1,90 +0,0 @@
-[[= ttabs('u', $d{user}, 'list') ]]
-<h2>[[: $p{PageTitle} ]]</h2>
-
-[[
- my $url = '/u'.$d{user}{id}.'/list';
- my $surl = sprintf '%s?s=%s;o=%s', $url, $d{order}[0], $d{order}[1]; # main URL + order
- my $purl = "$surl;c=$d{char}"; # full URL - page
- my $sourl = "$url?c=$d{char}"; # full URL - page & order
- my $curl = $surl; # full URL - character & page
- my $furl = "$surl;c=$d{char};p=$d{page}"; # full URL
-
- my $i=0;my $j=0;
-
-]]-
-
-<p class="chr">
- -[[= $d{char} ne 'all' ? '<a href="'.$curl.';c=all">all</a>' : 'all' ]]- |
- [[ for('a'..'z', 0) { ]]-
- -[[ if($d{char} eq $_) { ]][[= $_?$_:'#' ]][[ } else { ]]<a href="[[= $curl.';c='.$_ ]]">[[= $_?$_:'#' ]]</a>[[ } ]]
- [[ } ]]-
- <br /><br />
-</p>
-
-
--[[ if(@{$d{list}}) { ]]
-[[= pagebut($surl) ]]
-[[ if($d{user}{username} eq $p{AuthUsername}) { ]]
-<form method="post" action="[[= $furl ]]" class="tblf">
-[[ } ]]-
-<table id="rli">
- <thead><tr>
- <td colspan="3" class="tc1">Title -[[= sortbut($sourl, 'title') ]]</td>
- <td class="tc2" id="relhidpar"><b id="relhidparb">&#9656;</b>Releases*</td>
- <td class="tc3">Vote -[[= sortbut($sourl, 'vote') ]]</td>
- </tr></thead>
-[[ for (@{$d{list}}) { $j=0; my $c = ' style="background-color: #'.($i++%2?'fff':'f5f5f5').'"'; ]]-
- <tr[[=$c]]>
- <td colspan="3" class="tc1"><a href="/v[[= $_->{vid} ]]" title="[[: $_->{original}||$_->{title} ]]">[[= shorten $_->{title}, 50 ]]</a></td>
- <td class="tc2[[= @{$_->{rels}} ? ' relhid" id="rh'.$_->{vid}.'"' : ' relnone"' ]]><b[[= @{$_->{rels}} ? ' id="rhd'.$_->{vid}.'"' : '' ]]>&#9656;</b>
- [[= grep $_->{rstat}==2, @{$_->{rels}} ]]/[[= grep $_->{vstat}==2, @{$_->{rels}} ]]/[[= @{$_->{rels}} ]]
- </td>
- <td class="tc3">[[= $_->{vote} || '-' ]]</td>
- </tr>
- [[ for (@{$_->{rels}}) { ]]-
- <tr class="relhid" id="rr[[= $_->{vid}.'-'.++$j ]]">
- <td class="tc1_1">[[= datestr $_->{released} ]]</td>
- <td class="tc1_2">
- <acronym class="icons lang -[[= $_->{language} ]]" title="[[: $$VNDB::LANG{$_->{language}} ]]">&nbsp;</acronym><acronym
- title="[[= $VNDB::RTYP->[$_->{type}] ]]- release" class="icons -[[= lc substr($VNDB::RTYP->[$_->{type}],0,3) ]]">&nbsp;</acronym>
- </td>
- <td class="tc1_3"><a href="/r[[= $_->{rid} ]]" title="[[: $_->{original}||$_->{title} ]]">[[= shorten $_->{title}, 60 ]]</a></td>
- <td class="tc1_4">
- <acronym title="[[: $VNDB::RSTAT->[$_->{rstat}] ]]" class="uicons r[[= $_->{rstat} ]]">&nbsp;</acronym><acronym
- title="[[: $VNDB::VSTAT->[$_->{vstat}] ]]" class="uicons v[[= $_->{vstat} ]]">&nbsp;</acronym>
- </td>
- <td class="tc1_5">[[ if($d{user}{username} eq $p{AuthUsername}) { ]]<input type="checkbox" name="rsel" value="[[= $_->{rid} ]]" />[[ } else { ]]&nbsp;[[ } ]]</td>
- </tr>
- [[ } ]]
-[[ } ]]-
-</table>
-[[ if($d{user}{username} eq $p{AuthUsername}) { ]]
-<select id="vnlistchange" name="vnlistchange" class="right">
- <option value="n">- with selected -</option>
- <option value="d">Delete</option>
- <optgroup label="Update release status:">
- [[ for (0..$#$VNDB::RSTAT) { ]]-
- <option value="r[[= $_ ]]">[[: $VNDB::RSTAT->[$_] ]]</option>
- [[ } ]]
- </optgroup>
- <optgroup label="Update play status:">
- [[ for (0..$#$VNDB::VSTAT) { ]]-
- <option value="v[[= $_ ]]">[[: $VNDB::VSTAT->[$_] ]]</option>
- [[ } ]]
- </optgroup>
-</select>
-</form>
-[[ } ]]
-[[= pagebut($surl) ]]
-<p>
- <br />
- <b>*</b> Obtained/finished/total.
-</p>
-
-
-
-[[ } else { ]]-
-<p>
- No results found.
-</p>
-[[ } ]]
diff --git a/data/tpl/rpage b/data/tpl/rpage
deleted file mode 100644
index d31ffe24..00000000
--- a/data/tpl/rpage
+++ /dev/null
@@ -1,68 +0,0 @@
-[[= ttabs('r', $d{rel}) ]]
-<h2>[[: $p{PageTitle} ]]</h2>
-[[ if($d{rel}{original}) { ]]<h3 class="alttitle">[[: $d{rel}{original} ]]</h3>[[ } ]]
-
-[[ if($d{rel}{hidden}) { ]]-
- <span class="warning">
- This item has been deleted from the database. File a request on the
- <a href="/t/v[[= $d{rel}{vn}[0]{vid} ]]">discussion board</a> to undelete this page.
- </span>
-[[ } ]]
-[[ if(!$d{rel}{hidden} || $p{Authdel}) { ]]-
-
--[[ if($p{AuthLoggedin}) { ]]
-<p class="mod">&lt;
-<a href="/u[[= $p{AuthId} ]]/list" rel="rlistDD[[= $d{rel}{id} ]]" class="dropdown">
-[[= !$d{rel}{rlist} ? 'not in your list' : "$$VNDB::RSTAT[$d{rel}{rlist}{rstat}] / $$VNDB::VSTAT[$d{rel}{rlist}{vstat}]" ]]
-</a> &gt;</p>
-[[= rlist_dd($d{rel}) ]]
-[[ } ]]-
-
-
--[[ if($d{change}) { ]]
-[[= cdiff($d{prev}, $d{rel},
- [ vn => 'Relations', sub { join("<br />\n", map { $_->{title} } @{$_[0]}) } ],
- [ type => 'Type', sub { $VNDB::RTYP->[$_[0] ] } ],
- [ title => 'Title', 1 ],
- [ original => 'Orig. title', 1 ],
- [ gtin => 'JAN/UPC/EAN', 1 ],
- [ language => 'Language', sub { $VNDB::LANG->{$_[0]} } ],
- [ website => 'Website', \&summary ],
- [ released => 'Release date', \&datestr ],
- [ minage => 'Age rating', sub { $VNDB::VRAGES->{$_[0]} } ],
- [ notes => 'Notes', 1, 1 ],
- [ platforms => 'Platforms', sub { join(', ', sort @{$_[0]}) } ],
- [ media => 'Media', \&mediastr ],
- [ producers => 'Producers', sub { join(', ', map { _hchar($_->{name}) } sort { $a->{name} cmp $b->{name} } @{$_[0]}) } ],
- ) ]]
-[[ } ]]
-
-<dl>
- <dt>Relation</dt><dd>[[= join('<br />', map { '<a href="/v'.$_->{vid}.'" title="'._hchar($_->{original}||$_->{title}).'">'._hchar($_->{title}).'</a>' } @{$d{rel}{vn}}) ]]</dd>
- <dt>Type</dt><dd>[[: $VNDB::RTYP->[$d{rel}{type}] ]]</dd>
- <dt>Language</dt><dd>[[: $VNDB::LANG->{$d{rel}{language}} ]]</dd>
- <dt>Release date</dt><dd>[[= datestr($d{rel}{released}) ]]</dd>
-[[ if($d{rel}{gtin}) { ]]-
- <dt>[[: VNDB::GTINType($d{rel}{gtin}) ]]- code</dt><dd>[[= $d{rel}{gtin} ]]</dd>[[ } ]]-
-[[ if($d{rel}{minage} >= 0) { ]]-
- <dt>Age rating</dt><dd>[[: $VNDB::VRAGES->{$d{rel}{minage}} ]]</dd>[[ } ]]-
-[[ if($#{$d{rel}{producers}} >= 0) { ]]-
- <dt>Producer[[: $#{$d{rel}{producers}} > 0 ? 's' : '' ]]</dt><dd>[[= join(', ', map {
- sprintf('<a href="/p%d" title="'._hchar($_->{original}||$_->{name}).'">%s</a>', $_->{id}, _hchar($_->{name})) } @{$d{rel}{producers}})
- ]]</dd>[[ } ]]-
-[[ if($#{$d{rel}{platforms}} >= 0) { ]]-
- <dt>Platform[[: $#{$d{rel}{platforms}} > 0 ? 's' : '' ]]</dt><dd>[[: join(', ', map {
- $VNDB::PLAT->{$_} } @{$d{rel}{platforms}}) ]]</dd>[[ } ]]-
-[[ if($#{$d{rel}{media}} >= 0) { ]]-
- <dt>Medi[[: $#{$d{rel}{media}} > 0 ? 'a' : 'um' ]]</dt><dd>[[: mediastr($d{rel}{media}) ]]</dd>[[ } ]]-
-[[ if($d{rel}{website}) { ]]-
- <dt>Links</dt><dd><a href="[[: $d{rel}{website} ]]">Official website</a></dd>[[ } ]]-
-</dl>
-
-[[ if($d{rel}{notes}) { ]]-
-<p>[[= summary($d{rel}{notes}) ]]<br /><br /></p>
-[[ } ]]-
-
-
-
-[[ } ]]
diff --git a/data/tpl/tedit b/data/tpl/tedit
deleted file mode 100644
index 5953ead0..00000000
--- a/data/tpl/tedit
+++ /dev/null
@@ -1,33 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-[[ if($d{tag}) { my($type, $iid) = ($1, $2||0) if $d{tag} =~ /^([a-z]{1,2})([0-9]*)$/; ]]-
-<p>
- <a href="/t">Discussion board</a>
- &gt; <a href="/t/[[= $type ]]">[[: $VNDB::DTAGS->{$type} ]]</a>
- [[ if($iid) { ]]-
- &gt; <a href="/t/[[= $d{tag} ]]">[[: $d{tag} ]]</a>[[ } ]]-
-</p>
-[[ } ]]
-
--[[= cform( [
- { type => 'error' },
- { type => 'startform', action => $d{p} ? '/t'.$d{t}{id}.'.'.$d{p}{num}.'/edit' : $d{t} ? '/t'.$d{t}{id}.'/reply' : '/t/'.$d{tag}.'/new' },
- { type => 'static', name => 'Username', text => '<a href="/u'.($d{p}?$d{p}{uid}:$p{AuthId}).'">'.($d{p}?$d{p}{username}:$p{AuthUsername}).'</a>' },
- $d{t} && !($d{p} && $d{p}{num} == 1) ? (
- { type => 'static', name => 'Topic', text => '<a href="/t'.$d{t}{id}.'">'.$d{t}{title}.'</a>.' }
- ) : (
- { type => 'input', short => 'title', name => 'Thread title' },
- { type => 'input', short => 'tags', name => 'Tags' },
- { type => 'static', text => 'Read <a href="/d9.2">d9.2</a> for information about how to use tags' },
- $p{Authboardmod} ? (
- { type => 'check', short => 'lock', name => 'Locked' },
- ) : (),
- ),
- $p{Authboardmod} ? (
- { type => 'check', short => 'hide', name => 'Hidden' },
- ) : (),
- { type => 'textarea', short => 'msg', name => 'Message', rows => 10, cols => 60 },
- { type => 'static', text => 'It is possible to include formatting and ID codes, see <a href="/d9.3">d9.3</a> for more information.' },
- { type => 'submit', text => 'Submit' },
- { type => 'endform' },
-], $d{form}) ]]-
-
diff --git a/data/tpl/tindex b/data/tpl/tindex
deleted file mode 100644
index cb9cd154..00000000
--- a/data/tpl/tindex
+++ /dev/null
@@ -1,49 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-
-[[
- my %desc = (
- an => 'Yorhel\'s place to make useless announcements...',
- db => 'General discussions about VNDB.org. This is the place to be for feature requests and bug reports.',
- v => 'Discussions about the visual novels in the database',
- p => '...Producers',
- r => '...Releases',
- u => 'Messages to or discussions about other users on this site.'
- );
-]]
-
-
-[[ for my $tag (qw|an db v p u|) { ]]-
-
-<br />
-<h3>[[: $VNDB::DTAGS->{$tag} ]]</h3>
-[[ if(@{$d{$tag}}) { ]]-
-<table id="tin">
-[[ for (@{$d{$tag}}) { ]]-
- <tr>
- <td class="tc1">
- <a href="/t[[= $_->{id} ]]" title="[[= join ', ', sort map $$_[1]?$$_[0].$$_[1]:$$_[0], @{$_->{tags}} ]]">[[: $_->{title} ]]</a>
- [[ if($_->{locked}) { ]]- <b>[locked]</b>[[ } ]]
- </td>
- <td class="tc2">[[= $_->{count}-1 ]]</td>
- <td class="tc3">[[= userstr $_ ]]</td>
- <td class="tc4">[[= userstr $_->{luid}, $_->{lusername} ]]- @
- <a href="/t[[= $_->{id}.($_->{count}>$d{ppp}?'/'.ceil($_->{count}/$d{ppp}):'').'#'.$_->{count} ]]">
- [[= age $_->{ldate} ]]</a></td>
- </tr>
-[[ } ]]
-</table>
-<a class="right" href="/t/[[= $tag ]]">more...</a>
-[[ if($tag eq 'db') { ]]-
- <a class="right" href="/t/[[= $tag ]]/new" style="padding-right: 10px">start new thread</a>
-[[ } ]]
-
-[[ } else { ]]-
- <p>No threads yet.
- -[[ if($tag eq 'db') { ]]
- <a href="/t/[[= $tag ]]/new">Start a new thread.</a>
- [[ } ]]
- </p>
-[[ } ]]
-<br />
-
-[[ } ]]
diff --git a/data/tpl/ttag b/data/tpl/ttag
deleted file mode 100644
index 0d46ddf1..00000000
--- a/data/tpl/ttag
+++ /dev/null
@@ -1,60 +0,0 @@
-[[= $d{obj} ? ttabs($d{type}, $d{obj}, 'disc') : '' ]]-
-<h2>[[: $p{PageTitle} ]]</h2>
-<p>
- <a href="/t">Discussion board</a>
- &gt; <a href="/t/[[= $d{type} ]]">[[: $VNDB::DTAGS->{$d{type}} ]]</a>
- [[ if($d{obj}) { ]]-
- &gt; <b>[[= $d{tag} ]]</b>:<a href="/t/[[= $d{tag} ]]" title="[[: $d{original}||$d{title} ]]">[[: $d{title} ]]</a>[[ } ]]-
-</p>
-
-[[ if(@{$d{t}}) { ]]-
-
-[[ if(!$d{obj} && $d{tag} !~ /(an|db)/) {
- my @tags = grep $$_[0] eq $d{type}, map @{$_->{tags}}, @{$d{t}}; my %tags; my $i=0; ]]-
-<dl>
- <dt>Recent tags</dt>
- <dd>
- [[ for (@tags) { next if $tags{$$_[1]}++; last if $i++ == 5; ]]-
- <b>[[= $$_[0].$$_[1] ]]</b>:<a href="/t/[[= $$_[0].$$_[1] ]]">[[: $$_[2] ]]</a><br />[[ } ]]
- </dd>
-</dl>
-[[ } else { ]]
-<br />
-[[ } ]]
-
-
-[[= pagebut('/t/'.$d{tag}) ]]
-<table id="tin">
- <thead><tr>
- <td class="tc1">Topic</td>
- <td class="tc2">#</td>
- <td class="tc3">Starter</td>
- <td class="tc4">Last post</td>
- </tr></thead>
-[[ for (@{$d{t}}) { ]]-
- <tr>
- <td class="tc1">
- <a href="/t[[= $_->{id} ]]" title="[[= join ', ', sort map $$_[1]?$$_[0].$$_[1]:$$_[0], @{$_->{tags}} ]]">[[: $_->{title} ]]</a>
- [[ if($_->{locked}) { ]]- <b>[locked]</b>[[ } ]]
- </td>
- <td class="tc2">[[= $_->{count}-1 ]]</td>
- <td class="tc3">[[= userstr $_ ]]</td>
- <td class="tc4">[[= userstr $_->{luid}, $_->{lusername} ]]- @
- <a href="/t[[= $_->{id}.($_->{count}>$d{ppp}?'/'.ceil($_->{count}/$d{ppp}):'').'#'.$_->{count} ]]">
- [[= age $_->{ldate} ]]</a></td>
- </tr>
-[[ } ]]
-</table>
-[[= pagebut('/t/'.$d{tag}) ]]
-
-[[ } else { ]]
-<p><br />
- <b>No related threads found.</b>
-</p>
-[[ } ]]-
-
--[[ if($p{Authboard} && $d{tag} =~ /^(?:db|[vpru][0-9]+)$/) { ]]-
-<br />
-<a class="right" href="/t/[[= $d{tag} ]]/new">create a new thread</a>
-[[ } ]]
-
diff --git a/data/tpl/tthread b/data/tpl/tthread
deleted file mode 100644
index 0b67345c..00000000
--- a/data/tpl/tthread
+++ /dev/null
@@ -1,81 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-[[ if($d{t}{hidden}) { ]]
-<span class="warning">This thread has been deleted!</span>
-[[ } ]]
-
-<dl>
- <dt>Posted in</dt>
- <dd>
- [[ for (sort { $$a[0].$$a[1] cmp $$b[0].$$b[1] } @{$d{t}{tags}}) { ]]-
- <a href="/t/[[= $$_[0] ]]">[[: $VNDB::DTAGS->{$$_[0]} ]]</a>
- [[ if($$_[1]) { ]]-
- &gt; <b>[[= $$_[0].$$_[1] ]]</b>:<a href="/t/[[= $$_[0].$$_[1] ]]" title="[[: $$_[3]||$$_[2] ]]">[[: $$_[2] ]]</a>[[ } ]]-
- <br />
- [[ } ]]
- </dd>
-</dl>
-
-<br />
-
-[[
- my $pages='';
- my $lp = ceil($d{t}{count}/$d{ppp});
- if($d{t}{count} > $d{ppp}) {
- my @pages = (
- $d{page} == 1 ? '&lt;&lt;' : '<a href="/t%d">&lt;&lt;</a>',
- $lp > 2 ? (map
- $d{page} == $_ ? $_ : '<a href="/t%d/'.$_.'">'.$_.'</a>',
- 2..($lp-1) ) : (),
- $d{page} == $lp ? '&gt;&gt;' : '<a href="/t%d/'.$lp.'">&gt;&gt;</a>'
- );
- $pages = '<p class="browse">'.join(' &nbsp;', map sprintf($_,$d{t}{id}), @pages).'</p>';
- }
-]]
-
-[[= $pages ]]
-<table id="tth">
- [[ for (@{$d{p}}) { ]]-
- <tr>
- <td class="tc1">
- <a href="/t[[= $d{t}{id} ]].[[= $_->{num} ]]" name="[[= $_->{num} ]]">#[[= $_->{num} ]]</a>
- [[ if(!$_->{hidden}) { ]]-
- by -[[= userstr $_ ]]<br />
- <i>[[= formatdate('%Y-%m-%d %R', $_->{date}) ]]</i>
- [[ } ]]
- </td>
- <td class="tc2">
- [[ if($p{AuthId} == $_->{uid} && !$_->{hidden} || $p{Authboardmod}) { ]]-
- <p class="mod">&lt; <a href="/t[[= $d{t}{id}.'.'.$_->{num} ]]/edit">edit</a> &gt;</p>
- [[ } ]]
- [[ if(!$_->{hidden}) { ]]-
- [[= summary $_->{msg} ]]
- [[ if($_->{edited}) { ]]<br />
- <i>last modified -[[= formatdate('%Y-%m-%d %R', $_->{edited}) ]]</i>
- [[ } ]]
- [[ } else { ]]
- <b class="hidden">Post deleted.</b>
- [[ } ]]
- </td>
- </tr>
- [[ } ]]-
-</table>
-[[= $pages ]]
-
-<br />
-[[ if($lp == $d{page}) { ]]
- [[ if($d{t}{locked}) { ]]-
- <p>
- This thread has been locked, you can't reply anymore.
- </p>
- [[ } elsif(!$p{AuthLoggedin}) { ]]-
- <p>
- You need to be <a href="/u/login">logged in</a> to reply to this thread.
- </p>
- [[ } elsif($p{Authboard} && $lp == $d{page}) { ]]-
- <form action="/nospam?/t[[= $d{t}{id} ]]/reply" method="post" accept-charset="utf-8" id="qreply">
- <h3>Quick reply</h3>
- <textarea name="msg" id="msg" rows="5" cols="70"></textarea>
- <input type="submit" value="Post reply" />
- </form>
- [[ } ]]
-[[ } ]]
diff --git a/data/tpl/useredit b/data/tpl/useredit
deleted file mode 100644
index e6243fb5..00000000
--- a/data/tpl/useredit
+++ /dev/null
@@ -1,36 +0,0 @@
-[[= ttabs('u', $d{u}, 'edit') ]]
-<h2>[[: $p{PageTitle} ]]</h2>
-
--[[ if($d{done}) { ]]
-<span class="msg">
- Settings succesfully saved.
-</span>
-[[ } ]]
--[[= cform( [
- { type => 'error' },
- { type => 'startform', action => '/u'.$d{user}.'/edit' },
-
- { type => 'sub', title => 'General info', short => 'info' },
- { type => 'static', name => 'Username', text => _hchar($d{form}{username}) },
- { type => 'input', name => 'Email', short => 'mail' },
-
- { type => 'sub', title => 'Change password', short => 'pass' },
- { type => 'static', text => 'Leave blank to keep your current password.' },
- { type => 'pass', name => 'Password', short => 'pass1' },
- { type => 'pass', name => 'Confirm', short => 'pass2' },
-
- { type => 'sub', title => 'Miscellaneous options', short => 'misc' },
- { type => 'check', short => 'plist', name => sprintf
- 'Allow other people to see my visual novel list (<a href="/u%d/list">/u%1$d/list</a>) and wishlist (<a href="/u%1$d/wish">/u%1$d/wish</a>)', $d{user} },
- { type => 'check', short => 'pign_nsfw', name => 'Disable warnings for images that are not safe for work.' },
-
- $d{adm} ? (
- { type => 'sub', title => 'Admin', short => 'adm' },
- { type => 'input', name => 'Username', short => 'username' },
- { type => 'select', name => 'Rank', short => 'rank', options => [
- map { { name => $VNDB::VNDBopts{ranks}[0][0][$_], short => $_ } } 1..($#{$VNDB::VNDBopts{ranks}}-1) ] },
- ) : (),
-
- { type => 'submit', text => 'Save' },
- { type => 'endform' },
-], $d{form}) ]]
diff --git a/data/tpl/userlist b/data/tpl/userlist
deleted file mode 100644
index 578d320e..00000000
--- a/data/tpl/userlist
+++ /dev/null
@@ -1,50 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-<p class="chr">
- -[[= $d{chr} ne 'all' ? '<a href="/u/list/all">all</a>' : 'all' ]]- |
- [[ for('a'..'z', 0) { ]]-
- -[[ if($d{chr} eq $_) { ]][[= $_?$_:'#' ]][[ } else { ]]<a href="/u/list/[[= $_ ]]">[[= $_?$_:'#' ]]</a>[[ } ]]
- [[ } ]]-
- <br /><br />
-</p>
-
-[[ if($#{$d{users}} < 0) { ]]-
-<p>
- No users found...
-</p>
-[[ } else {
- my $url = sprintf '/u/list/%s', $d{chr};
- my $surl = sprintf '%s?s=%s&amp;o=%s', $url, $d{order}[0], $d{order}[1];
-]]
-[[= pagebut($surl) ]]-
-<table id="tul">
- <thead><tr>
- <td class="tc1">Username [[= sortbut($url, 'username') ]]</td>
-[[ if($p{Authusermod}) { ]]-
- <td class="tc2">Mail [[= sortbut($url, 'mail') ]]</td>
- <td class="tc3">Rank [[= sortbut($url, 'rank') ]]</td>[[ } ]]-
- <td class="tc4">Registered [[= sortbut($url, 'registered') ]]</td>
- <td class="tc6">Votes</td>
- <td class="tc7">Changes</td>
-[[ if($p{Authusermod}) { ]]-
- <td class="tc8">&nbsp;</td>[[ } ]]-
- </tr></thead>
- [[ for (@{$d{users}}) { ]]-
- <tr>
- <td class="tc1"><a href="/u[[= $_->{id} ]]">[[: $_->{username} ]]</a></td>
-[[ if($p{Authusermod}) { ]]-
- <td class="tc2">[[: $_->{mail} ]]</td>
- <td class="tc3">[[: $VNDB::VNDBopts{ranks}[0][0][$_->{rank}] ]]</td>[[ } ]]-
- <td class="tc4">[[= formatdate('%Y-%m-%d', $_->{registered}, 'wd') ]]</td>
- <td class="tc6">[[ if($_->{flags} & $VNDB::UFLAGS->{list} && $_->{votes}) { ]]
- <a href="/u[[= $_->{id} ]]/list" title="[[: $_->{username} ]]'s votes">[[= $_->{votes} ]]</a>
- [[ } else { ]][[= $_->{flags} & $VNDB::UFLAGS->{list} ? 0 : '-' ]][[ } ]]</td>
- <td class="tc7">[[ if($_->{changes}) { ]]
- <a href="/u[[= $_->{id} ]]/hist" title="Recent changes by -[[: $_->{username} ]]">[[= $_->{changes} ]]</a>
- [[ } else { ]]0[[ } ]]</td>
-[[ if($p{Authusermod}) { ]]-
- <td class="tc8">( <a href="/u[[= $_->{id} ]]/edit">edit</a> )</td>[[ } ]]-
- </tr>
- [[ } ]]-
-</table>
--[[= pagebut($surl) ]]-
-[[ } ]]
diff --git a/data/tpl/userlogin b/data/tpl/userlogin
deleted file mode 100644
index b4af29d2..00000000
--- a/data/tpl/userlogin
+++ /dev/null
@@ -1,14 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
--[[= cform( [
- { type => 'error' },
- { type => 'startform', action => '/u/login' },
- { type => 'input', short => 'username', name => 'Username' },
- { type => 'pass', short => 'userpass', name => 'Password' },
- { type => 'submit', text => 'Login!' },
- { type => 'endform' },
-], $d{log}) ]]-
-
-<p>
- <br /><br />
- <a href="/u/register">No account yet</a>, or <a href="/u/newpass">forgot your username or password?</a>
-</p>
diff --git a/data/tpl/userpage b/data/tpl/userpage
deleted file mode 100644
index aa02062e..00000000
--- a/data/tpl/userpage
+++ /dev/null
@@ -1,13 +0,0 @@
-[[= ttabs('u', $d{user}) ]]
-[[
- $d{pl} = $d{user}{flags} & $VNDB::UFLAGS->{list};
-]]
-<h2>[[: $p{PageTitle} ]]</h2>
-<dl>
- <dt>Username</dt><dd>[[: $d{user}{username} ]]- (<a href="/u[[= $d{user}{id} ]]">u[[= $d{user}{id} ]]</a>)</dd>
- <dt>Registered</dt><dd>[[= formatdate('%Y-%m-%d', $d{user}{registered}) ]]</dd>
- <dt>Votes</dt><dd>[[= $d{pl} ? $d{user}{votes}.' (<a href="/u'.$d{user}{id}.'/list">view all</a>)' : '(hidden)' ]]</dd>
- <dt>Changes</dt><dd>[[= $d{user}{changes}.($d{user}{changes}>0?' (<a href="/u'.$d{user}{id}.'/hist">recent changes</a>)':'') ]]</dd>
-</dl>
-
-[[= T_vnpage_stats($X) ]]
diff --git a/data/tpl/userpass b/data/tpl/userpass
deleted file mode 100644
index c3b04840..00000000
--- a/data/tpl/userpass
+++ /dev/null
@@ -1,21 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-<p>
- You're lucky that vndb has a very advanced password recovery tool! Just
- type your email address (the same one you used for your account), and
- wait for an email!
-</p>
-
--[[ if(!$d{done}) { ]]
-[[= cform( [
- { type => 'error', },
- { type => 'startform', action => '/u/newpass' },
- { type => 'input', short => 'mail', name => 'Email' },
- { type => 'submit', text => 'Gimme my password!' },
- { type => 'endform' },
-], $d{pas} ) ]]
-
-[[ } else { ]]
-<span class="msg">
- Your password succesfully been reset. Check your mail for instructions.
-</span>
-[[ } ]]
diff --git a/data/tpl/userreg b/data/tpl/userreg
deleted file mode 100644
index 31b2b622..00000000
--- a/data/tpl/userreg
+++ /dev/null
@@ -1,38 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-
--[[ if($d{denied}) { ]]
-[[ } ]]-
-
-<br /><br />
-<h3>Why should I register?</h3>
-<p>
- Registered users have access to special features on this site:
-</p>
-<ul>
- <li>You can keep track of the visual novels you'd like to play or have
- finished playing,</li>
- <li>Vote on visual novels,</li>
- <li>And more importantly: you can add and edit all information on the
- website!</li>
-</ul>
-<p>
- <br />
- And of course, registering an account is (and will always remain)
- completely free!
- <br /><br />
-</p>
-
--[[= cform( [
- { type => 'error' },
- { type => 'startform', action => '/u/register' },
- { type => 'input', short => 'username', name => 'Username' },
- { type => 'input', short => 'mail', name => 'Email' },
- { type => 'static', text => q|
- Your email address will only be used in case you lose your password, at least for now.
- We will never send spam or newsletters unless you explicitly ask us for it.
- | },
- { type => 'pass', short => 'pass1', name => 'Password' },
- { type => 'pass', short => 'pass2', name => 'Confirm pass.' },
- { type => 'submit', text => 'Register!' },
- { type => 'endform' },
-], $d{reg}) ]]
diff --git a/data/tpl/vnbrowse b/data/tpl/vnbrowse
deleted file mode 100644
index fa4ba1ac..00000000
--- a/data/tpl/vnbrowse
+++ /dev/null
@@ -1,108 +0,0 @@
-<h2>[[: $p{PageTitle} ]]</h2>
-
-
-[[ if($d{chr} eq 'search') { ]]
- <form id="vsearch" method="get" action="/v/search" accept-charset="UTF-8">
- <fieldset>
- <input type="text" name="q" id="q" value="[[: $p{searchquery} ]]" class="text"
- /><input type="submit" value="Search!" />
- <br />
- <b id="adsearchclick">[[= !$p{searchquery} ? '&#9662;' : '&#9656;' ]]- advanced options</b>
- </fieldset>
- </form>
-
- <div id="adsearch" [[= !$p{searchquery} ? '' : ' style="display: none"' ]]>
- <b>Categories</b> (boolean and, selecting more gives less results. The categories are explained on <a href="/d1">this page</a>)
- <ul id="cat">
- [[ for my $c (qw| e g t p h l s |) { ]]-
- -[[= $c !~ /[thl]/ ? '<li>' : '<br />' ]][[: $VNDB::CAT->{$c}[0] ]]-
- <ul>
- [[ for (sort keys %{$VNDB::CAT->{$c}[1]}) { my $ca = $c.$_; ]]-
- <li id="cat_[[= $ca ]]">
- [[: $VNDB::CAT->{$c}[1]{$_} ]]- ([[= $d{cat}{$ca} || 0 ]])</li>
- [[ } ]]
- </ul>[[= $c !~ /[gph]/ ? '</li>' : '' ]]-
- [[ } ]]-
- </ul>
- <br style="clear: both" />
- <br />
-
- <b>Languages</b> (boolean or, selecting more gives more results)<br />
- <ul class="filter" id="lfilter">
- [[ for (sort keys %{$d{langc}}) { next if !$d{langc}{$_}; my $l=$_; ]]-
- <li><input type="checkbox" name="lang_[[= $l ]]" id="lang_[[= $l ]]" value="[[: $VNDB::LANG->{$l} ]]" />
- <label for="lang_[[= $l ]]"><acronym class="icons lang -[[= $l ]]" title="[[: $VNDB::LANG->{$l} ]]">&nbsp;</acronym>([[= $d{langc}{$l} ]])</label></li>
- [[ } ]]-
- </ul>
- <br style="clear: both" />
- <br />
-
- <b>Platforms</b> (boolean or, selecting more gives more results)<br />
- <ul class="filter" id="pfilter">
- [[ for (sort keys %$VNDB::PLAT) { next if /oth/; my $l=$_; ]]-
- <li><input type="checkbox" name="plat_[[= $l ]]" id="plat_[[= $l ]]" value="[[: $VNDB::PLAT->{$l} ]]" />
- <label for="plat_[[= $l ]]"><acronym class="icons -[[= $l ]]" title="[[: $VNDB::PLAT->{$l} ]]">&nbsp;</acronym></label></li>
- [[ } ]]-
- </ul>
- <br style="clear: both" />
- <input type="button" class="right" id="vsearch_sub" name="vsearch_sub" value="Search!" />
- <br style="clear: left" />
- <br /><br />
- </div>
-
-[[ } else { ]]-
-<p class="chr">
- -[[= $d{chr} ne 'all' ? '<a href="/v/all">all</a>' : 'all' ]]- |
- [[ for('a'..'z', 0) { ]]-
- -[[ if($d{chr} eq $_) { ]][[= $_?$_:'#' ]][[ } else { ]]<a href="/v/[[= $_ ]]">[[= $_?$_:'#' ]]</a>[[ } ]]
- [[ } ]]-
- <br /><br />
-</p>
-[[ } ]]-
-
-
--[[ if($#{$d{vn}} < 0) { ]]
- -[[ if($d{chr} eq 'search' && $p{searchquery} || $d{chr} ne 'search') { ]]
-<p>
- No results again, life sucks... :'(
-</p>
- [[ } ]]
-[[ } else {
- my %url = (
- $p{searchquery} ? ( q => $p{searchquery} ) : (),
- );
- my %urls = ( %url,
- $d{order}[0] ne 'title' ? ( s => $d{order}[0] ) : (),
- $d{order}[1] ne 'a' ? ( o => $d{order}[1] ) : (),
- );
- my $url = sprintf '/v/%s', $d{chr};
- my $urls = $url;
- $urls .= '?'.join(';', map { $_.'='.$urls{$_} } keys %urls) if keys %urls;
- $url .= '?'.join(';', map { $_.'='.$url{$_} } keys %url) if keys %url;
-]]
-
-[[= pagebut($urls) ]]
-<table id="tbv">
- <thead><tr>
- <td class="tc1">Title [[= sortbut($url, 'title') ]]</td>
- <td class="tc2">&nbsp;</td>
- <td class="tc3">&nbsp;</td>
- <td class="tc4">Released [[= sortbut($url, 'released') ]]</td>
- </tr></thead>
- [[ for (@{$d{vn}}) {
- $_->{c_released} =~ s#^([0-9]{4})([0-9]{2}).+#$1==0?'N/A':$1==9999?'TBA':(($2&&$2<13?($Time::CTime::MoY[$2-1].' '):'').$1)#e;
- $_->{c_platforms} = join '', map {
- $_ ne 'oth' ? '<acronym class="icons '.$_.'" title="'._hchar($VNDB::PLAT->{$_}).'">&nbsp;</acronym>' : ()
- } split /\//, $_->{c_platforms};
- $_->{c_languages} = join '', map qq|<acronym class="icons lang $_" title="$$VNDB::LANG{$_}">&nbsp;</acronym>|, reverse sort split /\//, $_->{c_languages};
- ]]-
- <tr>
- <td class="tc1"><a href="/v[[= $_->{id} ]]" title="[[: $_->{original}||$_->{title} ]]">[[: shorten $_->{title}, 50 ]]</a></td>
- <td class="tc2">[[= $_->{c_platforms} ]]</td>
- <td class="tc3">[[= $_->{c_languages} ]]</td>
- <td class="tc4">[[: $_->{c_released} ]]</td>
- </tr>
- [[ } ]]-
-</table>
-[[= pagebut($urls) ]]
-[[ } ]]
diff --git a/data/tpl/vnedit b/data/tpl/vnedit
deleted file mode 100644
index a9801674..00000000
--- a/data/tpl/vnedit
+++ /dev/null
@@ -1,120 +0,0 @@
-[[= $d{id} ? ttabs('v', $d{vn}, 'edit') : '' ]]-
-<h2>[[: $p{PageTitle} ]]</h2>
-
-[[ if(!$d{id}) { ]]
- <span class="msg">Please search the database before adding a new visual novel
- in order to prevent duplicate entries.</span>
-[[ } else { ]]
- <span class="msg">
- Please check the <a href="/t/v[[= $d{id} ]]">discussion board</a> <b>before</b> making
- any changes!
- </span>
-[[ } if($d{id} && $d{vn}{cid} != $d{vn}{latest}) { ]]
- <span class="warning">
- You are editing an old revision of this visual novel. If you save it, all changes made after
- -[[= formatdate('%Y-%m-%d %R', $d{vn}{added}) ]]- will be removed!
- </span>
-[[ } ]]
-
-
--[[= cform([
- { type => 'error' },
- { type => 'startform', action => $d{id} ?( '/v'.$d{id}.'/edit') : '/v/new', upload => 1, fh => 1 },
-
- { type => 'sub', title => 'General info', short => 'info' },
- { type => 'input', name => 'Title (romaji)', short => 'title', r=>1 },
- { type => 'input', name => 'Original title', short => 'original' },
- { type => 'static', text => q|
- The original title of this visual novel, leave blank if it already is in the Latin alphabet.<br /><br />| },
-
- { type => 'textarea', name => 'Aliases', short => 'alias', rows => 2, cols => 60 },
- { type => 'static', text => q|
- Comma seperated list of alternative titles or abbreviations. Can include both official
- (japanese/english) titles and unofficial titles used around net. <b>Titles that are listed in the releases do not have to be added here.</b><br /><br />| },
-
- { type => 'textarea', name => 'Description', short => 'desc', rows => 7, cols => 70, r=>1 },
- { type => 'static', text => q|
- Short description of the main story. Please do not include spoilers, and don't forget to list the source
- in case you didn't write the description yourself. ([url] BBCode tag is allowed)<br /><br />| },
-
- { type => 'select', name => 'Length', short => 'length', class => 'longopts', options => [ map {
- { short => $_,
- name => !$_?$VNDB::VNLEN->[$_][0]:($VNDB::VNLEN->[$_][0].', '.$VNDB::VNLEN->[$_][1].' ('.$VNDB::VNLEN->[$_][2].')') } } 0..$#$VNDB::VNLEN
- ] },
- { type => 'static', text => '<br />' },
- { type => 'input', name => 'External links', short => 'l_wp', pre => 'http://en.wikipedia.org/wiki/' },
- { type => 'input', name => '&nbsp;', short => 'l_encubed', pre => 'http://novelnews.net/tag/', post => '/' },
- { type => 'input', name => '&nbsp;', short => 'l_renai', pre => 'http://renai.us/game/', post => '.shtml' },
- { type => 'input', name => '&nbsp;', short => 'l_vnn', pre => 'http://visual-novels.net/vn/index.php?option=com_content&amp;task=view&amp;id=', class => 'shortopts' },
-
- { type => 'static', text => '<br />' },
- { type => 'input', name => 'Related anime', short => 'anime' },
- { type => 'static', text => q|
- Whitespace seperated list of <a href="http://anidb.net/">AniDB</a> anime IDs.
- E.g. "1015 3348" will add <a href="http://anidb.net/a1015">Shingetsutan Tsukihime</a>
- and <a href="http://anidb.net/a3348">Fate/stay night</a> as related anime.<br />
- <b>Note:</b> It can take a few minutes for the anime titles to appear on the VN page.| },
-
- { type => 'sub', title => 'Categories', short => 'cat' },
- { type => 'hidden', short => 'categories' },
- { type => 'static', raw => 1, text => eval {
- my $r = 'Please read the <a href="/d1">category descriptions</a> before modifying categories!<br /><br />'
- .'<ul id="cat">';
- for my $c (qw| e g t p h l s |) {
- $r .= ($c !~ /[thl]/ ? '<li>' : '<br />').$VNDB::CAT->{$c}[0].'<a href="/d1#'.$VNDB::CAT->{$c}[2].'" class="help">?</a><ul>';
- for (sort keys %{$VNDB::CAT->{$c}[1]}) {
- $r .= sprintf '<li><a href="#" id="cat_%1$s"><b id="b_%1$s">-</b> %2$s</a></li>',
- $c.$_, $VNDB::CAT->{$c}[1]{$_};
- }
- $r .= '</ul>'.($c !~ /[gph]/ ? '</li>' : '');
- }
- $r.'</ul>';
- } },
-
- { type => 'sub', title => 'Image', short => 'img' },
- $d{id} ? (
- { type => 'static', text => $d{vn}{image} > 0 ?
- sprintf '<img src="%s/cv/%02d/%d.jpg" style="float: right" />', $p{st}, $d{vn}{image}%100, $d{vn}{image} :
- $d{vn}{image} < 0 ? '[processing]' : 'No image uploaded yet...' },
- ) : (),
- { type => 'upload', name => $d{vn}{image} ? 'Change' : 'Upload', short => 'img' },
- { type => 'static', text => q|
- Preferably the cover of the CD/DVD/package. Image must be in JPEG or PNG format and at most 500kB. Images larger than 256x400 will automatically be resized.<br /><br />| },
- { type => 'check', short => 'img_nsfw', name => '<b>NSFW.</b> Please check this option if the image contains nudity, gore, or is otherwise not safe in a work-friendly environment.' },
-
- { type => 'sub', title => 'Visual novel relations', short => 'rel' },
- { type => 'jssel', name => 'Relations', short => 'relations', sh => 'rl' },
- { type => 'static', text => q|
- <b>Direct relations:</b> Please only add direct relations. E.g. the sequel of a sequel does not have to be listed
- here because it's already listed on an other visual novel that is in turn listed here. VNDB will handle these
- relations automatically.<br />
- <b>Reverse relations:</b> If you add a relation with an other visual novel here, the same (or "reverse") relation
- will automatically be added to the other visual novel. For example: if you add Tsukihime as a prequel of Kagetsu Tohya,
- Kagetsu Tohya will automatically be added as a sequel for Tsukihime.
- |},
-
- { type => 'sub', title => 'Screenshots', short => 'scr' },
- { type => 'hidden', short => 'screenshots' },
- { type => 'static', raw => 1, text => qq|
- <span class="warning">
- <b style="float: none; display: inline; font-weight: bold">Please keep the following in mind when uploading screenshots:</b><br />
- * Screenshots have to be in the native resolution of the game,<br />
- * Remove any window borders and make sure the image is unmarked,<br />
- * Don't only upload event CGs.<br />
- Please read the <a href="/d2#6">guidelines</a> for more information.<br />
- <b style="float: none; display: inline; font-weight: bold">Make sure to submit the form after the upload has finished!</b>
- </span><br />
- <div id="scrfrm" class="$p{st}">...make sure to enable Javascript...</div>
- <script type="text/javascript">
- var scrRel = [|.join(', ', map { ($$_{title} = _hchar($$_{title})) =~ s/\\/\\\\/g; $$_{title}=~s/'/\\'/g; "[ $$_{id}, '$$_{language}', '$$_{title}' ]" } @{$d{rel}}).q|];
- </script>
- |},
-
- { type => 'sub', title => 'Edit summary', short => 'com' },
- { type => 'textarea', name => 'Edit summary', short => 'comm', rows => 3, cols => 60 },
- { type => 'static', text => 'Please explain your modifications and cite all sources.' },
-
- { type => 'submit', text => $d{id} ? 'Edit' : 'Add' },
- { type => 'endform' },
-
-], $d{form}) ]]
diff --git a/data/tpl/vnlist b/data/tpl/vnlist
deleted file mode 100644
index d2763b39..00000000
--- a/data/tpl/vnlist
+++ /dev/null
@@ -1,63 +0,0 @@
-[[= ttabs('u', $d{user}) ]]
-<h2>[[: $p{PageTitle} ]]</h2>
-[[
- my $url = sprintf '/u%d/vlist', $d{user}{id};
- my $surl = sprintf '%s?s=%s;o=%s', $url, $d{order}[0], $d{order}[1];
- my $purl = $surl . ';t='.$d{status};
- my $sourl = $url . '?t='.$d{status};
- my $furl = $purl . ';p='.$d{page};
-]]
-
-<span class="warning">
- This visual novel list is read-only, only visible to you, and may be
- deleted in future versions of the site. You are highly encouraged to
- move everything in this list to the new <a href="/u[[= $d{user}{id} ]]/list">visual novel list</a>.
-</span>
-
-<p class="chr">
- status: -[[ for (-1..$#$VNDB::LSTAT) { if($_ >= 0) { ]]- | -[[ }
- if($d{status} == $_) { ]]<b>[[= $_ eq -1 ? 'all' : lc $VNDB::LSTAT->[$_] ]]</b>[[ }
- else { ]]<a href="[[= $surl ]]&amp;t=[[= $_ ]]">[[= $_ eq -1 ? 'all' : lc $VNDB::LSTAT->[$_] ]]</a>[[ } } ]]
- <br /><br />
-</p>
-
-
-[[ if($#{$d{list}} < 0) { ]]-
-<p>
-[[ if($d{status} >= 0) { ]]
- No results found...
-[[ } elsif($d{user}{username} eq $p{AuthUsername}) { ]]
- Your visual novel list is empty. You can keep track of all the visual novels
- you'd like to play, you're currently playing, or you've finished. Just go to
- a visual novel page and add it to your VN list!
-[[ } else { ]]
- [[: $d{user}{username} ]]'s visual novel list is empty...
-[[ } ]]
-</p>
-
-[[ } else { ]]
-[[= pagebut($purl) ]]-
-<form method="post" action="[[= $furl ]]" class="tblf">
-<table id="tvl">
- <thead><tr>
- <td class="tc1">Title [[= sortbut($sourl, 'title') ]]</td>
- <td class="tc2">Status</td>
- <td class="tc3">Added [[= sortbut($sourl, 'date') ]]</td>
- <td class="tc4">Personal note</td>
- <td class="tc5">&nbsp;</td>
- </tr></thead>
- [[ for (@{$d{list}}) { ]]-
- <tr>
- <td class="tc1"><a href="/v[[= $_->{vid} ]]" title="[[: $_->{title} ]]">[[: length($_->{title})>40 ? substr($_->{title},0, 37).'...' : $_->{title} ]]</a></td>
- <td class="tc2">[[= $VNDB::LSTAT->[$_->{status}] ]]</td>
- <td class="tc3">[[= formatdate('%Y-%m-%d', $_->{date}, 'dh') ]]</td>
- <td class="tc4">[[: $_->{comments}||'-' ]]</td>
- <td class="tc5"><input type="checkbox" name="sel" value="[[= $_->{vid} ]]" /></td>
- </tr>
- [[ } ]]-
-</table>
-<input type="submit" value="Delete selected items" class="right" />
-</form>
--[[= pagebut($purl) ]]
-[[ } ]]-
-
diff --git a/data/tpl/vnpage b/data/tpl/vnpage
deleted file mode 100644
index bca1bf35..00000000
--- a/data/tpl/vnpage
+++ /dev/null
@@ -1,204 +0,0 @@
-[[= ttabs('v', $d{vn}) ]]
-
-<h2>[[: $d{vn}{title} ]]</h2>
-[[ if($d{vn}{original}) { ]]<h3 class="alttitle">[[: $d{vn}{original} ]]</h3>[[ } ]]
-
-
-[[ if($d{vn}{hidden}) { ]]-
- <span class="warning">
- This item has been deleted from the database. File a request on the
- <a href="/t/v[[= $d{vn}{id} ]]">discussion board</a> to undelete this page.
- </span>
-[[ } ]]
-[[ if(!$d{vn}{hidden} || $p{Authdel}) { ]]-
-
--[[ if($p{AuthLoggedin}) { ]]
-<p class="mod">&lt;
- user options -
- <a href="/u[[= $p{AuthId} ]]/list" rel="voteDD" class="dropdown">[[= $d{vote}{vid} ? 'your vote: '.$d{vote}{vote} : 'vote' ]]</a>
- - <a href="/u[[= $p{AuthId} ]]/wish" rel="wishDD" class="dropdown">[[= $d{wlist}{vid} ? 'wishlist: '.lc($$VNDB::WSTAT[$d{wlist}{wstat}]) : 'wishlist' ]]</a>
-&gt;</p>
-[[ } ]]-
-
-
-
-[[ if($d{change}) { ]]
-[[= cdiff($d{prev}, $d{vn},
- [ title => 'Title (romaji)', 1 ],
- [ original => 'Original title', 1 ],
- [ alias => 'Alias', 1, 1 ],
- [ desc => 'Description', 1, 1 ],
- [ length => 'Length', sub { $VNDB::VNLEN->[$_[0] ][0] } ],
- [ l_wp => 'Wikipedia link', sub { $_[0] ? '<a href="http://en.wikipedia.org/wiki/'.$_[0].'">'.$_[0].'</a>' : 'No link' } ],
- [ l_encubed => 'Encubed tag', sub { $_[0] ? '<a href="http://novelnews.net/tag/'._huri($_[0]).'/">'.$_[0].'</a>' : 'No link' } ],
- [ l_renai => 'Renai.us link', sub { $_[0] ? '<a href="http://renai.us/game/'._huri($_[0]).'.shtml">'.$_[0].'</a>' : 'No link' } ],
- [ l_vnn => 'V-N.net link', sub { $_[0] ? '<a href="http://visual-novels.net/vn/index.php?option=com_content&amp;task=view&amp;id='.$_[0].'">'.$_[0].'</a>' : 'No link' } ],
- [ anime => 'Related anime', sub { join(' ', map qq|<a href="http://anidb.net/a$$_{id}">$$_{id}</a>|, sort { $a->{id} <=> $b->{id} } @{$_[0]}) } ],
- [ categories => 'Categories', sub { join(' ', map { my $l=$VNDB::CAT->{substr($_->[0],0,1)}[1]{substr($_->[0],1,2)}; $l?$l.'('.$_->[1].')':() } sort { $a->[0] cmp $b->[0] } @{$_[0]}) || 'No categories selected' }, 1 ],
- [ relations => 'Relations', sub { join("<br />\n", map { $VNDB::VREL->[$_->{relation}].': '._hchar($_->{title}) } sort { $a->{id} <=> $b->{id} } @{$_[0]}) } ],
- [ image => 'Image', sub { $_[0] > 0 ? sprintf '<img src="%s/cv/%02d/%d.jpg" />', $p{st}, $_[0]%100, $_[0] : $_[0] < 0 ? '[processing]' : 'No image'; } ],
- [ screenshots => 'Screenshots', sub { join "<br />\n", map sprintf('[%s] <a href="%s/sf/%02d/%d.jpg">%4$d</a> (%s)',$$_{rid}?qq|<a href="/r$$_{rid}">r$$_{rid}</a>|:'no release',$p{st},$$_{id}%100,$$_{id},$$_{nsfw}?'NSFW':'Safe'), @{$_[0]} } ],
- [ img_nsfw => 'NSFW', sub { $_[0] ? 'Not safe' : 'Safe' } ]
- ) ]]
-[[ } ]]-
-
-[[
- my @lang;
- for (@{$d{rel}}) {
- my $l = $_->{language};
- next if grep { $_ eq $l } @lang;
- push @lang, $l;
- }
-
-]]
-
-
-<div id="vnheader">
-<div>
-[[ if($d{vn}{image} > 0) { ]]
- [[ if($d{vn}{img_nsfw} && !$p{AuthNsfw}) { ]]
- <img src="[[: $p{st} ]]/cv/nsfw.png" id="nsfw" class="[[: $p{st} ]]/cv/[[= sprintf '%02d/%d', $d{vn}{image}%100, $d{vn}{image} ]].jpg" />
- [[ } else { ]]
- <img src="[[: $p{st} ]]/cv/[[= sprintf '%02d/%d', $d{vn}{image}%100, $d{vn}{image} ]].jpg" alt="[[: $p{PageTitle} ]]" />
- [[ if($d{vn}{img_nsfw}) { ]]
- <p class="nsfw">[ flagged as NSFW ]</p>
- [[ } ]]
- [[ } ]]
-[[ } elsif($d{vn}{image} < 0) { ]]-
- [processing image, please return in a few minutes]
-[[ } else { ]]-
- No image uploaded yet...
-[[ } ]]-
-</div>
-
--[[
- my @links = (
- $d{vn}{l_wp} ? [ 'Wikipedia', 'http://en.wikipedia.org/wiki/%s', $d{vn}{l_wp} ] : (),
- $d{vn}{l_encubed} ? [ 'Encubed', 'http://novelnews.net/tag/%s/', _huri $d{vn}{l_encubed} ] : (),
- $d{vn}{l_renai} ? [ 'Renai.us', 'http://renai.us/game/%s.shtml', _huri $d{vn}{l_renai} ] : (),
- $d{vn}{l_vnn} ? [ 'V-N.net', 'http://visual-novels.net/vn/index.php?option=com_content&amp;task=view&amp;id=%d', $d{vn}{l_vnn} ] : (),
- );
-
- my $prod = @lang && grep { @{$_->{producers}} } @{$d{rel}};
-
-if($d{vn}{length} || $d{vn}{alias} || @links || $prod) { ]]
- <h3>General info</h3>
- <dl>
- [[ if($d{vn}{length}) { ]]-
- <dt>Length</dt><dd>[[: $VNDB::VNLEN->[$d{vn}{length}][0] ]]- ([[: $VNDB::VNLEN->[$d{vn}{length}][1] ]])</dd>[[ } ]]-
- [[ if($d{vn}{alias}) { ]]-
- <dt>Aliases</dt><dd>[[: $d{vn}{alias} ]]</dd>[[ } ]]-
- [[ if(@links > 0) { ]]-
- <dt>Links</dt><dd>[[= join(', ', map { '<a href="'.sprintf($_->[1],$_->[2]).'">'.$_->[0].'</a>' } @links) ]]</dd>[[ } ]]-
- [[ if($prod) { ]]-
- <dt>Producers</dt><dd>
- [[ for my $l (@lang) { my %l;
- $_->{language} eq $l && (%l = ( %l, map {
- sprintf('<a href="/p%d" title="%s">%s</a>',
- $_->{id}, _hchar($_->{original}||$_->{name}), _hchar shorten $_->{name}, 30) => 1
- } @{$_->{producers}} )) for (@{$d{rel}});
- if(keys %l) { ]]-
- <acronym class="icons lang -[[= $l ]]" title="[[: $VNDB::LANG->{$l} ]]">&nbsp;</acronym>[[= join(' &amp; ', keys %l) ]]<br />
- [[ } } ]]
- </dd>[[ } ]]-
- </dl>
-[[ } ]]-
-
- [[ if(@{$d{vn}{categories}}) { my %nolvl = (map {$_=>1} qw| pli pbr gaa gab hfa hfe lea lfa lsp tfu tpa tpr |); ]]-
- <h3>Categories</h3>
- <dl class="vnrel">
- [[ for (qw|e s g p h|) {
- my $c = $_;
- my @c = map { my $s=$_;
- my ($cs) = grep { $_->[0] eq $c.$s } @{$d{vn}{categories}};
- $cs ? sprintf('<i class="crgn%d">%s</i>', $nolvl{$c.$_}?0:$cs->[1], $VNDB::CAT->{$c}[1]{$s})
- : ()
- } sort keys %{$VNDB::CAT->{$c}[1]};
- if(@c) { ]]-
- <dt>[[: $VNDB::CAT->{$c}[0] ]]</dt><dd>[[= join(', ', @c) ]]</dd>
- [[ } } ]]
- [[ if(grep $_->[0] =~ /^[tl]/, @{$d{vn}{categories}}) { ]]-
- <dt>Place/Time</dt><dd>[[= join ', ', map $VNDB::CAT->{substr($_->[0],0,1)}[1]{substr($_->[0],1,2)},
- sort { $a->[0] cmp $b->[0] } grep $_->[0] =~ /^[tl]/, @{$d{vn}{categories}} ]]</dd>
- [[ } ]]-
- </dl>
- [[ } ]]-
-
- [[ if($#{$d{vn}{relations}} >= 0) { ]]-
- <h3>[[= $d{page} eq 'rg' ? 'Relations' : '<a href="/v'.$d{vn}{id}.'/rg">Relations</a>' ]]</h3>
- <dl class="vnrel">
- [[ my $lrel = -1; my $i=0; for (sort { $a->{relation} <=> $b->{relation} } @{$d{vn}{relations}}) {
- if($_->{relation} != $lrel) { $lrel=$_->{relation}; if($i) { ]]</dd>[[ } ]]-
- <dt>[[: $VNDB::VREL->[$lrel] ]]</dt><dd>[[ } else { ]]<br />[[ } ]]
- <a href="/v[[= $_->{id} ]]" title="[[: $_->{original}||$_->{title} ]]">[[: shorten $_->{title}, 40 ]]</a>
- [[ ++$i;} ]]</dd>
- </dl>
- [[ } ]]-
-
- [[ if(@{$d{vn}{anime}}) { ]]-
- <h3>Related anime</h3>
- <ul class="vnani">
- [[ for (sort { $a->{year} < 1 ? 1 : $b->{year} < 1 ? -1 : $a->{year} <=> $b->{year} } @{$d{vn}{anime}}) { ]]-
- <li>
- -[[ if($_->{lastfetch} < 1) { ]]
- <b>[[= $_->{lastfetch} < 0 ? '[unknown anidb id: ' : '[no information available at this time: ' ]]<a href="http://anidb.net/a[[= $_->{id} ]]">[[= $_->{id} ]]</a>]</b>
- [[ } else {
- my $l = join '-', qq|<a href="http://anidb.net/a$_->{id}" title="AniDB">DB</a>|,
- $_->{nfo_id} ? qq|<a href="http://animenfo.com/animetitle,$_->{nfo_id},vndb.html" title="AnimeNFO">NFO</a>| : (),
- $_->{ann_id} ? qq|<a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=$_->{ann_id}" title="Anime News Network">ANN</a>| : ();
- ]]
- <b>[-[[= $l ]]-]</b> <acronym title="[[: $_->{title_kanji} ]]">[[: shorten $_->{title_romaji}, 40 ]]</acronym>
- <b>([[: $VNDB::ANITYPE->[$_->{type}][0] eq 'unknown' ? '' : $VNDB::ANITYPE->[$_->{type}][0].', ' ]][[= $_->{year} ]])</b>
- [[ } ]]
- </li>
- [[ } ]]
- </ul>
- [[ } ]]-
-</div>
-
--[[
- my @lnks = (
- !$d{page} ? '<b>description &amp; releases</b>' : '<a href="/v'.$d{vn}{id}.'">description &amp; releases</a>',
- $d{page} eq 'stats' ? '<b>stats</b>' : '<a href="/v'.$d{vn}{id}.'/stats">stats</a>',
- @{$d{vn}{screenshots}} ? (
- $d{page} eq 'scr' ? '<b>screenshots</b>' : '<a href="/v'.$d{vn}{id}.'/scr">screenshots</a>',
- ) : (),
- @{$d{vn}{relations}} ? (
- $d{page} eq 'rg' ? '<b>relations</b>' : '<a href="/v'.$d{vn}{id}.'/rg">relations</a>',
- ) : (),
- );
-]]
-<p class="opts">- -[[= join(' - ', @lnks) ]]- -</p>
-
-[[ if(!$d{page}) { ]][[+ vnpage_rel ]][[ } ]]
-[[ if($d{page} eq 'stats') { ]][[+ vnpage_stats ]][[ } ]]
-[[ if($d{page} eq 'rg') { ]][[+ vnpage_rg ]][[ } ]]
-[[ if($d{page} eq 'scr') { ]][[+ vnpage_scr ]][[ } ]]
-
-[[ if($p{AuthLoggedin}) { ]]-
-<div class="dropdown" id="voteDD">
- <ul>
- [[ if($d{vote}{vid}) { ]]-
- <li><a href="/v[[= $d{vn}{id} ]]/vote?v=-1">revoke</a></li>
- [[ } for (reverse 1..10) { ]]-
- <li class="center"><a href="/v[[= $d{vn}{id} ]]/vote?v=[[= $_ ]]" id="dovote_[[= $_ ]]">[[= $_ ]]</a></li>
- [[ } ]]
- </ul>
-</div>
-
-<div class="dropdown" id="wishDD">
- <ul>
- [[ for (0..$#$VNDB::WSTAT) {
- if($d{wlist}{vid} && $d{wlist}{wstat} == $_) { ]]-
- <li><b>[[: $$VNDB::WSTAT[$_] ]]</b></li>
- [[ } else { ]]-
- <li><a href="/v[[= $d{vn}{id} ]]/wish?w=[[= $_ ]]">[[: $$VNDB::WSTAT[$_] ]]</a></li>
- [[ } } if($d{wlist}{vid}) { ]]-
- <li><a href="/v[[= $d{vn}{id} ]]/wish?w=-1">remove</a></li>
- [[ } ]]
- </ul>
-</div>
-[[ } ]]
-
-
-[[ } ]]
diff --git a/data/tpl/vnpage_rel b/data/tpl/vnpage_rel
deleted file mode 100644
index 4e5d29b2..00000000
--- a/data/tpl/vnpage_rel
+++ /dev/null
@@ -1,59 +0,0 @@
-<h3>Description</h3>
-<p class="desc">
- [[= summary($d{vn}{desc}) ]]
- <br /><br /><br />
-</p>
-
-
-
-[[
- my @lang;
- for (@{$d{rel}}) {
- my $l = $_->{language};
- next if grep { $_ eq $l } @lang;
- push @lang, $l;
- }
-
-]]
-
-
-<h3>Releases
-[[ if((!$d{vn}{locked} && $p{Authedit}) || $p{Authlock}) { ]]- <p class="actions">(<a href="/v[[= $d{vn}{id} ]]/add">add release</a>)</p>[[ } ]]</h3>
-[[ if(@{$d{rel}}) { ]]-
-<table id="tre">
-[[ for(@lang) { my $l = $_; ]]-
-<tr class="lang">
- <td colspan="6">[[: $VNDB::LANG->{$l} ]]</td>
-</tr>
-[[ for (@{$d{rel}}) { next if $l ne $_->{language}; ]]-
- <tr>
- <td class="tc1">[[= datestr($_->{released}) ]]</td>
- <td class="tc2">[[= $_->{minage}<0 ? '' : $VNDB::VRAGES->{$_->{minage}} ]]</td>
- <td class="tc3">
- [[= join('', map { $_ ne 'oth' ? '<acronym class="icons '.$_.'" title="'._hchar($VNDB::PLAT->{$_}).'">&nbsp;</acronym>' : () } sort @{$_->{platforms}}) ]]
- <acronym title="[[= $VNDB::RTYP->[$_->{type}] ]]- release" class="icons -[[= lc substr($VNDB::RTYP->[$_->{type}],0,3) ]]">&nbsp;</acronym>
- </td>
- <td class="tc4"><a href="/r[[= $_->{id} ]]" title="[[: $_->{original} || $_->{title} ]]">[[: shorten $_->{title},60 ]]</a></td>
- <td class="tc5">[[ if($p{AuthId}) { ]]
- [[= sprintf '<a href="/r%d" class="dropdown above" rel="rlistDD%1$d">%s</a>', $_->{id}, $_->{rlist} ?
- ('<acronym title="'.$VNDB::RSTAT->[$_->{rlist}{rstat}].'" class="uicons r'.$_->{rlist}{rstat}.'">&nbsp;</acronym>'.
- '<acronym title="'.$VNDB::VSTAT->[$_->{rlist}{vstat}].'" class="uicons v'.$_->{rlist}{vstat}.'">&nbsp;</acronym>')
- : '<acronym title="Add to your visual novel list" class="uicons no">&nbsp;</acronym>' ]]
- [[ } else { ]]&nbsp;[[ } ]]</td>
- <td class="tc6">[[ if($_->{website}) { ]]<a href="[[: $_->{website} ]]" class="icons ext" title="WWW">&nbsp;</a>[[ } ]]</td>
- </tr>
-[[ } ]]-
-[[ } ]]-
-</table>
-[[ } else { ]]-
-<p>
- This game has either not been released yet, or we just don't have information about
- any releases.
-</p>
-[[ } ]]
-
-
-[[ if($p{AuthId}) { ]]
-[[ for my $r (@{$d{rel}}) { ]]-
--[[= rlist_dd($r) ]]
-[[ } } ]]
diff --git a/data/tpl/vnpage_rg b/data/tpl/vnpage_rg
deleted file mode 100644
index deae6124..00000000
--- a/data/tpl/vnpage_rg
+++ /dev/null
@@ -1,11 +0,0 @@
-<h3>Relations</h3>
-[[ if(!$d{vn}{rgraph}) { ]]
- <p>
- Relation graph has not been generated yet...
- </p>
-[[ } else { ]]
- [[= $d{vn}{cmap} ]]
- <p id="relations">
- <img src="[[= sprintf "%s/rg/%02d/%d.png", $p{st}, $d{vn}{rgraph}%100, $d{vn}{rgraph} ]]" usemap="#rgraph" alt="Relation graph for -[[: $d{vn}{title} ]]" />
- </p>
-[[ } ]]
diff --git a/data/tpl/vnpage_scr b/data/tpl/vnpage_scr
deleted file mode 100644
index f0c4ae9f..00000000
--- a/data/tpl/vnpage_scr
+++ /dev/null
@@ -1,37 +0,0 @@
-<h3>Screenshots
-[[ if((!$d{vn}{locked} && $p{Authedit}) || $p{Authlock}) { ]]- <p class="actions">(<a href="/v[[= $d{vn}{id} ]]/edit?fh=scr">manage screenshots</a>)</p>[[ } ]]</h3>
-
-[[ if(@{$d{vn}{screenshots}}) {
- my $tot = @{$d{vn}{screenshots}};
- my $nsfw = grep $$_{nsfw}, @{$d{vn}{screenshots}};
-]]-
-
-<div id="screenshots">
-[[ for my $r (undef, @{$d{rel}}) {
- my @s = grep { !$r && !$_->{rid} || $r && $_->{rid} && $_->{rid} == $r->{id} } @{$d{vn}{screenshots}};
- next if !@s;
-]]-
-[[ if($r) { ]]
-<b><acronym class="icons lang -[[= $r->{language} ]]" title="[[: $VNDB::LANG->{$r->{language}} ]]">&nbsp;</acronym>
-[[: $r->{title} ]]</b>
-[[ } ]]
-[[ for(@s) { ]]
- <a href="[[= sprintf '%s/sf/%02d/%d.jpg', $p{st}, $$_{id}%100, $$_{id} ]]"
- class="shot [[= $$_{nsfw} ? ' scr_nsfw':'' ]]" [[= !$p{AuthNsfw}&&$$_{nsfw}?' style="display: none"':'' ]]-
- rel="[[= $$_{width}.'x'.$$_{height} ]]"><img src="[[= sprintf '%s/st/%02d/%d.jpg', $p{st}, $$_{id}%100, $$_{id} ]]"
- /><b>[[= $$_{nsfw} ? 'x' : '&nbsp;' ]]</b></a>
-[[ } ]]-
-<br style="clear: left" /><br />
-[[ } ]]
-
-</div>
-[[ if($nsfw) { ]]-
-<p id="scrNsfwHid">&nbsp;</p>
-<i style="font-size: 10px;">Items marked with a red X are flagged as NSFW.</i>
-[[ } ]]-
-
-[[ } else { ]]-
-<p>
- No screenshots have been uploaded yet for this visual novel.
-</p>
-[[ } ]]
diff --git a/data/tpl/vnpage_stats b/data/tpl/vnpage_stats
deleted file mode 100644
index ab159f14..00000000
--- a/data/tpl/vnpage_stats
+++ /dev/null
@@ -1,39 +0,0 @@
-<ul id="stats">
-
-[[
- my $max = 1; my $total = 0; my $sum = 0;
- for (0..$#{$d{votes}{graph}}) {
- $total += $d{votes}{graph}[$_];
- $max = $d{votes}{graph}[$_] if $d{votes}{graph}[$_] > $max;
- $sum += ($_+1) * $d{votes}{graph}[$_];
- }
-]]
-[[ if(!$d{user} || ($d{pl} && $d{user}{votes})) { ]]-
-<li><h3>Vote graph <p class="actions">[[= $total ]]- vote[[= $total==1?'':'s' ]]- total
- [[= $total && $d{user} ? sprintf(', average: %.1f.', $sum/$total) : '' ]]</p></h3>
-<table id="tvg">
-[[ for (reverse 0..$#{$d{votes}{graph}}) { ]]-
- <tr>
- <td class="tc1">[[= $_+1 ]]</td>
- <td class="tc2"><div style="width: -[[= ($d{votes}{graph}[$_]/$max)*270 + 5 ]]px">&nbsp;</div>[[= $d{votes}{graph}[$_] ]]</td>
- </tr>
-[[ } ]]-
-</table></li>
-
-[[ if($#{$d{votes}{latest}} >= 0) { ]]
-<li><h3>Recent votes</h3>
-<table id="tvr">
-[[ for (@{$d{votes}{latest}}) { ]]-
- <tr>
- [[ if(!$d{user}) { ]]-
- <td class="tc1">[[= userstr $_ ]]</td>
- [[ } else { ]]-
- <td class="tc1"><a href="/v[[= $_->{vid} ]]" title="[[: $_->{original}||$_->{title} ]]">[[: shorten $_->{title}, 30 ]]</a></td>
- [[ } ]]-
- <td class="tc2">[[= $_->{vote} ]]</td>
- <td class="tc3">[[= formatdate('%Y-%m-%d %R', $_->{date}, 'dh') ]]</td>
- </tr>
-[[ } ]]-
-</table></li>
-[[ } } ]]-
-</ul>
diff --git a/data/tpl/wlist b/data/tpl/wlist
deleted file mode 100644
index 049d28ca..00000000
--- a/data/tpl/wlist
+++ /dev/null
@@ -1,55 +0,0 @@
-[[= ttabs('u', $d{user}, 'wish') ]]
-<h2>[[: $p{PageTitle} ]]</h2>
-[[
- my $url = sprintf '/u%d/wish', $d{user}{id};
- my $surl = sprintf '%s?s=%s;o=%s', $url, $d{order}[0], $d{order}[1];
- my $furl = $surl . ';p='.$d{page};
-]]
-
-
-[[ if($#{$d{list}} < 0) { ]]-
-<p>
-[[ if($d{user}{username} eq $p{AuthUsername}) { ]]
- Your wishlist is empty. You can keep track of all the visual novels
- you'd like to play. Just go to a visual novel page and add it to your wishlist!
-[[ } else { ]]
- [[: $d{user}{username} ]]'s wishlist is empty...
-[[ } ]]
-</p>
-
-[[ } else { ]]
-[[= pagebut($surl) ]]-
-[[ if($d{user}{username} eq $p{AuthUsername}) { ]]
-<form method="post" action="[[= $furl ]]" class="tblf">
-[[ } ]]
-<table id="twl">
- <thead><tr>
- <td class="tc1">Title [[= sortbut($url, 'title') ]]</td>
- <td class="tc2">Priority [[= sortbut($url, 'wstat') ]]</td>
- <td class="tc3">Added [[= sortbut($url, 'added') ]]</td>
- <td class="tc4">&nbsp;</td>
- </tr></thead>
- [[ for (@{$d{list}}) { ]]-
- <tr>
- <td class="tc1"><a href="/v[[= $_->{vid} ]]" title="[[: $_->{original}||$_->{title} ]]">[[: shorten $_->{title}, 40 ]]</a></td>
- <td class="tc2">[[= $VNDB::WSTAT->[$_->{wstat}] ]]</td>
- <td class="tc3">[[= formatdate('%Y-%m-%d', $_->{added}) ]]</td>
- <td class="tc4">[[ if($d{user}{username} eq $p{AuthUsername}) { ]]<input type="checkbox" name="sel" value="[[= $_->{vid} ]]" />[[ } else { ]]&nbsp;[[ } ]]</td>
- </tr>
- [[ } ]]-
-</table>
-[[ if($d{user}{username} eq $p{AuthUsername}) { ]]
-<select id="vnlistchange" name="vnlistchange" class="right">
- <option value="n">- with selected -</option>
- <option value="d">Delete</option>
- <optgroup label="Update priority:">
- [[ for (0..$#$VNDB::WSTAT) { ]]-
- <option value="[[= $_ ]]">[[: $VNDB::WSTAT->[$_] ]]</option>
- [[ } ]]
- </optgroup>
-</select>
-</form>
-[[ } ]]
--[[= pagebut($surl) ]]
-[[ } ]]-
-
diff --git a/lib/VNDB.pm b/lib/VNDB.pm
deleted file mode 100644
index 94edf82e..00000000
--- a/lib/VNDB.pm
+++ /dev/null
@@ -1,247 +0,0 @@
-package VNDB;
-
-use strict;
-use warnings;
-
-BEGIN { require 'global.pl'; }
-our $DEBUG;
-
-require Time::HiRes if $DEBUG;
-require Data::Dumper if $DEBUG;
-use VNDB::Util::Template;
-use VNDB::Util::Request;
-use VNDB::Util::Response;
-use VNDB::Util::DB;
-use VNDB::Util::Tools;
-use VNDB::Util::Auth;
-use VNDB::Discussions;
-use VNDB::HomePages;
-use VNDB::Producers;
-use VNDB::Releases;
-use VNDB::VNLists;
-use VNDB::Users;
-use VNDB::VN;
-
-
-my %VNDBuris = ( # wildcards: * -> (.+), + -> ([0-9]+)
- '/' => sub { shift->HomePage },
- 'd+' => sub { shift->DocPage(shift) },
- 'd+.+' => sub { shift->ResRedirect('/d'.$_[0][0].'#'.$_[0][1]) },
- nospam => sub { shift->ResAddTpl(error => { err => 'formerr' }) },
- hist => {'*'=> sub { shift->History(undef, undef, $_[1]) } },
- # users
- u => {
- login => sub { shift->UsrLogin },
- logout => sub { shift->UsrLogout },
- register => sub { shift->UsrReg },
- newpass => sub { shift->UsrPass },
- list => {
- '/' => sub { shift->UsrList },
- '*' => sub { $_[3] =~ /^([a-z0]|all)$/ ? shift->UsrList($_[2]) : shift->ResNotFound },
- },
- },
- 'u+' => {
- '/' => sub { shift->UsrPage(shift) },
- edit => sub { shift->UsrEdit(shift) },
- del => sub { shift->UsrDel(shift) },
- list => sub { shift->RList(shift) },
- vlist => sub { shift->VNMyList(shift) },
- wish => sub { shift->WList(shift) },
- hist => {'*'=> sub { shift->History('u', shift, $_[1]) } },
- },
- # visual novels
- v => {
- '/' => sub { shift->VNBrowse },
- new => sub { shift->VNEdit(0); },
- '*' => sub { $_[2] =~ /^([a-z0]|all|search)$/ ? shift->VNBrowse($_[1]) : shift->ResNotFound; },
- },
- 'v+' => {
- '/' => sub { shift->VNPage(shift) },
- stats => sub { shift->VNPage(shift, shift) },
- rg => sub { shift->VNPage(shift, shift) },
- scr => sub { shift->VNPage(shift, shift) },
- edit => sub { shift->VNEdit(shift) },
- vote => sub { shift->VNVote(shift) },
- wish => sub { shift->WListMod(shift) },
- add => sub { shift->REdit('v', shift) },
- lock => sub { shift->VNLock(shift) },
- hide => sub { shift->VNHide(shift) },
- hist => {'*'=> sub { shift->History('v', shift, $_[1]) } },
- },
- 'v+.+' => sub { shift->VNPage($_[0][0], '', $_[0][1]) },
- # releases
- 'r+' => {
- '/' => sub { shift->RPage(shift) },
- edit => sub { shift->REdit('r', shift) },
- lock => sub { shift->RLock(shift) },
- hide => sub { shift->RHide(shift) },
- list => sub { shift->RListMod(shift) },
- hist => {'*'=> sub { shift->History('r', shift, $_[1]) } },
- },
- 'r+.+' => sub { shift->RPage($_[0][0], $_[0][1]) },
- # producers
- p => {
- '/' => sub { shift->PBrowse },
- add => sub { shift->PEdit(0) },
- '*' => sub { $_[2] =~ /^([a-z0]|all)$/ ? shift->PBrowse($_[1]) : shift->ResNotFound; }
- },
- 'p+' => {
- '/' => sub { shift->PPage(shift) },
- edit => sub { shift->PEdit(shift) },
- lock => sub { shift->PLock(shift) },
- hide => sub { shift->PHide(shift) },
- hist => {'*'=> sub { shift->History('p', shift, $_[1]) } },
- },
- 'p+.+' => sub { shift->PPage($_[0][0], $_[0][1]) },
- # discussions
- t => {
- '/' => sub { shift->TIndex },
- '*' => {
- '/' => sub { shift->TTag($_[1]) },
- new => sub { shift->TEdit(0, 0, $_[1]) },
- },
- },
- 't+' => {
- '/' => sub { shift->TThread(shift) },
- reply => sub { shift->TEdit(shift) },
- '+' => sub { shift->TThread(shift, shift) },
- },
- 't+.+' => {
- edit => sub { shift->TEdit($_[0][0], $_[0][1]) },
- '/' => sub { $_[0]->ResRedirect('/t'.$_[1][0].($_[1][1]>$_[0]->{postsperpage}?'/'.ceil($_[1][1]/$_[0]->{postsperpagee}):'').'#'.$_[1][1], 'perm') },
- },
- # stuff (.xml extension to make sure they aren't counted as pageviews)
- xml => {
- 'producers.xml' => sub { shift->PXML },
- 'vn.xml' => sub { shift->VNXML },
- 'screenshots.xml' => sub { shift->VNScrXML },
- },
-);
-
-
-# provide redirects for old URIs
-my %OLDuris = (
- faq => sub { shift->ResRedirect('/d6', 'perm') },
- notes => sub { shift->ResRedirect('/d8', 'perm') },
- vn => {
- rss => sub { shift->ResRedirect('/hist/rss?t=v&e=1', 'perm') },
- '*' => sub { shift->ResRedirect('/v/'.$_[1], 'perm') },
- },
- v => {
- cat => sub {
- my $f = $_[0]->FormCheck({name=>'i',required=>0},{name=>'e',required=>0},{name=>'l',required=>0},
- {name=>'p',required=>0},{name=>'o',required=>0},{name=>'s',required=>0});
- my %f;
- $f{$_} = $f->{$_} for (qw|p o s|);
- $f{q} = join ' ', (map $VNDB::CAT->{substr($_,0,1)}[1]{substr($_,1,2)}, split /,/, $f->{i}),
- (map '-'.$VNDB::CAT->{substr($_,0,1)}[1]{substr($_,1,2)}, split /,/, $f->{e}),
- (map $VNDB::LANG->{$_}, split /,/, $f->{l});
- !$f{$_}&&delete $f{$_} for keys %f;
- $_[0]->ResRedirect('/v/search'.(!(keys %f)?'':'?'.join(';', map $_.'='.$f{$_}, keys %f) ), 'perm');
- },
- },
- 'v+' => {
- votes => sub { shift->ResRedirect('/v'.(shift).'/stats', 'perm') },
- hist=>{rss => sub { shift->ResRedirect('/v'.(shift).'/hist/rss.xml', 'perm') } },
- },
- u => {
- '*' => {
- '*' => sub {
- if($_[2] =~ /^_(login|logout|register|newpass|list)$/) {
- $_[3] eq '/' ? $_[0]->ResRedirect('/u/'.$1, 'perm') : $_[0]->ResRedirect('/u/'.$1.'/'.$_[3], 'perm');
- } else {
- my $id = $_[0]->DBGetUser(username => $_[2])->[0]{id};
- $id ? $_[0]->ResRedirect('/u'.$id.'/'.$_[3], 'perm') : $_[0]->ResNotFound;
- }
- },
- }
- },
- 'u+' => {
- votes => sub { shift->ResRedirect('/u'.(shift).'/list', 'perm') },
- hist=>{rss => sub { shift->ResRedirect('/u'.(shift).'/hist/rss.xml', 'perm') } },
- },
- 'p+' => {
- hist=>{rss => sub { shift->ResRedirect('/p'.(shift).'/hist/rss.xml', 'perm') } },
- },
- 'r+' => {
- hist=>{rss => sub { shift->ResRedirect('/r'.(shift).'/hist/rss.xml', 'perm') } },
- },
- hist=>{rss => sub { shift->ResRedirect('/hist/rss.xml', 'perm') } },
-);
-
-
-
-sub new {
- my $self = shift;
- my $type = ref($self) || $self;
- my %args = @_;
-
- my $me = bless {
- debug => $VNDB::DEBUG,
- %args,
- _DB => VNDB::Util::DB->new(@VNDB::DBLOGIN),
- _TPL => VNDB::Util::Template->new(%{$args{tplopts}}),
- cmds => [],
- }, $type;
-
- return $me;
-}
-
-
-sub get_page {
- my $self = shift;
- my $r = shift;
-
- $self->{_Req} = VNDB::Util::Request->new($r);
- $self->{_Res} = VNDB::Util::Response->new($self->{_TPL});
-
- $self->AuthCheckCookie();
- $self->checkuri();
-
- my $res = $self->ResSetModPerl($r);
- $self->DBCommit();
-
- # commands have to be executed _after_ the call to DBCommit,
- # otherwise Multi can't see the new additions
- $self->RunCmd();
-
- return($self, $res);
-}
-
-
-sub checkuri {
- my $self = shift;
- (my $uri = lc($self->ReqUri)) =~ s/^\/+//;
- $uri =~ s/\?.*$//;
- return $self->ResRedirect("/$uri", 'perm') if $uri =~ s/\/+$//;
- $uri =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; # ugly hack, but we only accept ASCII anyway
- return $self->ResNotFound() if $uri !~ /^[a-z0-9\-\._~\/]*$/; # rfc3986 section 2.3, "Unreserved Characters"
- my @uri;
- defined $_ and push(@uri, $_) for (split(/\/+/, $uri));
- my @ouri = @uri; # items in @uri can be modified by uri2page
- $self->uri2page(\%VNDBuris, \@uri, 0);
- $self->uri2page(\%OLDuris, \@ouri, 0) # provide redirects for old uris
- if $self->{_Res}->{code} == 404;
-}
-
-
-sub uri2page {
- my($s, $o, $u, $i) = @_;
- $u->[$i] = '/' if !defined $u->[$i];
- my $n = $o->{$u->[$i]} ? $u->[$i] : ((map {
- if(/[\*\+]/) {
- (my $t = "^$_\$") =~ s/\./\\./g;
- /\*/ ? ($t =~ s/\*/(.+)/g) : ($t =~ s/\+/([1-9][0-9]*)/g);
- $u->[$i] =~ /$t/ ? ($u->[$i] = $2?[$1,$2]:$1) && $_ : ();
- } else { () } }
- sort { length($b) <=> length($a) } keys %$o)[0] || '*');
- ref($o->{$n}) eq 'HASH' && $n ne '/' ?
- $s->uri2page($o->{$n}, $u, ++$i) :
- ref($o->{$n}) eq 'CODE' && $i == $#$u ?
- &{$o->{$n}}($s, @$u) :
- $s->ResNotFound();
-}
-
-
-1;
-
diff --git a/lib/VNDB/Discussions.pm b/lib/VNDB/Discussions.pm
deleted file mode 100644
index 9f80b0b0..00000000
--- a/lib/VNDB/Discussions.pm
+++ /dev/null
@@ -1,193 +0,0 @@
-
-package VNDB::Discussions;
-
-use strict;
-use warnings;
-use Exporter 'import';
-use POSIX 'ceil';
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-@EXPORT = qw| TThread TEdit TIndex TTag |;
-
-
-sub TThread {
- my $self = shift;
- my $id = shift;
- my $page = shift||1;
-
- my $t = $self->DBGetThreads(id => $id, what => 'tagtitles')->[0];
- return $self->ResNotFound if !$t || $t->{hidden} && !$self->AuthCan('boardmod');
-
- my $p = $self->DBGetPosts(tid => $id, results => $self->{postsperpage}, page => $page);
- return $self->ResNotFound if !$p->[0];
-
- $self->ResAddTpl(tthread => {
- t => $t,
- ppp => $self->{postsperpage},
- page => $page,
- p => $p,
- });
-}
-
-
-# tid num action
-# 0 0 Start a new thread
-# x 0 Reply to a thread
-# x 1 Edit thread (and first post)
-# x x Edit post
-sub TEdit {
- my $self = shift;
- my $tid = shift||0;
- my $num = shift||0;
- my $tag = shift||'';
-
- my $t = $tid && $self->DBGetThreads(id => $tid, what => 'tags')->[0];
- return $self->ResNotFound if $tid && !$t;
-
- my $p = $num && $self->DBGetPosts(tid => $tid, num => $num)->[0];
-
- my $frm = {};
- if($self->ReqMethod eq 'POST') {
- $frm = $self->FormCheck(
- { name => 'msg', required => 1, maxlength => 5000 },
- !$tid || $num == 1 ? (
- { name => 'title', required => 1, maxlength => 50 },
- { name => 'tags', required => 1, maxlength => 50 },
- ) : (),
- $self->AuthCan('boardmod') ? (
- { name => 'hide', required => 0 },
- { name => 'lock', required => 0 }
- ) : (),
- );
- $frm->{msg} =~ s/[\r\s\n]$//g;
-
- my %tags = !$frm->{tags} || $frm->{_err} ? () : map {
- $frm->{_err} = [ 'wrongtag' ] if
- !/^([a-z]{1,2})([0-9]*)$/ || !$VNDB::DTAGS->{$1}
- || $1 eq 'v' && (!$2 || !$self->DBGetVN(id => $2)->[0])
- #|| $1 eq 'r' && (!$2 || !$self->DBGetRelease(id => $2)->[0])
- || $1 eq 'p' && (!$2 || !$self->DBGetProducer(id => $2)->[0])
- || $1 eq 'u' && (!$2 || !$self->DBGetUser(id => $2)->[0])
- || $1 eq 'an' && !$self->AuthCan('boardmod');
- $1.($2||0) => [ $1, $2||0 ]
- } split / /, $frm->{tags};
- my @tags = values %tags;
-
- if(!$frm->{_err}) {
- my $otid = $tid;
- if(!$tid || $num == 1) {
- my @tags =
- my %thread = (
- id => $tid,
- title => $frm->{title},
- tags => \@tags,
- hidden => $frm->{hide},
- locked => $frm->{lock},
- );
- $self->DBEditThread(%thread) if $tid; # edit thread
- $tid = $self->DBAddThread(%thread) if !$tid; # create thread
- }
-
- my $onum = $num;
- my %post = (
- tid => $tid,
- num => !$otid ? 1 : $num,
- msg => $frm->{msg},
- hidden => $num != 1 && $frm->{hide},
- );
- $self->DBEditPost(%post) if $num; # edit post
- $num = $self->DBAddPost(%post) if !$num; # add post
-
- $self->RunCmd('ircnotify t'.$tid.'.'.$num) if !$onum && !$frm->{hide};
-
- my $pagenum = ceil($num/$self->{postsperpage});
- $pagenum = $pagenum > 1 ? '/'.$pagenum : '';
- $self->ResRedirect('/t'.$tid.$pagenum.'#'.$num, 'POST');
- }
- }
-
- if($p) {
- $frm->{msg} ||= $p->{msg};
- $frm->{hide} = $p->{hidden};
- if($num == 1) {
- $frm->{tags} ||= join ' ', sort map $_->[1]?$_->[0].$_->[1]:$_->[0], @{$t->{tags}};
- $frm->{title} ||= $t->{title};
- $frm->{lock} = $t->{locked};
- $frm->{hide} = $t->{hidden};
- }
- }
- $frm->{tags} ||= $tag;
-
- $self->ResAddTpl(tedit => {
- t => $t,
- p => $p,
- tag => $tag,
- form => $frm,
- });
-}
-
-
-sub TIndex {
- my $self = shift;
-
- my %opts = (
- results => 6,
- what => 'firstpost lastpost tags',
- order => 'tp2.date DESC',
- );
-
- $self->ResAddTpl(tindex => {
- ppp => $self->{postsperpage},
- map +($_, scalar $self->DBGetThreads(%opts, type => $_)), qw| an db v p u|
- });
-}
-
-
-sub TTag {
- my $self = shift;
- my $tag = shift;
- my($type, $iid) = ($1, $2||0) if $tag =~ /^([a-z]{1,2})([0-9]*)$/;
- return $self->ResNotFound if !$type;
-
- my $f = $self->FormCheck(
- { name => 'p', required => 0, default => 1, template => 'int' },
- );
- return $self->ResNotFound if $f->{_err};
-
- my $o = !$iid ? undef :
- $type eq 'u' ? $self->DBGetUser(uid => $iid)->[0] :
- $type eq 'v' ? $self->DBGetVN(id => $iid)->[0] :
- #$type eq 'r' ? $self->DBGetRelease(id => $iid)->[0] :
- $self->DBGetProducer(id => $iid)->[0];
- return $self->ResNotFound if $iid && !$o || !$VNDB::DTAGS->{$type};
- my $title = $o ? $o->{username} || $o->{romaji} || $o->{title} || $o->{name} : $VNDB::DTAGS->{$type};
- my $original = $o ? $o->{username} || $o->{original} : $VNDB::DTAGS->{$type};
-
- my($t, $np) = $self->DBGetThreads(
- type => $type,
- iid => $iid,
- results => 50,
- page => $f->{p},
- what => 'firstpost lastpost tagtitles',
- order => $tag eq 'an' ? 't.id DESC' : 'tp2.date DESC',
- );
-
- $self->ResAddTpl(ttag => {
- page => $f->{p},
- npage => $np,
- obj => $o,
- type => $type,
- iid => $iid,
- title => $title,
- original => $original,
- tag => $tag,
- t => $t,
- ppp => $self->{postsperpage},
- });
-}
-
-
-
-1;
-
diff --git a/lib/VNDB/HomePages.pm b/lib/VNDB/HomePages.pm
deleted file mode 100644
index 63adcab7..00000000
--- a/lib/VNDB/HomePages.pm
+++ /dev/null
@@ -1,306 +0,0 @@
-
-package VNDB::HomePages;
-
-use strict;
-use warnings;
-use Exporter 'import';
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-@EXPORT = qw| HomePage DocPage History HistRevert HistDelete |;
-
-
-sub HomePage {
- my $self = shift;
-
- my $an = $self->DBGetThreads(type => 'an', order => 't.id DESC', results => 1)->[0];
- $self->ResAddTpl(home => {
- an => $an,
- anpost => $self->DBGetPosts(tid => $an->{id}, num => 1)->[0],
- recentedits => scalar $self->DBGetHist( results => 10, what => 'iid ititle'),
- recentvns => scalar $self->DBGetHist( results => 10, what => 'iid ititle', edits => 0, type => 'v'),
- randomvns => scalar $self->DBGetVN( results => 10, order => 'RANDOM()'),
- recentposts => scalar $self->DBGetThreads(results => 10, what => 'lastpost', order => 'tp2.date DESC'),
- # cache this shit when performance is going to be problematic
- upcomingrel => scalar $self->DBGetRelease(results => 10, unreleased => 1),
- justrel => scalar $self->DBGetRelease(results => 10, order => 'rr.released DESC', unreleased => 0),
- });
-}
-
-
-sub DocPage {
- my($s,$p) = @_;
-
- open my $F, '<', sprintf('%s/%d', $s->{docpath}, $p) or return $s->ResNotFound();
- my @c = <$F>;
- close $F;
-
- (my $title = shift @c) =~ s/^:TITLE://;
- chomp $title;
-
- my $sec = 0;
- for (@c) {
- s{^:SUB:(.+)\r?\n$}{
- $sec++;
- qq|<h3><a href="#$sec" name="$sec">$sec. $1</a></h3>\n|
- }eg;
- s{^:INC:(.+)\r?\n$}{
- open $F, '<', sprintf('%s/%s', $s->{docpath}, $1) or die $!;
- my $ii = join('', <$F>);
- close $F;
- $ii;
- }eg;
- }
-
- $s->ResAddTpl(docs => {
- title => $title,
- content => join('', @c),
- });
-}
-
-
-sub History { # type(p,v,r,u), id, [rss.xml|/]
- my($self, $type, $id, $fmt) = @_;
- $type ||= '';
- $id ||= 0;
-
- $fmt = undef if !$fmt || $fmt eq '/';
- return $self->ResNotFound if $fmt && $fmt ne 'rss.xml';
-
- my $f = $self->FormCheck(
- { name => 'p', required => 0, default => 1, template => 'int' },
- { name => 'ip', required => 0, default => 0 }, # hidden option
- { name => 't', required => 0, default => 'a', enum => [ qw| v r p a | ] },
- { name => 'e', required => 0, default => 0, enum => [ 0..2 ] },
- { name => 'r', required => 0, default => $fmt ? 10 : 50, template => 'int' },
- { name => 'i', required => 0, default => 0, enum => [ 0..1 ] },
- { name => 'h', required => 0, default => 0, enum => [ 0..2 ] }, # hidden option
- );
- return $self->ResNotFound if $f->{_err};
-
- my $o =
- $type eq 'u' ? $self->DBGetUser(uid => $id)->[0] :
- $type eq 'v' ? $self->DBGetVN(id => $id)->[0] :
- $type eq 'r' ? $self->DBGetRelease(id => $id)->[0] :
- $type eq 'p' ? $self->DBGetProducer(id => $id)->[0] :
- undef;
- return $self->ResNotFound if $type && !$o;
- my $t =
- $type eq 'u' ? $o->{username} :
- $type eq 'v' ? $o->{title} :
- $type eq 'r' ? $o->{romaji} || $o->{title} :
- $type eq 'p' ? $o->{name} :
- undef;
-
- my($h, $np, $act);
-
- if($self->ReqMethod ne 'POST' || $fmt) {
- ($h, $np) = $self->DBGetHist(
- what => 'iid ititle user',
- type => $type,
- !$type && $f->{t} ne 'a' ? (
- type => $f->{t} ) : (),
- $f->{e} ? (
- edits => $f->{e} == 1 ? 0 : 1 ) : (),
- id => $id,
- page => $fmt ? 0 : $f->{p},
- results => $f->{r},
- releases => $type eq 'v' ? $f->{i} : 0,
- showhid => $f->{h},
- $f->{ip} ? (
- ip => $f->{ip} ) : (),
- );
- }
- else {
- my $frm = $self->FormCheck(
- { name => 'sel', required => 1, multi => 1 },
- { name => 'post', required => 1, default => 'Mass revert', enum => [ 'Mass revert', 'Mass delete' ] },
- );
- my @s = grep /^[0-9]+$/, @{$frm->{sel}};
- if(!$frm->{_err} && @s) {
- $np = 0;
- $h = $frm->{post} =~ /revert/ ? $self->HistRevert(\@s) : $self->HistDelete(\@s);
- $act = $frm->{post} =~ /revert/ ? 'r' : 'd';
- }
- }
-
- if(!$fmt) {
- $self->ResAddTpl(hist => {
- title => $t,
- selt => $f->{t},
- sele => $f->{e},
- seli => $f->{i},
- type => $type,
- id => $id,
- hist => $h,
- page => $f->{p},
- npage => $np,
- obj => $o,
- act => $act || '',
- });
- } else {
- my $x = $self->ResStartXML;
- $x->startTag('rss', version => '2.0');
- $x->startTag('channel');
- $x->dataElement('language', 'en');
- $x->dataElement('title', !$type ? 'Recent changes at VNDB.org' : $type eq 'u' ? 'Recent changes by '.$t : 'Edit history of '.$t);
- $x->dataElement('link', $self->{root_url}.(!$type ? '/hist' : '/'.$type.$id.'/hist'));
-
- for (@$h) {
- my $t = (qw| v r p |)[$_->{type}];
- my $url = $self->{root_url}.'/'.$t.$_->{iid}.'?rev='.$_->{id};
- $_->{comments} = VNDB::Util::Template::tpl::summary($_->{comments})||'[no summary]';
- $x->startTag('item');
- $x->dataElement(title => $_->{ititle});
- $x->dataElement(link => $url);
- $x->dataElement(pubDate => NTL::time2str($_->{requested}));
- $x->dataElement(guid => $url);
- $x->dataElement(description => $_->{comments});
- $x->endTag('item');
- }
-
- $x->endTag('channel');
- $x->endTag('rss');
- }
-}
-
-
-
-
-1;
-
-__END__
-
-
-#############################################################
-# E X P E R I M E N T A L S T U F F #
-# #
-
-# !WARNING!: this code has not been updated to reflect the recent database changes!
-
-
-# !WARNING!: this code uses rather many large SQL queries, use with care...
-sub HistRevert { # \@ids
- my($self, $l) = @_;
- my $comm = 'Mass revert to revision %d by %s';
-
- # first, get objects, remove newly created items and causedby edits and add original edits
- $l = $self->DBGetHist(cid => $l, results => 1000, what => 'iid');
- my @todo;
- for (@$l) {
- next if !$_->{prev}; # remove newly created items
- if($_->{causedby}) { # remove causedby edits
- push @todo, $self->DBGetHist(cid => [ $_->{causedby} ], what => 'iid')->[0]; # add original edit
- } else {
- push @todo, $_;
- }
- }
-
- # second, group all items and remove duplicate edits
- my %todo; # key=type.iid, value = [objects]
- for my $t (@todo) {
- my $k = $t->{type}.$t->{iid};
- $todo{$k} = [ $t ] and next
- if !$todo{$k};
- push @{$todo{$k}}, $t
- if !grep { $_->{id} == $t->{id} } @{$todo{$k}};
- }
-
- # third, make sure we don't revert edits we don't want to revert
- #TODO
-
- # fourth, get the lowest revision of each item to revert to (ignoring intermetiate edits)
- @todo = map { (sort { $a->{id} <=> $b->{id} } @{$todo{$_}})[0] } keys %todo;
-
- # fifth, actually revert the edits
- my @relupd;
- for (@todo) {
-
- if($_->{type} == 0) { # visual novel
- my $v = $self->DBGetVN(id => $_->{iid}, rev => $_->{prev}, what => 'extended changes relations')->[0];
- my $old = $self->DBGetVN(id => $_->{iid}, rev => $_->{id}, what => 'relations')->[0];
- my $cid = $self->DBEditVN($_->{iid},
- (map { $_ => $v->{$_} } qw| title desc alias categories comm length l_wp l_cisv l_vnn img_nsfw image|),
- relations => [ map { [ $_->{relation}, $_->{id} ] } @{$v->{relations}} ],
- comm => sprintf($comm, $v->{cid}, $v->{username}),
- );
- my %old = map { $_->{id} => $_->{relation} } @{$old->{relations}};
- my %new = map { $_->{id} => $_->{relation} } @{$v->{relations}};
- push @relupd, $self->VNUpdReverse(\%old, \%new, $_->{iid}, $cid);
- }
-
- if($_->{type} == 1) { # release
- my $r = $self->DBGetRelease(id => $_->{iid}, rev => $_->{prev}, what => 'producers platforms media vn changes')->[0];
- $self->DBEditRelease($_->{iid},
- (map { $_ => $r->{$_} } qw| title original language website notes minage type released platforms |),
- media => [ map { [ $_->{medium}, $_->{qty} ] } @{$r->{media}} ],
- producers => [ map { $_->{id} } @{$r->{producers}} ],
- comm => sprintf($comm, $r->{cid}, $r->{username}),
- vn => [ map { $_->{vid} } @{$r->{vn}} ],
- );
- }
-
- if($_->{type} == 2) { # producer
- my $p = $self->DBGetProducer(id => $_->{iid}, rev => $_->{prev}, what => 'changes')->[0];
- $self->DBEditProducer($_->{iid},
- (map { $_ => $p->{$_} } qw| name original website type lang desc |),
- comm => sprintf($comm, $p->{cid}, $p->{username}),
- );
- }
- }
- # update relation graphs
- $self->VNRecreateRel(@relupd) if @relupd;
-
- # sixth, create report of what happened
- my @done;
- for my $t (@todo, @$l) {
- next if $t->{_status};
- $t->{_status} =
- (scalar grep { $t->{id} == $_->{id} } @todo) ? 'reverted' :
- $t->{causedby} ? 'automated' :
- 'skipped';
- push @done, $t;
- }
- return \@done;
-}
-
-
-# ONLY DELETES NEWLY CREATED PAGES (for now...)
-sub HistDelete { # \@ids
- my ($self, $l) = @_;
-
- # get objects and add causedby edits
- $l = $self->DBGetHist(cid => $l, results => 1000, what => 'iid');
- my @todo = @$l;
-# for (@$l) {
-# if($_->{causedby}) { # remove causedby edits
-# my $n = $self->DBGetHist(cid => [ $_->{causedby} ])->[0]; # add original edit
-# push @todo, $n, $self->DBGetHist(causedby => $n->{id} ])->[0]; # add causedby edits
-# } else {
-# push @todo, $_;
-# }
-# }
-
- # remove duplicate edit
- # (not necessary now)
-
- # completely delete newly created items (sort on type to make sure we delete vn's before releases, which is faster)
- my @vns;
- for my $t (sort { $a->{type} <=> $b->{type} } @todo) {
- next if $t->{prev};
- $self->DBDelVN($t->{iid}) if $t->{type} == 0;
- $self->DBDelProducer($t->{iid}) if $t->{type} == 2;
- if($t->{type} == 1) { # we need to know the vn's to remove a release
- my $r = $self->DBGetRelease(id => $t->{iid}, what => 'vn')->[0];
- next if !$r; # we could have deleted this release by deleting the related vn
- $self->DBDelRelease([ map { $_->{vid} } @{$r->{vn}} ], $t->{iid});
- }
- }
-
- # delete individual edits
- #TODO
-
- return \@todo;
-}
-
-
diff --git a/lib/VNDB/Producers.pm b/lib/VNDB/Producers.pm
deleted file mode 100644
index 9756855d..00000000
--- a/lib/VNDB/Producers.pm
+++ /dev/null
@@ -1,176 +0,0 @@
-
-package VNDB::Producers;
-
-use strict;
-use warnings;
-use Exporter 'import';
-use Digest::MD5;
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-@EXPORT = qw| PPage PBrowse PEdit PLock PHide PXML |;
-
-
-sub PPage {
- my $self = shift;
- my $id = shift;
- my $rev = shift||0;
-
- return $self->ResNotFound if $self->ReqParam('rev');
-
- my $p = $self->DBGetProducer(
- id => $id,
- $rev ? ( what => 'changes', rev => $rev ) : (),
- )->[0];
- return $self->ResNotFound if !$p->{id};
-
- my $c = $rev && $rev > 1 && $self->DBGetProducer(id => $id, rev => $rev-1, what => 'changes')->[0];
- $p->{next} = $rev && $p->{latest} > $p->{cid} ? $rev+1 : 0;
-
- return $self->ResAddTpl(ppage => {
- prod => $p,
- prev => $c,
- change => $rev,
- vn => $self->DBGetProducerVN($id),
- });
-}
-
-
-sub PBrowse {
- my $self = shift;
- my $chr = shift;
- $chr = 'all' if !defined $chr;
-
- my $p = $self->FormCheck(
- { name => 'p', required => 0, default => 1, template => 'int' },
- { name => 'q', required => 0, default => '' }
- );
- return $self->ResNotFound if $p->{_err};
-
- my($r, $np) = $self->DBGetProducer(
- $chr ne 'all' ? (
- char => $chr ) : (),
- $p->{q} ? (
- search => $p->{q} ) : (),
- page => $p->{p},
- results => 50,
- );
-
- $self->ResAddTpl(pbrowse => {
- prods => $r,
- page => $p->{p},
- npage => $np,
- query => $p->{q},
- chr => $chr,
- });
-}
-
-
-sub PEdit {
- my $self = shift;
- my $id = shift || 0; # 0 = new
-
- my $rev = $self->FormCheck({ name => 'rev', required => 0, default => 0, template => 'int' });
- return $self->ResNotFound if $rev->{_err};
- $rev = $rev->{rev};
-
- my $p = $self->DBGetProducer(id => $id, what => 'changes', $rev ? ( rev => $rev ) : ())->[0] if $id;
- return $self->ResNotFound() if $id && !$p;
-
- return $self->ResDenied if !$self->AuthCan('edit') || ($p->{locked} && !$self->AuthCan('lock'));
-
-
- my %b4 = $id ? (
- map { $_ => $p->{$_} } qw|name original website type lang desc|
- ) : ();
-
- my $frm = {};
- if($self->ReqMethod() eq 'POST') {
- $frm = $self->FormCheck(
- { name => 'type', required => 1, enum => [ keys %$VNDB::PROT ] },
- { name => 'name', required => 1, maxlength => 200 },
- { name => 'original', required => 0, maxlength => 200, default => '' },
- { name => 'lang', required => 1, enum => [ keys %$VNDB::LANG ] },
- { name => 'website', required => 0, maxlength => 200, template => 'url', default => '' },
- { name => 'desc', required => 0, maxlength => 10240, default => '' },
- { name => 'comm', required => 0, default => '' },
- );
-
- return $self->ResRedirect('/p'.$id, 'post')
- if $id && 6 == scalar grep { $_ ne 'comm' && $b4{$_} eq $frm->{$_} } keys %b4;
-
- if(!$frm->{_err}) {
- my $nrev = 1;
- ($nrev) = $self->DBEditProducer($id, %$frm) if $id; # edit
- ($id) = $self->DBAddProducer(%$frm) if !$id; # add
-
- $self->RunCmd('ircnotify p'.$id.'.'.$nrev);
- return $self->ResRedirect('/p'.$id.'.'.$nrev, 'post');
- }
- }
-
- if($id) {
- $frm->{$_} ||= $b4{$_} for (keys %b4);
- $frm->{comm} = sprintf 'Reverted to revision p%d.%d', $p->{id}, $p->{rev} if $p->{cid} != $p->{latest};
- } else {
- $frm->{lang} ||= 'ja';
- }
-
- $self->ResAddTpl(pedit => {
- form => $frm,
- id => $id,
- prod => $p,
- });
-}
-
-
-sub PLock {
- my $self = shift;
- my $id = shift;
-
- my $p = $self->DBGetProducer(id => $id)->[0];
- return $self->ResNotFound() if !$p;
- return $self->ResDenied if !$self->AuthCan('lock');
- $self->DBLockItem('producers', $id, $p->{locked}?0:1);
- return $self->ResRedirect('/p'.$id, 'perm');
-}
-
-
-sub PHide {
- my $self = shift;
- my $id = shift;
-
- my $p = $self->DBGetProducer(id => $id)->[0];
- return $self->ResNotFound() if !$p;
- return $self->ResDenied if !$self->AuthCan('del');
- $self->DBHideProducer($id, $p->{hidden}?0:1);
- return $self->ResRedirect('/p'.$id, 'perm');
-}
-
-sub PXML {
- my $self = shift;
-
- my $q = $self->FormCheck(
- { name => 'q', required => 0, maxlength => 100 }
- )->{q};
-
- my $r = [];
- if($q) {
- $r = $self->DBGetProducer(results => 10,
- $q =~ /^p([0-9]+)$/ ? (id => $1) : (search => $q));
- }
-
- my $x = $self->ResStartXML;
- $x->startTag('producers', results => $#$r+1, query => $q);
- for (@$r) {
- $x->startTag('item');
- $x->dataElement(id => $_->{id});
- $x->dataElement(name => $_->{name});
- $x->dataElement(original => $_->{original}) if $_->{original};
- $x->dataElement(website => $_->{website}) if $_->{website};
- $x->endTag('item');
- }
- $x->endTag('producers');
-}
-
-
diff --git a/lib/VNDB/Releases.pm b/lib/VNDB/Releases.pm
deleted file mode 100644
index 0f36c4fe..00000000
--- a/lib/VNDB/Releases.pm
+++ /dev/null
@@ -1,188 +0,0 @@
-
-package VNDB::Releases;
-
-use strict;
-use warnings;
-use Exporter 'import';
-use Digest::MD5;
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-@EXPORT = qw| RPage REdit RLock RHide RVNCache |;
-
-
-sub RPage {
- my $self = shift;
- my $id = shift;
- my $rev = shift||0;
-
- return $self->ResNotFound if $self->ReqParam('rev');
-
- my $v = $self->DBGetRelease(
- id => $id,
- what => 'producers platforms media vn'.($rev ? ' changes':''),
- $rev ? ( rev => $rev ) : ()
- )->[0];
- return $self->ResNotFound if !$v->{id};
-
- my $c = $rev && $rev > 1 && $self->DBGetRelease(id => $id, rev => $rev-1, what => 'changes producers platforms media vn')->[0];
- $v->{next} = $rev && $v->{latest} > $v->{cid} ? $rev+1 : 0;
-
- $self->ResRedirect('/v'.$v->{vn}[0]{vid})
- if ($self->ReqHeader('Referer')||'') =~ m{^http://[^/]*(yahoo|google)} && @{$v->{vn}} == 1;
-
- $v->{rlist} = $self->DBGetRList(rids => [ $id ], uid => $self->AuthInfo->{id})->[0]
- if $self->AuthInfo->{id};
-
- return $self->ResAddTpl(rpage => {
- rel => $v,
- prev => $c,
- change => $rev,
- });
-}
-
-
-sub REdit {
- my $self = shift;
- my $act = shift||'v';
- my $id = shift || 0;
-
- my $rid = $act eq 'r' ? $id : 0;
-
- my $rev = $self->FormCheck({ name => 'rev', required => 0, default => 0, template => 'int' });
- return $self->ResNotFound if $rev->{_err};
- $rev = $rev->{rev};
-
- my $r = $self->DBGetRelease(id => $rid, what => 'changes producers platforms media vn', $rev ? ( rev => $rev ) : ())->[0] if $rid;
- my $ivn = $self->DBGetVN(id => $id)->[0] if !$rid;
- return $self->ResNotFound() if ($rid && !$r) || (!$rid && !$ivn);
-
- my $vn = $rid ? $r->{vn} : [ { vid => $id, title => $ivn->{title} } ];
-
- return $self->ResDenied if !$self->AuthCan('edit') || ($r->{locked} && !$self->AuthCan('lock'));
-
- my %b4 = $rid ? (
- (map { $_ => $r->{$_} } qw|title original gtin language website notes minage type platforms|),
- released => $r->{released} =~ /^([0-9]{4})([0-9]{2})([0-9]{2})$/ ? [ $1, $2, $3 ] : [ 0, 0, 0 ],
- media => join(',', map { $_->{medium} =~ /^(cd|dvd|gdr|blr)$/ ? ($_->{medium}.'_'.$_->{qty}) : $_->{medium} } @{$r->{media}}),
- producers => join('|||', map { $_->{id}.','.$_->{name} } @{$r->{producers}}),
- ) : ();
- $b4{vn} = join('|||', map { $_->{vid}.','.$_->{title} } @$vn);
-
- my $frm = {};
- if($self->ReqMethod() eq 'POST') {
- $frm = $self->FormCheck(
- { name => 'type', required => 1, enum => [ 0..$#{$VNDB::RTYP} ] },
- { name => 'title', required => 1, maxlength => 250 },
- { name => 'original', required => 0, maxlength => 250, default => '' },
- { name => 'gtin', required => 0, template => 'gtin', default => '0' },
- { name => 'language', required => 1, enum => [ keys %{$VNDB::LANG} ] },
- { name => 'website', required => 0, template => 'url', default => '' },
- { name => 'released', required => 0, multi => 1, template => 'int', default => 0 },
- { name => 'minage' , required => 0, enum => [ keys %{$VNDB::VRAGES} ], default => -1 },
- { name => 'notes', required => 0, maxlength => 10240, default => '' },
- { name => 'platforms', required => 0, multi => 1, enum => [ keys %$VNDB::PLAT ], default => '' },
- { name => 'media', required => 0, default => '' },
- { name => 'producers', required => 0, default => '' },
- { name => 'vn', required => 1, maxlength => 10240 },
- { name => 'comm', required => 0, default => '' },
- );
-
- my $released = !$frm->{released}[0] ? 0 :
- $frm->{released}[0] == 9999 ? 99999999 :
- sprintf '%04d%02d%02d', $frm->{released}[0], $frm->{released}[1]||99, $frm->{released}[2]||99;
- my $media = [ map { /_/ ? [ split /_/ ] : [ $_, 0 ] } split /,/, $frm->{media} ];
- my $producers = [ map { /^([0-9]+)/ ? $1 : () } split /\|\|\|/, $frm->{producers} ];
- my $new_vn = [ map { /^([0-9]+)/ ? $1 : () } split /\|\|\|/, $frm->{vn} ];
-
- $frm->{_err} = $frm->{_err} ? [ @{$frm->{_err}}, 'vn_1' ] : [ 'vn_1' ]
- if !@$new_vn;
-
- # weed out empty string
- $frm->{platforms} = [ map { $_ ? $_ : () } @{$frm->{platforms}} ];
-
- return $self->ResRedirect('/r'.$rid, 'post')
- if $rid && $released == $r->{released} &&
- (join(',', sort @{$b4{platforms}}) eq join(',', sort @{$frm->{platforms}})) &&
- 11 == scalar grep { $_ ne 'comm' && $_ ne 'released' && $_ ne 'platforms' && $frm->{$_} eq $b4{$_} } keys %b4;
-
- if(!$frm->{_err}) {
- my %opts = (
- vn => $new_vn,
- (map { $_ => $frm->{$_} } qw|title original gtin language website notes minage type comm platforms|),
- released => $released,
- media => $media,
- producers => $producers,
- );
- my $nrev = 1;
- ($nrev) = $self->DBEditRelease($rid, %opts) if $rid; # edit
- ($rid) = $self->DBAddRelease(%opts) if !$rid; # add
-
- $self->RVNCache(@$new_vn, (map { $_->{vid} } @$vn));
-
- $self->RunCmd('ircnotify r'.$rid.'.'.$nrev);
- return $self->ResRedirect('/r'.$rid.'.'.$nrev, 'post');
- }
- }
-
- if($rid) {
- $frm->{$_} ||= $b4{$_} for (keys %b4);
- $frm->{comm} = sprintf 'Reverted to revision r%d.%d', $r->{id}, $r->{rev} if $r->{cid} != $r->{latest};
- } else {
- $frm->{language} = 'ja';
- $frm->{vn} = $b4{vn};
- }
-
- $self->AddHid($frm);
- $frm->{_hid} = {map{$_=>1} qw| info pnm prod com |}
- if !$frm->{_hid} && !$rid;
- $self->ResAddTpl(redit => {
- form => $frm,
- id => $rid,
- rel => $r,
- vn => !$rid ? $ivn : $vn,
- });
-}
-
-
-sub RLock {
- my $self = shift;
- my $id = shift;
-
- my $r = $self->DBGetRelease(id => $id)->[0];
- return $self->ResNotFound() if !$r;
- return $self->ResDenied if !$self->AuthCan('lock');
- $self->DBLockItem('releases', $id, $r->{locked}?0:1);
- return $self->ResRedirect('/r'.$id, 'perm');
-}
-
-
-sub RHide {
- my $self = shift;
- my $id = shift;
-
- return $self->ResDenied if !$self->AuthCan('del');
- my $r = $self->DBGetRelease(id => $id, what => 'vn')->[0];
- return $self->ResNotFound if !$r;
- $self->DBHideRelease($id, $r->{hidden}?0:1);
- $self->RVNCache(map { $_->{vid} } @{$r->{vn}});
- return $self->ResRedirect('/r'.$id, 'perm');
-}
-
-
-sub RVNCache { # @vids - calls update_vncache and regenerates relation graphs if needed
- my($self, @vns) = @_;
- my $before = $self->DBGetVN(id => \@vns, order => 'v.id', what => 'relations');
- $self->DBVNCache(@vns);
- my $after = $self->DBGetVN(id => \@vns, order => 'v.id');
- my @upd = map {
- @{$before->[$_]{relations}} && (
- $before->[$_]{c_released} != $after->[$_]{c_released}
- || $before->[$_]{c_languages} ne $after->[$_]{c_languages}
- ) ? $before->[$_]{id} : ();
- } 0..$#$before;
- $self->RunCmd('relgraph '.join(' ', @upd)) if @upd;
-}
-
-1;
-
diff --git a/lib/VNDB/Users.pm b/lib/VNDB/Users.pm
deleted file mode 100644
index e2021627..00000000
--- a/lib/VNDB/Users.pm
+++ /dev/null
@@ -1,238 +0,0 @@
-
-package VNDB::Users;
-
-use strict;
-use warnings;
-use Exporter 'import';
-use Digest::MD5 'md5_hex';
-
-our $VERSION = $VNDB::VERSION;
-our @EXPORT = qw| UsrLogin UsrLogout UsrReg UsrPass UsrEdit UsrList UsrPage UsrDel |;
-
-
-sub UsrLogin {
- my $self = shift;
-
- (return $self->ResRedirect('/', 'temp')) if $self->AuthInfo()->{id};
-
- my $frm = {};
- if($self->ReqMethod() eq 'POST') {
- $frm = $self->FormCheck(
- { name => 'username', required => 1, minlength => 2, maxlength => 15, template => 'pname' },
- { name => 'userpass', required => 1, minlength => 4, maxlength => 15, template => 'asciiprint' },
- );
- if(!$frm->{_err}) {
- (my $ref = $self->ReqHeader('Referer')||'/') =~ s/^$self->{root_url}//;
- my $r = $self->AuthLogin($frm->{username}, $frm->{userpass}, 1, $ref);
- $r == 1 ? (return) : ($frm->{_err} = [ 'loginerr' ]);
- }
- }
-
- $self->ResAddTpl(userlogin => {
- log => $frm,
- } );
-}
-
-
-sub UsrLogout {
- shift->AuthLogout();
-}
-
-
-sub UsrReg {
- my $self = shift;
-
- (return $self->ResRedirect('/', 'temp')) if $self->AuthInfo()->{id};
-
- my $frm = {};
- if($self->ReqMethod() eq 'POST') {
- $frm = $self->FormCheck(
- { name => 'username', required => 1, minlength => 2, maxlength => 15, template => 'pname' },
- { name => 'mail', required => 1, template => 'mail' },
- { name => 'pass1', required => 1, minlength => 4, maxlength => 15, template => 'asciiprint' },
- { name => 'pass2', required => 1, minlength => 4, maxlength => 15, template => 'asciiprint' },
- );
- $frm->{_err} = $frm->{_err} ? [ @{$frm->{_err}}, 'badpass' ] : [ 'badpass' ]
- if $frm->{pass1} ne $frm->{pass2};
- $frm->{_err} = $frm->{_err} ? [ @{$frm->{_err}}, 'usrexists' ] : [ 'usrexists' ]
- if $frm->{username} eq 'anonymous' || $self->DBGetUser(username => $frm->{username})->[0];
- $frm->{_err} = $frm->{_err} ? [ @{$frm->{_err}}, 'mailexists' ] : [ 'mailexists' ]
- if $frm->{mail} && $self->DBGetUser(mail => $frm->{mail})->[0];
-
- if(!$frm->{_err}) {
- $self->DBAddUser($frm->{username}, md5_hex($frm->{pass1}), $frm->{mail}, 2);
- return $self->AuthLogin($frm->{username}, $frm->{pass1}, 1, '/');
- }
- }
- $self->ResAddTpl(userreg => {
- reg => $frm,
- });
-}
-
-
-sub UsrPass {
- my $self = shift;
-
- (return $self->ResRedirect('/', 'temp')) if $self->AuthInfo()->{id};
-
- my $d = $self->ReqParam('d');
-
- my $frm = {};
- if(!$d && $self->ReqMethod() eq 'POST') {
- $frm = $self->FormCheck({ name => 'mail', required => 1, template => 'mail' });
- my $unfo;
- if(!$frm->{_err}) {
- $frm->{mail} =~ s/%//g;
- $unfo = $self->DBGetUser(mail => $frm->{mail})->[0];
- $frm->{_err} = $frm->{_err} ? [ @{$frm->{_err}}, 'nomail' ] : [ 'nomail' ]
- if !$unfo;
- }
- if(!$frm->{_err}) {
- my @chars = ( 'A'..'Z', 'a'..'z', 0..9 );
- my $pass = join('', map $chars[int rand $#chars+1], 0..8);
- $self->DBUpdateUser($unfo->{id}, passwd => md5_hex($pass));
- $self->SendMail(sprintf(<<__, $unfo->{username}, $unfo->{username}, $pass),
-Hello %s,
-
-Your password has been reset, you can now login at http://vndb.org/ with the
-following information:
-
-Username: %s
-Password: %s
-
-Now don't forget your password again! :-)
-
-vndb.org
-__
- To => $frm->{mail},
- Subject => sprintf('Password request for %s', $unfo->{username}),
- );
- return $self->ResRedirect('/u/newpass?d=1', 'post');
- }
- }
-
- $self->ResAddTpl(userpass => {
- pas => $frm,
- done => $d,
- });
-}
-
-
-sub UsrEdit {
- my $self = shift;
- my $user = shift;
-
- my $u = $self->AuthInfo();
- return $self->ResDenied if !$u->{id};
- my $adm = $u->{id} != $user;
- return $self->ResDenied if $adm && !$self->AuthCan('usermod');
- $u = $self->DBGetUser(uid => $user)->[0] if $adm;
- return $self->ResNotFound if !$u->{id};
-
- my $d = $self->ReqParam('d');
-
- my $frm = {};
- if(!$d && $self->ReqMethod() eq 'POST') {
- $frm = $self->FormCheck(
- { name => 'mail', required => 1, template => 'mail' },
- { name => 'pass1', required => 0, template => 'asciiprint' },
- { name => 'pass2', required => 0, template => 'asciiprint' },
- $adm ? (
- { name => 'username',required => 1, template => 'pname', minlength => 2, maxlength => 15 },
- { name => 'rank', required => 1, enum => [ '1'..($#{$self->{ranks}}-1) ] },
- ) : (),
- { name => 'plist', required => 0 },
- { name => 'pign_nsfw', required => 0 },
- );
- if(($frm->{pass1} || $frm->{pass2}) && $frm->{pass1} ne $frm->{pass2}) {
- $frm->{_err} = [] if !$frm->{_err};
- push(@{$frm->{_err}}, 'badpass');
- }
- if(!$frm->{_err}) {
- my $pass = $frm->{pass1} ? md5_hex($frm->{pass1}) : '';
- my %opts = (
- username => $frm->{username}||undef,
- rank => $frm->{rank}||undef,
- mail => $frm->{mail},
- );
- $opts{passwd} = $pass if $pass;
- $opts{flags} = $frm->{plist} ? $VNDB::UFLAGS->{list} : 0;
- $opts{flags} += $VNDB::UFLAGS->{nsfw} if $frm->{pign_nsfw};
- $self->DBUpdateUser($u->{id}, %opts);
- return $adm ? $self->ResRedirect('/u'.$user.'/edit?d=1', 'post') :
- $pass ? $self->AuthLogin($u->{username}, $frm->{pass1}, 1, '/u'.$user.'/edit?d=1') :
- $self->ResRedirect('/u'.$user.'/edit?d=1', 'post');
- }
- }
-
- $frm->{$_} ||= $u->{$_}
- for (qw| username mail rank |);
- $frm->{plist} ||= $u->{flags} & $VNDB::UFLAGS->{list};
- $frm->{pign_nsfw} ||= $u->{flags} & $VNDB::UFLAGS->{nsfw};
- $self->ResAddTpl(useredit => {
- form => $frm,
- done => $d,
- adm => $adm,
- user => $user,
- u => $u
- });
-}
-
-
-sub UsrList {
- my $self = shift;
- my $chr = shift;
- $chr = 'all' if !defined $chr;
-
- my $f = $self->FormCheck(
- { name => 's', required => 0, default => 'username', enum => [ qw|username mail rank registered| ] },
- { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] },
- { name => 'p', required => 0, default => 1, template => 'int' },
- );
- return $self->ResNotFound if $f->{_err};
-
- my($unfo, $np) = $self->DBGetUser(
- order => $f->{s}.($f->{o} eq 'a' ? ' ASC' : ' DESC'),
- $chr ne 'all' ? (
- firstchar => $chr ) : (),
- results => 50,
- page => $f->{p},
- what => 'list',
- );
-
- $self->ResAddTpl(userlist => {
- users => $unfo,
- chr => $chr,
- page => $f->{p},
- npage => $np,
- order => [ $f->{s}, $f->{o} ],
- } );
-}
-
-
-sub UsrPage {
- my($self, $id) = @_;
-
- my $u = $self->DBGetUser(uid => $id, what => 'list')->[0];
- return $self->ResNotFound if !$u;
-
- $self->ResAddTpl(userpage => {
- user => $u,
- votes => {
- latest => scalar $self->DBGetVotes(uid => $id, results => 10),
- graph => $self->DBVoteStats(uid => $id),
- },
- });
-}
-
-
-sub UsrDel {
- my($s, $id) = @_;
- return $s->ResDenied if !$s->AuthCan('usermod');
- $s->DBDelUser($id);
- $s->ResRedirect('/u/list', 'temp');
-}
-
-
-1;
-
diff --git a/lib/VNDB/Util/Auth.pm b/lib/VNDB/Util/Auth.pm
deleted file mode 100644
index 6f265253..00000000
--- a/lib/VNDB/Util/Auth.pm
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-
-
-
-# N E E D S M O A R S A L T !
-
-
-package VNDB::Util::Auth;
-
-use strict;
-use warnings;
-use Exporter 'import';
-use Digest::MD5 'md5_hex';
-use Crypt::Lite; # simple, small and easy encryption for cookies
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-@EXPORT = qw| AuthCheckCookie AuthLogin AuthLogout AuthInfo AuthCan AuthAddTpl |;
-
-
-{ # local data for these 2 methods only
- my $crl = Crypt::Lite->new(debug => 0);
- my $scrt = md5_hex($VNDB::COOKEY);
-
-sub AuthCheckCookie {
- my $self = shift;
- my $info = $self->{_Req} || $self;
- $info->{_auth} = {} if !exists $info->{_auth};
-
- my $cookie = $self->ReqCookie('vndb_auth');
- return 0 if !$cookie;
- my $str = $crl->decrypt($cookie, $scrt);
- return 0 if length($str) < 36;
- my $pass = substr($str, 4, 32);
- my $user = substr($str, 36);
- return _AuthCheck($self, $user, $pass);
-}
-
-sub AuthLogin {
- my $self = shift;
- my $user = lc(scalar shift);
- my $psbk = shift;
- my $pass = md5_hex($psbk);
- my $keep = shift;
- my $to = shift;
- my $status = _AuthCheck($self, $user, $pass);
- if($status == 1) {
- (my $cookie = $crl->encrypt("VNDB$pass$user", $scrt)) =~ s/\r?\n//g;
- $self->ResRedirect($to, "post");
- $self->ResAddHeader('Set-Cookie', "vndb_auth=$cookie; " . ($keep ? 'expires=Sat, 01-Jan-2030 00:00:00 GMT; ' : ' ') . "path=/; domain=$self->{CookieDomain}");
- return 1;
- }
- return $status;
-}
-} # end of local data
-
-sub AuthLogout {
- my $self = shift;
- $self->ResRedirect('/', 'temp');
- $self->ResAddHeader('Set-Cookie', "vndb_auth= ; expires=Sat, 01-Jan-2000 00:00:00 GMT; path=/; domain=$self->{CookieDomain}");
-}
-
-sub AuthInfo {
- my $self = shift;
- my $info = $self->{_Req} || shift;
- return $info->{_auth} || {};
-}
-
-sub AuthCan {
- my $self = shift;
- my $act = shift;
- my $info = $self->{_Req} || shift;
- return $self->{ranks}[($info->{_auth}{rank}||0)+1]{$act};
-}
-
-sub _AuthCheck {
- my $self = shift;
- my $user = shift;
- my $pass = shift;
- my $info = $self->{_Req} || shift;
-
- $info->{_auth} = undef;
-
- return 2 if !$user || length($user) > 15 || length($user) < 2;
- return 3 if !$pass || length($pass) != 32;
-
- my $d = $self->DBGetUser(username => $user, passwd => $pass)->[0];
- return 4 if !defined $d->{id};
- return 5 if !$d->{rank};
-
- $d->{oldvnlist} = $self->DBGetVNList(uid => $d->{id}, results => 1)->[0] ? 1 : 0;
- $info->{_auth} = $d;
-
- return 1;
-}
-
-
-# adds the keys AuthLoggedin, AuthRank, AuthUsername, AuthMail, AuthId
-sub AuthAddTpl {
- my $self = shift;
- my $info = $self->{_Req} || shift;
- my %tpl;
-
- if($info->{_auth}{id}) {
- %tpl = (
- AuthLoggedin => 1,
- AuthRank => $info->{_auth}{rank},
- AuthRankname => $self->{ranks}[0][0][$info->{_auth}{rank}],
- AuthUsername => $info->{_auth}{username},
- AuthMail => $info->{_auth}{mail},
- AuthId => $info->{_auth}{id},
- AuthNsfw => $info->{_auth}{flags} & $VNDB::UFLAGS->{nsfw},
- AuthOldList => $info->{_auth}{oldvnlist},
- );
- } else {
- %tpl = (
- AuthLoggedin => 0,
- AuthRank => '',
- AuthRankname => '',
- AuthUsername => '',
- AuthMail => '',
- AuthId => 0,
- AuthNsfw => 0,
- );
- }
- $tpl{'Auth'.$_} = $self->{ranks}[($info->{_auth}{rank}||0)+1]{$_}
- for (keys %{$self->{ranks}[0][1]});
- $self->ResAddTpl(%tpl);
-}
-
-1;
-
diff --git a/lib/VNDB/Util/DB.pm b/lib/VNDB/Util/DB.pm
deleted file mode 100644
index dac01a52..00000000
--- a/lib/VNDB/Util/DB.pm
+++ /dev/null
@@ -1,1582 +0,0 @@
-
-package VNDB::Util::DB;
-
-use strict;
-use warnings;
-use DBI;
-use Exporter 'import';
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-
-@EXPORT = qw|
- DBInit DBCheck DBCommit DBRollBack DBExit
- DBLanguageCount DBCategoryCount DBTableCount DBGetHist DBLockItem DBIncId DBAddScreenshot DBGetScreenshot
- DBGetUser DBAddUser DBUpdateUser DBDelUser
- DBGetVotes DBVoteStats DBAddVote DBDelVote
- DBGetVNList DBDelVNList
- DBGetWishList DBEditWishList DBDelWishList
- DBGetRList DBGetRLists DBEditRList DBDelRList
- DBGetVN DBAddVN DBEditVN DBHideVN DBVNCache
- DBGetRelease DBAddRelease DBEditRelease DBHideRelease
- DBGetProducer DBGetProducerVN DBAddProducer DBEditProducer DBHideProducer
- DBGetThreads DBGetPosts DBAddPost DBEditPost DBEditThread DBAddThread
- DBExec DBRow DBAll
-|;
-
-
-
-
-
-#-----------------------------------------------------------------------------#
-# I M P O R T A N T S T U F F #
-#-----------------------------------------------------------------------------#
-
-
-sub new {
- my $me = shift;
-
- my $type = ref($me) || $me;
- $me = bless { o => \@_ }, $type;
-
- $me->DBInit();
-
- return $me;
-}
-
-
-sub DBInit {
- my $self = shift;
- my $info = $self->{_DB} || $self;
-
- $info->{sql} = DBI->connect(@{$self->{o}}, {
- PrintError => 0, RaiseError => 1,
- AutoCommit => 0, pg_enable_utf8 => 1,
- }
- );
-}
-
-
-sub DBCheck {
- my $self = shift;
- my $info = $self->{_DB} || $self;
-
- require Time::HiRes
- if $self->{debug} && !$Time::Hires::VERSION;
- $info->{Queries} = [] if $self->{debug};
- my $start = [Time::HiRes::gettimeofday()] if $self->{debug};
-
- if(!$info->{sql}->ping) {
- warn "Ping failed, reconnecting";
- $self->DBInit;
- }
- $info->{sql}->rollback();
- push(@{$info->{Queries}},
- [ 'ping/rollback', Time::HiRes::tv_interval($start) ])
- if $self->{debug};
-}
-
-
-sub DBCommit {
- my $self = shift;
- my $info = $self->{_DB} || $self;
- my $start = [Time::HiRes::gettimeofday()] if $self->{debug};
- $info->{sql}->commit();
- push(@{$info->{Queries}},
- [ 'commit', Time::HiRes::tv_interval($start) ])
- if $self->{debug};
-}
-
-
-sub DBRollBack {
- my $self = shift;
- my $info = $self->{_DB} || $self;
- $info->{sql}->rollback();
-}
-
-
-sub DBExit {
- my $self = shift;
- my $info = $self->{_DB} || $self;
- $info->{sql}->disconnect();
-}
-
-
-# XXX: this function should be disabled when performance is going to be a problem
-sub DBCategoryCount {
- return {
- (map { map { $_, 0 } keys %{$VNDB::CAT->{$_}[1]} } keys %{$VNDB::CAT}),
- map { $_->{cat}, $_->{cnt} } @{shift->DBAll(q|
- SELECT cat, COUNT(vid) AS cnt
- FROM vn_categories vc
- JOIN vn v ON v.latest = vc.vid
- WHERE v.hidden = FALSE
- GROUP BY cat
- ORDER BY cnt|
- )}
- };
-}
-
-
-# XXX: Above comment also applies to this function
-sub DBLanguageCount {
- return { (map { $_ => 0 } keys %$VNDB::LANG ),
- map { $_->{language} => $_->{count} } @{shift->DBAll(q|
- SELECT rr.language, COUNT(DISTINCT v.id) AS count
- FROM releases_rev rr
- JOIN releases r ON r.latest = rr.id
- JOIN releases_vn rv ON rv.rid = rr.id
- JOIN vn v ON v.id = rv.vid
- WHERE r.hidden = FALSE
- AND v.hidden = FALSE
- AND rr.type <> 2
- AND rr.released <= TO_CHAR('today'::timestamp, 'YYYYMMDD')::integer
- GROUP BY rr.language|)} };
-}
-
-
-sub DBTableCount { # table (users, producers, vn, releases, votes)
- return $_[0]->DBRow(q|
- SELECT COUNT(*) as cnt
- FROM !s
- !W|,
- $_[1],
- $_[1] =~ /producers|vn|releases/ ? { 'hidden = ?' => 0 } : {},
- )->{cnt} - ($_[1] eq 'users' ? 1 : 0);
-}
-
-
-
-# XXX: iid, ititle and hidden columns should be cached if performance will be a problem
-sub DBGetHist { # %options->{ type, id, cid, caused, next, page, results, ip, edits, showhid, what } (Item hist)
- my($s, %o) = @_;
-
- $o{results} ||= $o{next} ? 1 : 50;
- $o{page} ||= 1;
- $o{type} ||= '';
- $o{what} ||= ''; #flags: user iid ititle
- $o{showhid} ||= $o{type} && $o{type} ne 'u' && $o{id} || $o{cid} ? 1 : 0;
-
- my %where = (
- $o{cid} ? (
- 'c.id IN(!l)' => [$o{cid}] ) : (),
- $o{type} eq 'u' ? (
- 'c.requester = ?' => $o{id} ) : (),
-
- $o{type} eq 'v' && !$o{releases} ? ( 'c.type = ?' => 0,
- $o{id} ? ( 'vr.vid = ?' => $o{id} ) : () ) : (),
- $o{type} eq 'v' && $o{releases} ? (
- '((c.type = ? AND vr.vid = ?) OR (c.type = ? AND rv.vid = ?))' => [0,$o{id},1,$o{id}] ) : (),
-
- $o{type} eq 'r' ? ( 'c.type = ?' => 1,
- $o{id} ? ( 'rr.rid = ?' => $o{id} ) : () ) : (),
- $o{type} eq 'p' ? ( 'c.type = ?' => 2,
- $o{id} ? ( 'pr.pid = ?' => $o{id} ) : () ) : (),
-
- $o{caused} ? (
- 'c.causedby = ?' => $o{caused} ) : (),
- $o{ip} ? (
- 'c.ip = ?' => $o{ip} ) : (),
- defined $o{edits} && !$o{edits} ? (
- 'c.rev = ?' => 1 ) : (),
- $o{edits} ? (
- 'c.rev > ?' => 1 ) : (),
-
- # get rid of 'hidden' items
- !$o{showhid} ? (
- '(v.hidden IS NOT NULL AND v.hidden = FALSE OR r.hidden IS NOT NULL AND r.hidden = FALSE OR p.hidden IS NOT NULL AND p.hidden = FALSE)' => 1,
- ) : $o{showhid} == 2 ? (
- '(v.hidden IS NOT NULL AND v.hidden = TRUE OR r.hidden IS NOT NULL AND r.hidden = TRUE OR p.hidden IS NOT NULL AND p.hidden = TRUE)' => 1,
- ) : (),
- );
-
- my $select = 'c.id, c.type, c.added, c.requester, c.comments, c.rev, c.causedby';
- $select .= ', u.username' if $o{what} =~ /user/;
- $select .= ', COALESCE(vr.vid, rr.rid, pr.pid) AS iid' if $o{what} =~ /iid/;
- $select .= ', COALESCE(vr2.title, rr2.title, pr2.name) AS ititle, COALESCE(vr2.original, rr2.original, pr2.original) AS ioriginal' if $o{what} =~ /ititle/;
-
- my $join = '';
- $join .= ' JOIN users u ON u.id = c.requester' if $o{what} =~ /user/;
- $join .= ' LEFT JOIN vn_rev vr ON c.type = 0 AND c.id = vr.id'.
- ' LEFT JOIN releases_rev rr ON c.type = 1 AND c.id = rr.id'.
- ' LEFT JOIN producers_rev pr ON c.type = 2 AND c.id = pr.id' if $o{what} =~ /(iid|ititle)/ || $o{releases} || $o{id} || !$o{showhid};
- # these joins should be optimised away at some point (cache the required columns in changes as mentioned above)
- $join .= ' LEFT JOIN vn v ON v.id = vr.vid'.
- ' LEFT JOIN vn_rev vr2 ON vr2.id = v.latest'.
- ' LEFT JOIN releases r ON r.id = rr.rid'.
- ' LEFT JOIN releases_rev rr2 ON rr2.id = r.latest'.
- ' LEFT JOIN producers p ON p.id = pr.pid'.
- ' LEFT JOIN producers_rev pr2 ON pr2.id = p.latest' if $o{what} =~ /ititle/ || $o{releases} || !$o{showhid};
- $join .= ' LEFT JOIN releases_vn rv ON c.id = rv.rid' if $o{type} eq 'v' && $o{releases};
-
- my $r = $s->DBAll(qq|
- SELECT $select
- FROM changes c
- $join
- !W
- ORDER BY c.id !s
- LIMIT ? OFFSET ?|,
- \%where,
- $o{next} ? 'ASC' : 'DESC',
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
- return $r if !wantarray;
- return ($r, 0) if $#$r != $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBLockItem { # table, id, locked
- my($s, $tbl, $id, $l) = @_;
- $s->DBExec(q|
- UPDATE !s
- SET locked = ?
- WHERE id = ?|,
- $tbl, $l?1:0, $id);
-}
-
-
-sub DBIncId { # sequence (this is a rather low-level function... aww heck...)
- return $_[0]->DBRow(q|SELECT nextval(?) AS ni|, $_[1])->{ni};
-}
-
-
-sub DBAddScreenshot { # just returns an ID
- return $_[0]->DBRow(q|INSERT INTO screenshots (status) VALUES(0) RETURNING id|)->{id};
-}
-
-
-sub DBGetScreenshot { # ids
- return $_[0]->DBAll(q|SELECT * FROM screenshots WHERE id IN(!l)|, $_[1]);
-}
-
-
-
-#-----------------------------------------------------------------------------#
-# A U T H / U S E R S T U F F #
-#-----------------------------------------------------------------------------#
-
-
-sub DBGetUser { # %options->{ username mail passwd order firstchar uid results page what }
- my $s = shift;
- my %o = (
- order => 'username ASC',
- page => 1,
- results => 10,
- what => '',
- @_
- );
-
- my %where = (
- 'id > 0' => 1,
- $o{username} ? (
- 'username = ?' => $o{username} ) : (),
- $o{mail} ? (
- 'mail = ?' => $o{mail} ) : (),
- $o{passwd} ? (
- 'passwd = decode(?, \'hex\')' => $o{passwd} ) : (),
- $o{firstchar} ? (
- 'SUBSTRING(username from 1 for 1) = ?' => $o{firstchar} ) : (),
- !$o{firstchar} && defined $o{firstchar} ? (
- 'ASCII(username) < 97 OR ASCII(username) > 122' => 1 ) : (),
- $o{uid} ? (
- 'id = ?' => $o{uid} ) : (),
- !$o{uid} && !$o{username} ? (
- 'id > 0' => 1 ) : (),
- );
-
- my $r = $s->DBAll(q|
- SELECT *
- FROM users u
- !W
- ORDER BY !s
- LIMIT ? OFFSET ?|,
- \%where,
- $o{order},
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
-
- # XXX: easy to cache, good performance win
- if($o{what} =~ /list/ && $#$r >= 0) {
- my %r = map {
- $r->[$_]{votes} = 0;
- $r->[$_]{changes} = 0;
- ($r->[$_]{id}, $_)
- } 0..$#$r;
-
- $r->[$r{$_->{uid}}]{votes} = $_->{cnt} for (@{$s->DBAll(q|
- SELECT uid, COUNT(vid) AS cnt
- FROM votes
- WHERE uid IN(!l)
- GROUP BY uid|,
- [ keys %r ]
- )});
-
- $r->[$r{$_->{requester}}]{changes} = $_->{cnt} for (@{$s->DBAll(q|
- SELECT requester, COUNT(id) AS cnt
- FROM changes
- WHERE requester IN(!l)
- GROUP BY requester|,
- [ keys %r ]
- )});
- }
-
- return $r if !wantarray;
- return ($r, 0) if $#$r != $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBAddUser { # username, passwd, mail, rank
- return $_[0]->DBExec(q|
- INSERT INTO users
- (username, passwd, mail, rank, registered)
- VALUES (?, decode(?, 'hex'), ?, ?, ?)|,
- lc($_[1]), $_[2], $_[3], $_[4], time
- );
-}
-
-
-sub DBUpdateUser { # uid, %options->{ columns in users table }
- my $s = shift;
- my $user = shift;
- my %opt = @_;
- my %h;
-
- defined $opt{$_} && ($h{$_.' = ?'} = $opt{$_})
- for (qw| username mail rank flags |);
- $h{'passwd = decode(?, \'hex\')'} = $opt{passwd}
- if defined $opt{passwd};
-
- return 0 if scalar keys %h <= 0;
- return $s->DBExec(q|
- UPDATE users
- !H
- WHERE id = ?|,
- \%h, $user);
-}
-
-
-sub DBDelUser { # uid
- my($s, $id) = @_;
- $s->DBExec($_, $id) for (
- q|DELETE FROM vnlists WHERE uid = ?|,
- q|DELETE FROM rlists WHERE uid = ?|,
- q|DELETE FROM wlists WHERE uid = ?|,
- q|DELETE FROM votes WHERE uid = ?|,
- q|UPDATE changes SET requester = 0 WHERE requester = ?|,
- q|UPDATE threads_posts SET uid = 0 WHERE uid = ?|,
- q|DELETE FROM users WHERE id = ?|
- );
-}
-
-
-
-
-
-
-#-----------------------------------------------------------------------------#
-# V O T E S #
-#-----------------------------------------------------------------------------#
-
-
-sub DBGetVotes { # %options->{ uid vid hide order results page }
- my($s, %o) = @_;
- $o{order} ||= 'n.date DESC';
- $o{results} ||= 50;
- $o{page} ||= 1;
-
- my %where = (
- $o{uid} ? ( 'n.uid = ?' => $o{uid} ) : (),
- $o{vid} ? ( 'n.vid = ?' => $o{vid} ) : (),
- $o{hide} ? ( 'u.flags & ? = ?' => [ $VNDB::UFLAGS->{list}, $VNDB::UFLAGS->{list} ] ) : (),
- );
-
- my $r = $s->DBAll(q|
- SELECT n.vid, vr.title, vr.original, n.vote, n.date, n.uid, u.username
- FROM votes n
- JOIN vn v ON v.id = n.vid
- JOIN vn_rev vr ON vr.id = v.latest
- JOIN users u ON u.id = n.uid
- !W
- ORDER BY !s
- LIMIT ? OFFSET ?|,
- \%where,
- $o{order},
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
- return $r if !wantarray;
- return ($r, 0) if $#$r < $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBVoteStats { # uid|vid => id
- my($s, $col, $id) = @_;
- my $r = [ qw| 0 0 0 0 0 0 0 0 0 0 | ];
- $r->[$_->{vote}-1] = $_->{votes} for (@{$s->DBAll(q|
- SELECT vote, COUNT(vote) as votes
- FROM votes
- !W
- GROUP BY vote|,
- $col ? { '!s = ?' => [ $col, $id ] } : {},
- )});
- return $r;
-}
-
-
-sub DBAddVote { # vid, uid, vote
- $_[0]->DBExec(q|
- UPDATE votes
- SET vote = ?
- WHERE vid = ?
- AND uid = ?|,
- $_[3], $_[1], $_[2]
- ) || $_[0]->DBExec(q|
- INSERT INTO votes
- (vid, uid, vote, date)
- VALUES (!l)|,
- [ @_[1..3], time ]
- );
-}
-
-
-sub DBDelVote { # uid, vid # uid = 0 to delete all
- $_[0]->DBExec(q|
- DELETE FROM votes
- !W|,
- { 'vid = ?' => $_[2],
- $_[1] ? ('uid = ?' => $_[1]) : ()
- }
- );
-}
-
-
-
-
-
-#-----------------------------------------------------------------------------#
-# U S E R V I S U A L N O V E L L I S T S #
-#-----------------------------------------------------------------------------#
-
-
-sub DBGetVNList { # %options->{ uid vid hide order results page status }
- my($s, %o) = @_;
- $o{results} ||= 10;
- $o{page} ||= 1;
- $o{order} ||= 'l.date DESC';
-
- my %where = (
- $o{uid} ? (
- 'l.uid = ?' => $o{uid} ) : (),
- $o{vid} ? (
- 'l.vid = ?' => $o{vid} ) : (),
- defined $o{status} ? (
- 'l.status = ?' => $o{status} ) : (),
- $o{hide} ? ( 'u.flags & ? = ?' => [ $VNDB::UFLAGS->{list}, $VNDB::UFLAGS->{list} ] ) : (),
- );
-
- return wantarray ? ([], 0) : [] if !keys %where;
-
- my $r = $s->DBAll(q|
- SELECT l.vid, vr.title, l.status, l.comments, l.date, l.uid, u.username
- FROM vnlists l
- JOIN vn v ON l.vid = v.id
- JOIN vn_rev vr ON vr.id = v.latest
- JOIN users u ON l.uid = u.id
- !W
- ORDER BY !s
- LIMIT ? OFFSET ?|,
- \%where,
- $o{order},
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
- return $r if !wantarray;
- return ($r, 0) if $#$r < $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBDelVNList { # uid, @vid # uid = 0 to delete all
- my($s, $uid, @vid) = @_;
- $s->DBExec(q|
- DELETE FROM vnlists
- !W|,
- { 'vid IN (!l)' => [\@vid],
- $uid ? ('uid = ?' => $uid) : ()
- }
- );
-}
-
-
-
-
-
-#-----------------------------------------------------------------------------#
-# U S E R W I S H L I S T S #
-#-----------------------------------------------------------------------------#
-
-
-sub DBGetWishList { # %options->{ uid vid what order page results }
- my($s, %o) = @_;
-
- $o{order} ||= 'wl.wstat ASC';
- $o{page} ||= 1;
- $o{results} ||= 50;
- $o{what} ||= '';
-
- my %where = (
- 'wl.uid = ?' => $o{uid},
- $o{vid} ? ( 'wl.vid = ?' => $o{vid} ) : (),
- );
-
- my $select = 'wl.vid, wl.wstat, wl.added';
- my @join;
- if($o{what} =~ /vn/) {
- $select .= ', vr.title, vr.original';
- push @join, 'JOIN vn v ON v.id = wl.vid',
- 'JOIN vn_rev vr ON vr.id = v.latest';
- }
-
- my $r = $s->DBAll(qq|
- SELECT $select
- FROM wlists wl
- @join
- !W
- ORDER BY !s
- LIMIT ? OFFSET ?|,
- \%where,
- $o{order},
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
- return $r if !wantarray;
- return ($r, 0) if $#$r < $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBEditWishList { # %options->{ uid vid wstat }
- my($s, %o) = @_;
- $s->DBExec(q|UPDATE wlists SET wstat = ? WHERE uid = ? AND vid IN(!l)|,
- $o{wstat}, $o{uid}, ref($o{vid}) eq 'ARRAY' ? $o{vid} : [ $o{vid} ])
- ||
- $s->DBExec(q|INSERT INTO wlists (uid, vid, wstat)
- VALUES(!l)|,
- [@o{qw| uid vid wstat |}]);
-}
-
-
-sub DBDelWishList { # uid, vids
- my($s, $uid, $vid) = @_;
- $s->DBExec(q|DELETE FROM wlists WHERE uid = ? AND vid IN(!l)|, $uid, $vid);
-}
-
-
-
-
-
-
-#-----------------------------------------------------------------------------#
-# U S E R R E L E A S E L I S T S #
-#-----------------------------------------------------------------------------#
-
-
-sub DBGetRList { # %options->{ uid rids }
- my($s, %o) = @_;
-
- my %where = (
- 'uid = ?' => $o{uid},
- $o{rids} ? (
- 'rid IN(!l)' => [$o{rids}] ) : (),
- );
-
- return $s->DBAll(q|
- SELECT uid, rid, rstat, vstat
- FROM rlists
- !W|,
- \%where);
-}
-
-
-# separate function, which also fetches VN info and votes
-sub DBGetRLists { # %options->{ uid order char rstat vstat voted page results }
- my($s, %o) = @_;
-
- $o{results} ||= 50;
- $o{page} ||= 1;
-
- # bit ugly...
- my $where = !$o{rstat} && !$o{vstat} ? 'vo.vote IS NOT NULL' : '';
- $where .= ($where?' OR ':'').q|v.id IN(
- SELECT irv.vid
- FROM rlists irl
- JOIN releases ir ON ir.id = irl.rid
- JOIN releases_vn irv ON irv.rid = ir.latest
- !W
- )| if !$o{voted};
- $where = '('.$where.') AND LOWER(SUBSTR(vr.title, 1, 1)) = \''.$o{char}.'\'' if $o{char};
- $where = '('.$where.') AND (ASCII(vr.title) < 97 OR ASCII(vr.title) > 122) AND (ASCII(vr.title) < 65 OR ASCII(vr.title) > 90)' if defined $o{char} && !$o{char};
-
- # WHERE clause for the rlists subquery
- my %where = (
- 'uid = ?' => $o{uid},
- defined $o{rstat} ? ( 'rstat = ?' => $o{rstat} ) : (),
- defined $o{vstat} ? ( 'vstat = ?' => $o{vstat} ) : (),
- );
-
- my $r = $s->DBAll(qq|
- SELECT vr.vid, vr.title, vr.original, v.c_released, v.c_languages, v.c_platforms, COALESCE(vo.vote, 0) AS vote
- FROM vn v
- JOIN vn_rev vr ON vr.id = v.latest
- !s JOIN votes vo ON vo.vid = v.id AND vo.uid = ?
- WHERE $where
- ORDER BY !s
- LIMIT ? OFFSET ?|,
- $o{voted} ? '' : 'LEFT', $o{uid}, # JOIN if we only want votes, LEFT JOIN if we also want rlist items
- $o{voted} ? () : \%where,
- $o{order},
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
-
- # now fetch the releases and link them to VNs
- if(@$r) {
- my %vns = map { $_->{rels}=[]; $_->{vid}, $_->{rels} } @$r;
- push @{$vns{$_->{vid}}}, $_ for (@{$s->DBAll(q|
- SELECT rv.vid, rr.rid, rr.title, rr.original, rr.released, rr.type, rr.language, rr.minage, rl.rstat, rl.vstat
- FROM rlists rl
- JOIN releases r ON rl.rid = r.id
- JOIN releases_rev rr ON rr.id = r.latest
- JOIN releases_vn rv ON rv.rid = r.latest
- WHERE rl.uid = ?
- AND rv.vid IN(!l)
- ORDER BY rr.released ASC|,
- $o{uid}, [ keys %vns ]
- )});
- }
-
- return $r if !wantarray;
- return ($r, 0) if $#$r < $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBEditRList { # %options->{ uid rid rstat vstat }
- # rid can only be a arrayref with UPDATE
- my($s, %o) = @_;
- my %s = (
- defined $o{rstat} ? ( 'rstat = ?', $o{rstat} ) : (),
- defined $o{vstat} ? ( 'vstat = ?', $o{vstat} ) : (),
- );
- $o{rstat}||=0;
- $o{vstat}||=0;
-
- $s->DBExec(q|UPDATE rlists !H WHERE uid = ? AND rid IN(!l)|,
- \%s, $o{uid}, ref($o{rid}) eq 'ARRAY' ? $o{rid} : [ $o{rid} ])
- ||
- $s->DBExec(q|INSERT INTO rlists (uid, rid, rstat, vstat)
- VALUES(!l)|,
- [@o{qw| uid rid rstat vstat |}]);
-}
-
-
-sub DBDelRList { # uid, \@rids
- my($s, $uid, $rid) = @_;
- $s->DBExec(q|DELETE FROM rlists WHERE uid = ? AND rid IN(!l)|, $uid, ref($rid) eq 'ARRAY' ? $rid : [ $rid ]);
-}
-
-
-
-
-
-#-----------------------------------------------------------------------------#
-# V I S U A L N O V E L S #
-#-----------------------------------------------------------------------------#
-
-
-sub DBGetVN { # %options->{ id rev char search order results page what cati cate lang platform }
- my $s = shift;
- my %o = (
- page => 1,
- results => 50,
- order => 'vr.title ASC',
- what => '',
- @_ );
-
- my %where = (
- !$o{id} && !$o{rev} ? ( # don't fetch hidden items unless we ask for an ID
- 'v.hidden = ?' => 0 ) : (),
- $o{id} && !ref($o{id}) ? (
- 'v.id = ?' => $o{id} ) : (),
- $o{id} && ref($o{id}) ? (
- 'v.id IN(!l)' => [$o{id}] ) : (),
- $o{rev} ? (
- 'c.rev = ?' => $o{rev} ) : (),
- $o{char} ? (
- 'LOWER(SUBSTR(vr.title, 1, 1)) = ?' => $o{char} ) : (),
- defined $o{char} && !$o{char} ? (
- '(ASCII(vr.title) < 97 OR ASCII(vr.title) > 122) AND (ASCII(vr.title) < 65 OR ASCII(vr.title) > 90)' => 1 ) : (),
- $o{cati} && @{$o{cati}} ? ( q|
- v.id IN(SELECT iv.id
- FROM vn_categories ivc
- JOIN vn iv ON iv.latest = ivc.vid
- WHERE cat IN(!l)
- GROUP BY iv.id
- HAVING COUNT(cat) = ?)| => [ $o{cati}, $#{$o{cati}}+1 ] ) : (),
- $o{cate} && @{$o{cate}} ? ( q|
- v.id NOT IN(SELECT iv.id
- FROM vn_categories ivc
- JOIN vn iv ON iv.latest = ivc.vid
- WHERE cat IN(!l)
- GROUP BY iv.id)| => [ $o{cate} ] ) : (),
- # this needs some proper handling...
- $o{lang} && @{$o{lang}} ? (
- '('.join(' OR ', map "v.c_languages ILIKE '%%$_%%'", @{$o{lang}}).')' => 1 ) : (),
- $o{platform} && @{$o{platform}} ? (
- '('.join(' OR ', map "v.c_platforms ILIKE '%%$_%%'", @{$o{platform}}).')' => 1 ) : (),
- );
-
- if($o{search}) {
- my @w;
- for (split /[ -,]/, $o{search}) {
- s/%//g;
- next if length($_) < 2;
- if(VNDB::GTINType($_)) {
- push @w, 'irr.gtin = ?', $_;
- } else {
- $_ = "%$_%";
- push @w, '(ivr.title ILIKE ? OR ivr.alias ILIKE ? OR irr.title ILIKE ? OR irr.original ILIKE ?)',
- [ $_, $_, $_, $_ ];
- }
- }
- $where{ q|
- v.id IN(SELECT iv.id
- FROM vn iv
- JOIN vn_rev ivr ON iv.latest = ivr.id
- LEFT JOIN releases_vn irv ON irv.vid = iv.id
- LEFT JOIN releases_rev irr ON irr.id = irv.rid
- LEFT JOIN releases ir ON ir.latest = irr.id
- !W
- GROUP BY iv.id)| } = [ \@w ] if @w;
- }
-
- my @join = (
- $o{rev} ?
- 'JOIN vn v ON v.id = vr.vid' :
- 'JOIN vn v ON vr.id = v.latest',
- $o{what} =~ /changes/ || $o{rev} ? (
- 'JOIN changes c ON c.id = vr.id',
- 'JOIN users u ON u.id = c.requester' ) : (),
- $o{what} =~ /relgraph/ ? (
- 'LEFT JOIN relgraph rg ON rg.id = v.rgraph' ) : (),
- );
-
- my $sel = 'v.id, v.locked, v.hidden, v.c_released, v.c_languages, v.c_platforms, vr.title, vr.original, vr.id AS cid';
- $sel .= ', vr.alias, vr.image AS image, vr.img_nsfw, vr.length, vr.desc, vr.l_wp, vr.l_encubed, vr.l_renai, vr.l_vnn' if $o{what} =~ /extended/;
- $sel .= ', c.added, c.requester, c.comments, v.latest, u.username, c.rev, c.causedby' if $o{what} =~ /changes/;
- $sel .= ', v.rgraph, rg.cmap' if $o{what} =~ /relgraph/;
-
- my $r = $s->DBAll(qq|
- SELECT $sel
- FROM vn_rev vr
- @join
- !W
- ORDER BY !s
- LIMIT ? OFFSET ?|,
- \%where,
- $o{order},
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
- $_->{c_released} = sprintf '%08d', $_->{c_released} for @$r;
-
- if($o{what} =~ /(?:relations|categories|anime|screenshots)/ && $#$r >= 0) {
- my %r = map {
- $r->[$_]{relations} = [];
- $r->[$_]{categories} = [];
- $r->[$_]{anime} = [];
- $r->[$_]{screenshots} = [];
- ($r->[$_]{cid}, $_)
- } 0..$#$r;
-
- if($o{what} =~ /categories/) {
- push(@{$r->[$r{$_->{vid}}]{categories}}, [ $_->{cat}, $_->{lvl} ]) for (@{$s->DBAll(q|
- SELECT vid, cat, lvl
- FROM vn_categories
- WHERE vid IN(!l)|,
- [ keys %r ]
- )});
- }
-
- if($o{what} =~ /anime/) {
- push(@{$r->[$r{$_->{vid}}]{anime}}, $_) && delete $_->{vid} for (@{$s->DBAll(q|
- SELECT va.vid, a.*
- FROM vn_anime va
- JOIN anime a ON va.aid = a.id
- WHERE va.vid IN(!l)|,
- [ keys %r ]
- )});
- }
-
- if($o{what} =~ /screenshots/) {
- push(@{$r->[$r{$_->{vid}}]{screenshots}}, $_) && delete $_->{vid} for (@{$s->DBAll(q|
- SELECT vs.vid, s.id, vs.nsfw, vs.rid, s.width, s.height
- FROM vn_screenshots vs
- JOIN screenshots s ON vs.scr = s.id
- WHERE vs.vid IN(!l)
- ORDER BY vs.scr|,
- [ keys %r ]
- )});
- }
-
- if($o{what} =~ /relations/) {
- my $rel = $s->DBAll(q|
- SELECT rel.vid1, rel.vid2, rel.relation, vr.title, vr.original
- FROM vn_relations rel
- JOIN vn v ON rel.vid2 = v.id
- JOIN vn_rev vr ON v.latest = vr.id
- WHERE rel.vid1 IN(!l)|,
- [ keys %r ]);
- push(@{$r->[$r{$_->{vid1}}]{relations}}, {
- relation => $_->{relation},
- id => $_->{vid2},
- title => $_->{title},
- original => $_->{original}
- }) for (@$rel);
- }
- }
-
- return $r if !wantarray;
- return ($r, 0) if $#$r != $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBAddVN { # %options->{ comm + _insert_vn_rev }
- my($s, %o) = @_;
-
- my $id = $s->DBRow(q|
- INSERT INTO changes (type, requester, ip, comments)
- VALUES (!l)
- RETURNING id|,
- [ 0, $s->AuthInfo->{id}, $s->ReqIP, $o{comm} ]
- )->{id};
-
- my $vid = $s->DBRow(q|
- INSERT INTO vn (latest)
- VALUES (?)
- RETURNING id|, $id
- )->{id};
-
- _insert_vn_rev($s, $id, $vid, \%o);
-
- return ($vid, $id); # item id, global revision
-}
-
-
-sub DBEditVN { # id, %options->( comm + _insert_vn_rev + uid + causedby }
- my($s, $vid, %o) = @_;
-
- my $c = $s->DBRow(q|
- INSERT INTO changes (type, requester, ip, comments, rev, causedby)
- VALUES (?, ?, ?, ?, (
- SELECT c.rev+1
- FROM changes c
- JOIN vn_rev vr ON vr.id = c.id
- WHERE vr.vid = ?
- ORDER BY c.id DESC
- LIMIT 1
- ), ?)
- RETURNING id, rev|,
- 0, $o{uid}||$s->AuthInfo->{id}, $s->ReqIP, $o{comm}, $vid, $o{causedby}||undef);
-
- _insert_vn_rev($s, $c->{id}, $vid, \%o);
-
- $s->DBExec(q|UPDATE vn SET latest = ? WHERE id = ?|, $c->{id}, $vid);
- return ($c->{rev}, $c->{id}); # local revision, global revision
-}
-
-
-sub _insert_vn_rev { # columns in vn_rev + categories + screenshots + relations
- my($s, $cid, $vid, $o) = @_;
-
- $$o{img_nsfw} = $$o{img_nsfw}?1:0;
- $s->DBExec(q|
- INSERT INTO vn_rev (id, vid, title, original, "desc", alias, image, img_nsfw, length, l_wp, l_encubed, l_renai, l_vnn)
- VALUES (!l)|,
- [ $cid, $vid, @$o{qw|title original desc alias image img_nsfw length l_wp l_encubed l_renai l_vnn|} ]);
-
- $s->DBExec(q|
- INSERT INTO vn_categories (vid, cat, lvl)
- VALUES (?, ?, ?)|,
- $cid, $_->[0], $_->[1]
- ) for (@{$o->{categories}});
-
- $s->DBExec(q|
- INSERT INTO vn_screenshots (vid, scr, nsfw, rid)
- VALUES (?, ?, ?, ?)|,
- $cid, $_->[0], $_->[1]?1:0, $_->[2]
- ) for (@{$o->{screenshots}});
-
- $s->DBExec(q|
- INSERT INTO vn_relations (vid1, vid2, relation)
- VALUES (?, ?, ?)|,
- $cid, $_->[1], $_->[0]
- ) for (@{$o->{relations}});
-
- if(@{$o->{anime}}) {
- $s->DBExec(q|
- INSERT INTO vn_anime (vid, aid)
- VALUES (?, ?)|,
- $cid, $_
- ) for (@{$o->{anime}});
-
- # insert unknown anime
- my $a = $s->DBAll(q|
- SELECT id FROM anime WHERE id IN(!l)|,
- $o->{anime});
- $s->DBExec(q|
- INSERT INTO anime (id) VALUES (?)|, $_
- ) for (grep {
- my $ia = $_;
- !(scalar grep $ia == $_->{id}, @$a)
- } @{$o->{anime}});
- }
-}
-
-
-sub DBHideVN { # id, hidden
- my($s, $id, $h) = @_;
- $s->DBExec(q|
- UPDATE vn
- SET hidden = ?
- WHERE id = ?|,
- $h?1:0, $id);
-}
-
-
-sub DBVNCache { # @vids
- my($s,@vn) = @_;
- $s->DBExec('SELECT update_vncache(?)', $_) for (@vn);
-}
-
-
-
-
-
-#-----------------------------------------------------------------------------#
-# R E L E A S E S #
-#-----------------------------------------------------------------------------#
-
-
-sub DBGetRelease { # %options->{ id vid results page rev }
- my($s, %o) = @_;
-
- $o{results} ||= 50;
- $o{page} ||= 1;
- $o{what} ||= '';
- $o{order} ||= 'rr.released ASC';
- my %where = (
- !$o{id} && !$o{rev} ? (
- 'r.hidden = ?' => 0 ) : (),
- $o{id} ? (
- 'r.id = ?' => $o{id} ) : (),
- $o{rev} ? (
- 'c.rev = ?' => $o{rev} ) : (),
- $o{vid} ? (
- 'rv.vid = ?' => $o{vid} ) : (),
- defined $o{unreleased} ? (
- q|rr.released !s TO_CHAR('today'::timestamp, 'YYYYMMDD')::integer| => $o{unreleased} ? '>' : '<=' ) : (),
- );
-
- my @join;
- push @join, $o{rev} ? 'JOIN releases r ON r.id = rr.rid' : 'JOIN releases r ON rr.id = r.latest';
- push @join, 'JOIN changes c ON c.id = rr.id' if $o{what} =~ /changes/ || $o{rev};
- push @join, 'JOIN users u ON u.id = c.requester' if $o{what} =~ /changes/;
- push @join, 'JOIN releases_vn rv ON rv.rid = rr.id' if $o{vid};
-
- my $select = 'r.id, r.locked, r.hidden, rr.id AS cid, rr.title, rr.original, rr.gtin, rr.language, rr.website, rr.released, rr.notes, rr.minage, rr.type';
- $select .= ', c.added, c.requester, c.comments, r.latest, u.username, c.rev' if $o{what} =~ /changes/;
-
- my $r = $s->DBAll(qq|
- SELECT $select
- FROM releases_rev rr
- @join
- !W
- ORDER BY !s
- LIMIT ? OFFSET ?|,
- \%where,
- $o{order},
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
- $_->{released} = sprintf '%08d', $_->{released} for @$r;
-
- if($#$r >= 0 && $o{what} =~ /(vn|producers|platforms|media)/) {
- my %r = map {
- $r->[$_]{producers} = [];
- $r->[$_]{platforms} = [];
- $r->[$_]{media} = [];
- $r->[$_]{vn} = [];
- ($r->[$_]{cid}, $_)
- } 0..$#$r;
-
- if($o{what} =~ /vn/) {
- push(@{$r->[$r{$_->{rid}}]{vn}}, $_) for (@{$s->DBAll(q|
- SELECT rv.rid, vr.vid, vr.title, vr.original
- FROM releases_vn rv
- JOIN vn v ON v.id = rv.vid
- JOIN vn_rev vr ON vr.id = v.latest
- WHERE rv.rid IN(!l)|,
- [ keys %r ]
- )});
- }
-
- if($o{what} =~ /producers/) {
- push(@{$r->[$r{$_->{rid}}]{producers}}, $_) for (@{$s->DBAll(q|
- SELECT rp.rid, p.id, pr.name, pr.original, pr.type
- FROM releases_producers rp
- JOIN producers p ON rp.pid = p.id
- JOIN producers_rev pr ON pr.id = p.latest
- WHERE rp.rid IN(!l)|,
- [ keys %r ]
- )});
- }
- if($o{what} =~ /platforms/) {
- push(@{$r->[$r{$_->{rid}}]{platforms}}, $_->{platform}) for (@{$s->DBAll(q|
- SELECT rid, platform
- FROM releases_platforms
- WHERE rid IN(!l)|,
- [ keys %r ]
- )});
- }
- if($o{what} =~ /media/) {
- ($_->{medium}=~s/\s+//||1)&&push(@{$r->[$r{$_->{rid}}]{media}}, $_) for (@{$s->DBAll(q|
- SELECT rid, medium, qty
- FROM releases_media
- WHERE rid IN(!l)|,
- [ keys %r ]
- )});
- }
- }
-
- return $r if !wantarray;
- return ($r, 0) if $#$r < $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBAddRelease { # options -> { comm + _insert_release_rev }
- my($s, %o) = @_;
-
- my $id = $s->DBRow(q|
- INSERT INTO changes (type, requester, ip, comments)
- VALUES (!l)
- RETURNING id|,
- [ 1, $s->AuthInfo->{id}, $s->ReqIP, $o{comm} ]
- )->{id};
-
- my $rid = $s->DBRow(q|
- INSERT INTO releases (latest)
- VALUES (?)
- RETURNING id|, $id)->{id};
-
- _insert_release_rev($s, $id, $rid, \%o);
- return ($rid, $id); # item id, global revision
-}
-
-
-sub DBEditRelease { # id, %opts->{ comm + _insert_release_rev }
- my($s, $rid, %o) = @_;
-
- my $c = $s->DBRow(q|
- INSERT INTO changes (type, requester, ip, comments, rev)
- VALUES (?, ?, ?, ?, (
- SELECT c.rev+1
- FROM changes c
- JOIN releases_rev rr ON rr.id = c.id
- WHERE rr.rid = ?
- ORDER BY c.id DESC
- LIMIT 1
- ))
- RETURNING id, rev|,
- 1, $s->AuthInfo->{id}, $s->ReqIP, $o{comm}, $rid);
-
- _insert_release_rev($s, $c->{id}, $rid, \%o);
-
- $s->DBExec(q|UPDATE releases SET latest = ? WHERE id = ?|, $c->{id}, $rid);
- return ($c->{rev}, $c->{id}); # local revision, global revision
-}
-
-
-sub _insert_release_rev { # %option->{ columns in releases_rev + producers + platforms + vn + media }
- my($s, $cid, $rid, $o) = @_;
-
- $s->DBExec(q|
- INSERT INTO releases_rev (id, rid, title, original, gtin, language, website, released, notes, minage, type)
- VALUES (!l)|,
- [ $cid, $rid, @$o{qw| title original gtin language website released notes minage type|} ]);
-
- $s->DBExec(q|
- INSERT INTO releases_producers (rid, pid)
- VALUES (?, ?)|,
- $cid, $_
- ) for (@{$o->{producers}});
-
- $s->DBExec(q|
- INSERT INTO releases_platforms (rid, platform)
- VALUES (?, ?)|,
- $cid, $_
- ) for (@{$o->{platforms}});
-
- $s->DBExec(q|
- INSERT INTO releases_vn (rid, vid)
- VALUES (?, ?)|,
- $cid, $_
- ) for (@{$o->{vn}});
-
- $s->DBExec(q|
- INSERT INTO releases_media (rid, medium, qty)
- VALUES (?, ?, ?)|,
- $cid, $_->[0], $_->[1]
- ) for (@{$o->{media}});
-}
-
-
-sub DBHideRelease { # id, hidden
- my($s, $id, $h) = @_;
- $s->DBExec(q|
- UPDATE releases
- SET hidden = ?
- WHERE id = ?|,
- $h?1:0, $id);
-}
-
-
-
-#-----------------------------------------------------------------------------#
-# P R O D U C E R S #
-#-----------------------------------------------------------------------------#
-
-
-sub DBGetProducer { # %options->{ id search char results page rev }
- my($s, %o) = @_;
-
- $o{results} ||= 50;
- $o{page} ||= 1;
- $o{search} =~ s/%//g if $o{search};
- $o{what} ||= '';
- my %where = (
- !$o{id} && !$o{rev} ? (
- 'p.hidden = ?' => 0 ) : (),
- $o{id} ? (
- 'p.id = ?' => $o{id} ) : (),
- $o{search} ? (
- '(pr.name ILIKE ? OR pr.original ILIKE ?)', [ '%%'.$o{search}.'%%', '%%'.$o{search}.'%%' ] ) : (),
- $o{char} ? (
- 'LOWER(SUBSTR(pr.name, 1, 1)) = ?' => $o{char} ) : (),
- defined $o{char} && !$o{char} ? (
- '(ASCII(pr.name) < 97 OR ASCII(pr.name) > 122) AND (ASCII(pr.name) < 65 OR ASCII(pr.name) > 90)' => 1 ) : (),
- $o{rev} ? (
- 'c.rev = ?' => $o{rev} ) : (),
- );
-
- my @join;
- push @join, $o{rev} ? 'JOIN producers p ON p.id = pr.pid' : 'JOIN producers p ON pr.id = p.latest';
- push @join, 'JOIN changes c ON c.id = pr.id' if $o{what} =~ /changes/ || $o{rev};
- push @join, 'JOIN users u ON u.id = c.requester' if $o{what} =~ /changes/;
-
- my $select = 'p.id, p.locked, p.hidden, pr.type, pr.name, pr.original, pr.website, pr.lang, pr.desc';
- $select .= ', c.added, c.requester, c.comments, p.latest, pr.id AS cid, u.username, c.rev' if $o{what} =~ /changes/;
-
- my $r = $s->DBAll(qq|
- SELECT $select
- FROM producers_rev pr
- @join
- !W
- ORDER BY pr.name ASC
- LIMIT ? OFFSET ?|,
- \%where,
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
-
- return $r if !wantarray;
- return ($r, 0) if $#$r < $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBGetProducerVN { # pid
- return $_[0]->DBAll(q|
- SELECT v.id, MAX(vr.title) AS title, MAX(vr.original) AS original, MIN(rr.released) AS date
- FROM releases_producers vp
- JOIN releases_rev rr ON rr.id = vp.rid
- JOIN releases r ON r.latest = rr.id
- JOIN releases_vn rv ON rv.rid = rr.id
- JOIN vn v ON v.id = rv.vid
- JOIN vn_rev vr ON vr.id = v.latest
- WHERE vp.pid = ?
- AND v.hidden = ?
- GROUP BY v.id
- ORDER BY date|,
- $_[1], 0);
-}
-
-
-sub DBAddProducer { # %opts->{ comm + _insert_producer_rev }
- my($s, %o) = @_;
-
- my $id = $s->DBRow(q|
- INSERT INTO changes (type, requester, ip, comments)
- VALUES (!l)
- RETURNING id|,
- [ 2, $s->AuthInfo->{id}, $s->ReqIP, $o{comm} ]
- )->{id};
-
- my $pid = $s->DBRow(q|
- INSERT INTO producers (latest)
- VALUES (?)
- RETURNING id|, $id
- )->{id};
-
- _insert_producer_rev($s, $id, $pid, \%o);
-
- return ($pid, $id); # item id, global revision
-}
-
-
-sub DBEditProducer { # id, %opts->{ comm + _insert_producer_rev }
- my($s, $pid, %o) = @_;
-
- my $c = $s->DBRow(q|
- INSERT INTO changes (type, requester, ip, comments, rev)
- VALUES (?, ?, ?, ?, (
- SELECT c.rev+1
- FROM changes c
- JOIN producers_rev pr ON pr.id = c.id
- WHERE pr.pid = ?
- ORDER BY c.id DESC
- LIMIT 1
- ))
- RETURNING id, rev|,
- 2, $s->AuthInfo->{id}, $s->ReqIP, $o{comm}, $pid);
-
- _insert_producer_rev($s, $c->{id}, $pid, \%o);
-
- $s->DBExec(q|UPDATE producers SET latest = ? WHERE id = ?|, $c->{id}, $pid);
- return ($c->{rev}, $c->{id}); # local revision, global revision
-}
-
-
-sub _insert_producer_rev { # %opts->{ columns in produces_rev }
- my($s, $cid, $pid, $o) = @_;
- $s->DBExec(q|
- INSERT INTO producers_rev (id, pid, name, original, website, type, lang, "desc")
- VALUES (!l)|,
- [ $cid, $pid, @$o{qw| name original website type lang desc|} ]);
-}
-
-
-sub DBHideProducer { # id, hidden
- my($s, $id, $h) = @_;
- $s->DBExec(q|
- UPDATE producers
- SET hidden = ?
- WHERE id = ?|,
- $h?1:0, $id);
-}
-
-
-
-
-
-#-----------------------------------------------------------------------------#
-# D I S C U S S I O N S #
-#-----------------------------------------------------------------------------#
-
-
-sub DBGetThreads { # %options->{ id type iid results page what }
- my($s, %o) = @_;
-
- $o{results} ||= 50;
- $o{page} ||= 1;
- $o{what} ||= '';
- $o{order} ||= 't.id DESC';
-
- my %where = (
- $o{id} ? (
- 't.id = ?' => $o{id} ) : (),
- !$o{id} ? (
- 't.hidden = ?' => 0 ) : (),
- $o{type} && !$o{iid} ? (
- 't.id IN(SELECT tid FROM threads_tags WHERE type = ?)' => $o{type} ) : (),
- $o{type} && $o{iid} ? (
- 'tt.type = ?' => $o{type}, 'tt.iid = ?' => $o{iid} ) : (),
- );
-
- my $select = 't.id, t.title, t.count, t.locked, t.hidden';
- $select .= ', tp.uid, tp.date, u.username' if $o{what} =~ /firstpost/;
- $select .= ', tp2.uid AS luid, tp2.date AS ldate, u2.username AS lusername' if $o{what} =~ /lastpost/;
-
- my @join;
- push @join, 'JOIN threads_posts tp ON tp.tid = t.id AND tp.num = 1' if $o{what} =~ /firstpost/;
- push @join, 'JOIN users u ON u.id = tp.uid' if $o{what} =~ /firstpost/;
- push @join, 'JOIN threads_posts tp2 ON tp2.tid = t.id AND tp2.num = t.count' if $o{what} =~ /lastpost/;
- push @join, 'JOIN users u2 ON u2.id = tp2.uid' if $o{what} =~ /lastpost/;
- push @join, 'JOIN threads_tags tt ON tt.tid = t.id' if $o{type} && $o{iid};
-
- my $r = $s->DBAll(qq|
- SELECT $select
- FROM threads t
- @join
- !W
- ORDER BY !s
- LIMIT ? OFFSET ?|,
- \%where,
- $o{order},
- $o{results}+(wantarray?1:0), $o{results}*($o{page}-1)
- );
-
- if($o{what} =~ /(tags|tagtitles)/ && $#$r >= 0) {
- my %r = map {
- $r->[$_]{tags} = [];
- ($r->[$_]{id}, $_)
- } 0..$#$r;
-
- if($o{what} =~ /tags/) {
- ($_->{type}=~s/ +//||1) && push(@{$r->[$r{$_->{tid}}]{tags}}, [ $_->{type}, $_->{iid} ]) for (@{$s->DBAll(q|
- SELECT tid, type, iid
- FROM threads_tags
- WHERE tid IN(!l)|,
- [ keys %r ]
- )});
- }
- if($o{what} =~ /tagtitles/) {
- ($_->{type}=~s/ +//||1) && push(@{$r->[$r{$_->{tid}}]{tags}}, [ $_->{type}, $_->{iid}, $_->{title}, $_->{original} ]) for (@{$s->DBAll(q|
- SELECT tt.tid, tt.type, tt.iid, COALESCE(u.username, vr.title, pr.name) AS title, COALESCE(u.username, vr.original, pr.original) AS original
- FROM threads_tags tt
- LEFT JOIN vn v ON tt.type = 'v' AND v.id = tt.iid
- LEFT JOIN vn_rev vr ON vr.id = v.latest
- LEFT JOIN producers p ON tt.type = 'p' AND p.id = tt.iid
- LEFT JOIN producers_rev pr ON pr.id = p.latest
- LEFT JOIN users u ON tt.type = 'u' AND u.id = tt.iid
- WHERE tt.tid IN(!l)|,
- [ keys %r ]
- )});
- }
- }
-
- return $r if !wantarray;
- return ($r, 0) if $#$r < $o{results};
- pop @$r;
- return ($r, 1);
-}
-
-
-sub DBGetPosts { # %options->{ tid num page results }
- my($s, %o) = @_;
-
- $o{results} ||= 50;
- $o{page} ||= 1;
-
- my %where = (
- 'tp.tid = ?' => $o{tid},
- $o{num} ? (
- 'tp.num = ?' => $o{num} ) : (),
- );
-
- my $r = $s->DBAll(q|
- SELECT tp.num, tp.date, tp.edited, tp.msg, tp.hidden, tp.uid, u.username
- FROM threads_posts tp
- JOIN users u ON u.id = tp.uid
- !W
- ORDER BY tp.num ASC
- LIMIT ? OFFSET ?|,
- \%where,
- $o{results}, $o{results}*($o{page}-1)
- );
-
- return $r if !wantarray;
-}
-
-
-sub DBAddPost { # %options->{ tid uid msg num }
- my($s, %o) = @_;
-
- $o{num} ||= $s->DBRow('SELECT num FROM threads_posts WHERE tid = ? ORDER BY num DESC LIMIT 1', $o{tid})->{num}+1;
- $o{uid} ||= $s->AuthInfo->{id};
-
- $s->DBExec(q|
- INSERT INTO threads_posts (tid, num, uid, msg)
- VALUES(?, ?, ?, ?)|,
- @o{qw| tid num uid msg |}
- );
- $s->DBExec(q|
- UPDATE threads
- SET count = count+1
- WHERE id = ?|,
- $o{tid});
-
- return $o{num};
-}
-
-
-sub DBEditPost { # %options->{ tid num msg hidden }
- my($s, %o) = @_;
-
- my %set = (
- 'msg = ?' => $o{msg},
- 'edited = ?' => time,
- 'hidden = ?' => $o{hidden}?1:0,
- );
-
- $s->DBExec(q|
- UPDATE threads_posts
- !H
- WHERE tid = ?
- AND num = ?|,
- \%set, $o{tid}, $o{num}
- );
-}
-
-
-sub DBEditThread { # %options->{ id title locked hidden tags }
- my($s, %o) = @_;
-
- my %set = (
- 'title = ?' => $o{title},
- 'locked = ?' => $o{locked}?1:0,
- 'hidden = ?' => $o{hidden}?1:0,
- );
-
- $s->DBExec(q|
- UPDATE threads
- !H
- WHERE id = ?|,
- \%set, $o{id});
-
- if($o{tags}) {
- $s->DBExec('DELETE FROM threads_tags WHERE tid = ?', $o{id});
- $s->DBExec(q|
- INSERT INTO threads_tags (tid, type, iid)
- VALUES (?, ?, ?)|,
- $o{id}, $_->[0], $_->[1]||0
- ) for (@{$o{tags}});
- }
-}
-
-
-sub DBAddThread { # %options->{ title hidden locked tags }
- my($s, %o) = @_;
-
- my $id = $s->DBRow(q|
- INSERT INTO threads (title, hidden, locked)
- VALUES (?, ?, ?)
- RETURNING id|,
- $o{title}, $o{hidden}?1:0, $o{locked}?1:0
- )->{id};
-
- $s->DBExec(q|
- INSERT INTO threads_tags (tid, type, iid)
- VALUES (?, ?, ?)|,
- $id, $_->[0], $_->[1]
- ) for (@{$o{tags}});
-
- return $id;
-}
-
-
-
-
-
-#-----------------------------------------------------------------------------#
-# U T I L I T I E S #
-#-----------------------------------------------------------------------------#
-
-
-sub DBExec { return sqlhelper(shift, 0, @_); }
-sub DBRow { return sqlhelper(shift, 1, @_); }
-sub DBAll { return sqlhelper(shift, 2, @_); }
-
-sub sqlhelper { # type, query, @list
- my $self = shift;
- my $type = shift;
- my $sqlq = shift;
- my $s = $self->{_DB}->{sql};
-
- my $start = [Time::HiRes::gettimeofday()] if $self->{debug};
-
- $sqlq =~ s/\r?\n/ /g;
- $sqlq =~ s/ +/ /g;
- my(@q) = @_ ? sqlprint(0, $sqlq, @_) : ($sqlq);
- #warn join(', ', map "'$_'", @q)."\n";
-
- my $q = $s->prepare($q[0]);
- $q->execute($#q ? @q[1..$#q] : ());
- my $r = $type == 1 ? $q->fetchrow_hashref :
- $type == 2 ? $q->fetchall_arrayref({}) :
- $q->rows;
- $q->finish();
-
- push(@{$self->{_DB}->{Queries}}, [ $q[0], Time::HiRes::tv_interval($start), @q[1..$#q] ]) if $self->{debug};
-
- $r = 0 if $type == 0 && !$r;
- $r = {} if $type == 1 && (!$r || ref($r) ne 'HASH');
- $r = [] if $type == 2 && (!$r || ref($r) ne 'ARRAY');
-
- return $r;
-}
-
-
-# sqlprint:
-# ? normal placeholder
-# !l list of placeholders, expects arrayref
-# !H list of SET-items, expects hashref or arrayref: format => (bind_value || \@bind_values)
-# !W same as !H, but for WHERE clauses (AND'ed together)
-# !s the classic sprintf %s, use with care
-# This isn't sprintf, so all other things won't work,
-# Only the ? placeholder is supported, so no dollar sign numbers or named placeholders
-# Indeed, this also means you can't use PgSQL operators containing a question mark
-
-sub sqlprint { # start, query, bind values. Returns new query + bind values
- my @a;
- my $q='';
- my $s = shift;
- for my $p (split /(\?|![lHWs])/, shift) {
- next if !defined $p;
- if($p eq '?') {
- push @a, shift;
- $q .= '$'.(@a+$s);
- } elsif($p eq '!s') {
- $q .= shift;
- } elsif($p eq '!l') {
- my $l = shift;
- $q .= join ', ', map '$'.(@a+$s+$_+1), 0..$#$l;
- push @a, @$l;
- } elsif($p eq '!H' || $p eq '!W') {
- my $h=shift;
- my @h=ref $h eq 'HASH' ? %$h : @$h;
- my @r;
- while(my($k,$v) = (shift(@h), shift(@h))) {
- last if !defined $k;
- my($n,@l) = sqlprint($#a+1, $k, ref $v eq 'ARRAY' ? @$v : $v);
- push @r, $n;
- push @a, @l;
- }
- $q .= ($p eq '!W' ? 'WHERE ' : 'SET ').join $p eq '!W' ? ' AND ' : ', ', @r
- if @r;
- } else {
- $q .= $p;
- }
- }
- return($q, @a);
-}
-
-1;
-
diff --git a/lib/VNDB/Util/Request.pm b/lib/VNDB/Util/Request.pm
deleted file mode 100644
index 5cffec99..00000000
--- a/lib/VNDB/Util/Request.pm
+++ /dev/null
@@ -1,46 +0,0 @@
-
-package VNDB::Util::Request;
-
-use strict;
-use warnings;
-use Encode;
-use Exporter 'import';
-
-our @EXPORT;
-@EXPORT = qw| ReqParam ReqSaveUpload ReqCookie
- ReqMethod ReqHeader ReqUri ReqIP |;
-
-sub new {
- return bless {}, ref($_[0]) || $_[0];
-}
-sub ReqParam {
- my($s,$n) = @_;
- return wantarray
- ? map { decode 'UTF-8', defined $_ ? $_ : '' } $FCGI::Handler::c->param($n)
- : decode 'UTF-8', defined $FCGI::Handler::c->param($n) ? $FCGI::Handler::c->param($n) : '';
-}
-sub ReqSaveUpload {
- my($s,$n,$f) = @_;
- open my $F, '>', $f or die "Unable to write to $f: $!";
- print $F $FCGI::Handler::c->param($n);
- close $F;
-}
-sub ReqCookie {
- my $c = CGI::Cookie::XS->fetch;
- return $c && ref($c) eq 'HASH' && $c->{$_[1]} ? $c->{$_[1]}[0] : '';
-}
-sub ReqMethod {
- return ($ENV{REQUEST_METHOD}||'') =~ /post/i ? 'POST' : 'GET';
-}
-sub ReqHeader {
- (my $v = uc $_[1]) =~ tr/-/_/;
- return $ENV{"HTTP_$v"}||'';
-}
-sub ReqUri {
- return $ENV{REQUEST_URI};
-}
-sub ReqIP {
- return $ENV{REMOTE_ADDR};
-}
-
-1;
diff --git a/lib/VNDB/Util/Response.pm b/lib/VNDB/Util/Response.pm
deleted file mode 100644
index c5e9a704..00000000
--- a/lib/VNDB/Util/Response.pm
+++ /dev/null
@@ -1,220 +0,0 @@
-
-package VNDB::Util::Response;
-
-
-use strict;
-use warnings;
-use POSIX ();
-use Encode;
-use XML::Writer;
-use Compress::Zlib;
-use Exporter 'import';
-require bytes;
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-@EXPORT = qw| ResRedirect ResNotFound ResDenied ResFile
- ResForceBody ResSetContentType ResAddHeader ResAddTpl ResAddDefaultStuff
- ResStartXML ResGetXML ResGetBody ResGet ResGetCGI ResSetModPerl |;
-
-sub new {
- my $self = shift;
- my $tplo = shift;
- my $type = ref($self) || $self;
- my $me = bless {
- headers => [ ],
- contenttype => 'text/html; charset=UTF-8',
- code => 200,
- tplo => $tplo,
- tpl => { },
- body => undef,
- xmlobj => undef,
- xmldata => undef,
- whattouse => 1,
- }, $type;
-
- return $me;
-}
-
-
-## Some ready-to-use methods
-sub ResRedirect {
- my $self = shift;
- my $url = shift; # should start with '/', if no URL specified, use referer or '/'
- my $type = shift;
- my $info = $self->{_Res} || $self;
-
- if(!$url) {
- $url = "/";
- my $ref = $self->ReqHeader('Referer');
- ($url = $ref) =~ s/^$self->{root_url}// if $ref;
- }
-
- my $code = !$type ? 301 :
- $type eq 'temp' ? 307 :
- $type eq 'post' ? 303 : 301;
- $info->{body} = 'Redirecting...';
- $info->{code} = $code;
- $info->{headers} = [ 'Location', "$self->{root_url}$url" ];
- $info->{contenttype} = 'text/html; charset=UTF-8';
- $info->{whattouse} = 1;
-}
-
-sub ResNotFound {
- my $s = shift;
- my $i = $s->{_Res};
- $i->{code} = 404;
- $i->{whattouse} = 2;
- $i->{tpl} = {
- page => { error => {
- err => 'notfound'
- }},
- };
-}
-
-sub ResDenied {
- my $self = shift;
- $self->ResRedirect('/u/register?n=1', 'temp');
-}
-
-sub ResFile {
- my($s,$f,@h) = @_;
- my $i = $s->{_Res};
- $i->{whattouse} = 4;
- $i->{code} = 200;
- $i->{contenttype} = '';
- push @{$i->{headers}},
- 'X-Sendfile' => $f,
- 'Cache-Control' => sprintf('max-age=%d, public', 7*24*3600),
- @h;
-}
-
-## And some often-used methods
-sub ResForceBody {
- my $self = shift;
- my $body = shift;
- my $info = $self->{_Res} || $self;
- $info->{whattouse} = 1;
- $info->{body} = $body;
-}
-
-sub ResSetContentType {
- my $self = shift;
- my $ctype = shift;
- my $info = $self->{_Res} || $self;
- $info->{contenttype} = $ctype;
- return 1;
-}
-
-sub ResAddHeader {
- my $self = shift;
- die("Odd number in parameters, must be in key => value format!") unless ((@_ % 2) == 0);
- my $info = $self->{_Res} || $self;
- $info->{headers} = [ @{$info->{headers}}, @_ ];
- return 1;
-}
-
-sub ResAddTpl {
- my $self = shift;
- die("Odd number in parameters, must be in key=>value format") unless ((@_ % 2) == 0);
- my $info = $self->{_Res} || $self;
- $info->{tpl} = { page => { } } if !$info->{tpl}->{page};
- $info->{tpl}->{page} = { %{$info->{tpl}->{page}}, @_ };
- $info->{whattouse} = 2;
- return 1;
-}
-
-sub ResStartXML {
- my $self = shift;
- my $info = $self->{_Res} || $self;
- $info->{xmldata} = undef;
- $info->{xmlobj} = XML::Writer->new(
- OUTPUT => \$info->{xmldata},
- NEWLINES => 0,
- ENCODING => 'UTF-8',
- DATA_MODE => 1,
- DATA_INDENT => 2,
- );
- $info->{xmlobj}->xmlDecl();
- $info->{contenttype} = "text/xml; charset=UTF-8";
- # disable caching on XML content, IE < 7 has "some" bugs...
- $self->ResAddHeader('Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
- 'Pragma' => 'public');
- $info->{whattouse} = 3;
- return $info->{xmlobj};
-}
-
-## And of course some methods to get the information
-sub ResGetXML {
- my $self = shift;
- my $info = $self->{_Res} || $self;
- return undef if !$info->{xmlobj} || !$info->{xmldata};
- $info->{xmlobj}->end();
- my $tmpvar = $info->{xmldata};
- undef $info->{xmldata};
- return $tmpvar;
-}
-
-sub ResGetBody {
- my $self = shift;
- my $info = $self->{_Res} || $self;
- my $whattouse = shift || $info->{whattouse};
- if($whattouse == 1) { return $info->{body}; }
- if($whattouse == 2) {
- $self->AddDefaultStuff() if exists $info->{tpl}->{page};
- my $start = [Time::HiRes::gettimeofday()] if $self->{debug} && $Time::HiRes::VERSION;
- my $output = $info->{tplo}->compile($info->{tpl});
- $info->{_tpltime} = Time::HiRes::tv_interval($start) if $self->{debug} && $Time::HiRes::VERSION;
- return $output;
- }
- if($whattouse == 3) { return $self->ResGetXML; }
-}
-
-sub ResGet {
- my $self = shift;
- my $info = $self->{_Res} || $self;
- my $whattouse = shift || $info->{whattouse};
-
- return ($info->{code}, $info->{headers}, $info->{contenttype}, $self->ResGetBody($whattouse));
-}
-
-
-my %scodes = (
- # just a few useful codes
- 200 => 'OK',
- 301 => 'Moved Permanently',
- 302 => 'Found',
- 303 => 'See Other',
- 304 => 'Not Modified',
- 307 => 'Temporary Redirect',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 500 => 'Internal Server Error'
-);
-
-# don't rename!
-sub ResSetModPerl {
- my $s = shift;
- my $i = $s->{_Res};
- printf "Status: %d %s\r\n", $i->{code}, $scodes{$i->{code}};
- print "X-Powered-By: Perl\r\n";
- printf "Content-Type: %s\r\n", $i->{contenttype} if $i->{contenttype};
- my $c=0;
- printf "%s: %s\r\n", $i->{headers}[$c++], $i->{headers}[$c++]
- while ($c<$#{$i->{headers}});
-
- my $b = $s->ResGetBody||'';
- if($b && $s->ReqHeader('Accept-Encoding') =~ /gzip/ && $i->{contenttype} =~ /^text/) {
- my $ol = bytes::length($b) if $s->{debug};
- $b = Compress::Zlib::memGzip(Encode::encode_utf8($b));
- $i->{_gzip} = [ $ol, bytes::length($b) ];
- print "Content-Encoding: gzip\n";
- }
- my $l = bytes::length($b);
- printf "Content-Length: %d\r\n", $l if $l;
- print "\r\n";
- print $b;
- $FCGI::Handler::outputted = 1;
-}
-
-1;
diff --git a/lib/VNDB/Util/Template.pm b/lib/VNDB/Util/Template.pm
deleted file mode 100644
index f9c63998..00000000
--- a/lib/VNDB/Util/Template.pm
+++ /dev/null
@@ -1,235 +0,0 @@
-# VNDB::Util::Template - A direct copy of NTL::Util::Template
-
-# This file has not been edited for at least a year,
-# and there's probably no need to do so in the near future
-
-# template specific stuff:
-# [[ perl code to execute at the specified place ]]
-# [[= perl code, append return value to the template at the specified place ]]
-# [[: same as above, but escape special HTML chars (<, >, &, " and \n) ]]
-# [[% same as above, but also escape as an URL (expects UTF-8 strings) ]]
-# [[! perl code, append at the top of the script (useful for subroutine-declarations etc) ]]
-# [[+ path to a file to include, relative to $searchdir ]]
-
-package VNDB::Util::Template;
-
-use strict;
-use warnings;
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-
-
-sub new {
- my $pack = shift;
- my %ops = @_;
- my $me = bless {
- namespace => __PACKAGE__ . '::tpl',
- pre_chomp => 0,
- post_chomp => 0,
- rm_newlines => 0,
- %ops,
- lastreload => 0
- }, ref($pack) || $pack;
-
- $me->{mainfile} = sprintf '%s/%s', $me->{searchdir}, $me->{filename};
-
- die "No filename specified!" if !$me->{filename};
- die "No searchdir specified!" if !$me->{searchdir};
- die "Filename does not exist!" if !-e $me->{mainfile};
- die "No place for the compiled script specified!" if !$me->{compiled};
-
- $me->includescript();
-
- return $me;
-}
-
-sub includescript {
- my $self = shift;
-
- my $dt = 0;
- my $dc = (stat($self->{compiled}))[9] || 0;
-
- if(-s $self->{compiled} && !exists $INC{$self->{compiled}}) {
- eval { require $self->{compiled}; };
- if(!$@) {
- $self->{lastreload} = $dc;
- } else {
- # make sure we can fix the problem and try again
- $INC{$self->{compiled}} = $self->{compiled};
- die $@;
- }
- }
-
- my $T_version = eval(sprintf '$%s::VERSION;', $self->{namespace});
-
- if($dc > $self->{lastreload} || !$T_version) {
- $dt = 1;
- }
- elsif($self->{deep_reload} && $T_version >= 0.1) {
- my @T_files = @{ eval(sprintf '\@%s::T_FILES;', $self->{namespace}) };
- if($#T_files >= 0) {
- foreach (@T_files) {
- if((stat(sprintf('%s/%s', $self->{searchdir}, $_)))[9] > $dc) {
- $dt = 2;
- last;
- }
- }
- }
- } elsif((stat($self->{mainfile}))[9] > $dc) {
- $dt = 2;
- }
- if($dt) {
- $self->compiletpl() if $dt == 2 || $dc <= $self->{lastreload};
- delete $INC{$self->{compiled}};
- eval { require $self->{compiled}; };
- if(!$@) {
- warn "Reloaded template\n";
- } else {
- $INC{$self->{compiled}} = $self->{compiled};
- warn "Template contains errors, not reloading\n";
- }
- $self->{lastreload} = (stat($self->{compiled}))[9];
- }
-}
-
-sub compile {
- my $self = shift;
- my $X = shift;
- $self->includescript();
-
- return $self->{namespace}->compile($X);
-}
-
-sub compiletpl {
- my $self = shift;
- open(my $T, '>', $self->{compiled}) || die sprintf '%s: %s', $self->{compiled}, $!;
- printf $T <<__, __PACKAGE__, $self->{namespace}, ($self->compilefile());
-# Compiled from a template by %s
-package %s;
-
-use strict;
-use warnings;
-no warnings qw(redefine);
-use URI::Escape \'uri_escape_utf8\';
-
-our \$VERSION = 0.1;
-our \@T_FILES = qw| %s |;
-
-sub _hchar { local\$_=shift||return\'\';s/&/&amp;/g;s/</&lt;/g;s/>/&gt;/g;s/"/&quot;/g;s/\\r?\\n/<br \\/>/g;return\$_; }
-sub _huri { _hchar(uri_escape_utf8((scalar shift)||return \'\')) }
-%s
-%s
-%s
-1;
-__
- close($T);
- warn "Recompiled template\n";
-}
-
-sub compilefile {
- my $self = shift;
- my $file = shift||$self->{filename};
- my $func = shift||'compile';
-
- my $files = $file;
- $file = sprintf('%s/%s', $self->{searchdir}, $file);
- open(my $F, '<', $file) || die "$file: $!";
- my $tpl = '';
- $tpl .= $_ while(<$F>);
- close($F);
- my @t = split(//, $tpl);
- $tpl = undef;
-
- my $inperl = 0;
- my $top = '';
- my $R = '';
- my $bottom = '';
- my $dat = '';
- my $perl = '';
-
- for(my $i=0; $i<=$#t; $i++) {
- # [[= (2), [[: (3) and [[% (4)
- if(!$inperl && $t[$i] eq '[' && $t[$i+1] eq '[' && $t[$i+2] =~ /[=:%]/) {
- $i+=2;
- if($t[$i] eq '=') {
- $inperl=2;
- $perl = '\' . ( scalar ';
- } elsif($t[$i] eq ':') {
- $inperl=3;
- $perl = '\' . _hchar( scalar ';
- } else {
- $inperl=4;
- $perl = '\' . _huri( scalar ';
- }
- $R .= $self->_pd($dat);
- } elsif($inperl >= 2 && $inperl <= 4 && $t[$i] eq ']' && $t[$i+1] eq ']') {
- $inperl=0; $i++;
- $R .= $perl . "\n) . '";
- $dat = '';
- # [[! (5)
- } elsif(!$inperl && $t[$i] eq '[' && $t[$i+1] eq '[' && $t[$i+2] eq '!') {
- $inperl=5; $i+=2;
- $perl = '';
- $R .= $self->_pd($dat);
- } elsif($inperl == 5 && $t[$i] eq ']' && $t[$i+1] eq ']') {
- $inperl=0; $i++;
- $top .= $perl . "\n";
- $dat = '';
- # [[+ (6)
- } elsif(!$inperl && $t[$i] eq '[' && $t[$i+1] eq '[' && $t[$i+2] eq '+') {
- $inperl=6; $i+=2;
- $R .= $self->_pd($dat);
- $perl = '';
- } elsif($inperl == 6 && $t[$i] eq ']' && $t[$i+1] eq ']') {
- $inperl=0;$i++;
- $perl =~ s/[\r\n\s]//g;
- die "Invalid file specified: $perl\n" if $perl !~ /^[a-zA-Z0-9-_\.\/]+$/;
- (my $func = $perl) =~ s/[^a-zA-Z0-9_]/_/g;
- my($ifiles, $itop, $imid, $ibot) = $self->compilefile($perl, "T_$func");
- $files .= ' ' . $ifiles;
- $top .= $itop;
- $bottom .= "\n\n$imid\n$ibot\n";
- $R .= "' . T_$func(\$X) . '";
- $dat = '';
- # [[ (1)
- } elsif(!$inperl && $t[$i] eq '[' && $t[$i+1] eq '[') {
- $inperl = 1; $i++;
- $R .= $self->_pd($dat);
- $perl = "';\n";
- } elsif($inperl == 1 && $t[$i] eq ']' && $t[$i+1] eq ']') {
- $inperl=0; $i++;
- $R .= $perl . "\n \$R .= '";
- $dat = '';
- # data
- } elsif(!$inperl) {
- (my $l = $t[$i]) =~ s/'/\\'/;
- $dat .= $l;
- } else {
- $perl .= $t[$i];
- }
- }
- if(!$inperl) {
- $R .= $self->_pd($dat) . "';\n";
- } else {
- die "Error, no ']]' found at $file!\n";
- }
- $R = "sub $func {
- my \$X = \$_[". ($func eq 'compile' ? 1 : 0) . "];
- my \$R = '".$R."
- return \$R;
- }";
- return($files, $top, $R, $bottom);
-}
-
-sub _pd { # Parse Dat
- my $self = shift;
- local $_ = shift;
-
- s/[\r\n\s]+$//g if $_ !~ s/-$// && $self->{pre_chomp};
- s/^[\r\n\s]+//g if $_ !~ s/^-// && $self->{post_chomp};
- s/([\s\t]*)[\r\n]+([\s\t]*)/{ $1||$2?' ':'' }/eg if $self->{rm_newlines};
- return $_;
-}
-
-1;
diff --git a/lib/VNDB/Util/Tools.pm b/lib/VNDB/Util/Tools.pm
deleted file mode 100644
index ee295a67..00000000
--- a/lib/VNDB/Util/Tools.pm
+++ /dev/null
@@ -1,172 +0,0 @@
-
-package VNDB::Util::Tools;
-
-use strict;
-use warnings;
-use Encode;
-use Tie::ShareLite ':lock';
-use Exporter 'import';
-
-our $VERSION = $VNDB::VERSION;
-our @EXPORT = qw| FormCheck AddHid GTINType SendMail AddDefaultStuff RunCmd |;
-
-
-# ...this function could use some serious rewriting
-sub FormCheck {
- my $self = shift;
- my @ps = @_;
- my %hash; my @err;
-
- foreach my $i (0..$#ps) {
- next if !$ps[$i] || ref($ps[$i]) ne 'HASH';
- my $k = $ps[$i]{name};
- $hash{$k} = [ ( $self->ReqParam($k) ) ];
- $hash{$k}[0] = '' if !defined $hash{$k}[0];
- foreach my $j (0..$#{$hash{$k}}) {
- my $val = \$hash{$k}[$j]; my $e = 0;
- $e = 1 if !$e && $ps[$i]{required} && !$$val && length($$val) < 1 && $$val ne '0';
- $e = 2 if !$e && $ps[$i]{minlength} && length($$val) < $ps[$i]{minlength};
- $e = 3 if !$e && $ps[$i]{maxlength} && length($$val) > $ps[$i]{maxlength};
- if(!$e && $ps[$i]{template}) {
- my $t = $ps[$i]{template};
- $hash{$k}[$j] = lc $hash{$k}[$j] if $t eq 'pname';
- $e = 4 if ($t eq 'mail' && $$val !~ # From regexlib.com, author: Gavin Sharp
- /^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+\@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$/)
- || ($t eq 'url' && $$val !~ # From regexlib.com, author: M H
- /^(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?$/)
- || ($t eq 'pname' && $$val !~ /^[a-z0-9][a-z0-9\-]*$/)
- || ($t eq 'asciiprint' && $$val !~ /^[\x20-\x7E]*$/)
- || ($t eq 'int' && $$val !~ /^\-?[0-9]+$/)
- || ($t eq 'date' && $$val !~ /^[0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?$/)
- || ($t eq 'gtin' && !GTINType($$val));
- }
- $e = 5 if !$e && $ps[$i]{enum} && ref($ps[$i]{enum}) eq "ARRAY" && !_inarray($$val, $ps[$i]{enum});
- if($e) {
- if(!$ps[$i]{required} && !$$val && length($$val) < 1 && $$val ne '0') {
- $hash{$k}[$j] = exists $ps[$i]{default} ? $ps[$i]{default} : undef;
- } else {
- my $errc = $ps[$i]{name}.'-'.$e;
- $errc .= '-'.$ps[$i]{minlength} if $e == 2;
- $errc .= '-'.$ps[$i]{maxlength} if $e == 3;
- $errc .= '-'.$ps[$i]{template} if $e == 4;
- push(@err, $errc);
- last;
- }
- }
- last if !$ps[$i]{multi};
- }
- $hash{$k} = $hash{$k}[0] if !$ps[$i]{multi};
- }
- $hash{_err} = $#err >= 0 ? \@err : 0;
-
- return \%hash;
-}
-
-
-sub AddHid {
- my $fh = $_[0]->FormCheck({ name => 'fh', required => 0, maxlength => 30 })->{fh};
- $_[1]->{_hid} = { map { $_ => 1 } 'com', 'mod', split /,/, $fh }
- if $fh;
-}
-
-
-sub GTINType { # returns 'JAN', 'EAN', 'UPC' or undef
- (my $c = $_[0]) =~ s/^0+//;
- return undef if $c !~ /^[0-9]{12,13}$/; # only gtin-12 and 13
- $c = ('0'x(13-length $c)) . $c; # pad with zeros
-
- # calculate check digit according to
- # http://www.gs1.org/productssolutions/barcodes/support/check_digit_calculator.html#how
- my @n = reverse split //, $c;
- my $n = shift @n;
- $n += $n[$_] * ($_ % 2 != 0 ? 1 : 3) for (0..$#n);
- return undef if $n % 10 != 0;
-
- # Do some rough guesses based on:
- # http://www.gs1.org/productssolutions/barcodes/support/prefix_list.html
- # and http://en.wikipedia.org/wiki/List_of_GS1_country_codes
- local $_ = $c;
- return 'JAN' if /^4[59]/; # prefix code 450-459 & 490-499
- return 'UPC' if /^(?:0[01]|0[6-9]|13|75[45])/; # prefix code 000-019 & 060-139 & 754-755
- return undef if /(?:0[2-5]|2|97[789]|9[6-9])/; # some codes we don't want: 020–059 & 200-299 & 977-999
- return 'EAN'; # let's just call everything else EAN :)
-}
-
-
-sub _inarray { # errr... this is from when I didn't know about grep
- foreach (@{$_[1]}) {
- (return 1) if $_[0] eq $_;
- }
- return 0;
-}
-
-
-sub SendMail {
- my $self = shift;
- my $body = shift;
- my %hs = @_;
-
- die "No To: specified!\n" if !$hs{To};
- die "No Subject specified!\n" if !$hs{Subject};
- $hs{'Content-Type'} ||= 'text/plain; charset=\'UTF-8\'';
- $hs{From} ||= 'vndb <noreply@vndb.org>';
- $hs{'X-mailer'} ||= "VNDB $VERSION";
- $body =~ s/\r?\n/\n/g; # force a '\n'-linebreak
-
- my $mail = '';
- foreach (keys %hs) {
- $hs{$_} =~ s/[\r\n]//g;
- $mail .= sprintf "%s: %s\n", $_, $hs{$_};
- }
- $mail .= sprintf "\n%s", $body;
-
- if(open(my $mailer, "|/usr/sbin/sendmail -t -f '$hs{From}'")) {
- print $mailer encode('UTF-8', $mail);
- die "Error running sendmail ($!)"
- if !close($mailer);
- } else {
- die "Error opening sendail: $!";
- }
-}
-
-
-sub AddDefaultStuff {
- my $self = shift;
-
- $self->AuthAddTpl;
- $self->ResAddTpl(st => $self->{static_url});
-
- $self->ResAddTpl('Stat'.$_, $self->DBTableCount($_))
- for (qw|users producers vn releases|);
-
- # development shit
- if($self->{debug}) {
- my $sqls;
- for (@{$self->{_DB}->{Queries}}) {
- $_->[0] =~ s/^\s//g;
- $sqls .= sprintf("[%6.2fms] %s\n", $_->[1]*1000, $_->[0] || '[undef]');
- $sqls .= " ".join(', ', map "'$_'", @{$_}[2..$#$_])."\n" if exists $$_[2];
- }
- $self->ResAddTpl(devshit => $sqls);
- }
-}
-
-
-# commands aren't actually sent until the function is called without cmd parameter
-sub RunCmd { # cmd
- my($self, $c) = @_;
- if($c) {
- push @{$self->{cmds}}, $c;
- } elsif(@{$self->{cmds}}) {
- my $s = tie my %s, 'Tie::ShareLite', @VNDB::SHMOPTS;
- $s->lock(LOCK_EX);
- my @q = ( ($s{queue} ? @{$s{queue}} : ()), @{$self->{cmds}} );
- $s{queue} = \@q;
- $s->unlock();
- $self->{cmds} = [];
- }
-}
-
-
-1;
-
diff --git a/lib/VNDB/VN.pm b/lib/VNDB/VN.pm
deleted file mode 100644
index c25f97dd..00000000
--- a/lib/VNDB/VN.pm
+++ /dev/null
@@ -1,419 +0,0 @@
-
-package VNDB::VN;
-
-use strict;
-use warnings;
-use Exporter 'import';
-use Digest::MD5;
-require bytes;
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-@EXPORT = qw| VNPage VNEdit VNLock VNHide VNBrowse VNXML VNScrXML VNUpdReverse |;
-
-
-sub VNPage {
- my $self = shift;
- my $id = shift;
- my $page = shift || '';
- my $rev = shift || 0;
-
- return $self->ResNotFound if $self->ReqParam('rev');
-
- my $what = 'extended relations categories anime screenshots';
- $what .= ' changes' if $rev;
- $what .= ' relgraph' if $page eq 'rg';
-
- my $v = $self->DBGetVN(
- id => $id,
- what => $what,
- $rev ? ( rev => $rev ) : ()
- )->[0];
- return $self->ResNotFound if !$v->{id};
-
- my $c = $rev && $rev > 1 && $self->DBGetVN(id => $id, rev => $rev-1, what => $what)->[0];
- $v->{next} = $rev && $v->{latest} > $v->{cid} ? $rev+1 : 0;
-
- my $rel = $self->DBGetRelease(vid => $id, what => 'producers platforms');
-
- if(!$page && @$rel && $self->AuthInfo->{id}) {
- my $rl = $self->DBGetRList(
- rids => [ map $_->{id}, @$rel ],
- uid => $self->AuthInfo->{id}
- );
- for my $i (@$rl) {
- my $r = (grep $i->{rid} == $_->{id}, @$rel)[0];
- $r->{rlist} = $i;
- }
- }
-
- $self->ResAddTpl(vnpage => {
- vote => $self->AuthInfo->{id} ? $self->DBGetVotes(uid => $self->AuthInfo->{id}, vid => $id)->[0] : {},
- wlist => $self->AuthInfo->{id} ? $self->DBGetWishList(uid => $self->AuthInfo->{id}, vid => $id)->[0] : {},
- vn => $v,
- rel => $rel,
- prev => $c,
- page => $page,
- change => $rev,
- $page eq 'stats' ? (
- votes => {
- latest => scalar $self->DBGetVotes(vid => $id, results => 10, hide => 1),
- graph => $self->DBVoteStats(vid => $id),
- },
- ) : (),
- });
-}
-
-
-sub VNEdit {
- my $self = shift;
- my $id = shift; # 0 = new
-
- my $rev = $self->FormCheck({ name => 'rev', required => 0, default => 0, template => 'int' });
- return $self->ResNotFound if $rev->{_err};
- $rev = $rev->{rev};
-
- my $v = $self->DBGetVN(id => $id, what => 'extended changes relations categories anime screenshots', $rev ? ( rev => $rev ) : ())->[0] if $id;
- return $self->ResNotFound() if $id && !$v;
-
- return $self->ResDenied if !$self->AuthCan('edit') || ($v->{locked} && !$self->AuthCan('lock'));
-
- my %b4 = $id ? (
- ( map { $_ => $v->{$_} } qw| title original desc alias img_nsfw length l_wp l_encubed l_renai l_vnn | ),
- relations => join('|||', map { $_->{relation}.','.$_->{id}.','.$_->{title} } @{$v->{relations}}),
- categories => join(',', map { $_->[0].$_->[1] } sort { $a->[0] cmp $b->[0] } @{$v->{categories}}),
- anime => join(' ', sort { $a <=> $b } map $_->{id}, @{$v->{anime}}),
- screenshots => join(' ', map sprintf('%d,%d,%d', $$_{id}, $$_{nsfw}?1:0, $$_{rid}||0), @{$v->{screenshots}}),
- ) : ();
-
- my $frm = {};
- if($self->ReqMethod() eq 'POST') {
- $frm = $self->FormCheck(
- { name => 'title', required => 1, maxlength => 250 },
- { name => 'original', required => 0, maxlength => 250 },
- { name => 'alias', required => 0, maxlength => 500, default => '' },
- { name => 'desc', required => 1, maxlength => 10240 },
- { name => 'length', required => 0, enum => [ 0..($#$VNDB::VNLEN+1) ], default => 0 },
- { 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 => 0, template => 'int' },
- { name => 'anime', required => 0, default => '' },
- { name => 'img_nsfw', required => 0 },
- { name => 'categories', required => 0, default => '' },
- { name => 'relations', required => 0, default => '' },
- { name => 'screenshots', required => 0, default => '' },
- { name => 'comm', required => 0, default => '' },
- );
- my $relations = [ map { /^([0-9]+),([0-9]+)/ && $2 != $id ? ( [ $1, $2 ] ) : () } split /\|\|\|/, $frm->{relations} ];
- my $cat = [ map { [ substr($_,0,3), substr($_,3,1) ] } split /,/, $frm->{categories} ];
- my $anime = [ grep /^[0-9]+$/, split / +/, $frm->{anime} ];
- my $screenshots = [ map { local $_=[split /,/];$$_[2]||=undef; $_ } grep /^[0-9]+,[01],[0-9]+$/, split / +/, $frm->{screenshots} ];
-
- $frm->{img_nsfw} = $frm->{img_nsfw} ? 1 : 0;
- $frm->{anime} = join ' ', sort { $a <=> $b } @$anime; # re-sort
- $frm->{screenshots} = join ' ', map sprintf('%d,%d,%d', $$_[0], $$_[1]?1:0, $$_[2]||0), sort { $$a[0] <=> $$b[0] } @$screenshots;
-
- return $self->ResRedirect('/v'.$id, 'post')
- if $id && !$self->ReqParam('img') && 14 == scalar grep { $b4{$_} eq $frm->{$_} } keys %b4;
-
- # upload image
- my $imgid = 0;
- if($self->ReqParam('img')) {
- my $tmp = sprintf '%s/00/tmp.%d.jpg', $self->{imgpath}, $$*int(rand(1000)+1);
- $self->ReqSaveUpload('img', $tmp);
-
- my $l;
- open(my $T, '<:raw:bytes', $tmp) || die $1;
- read $T, $l, 2;
- close($T);
-
- $frm->{_err} = $frm->{_err} ? [ @{$frm->{_err}}, 'nojpeg' ] : [ 'nojpeg' ]
- if $l ne pack('H*', 'ffd8') && $l ne pack('H*', '8950');
- $frm->{_err} = $frm->{_err} ? [ @{$frm->{_err}}, 'toolarge' ] : [ 'toolarge' ]
- if !$frm->{_err} && -s $tmp > 512*1024; # 500 KB max.
-
- if($frm->{_err}) {
- unlink $tmp;
- } else {
- $imgid = $self->DBIncId('covers_seq');
- my $new = sprintf '%s/%02d/%d.jpg', $self->{imgpath}, $imgid%100, $imgid;
- rename $tmp, $new or die $!;
- chmod 0666, $new;
- $self->RunCmd(sprintf 'coverimage %d', $imgid);
- $imgid = -1*$imgid;
- }
- } elsif($id) {
- $imgid = $v->{image};
- }
-
- my %args = (
- ( map { $_ => $frm->{$_} } qw| title original desc alias comm length l_wp l_encubed l_renai l_vnn img_nsfw| ),
- image => $imgid,
- anime => $anime,
- relations => $relations,
- categories => $cat,
- screenshots => $screenshots,
- );
-
- if(!$frm->{_err}) {
- my($oid, $nrev, $cid) = ($id, 1, 0);
- ($nrev, $cid) = $self->DBEditVN($id, %args) if $id; # edit
- ($id, $cid) = $self->DBAddVN(%args) if !$id; # add
-
- # update reverse relations and relation graph
- if((!$oid && $#$relations >= 0) || ($oid && $frm->{relations} ne $b4{relations})) {
- my %old = $oid ? (map { $_->{id} => $_->{relation} } @{$v->{relations}}) : ();
- my %new = map { $_->[1] => $_->[0] } @$relations;
- $self->VNUpdReverse(\%old, \%new, $id, $cid, $nrev);
- }
- # also regenerate relation graph if the title changes
- elsif(@$relations && $frm->{title} ne $b4{title}) {
- $self->RunCmd('relgraph '.$id);
- }
-
- # check for new anime data
- $self->RunCmd('anime') if $oid && $frm->{anime} ne $b4{anime} || !$oid && $frm->{anime};
-
- $self->RunCmd('ircnotify v'.$id.'.'.$nrev);
- return $self->ResRedirect('/v'.$id.'.'.$nrev, 'post');
- }
- }
-
- if($id) {
- $frm->{$_} ||= $b4{$_} for (keys %b4);
- $frm->{comm} = sprintf 'Reverted to revision v%d.%d', $v->{id}, $v->{rev} if $v->{cid} != $v->{latest};
- }
-
- $self->AddHid($frm);
- $frm->{_hid} = {map{$_=>1} qw| info cat img com |}
- if !$frm->{_hid} && !$id;
- $self->ResAddTpl(vnedit => {
- form => $frm,
- id => $id,
- vn => $v,
- rel => scalar $self->DBGetRelease(vid => $id),
- });
-}
-
-
-sub VNLock {
- my $self = shift;
- my $id = shift;
-
- my $v = $self->DBGetVN(id => $id)->[0];
- return $self->ResNotFound() if !$v;
- return $self->ResDenied if !$self->AuthCan('lock');
- $self->DBLockItem('vn', $id, $v->{locked}?0:1);
- $self->DBLockItem('releases', $_->{id}, $v->{locked}?0:1)
- for (@{$self->DBGetRelease(vid => $id)});
- return $self->ResRedirect('/v'.$id, 'perm');
-}
-
-
-sub VNHide {
- my $self = shift;
- my $id = shift;
-
- my $v = $self->DBGetVN(id => $id, what => 'relations')->[0];
- return $self->ResNotFound() if !$v;
- return $self->ResDenied if !$self->AuthCan('del');
- $self->DBHideVN($id, $v->{hidden}?0:1);
- return $self->ResRedirect('/v'.$id, 'perm');
-}
-
-
-sub VNBrowse {
- my $self = shift;
- my $chr = shift;
- $chr = 'all' if !defined $chr;
-
- my $f = $self->FormCheck(
- { name => 's', required => 0, default => 'title', enum => [ qw|title released votes| ] },
- { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] },
- { name => 'q', required => 0, default => '' },
- { name => 'sq', required => 0, default => '' },
- { name => 'p', required => 0, template => 'int', default => 1},
- );
- return $self->ResNotFound if $f->{_err};
- $f->{s} = 'title' if $f->{s} eq 'votes';
-
- $f->{q} ||= $f->{sq};
-
- my(@cati, @cate, @plat, @lang);
- my $q = $f->{q};
- if($chr eq 'search') {
- # VNDBID
- return $self->ResRedirect('/'.$1.$2.(!$3 ? '' : $1 eq 'd' ? '#'.$3 : '.'.$3), 'temp')
- if $q =~ /^([vrptud])([0-9]+)(?:\.([0-9]+))?$/;
-
- if(!($q =~ s/^title://)) {
- # categories
- my %catl = map {
- my $ic = $_;
- map { $ic.$_ => $VNDB::CAT->{$ic}[1]{$_} } keys %{$VNDB::CAT->{$ic}[1]}
- } keys %$VNDB::CAT;
-
- $q =~ s/-(?:$catl{$_}|c:$_)//ig && push @cate, $_ for keys %catl;
- $q =~ s/(?:$catl{$_}|c:$_)//ig && push @cati, $_ for keys %catl;
-
- # platforms
- $_ ne 'oth' && $q =~ s/(?:$VNDB::PLAT->{$_}|p:$_)//ig && push @plat, $_ for keys %$VNDB::PLAT;
-
- # languages
- $q =~ s/($VNDB::LANG->{$_}|l:$_)//ig && push @lang, $_ for keys %$VNDB::LANG;
- }
- }
- $q =~ s/ +$//;
- $q =~ s/^ +//;
-
- my($r, $np) = $chr ne 'search' || $q || @lang || @plat || @cati || @cate ? ($self->DBGetVN(
- $chr =~ /^[a-z0]$/ ? ( char => $chr ) : (),
- $q ? ( search => $q ) : (),
- @cati ? ( cati => \@cati ) : (),
- @cate ? ( cate => \@cate ) : (),
- @lang ? ( lang => \@lang ) : (),
- @plat ? ( platform => \@plat ) : (),
- results => 50,
- page => $f->{p},
- order => {title => 'vr.title', released => 'v.c_released',
- }->{$f->{s}}.{a=>' ASC',d=>' DESC'}->{$f->{o}},
- )) : ([], 0);
-
- $self->ResRedirect('/v'.$r->[0]{id}, 'temp')
- if $chr eq 'search' && $#$r == 0;
-
- $self->ResAddTpl(vnbrowse => {
- vn => $r,
- npage => $np,
- page => $f->{p},
- chr => $chr,
- $chr eq 'search' ? (
- cat => $self->DBCategoryCount,
- langc => $self->DBLanguageCount,
- ) : (),
- order => [ $f->{s}, $f->{o} ],
- },
- searchquery => $f->{q});
-}
-
-
-sub VNXML {
- my $self = shift;
-
- my $q = $self->FormCheck(
- { name => 'q', required => 0, maxlength => 100 }
- )->{q};
-
- my $r = [];
- if($q) {
- ($r,undef) = $self->DBGetVN(results => 10,
- $q =~ /^v([0-9]+)$/ ? (id => $1) : (search => $q));
- }
-
- my $x = $self->ResStartXML;
- $x->startTag('vn', results => $#$r+1, query => $q);
- for (@$r) {
- $x->startTag('item');
- $x->dataElement(id => $_->{id});
- $x->dataElement(title => $_->{title});
- $x->endTag('item');
- }
- $x->endTag('vn');
-}
-
-
-sub VNScrXML {
- my $self = shift;
- return $self->ResDenied if !$self->AuthCan('edit');
-
- # check the status of recently uploaded screenshots
- if($self->ReqMethod ne 'POST') {
- my $ids = $self->FormCheck(
- { name => 'id', required => 1, template => 'int', multi => 1 }
- );
- return $self->ResNotFound if $ids->{_err};
- my $r = $self->DBGetScreenshot($ids->{id});
- return $self->ResNotFound if !@$r;
- my $x = $self->ResStartXML;
- $x->startTag('images');
- $x->emptyTag('image', id => $_->{id}, status => $_->{status}, width => $_->{width}, height => $_->{height})
- for (@$r);
- $x->endTag('images');
- return;
- }
-
- # upload new screenshot
- my $i = $self->FormCheck(
- { name => 'itemnumber', required => 1, template => 'int' }
- );
- return $self->ResNotFound if $i->{_err};
- $i = $i->{itemnumber};
-
- my $tmp = sprintf '%s/00/tmp.%d.jpg', $self->{sfpath}, $$*int(rand(1000)+1);
- $self->ReqSaveUpload('scrAddFile'.$i, $tmp);
-
- 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');
- }
-
- if($id) {
- unlink $tmp;
- } else {
- $id = $self->DBAddScreenshot;
- my $new = sprintf '%s/%02d/%d.jpg', $self->{sfpath}, $id%100, $id;
- rename $tmp, $new or die $!;
- chmod 0666, $new;
- $self->RunCmd('screenshot');
- }
-
- my $x = $self->ResStartXML;
- $x->pi('xml-stylesheet', 'href="'.$self->{static_url}.'/files/blank.css" type="text/css"');
- $x->emptyTag('image', id => $id);
-}
-
-
-# Update reverse relations
-sub VNUpdReverse { # old, new, id, cid, rev
- my($self, $old, $new, $id, $cid, $rev) = @_;
- my %upd;
- for (keys %$old, keys %$new) {
- if(exists $$old{$_} and !exists $$new{$_}) {
- $upd{$_} = -1;
- } elsif((!exists $$old{$_} and exists $$new{$_}) || ($$old{$_} != $$new{$_})) {
- $upd{$_} = $$new{$_};
- if($VNDB::VRELW->{$upd{$_}}) { $upd{$_}-- }
- elsif($VNDB::VRELW->{$upd{$_}+1}) { $upd{$_}++ }
- }
- }
-
- for my $i (keys %upd) {
- my $r = $self->DBGetVN(id => $i, what => 'extended relations categories anime screenshots')->[0];
- my @newrel;
- $_->{id} != $id && push @newrel, [ $_->{relation}, $_->{id} ]
- for (@{$r->{relations}});
- push @newrel, [ $upd{$i}, $id ] if $upd{$i} != -1;
- $self->DBEditVN($i,
- relations => \@newrel,
- comm => 'Reverse relation update caused by revision v'.$id.'.'.$rev,
- causedby => $cid,
- uid => 1, # Multi - hardcoded
- anime => [ map $_->{id}, @{$r->{anime}} ],
- screenshots => [ map [ $_->{id}, $_->{nsfw}, $_->{rid} ], @{$r->{screenshots}} ],
- ( map { $_ => $r->{$_} } qw| title original desc alias categories img_nsfw length l_wp l_encubed l_renai l_vnn image | )
- );
- }
-
- $self->RunCmd('relgraph '.join(' ', $id, keys %upd));
-}
-
-
-
-1;
-
diff --git a/lib/VNDB/VNLists.pm b/lib/VNDB/VNLists.pm
deleted file mode 100644
index 0b7a5207..00000000
--- a/lib/VNDB/VNLists.pm
+++ /dev/null
@@ -1,230 +0,0 @@
-
-package VNDB::VNLists;
-
-use strict;
-use warnings;
-use Exporter 'import';
-
-use vars ('$VERSION', '@EXPORT');
-$VERSION = $VNDB::VERSION;
-@EXPORT = qw| VNMyList VNVote RListMod RList WListMod WList |;
-
-
-sub VNMyList {
- my $self = shift;
- my $user = shift;
-
- my $u = $self->DBGetUser(uid => $user)->[0];
- return $self->ResNotFound if !$user || !$u || !$self->AuthInfo->{id} || $self->AuthInfo->{id} != $user;
-
- my $f = $self->FormCheck(
- { name => 's', required => 0, default => 'title', enum => [ qw|title date| ] },
- { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] },
- { name => 'p', required => 0, template => 'int', default => 1 },
- { name => 't', required => 0, enum => [ -1..$#$VNDB::LSTAT ], default => -1 },
- );
- return $self->ResNotFound if $f->{_err};
-
- if($self->ReqMethod eq 'POST') {
- my $f = $self->FormCheck({ name => 'sel', required => 1, multi => 1, template => 'int' });
- $self->DBDelVNList($user, @{$f->{sel}}) if !$f->{_err};
- }
-
- my $order = $f->{s} . ($f->{o} eq 'a' ? ' ASC' : ' DESC');
- my($list, $np) = $self->DBGetVNList(
- uid => $u->{id},
- order => $order,
- results => 50,
- page => $f->{p},
- $f->{t} >= 0 ? (
- status => $f->{t} ) : ()
- );
-
- $self->ResAddTpl(vnlist => {
- npage => $np,
- page => $f->{p},
- list => $list,
- order => [ $f->{s}, $f->{o} ],
- user => $u,
- status => $f->{t},
- });
-}
-
-
-sub VNVote {
- my $self = shift;
- my $id = shift;
-
- my $uid = $self->AuthInfo()->{id};
- return $self->ResDenied() if !$uid;
-
- my $f = $self->FormCheck(
- { name => 'v', required => 0, default => 0, enum => [ '-1','1'..'10'] }
- );
- return $self->ResNotFound() if !$f->{v};
-
-
- $self->DBDelVote($uid, $id) if $f->{v} == -1 || $self->DBGetVotes(uid => $uid, vid => $id)->[0]{vid};
- $self->DBAddVote($id, $uid, $f->{v}) if $f->{v} > 0;
-
- $self->ResRedirect('/v'.$id, 'temp');
-}
-
-
-sub RListMod {
- my $self = shift;
- my $rid = shift;
-
- my $f = $self->FormCheck(
- { name => 'd', required => 0 },
- { name => 'r', required => 0, enum => [ 0..$#$VNDB::RSTAT ] },
- { name => 'v', required => 0, enum => [ 0..$#$VNDB::VSTAT ] },
- );
-
- return $self->ResNotFound if $f->{_err};
- return $self->ResDenied if !$self->AuthInfo->{id};
-
- if($f->{d}) {
- $self->DBDelRList($self->AuthInfo->{id}, $rid);
- } else {
- $self->DBEditRList(
- uid => $self->AuthInfo->{id},
- rid => $rid,
- rstat => $f->{r},
- vstat => $f->{v},
- );
- }
-
- my $r = $self->ReqHeader('Referer');
- $r = $r && $r =~ /([vr][0-9]+)$/ ? $1 : 'r'.$rid;
- return $self->ResRedirect('/'.$r, 'temp');
-}
-
-
-sub RList {
- my $self = shift;
- my $uid = shift;
-
- my $u = $self->DBGetUser(uid => $uid)->[0];
- return $self->ResNotFound if !$uid || !$u || (($self->AuthInfo->{id}||0) != $uid && !($u->{flags} & $VNDB::UFLAGS->{list}));
-
- my $f = $self->FormCheck(
- { name => 's', required => 0, default => 'title', enum => [ qw|title vote| ] },
- { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] },
- { name => 'p', required => 0, template => 'int', default => 1 },
- { name => 'c', required => 0, default => 'all', enum => [ 'a'..'z', '0', 'all' ] },
- );
- return $self->ResNotFound if $f->{_err};
-
- if($self->ReqMethod eq 'POST') {
- return $self->ResDenied if $uid != $self->AuthInfo->{id};
- my $frm = $self->FormCheck(
- { name => 'vnlistchange', required => 1, enum => [ 'd', 'r0'..('r'.$#$VNDB::RSTAT), 'v0'..('v'.$#$VNDB::VSTAT) ] },
- { name => 'rsel', required => 1, multi => 1, template => 'int' },
- );
- if(!$frm->{_err} && @{$frm->{rsel}}) {
- $self->DBDelRList($uid, $frm->{rsel}) if $frm->{vnlistchange} eq 'd';
- $self->DBEditRList(
- uid => $uid,
- rid => $frm->{rsel},
- substr($frm->{vnlistchange},0,1).'stat', substr($frm->{vnlistchange},1)
- ) if $frm->{vnlistchange} ne 'd';
- }
- }
-
- my $order = $f->{s} . ($f->{o} eq 'a' ? ' ASC' : ' DESC');
- my($list, $np) = $self->DBGetRLists(
- uid => $uid,
- results => 50,
- page => $f->{p},
- order => $order,
- char => $f->{c} eq 'all' ? undef : $f->{c},
- );
-
- $self->ResAddTpl(rlist => {
- user => $u,
- list => $list,
- char => $f->{c},
- order => [ $f->{s}, $f->{o} ],
- page => $f->{p},
- npage => $np,
- });
-}
-
-
-sub WListMod {
- my $self = shift;
- my $vid = shift;
-
- my $f = $self->FormCheck(
- { name => 'w', required => 1, enum => [ -1..$#$VNDB::RSTAT ] },
- );
-
- return $self->ResNotFound if $f->{_err};
- return $self->ResDenied if !$self->AuthInfo->{id};
-
- if($f->{w} == -1) {
- $self->DBDelWishList($self->AuthInfo->{id}, [ $vid ]);
- } else {
- $self->DBEditWishList(
- uid => $self->AuthInfo->{id},
- vid => $vid,
- wstat => $f->{w}
- );
- }
-
- return $self->ResRedirect('/v'.$vid, 'temp');
-}
-
-
-sub WList {
- my $self = shift;
- my $uid = shift;
-
- my $u = $self->DBGetUser(uid => $uid)->[0];
- return $self->ResNotFound if !$uid || !$u || (($self->AuthInfo->{id}||0) != $uid && !($u->{flags} & $VNDB::UFLAGS->{list}));
-
- my $f = $self->FormCheck(
- { name => 's', required => 0, default => 'title', enum => [ qw|title wstat added| ] },
- { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] },
- { name => 'p', required => 0, template => 'int', default => 1 },
- );
- return $self->ResNotFound if $f->{_err};
-
- if($self->ReqMethod eq 'POST') {
- return $self->ResDenied if $uid != $self->AuthInfo->{id};
- my $frm = $self->FormCheck(
- { name => 'sel', required => 1, multi => 1, template => 'int' },
- { name => 'vnlistchange', required => 1, enum => [ 'd', '0'.."$#$VNDB::WLIST" ] },
- );
- if(!$frm->{_err} && @{$frm->{sel}}) {
- $self->DBDelWishList($uid, $frm->{sel}) if $frm->{vnlistchange} eq 'd';
- $self->DBEditWishList(
- uid => $uid,
- vid => $frm->{sel},
- wstat => $frm->{vnlistchange}
- ) if $frm->{vnlistchange} ne 'd';
- }
- }
-
- my $order = $f->{s} . ($f->{o} eq 'a' ? ' ASC' : ' DESC');
- $order .= ', title' . ($f->{o} eq 'a' ? ' ASC' : ' DESC') if $f->{s} eq 'wstat';
- my($list, $np) = $self->DBGetWishList(
- uid => $u->{id},
- order => $order,
- results => 50,
- what => 'vn',
- page => $f->{p},
- );
-
- $self->ResAddTpl(wlist => {
- npage => $np,
- page => $f->{p},
- list => $list,
- order => [ $f->{s}, $f->{o} ],
- user => $u,
- });
-}
-
-
-1;
diff --git a/lib/global.pl b/lib/global.pl
deleted file mode 100644
index dea30098..00000000
--- a/lib/global.pl
+++ /dev/null
@@ -1,687 +0,0 @@
-package VNDB;
-
-our @DBLOGIN = ( 'dbi:Pg:dbname=vndb', 'vndb', 'passwd' );
-our @SHMOPTS = ( -key => 'VNDB', -create => 'yes', -destroy => 'no', -mode => 0666);
-our $DEBUG = 1;
-our $VERSION = 'svn';
-our $COOKEY = '73jkS39Sal2)'; # encryption key for cookies (not to worry, this one is fake)
-
-our $MULTI = [
- RG => {},
- Image => {},
- Sitemap => {},
- #Anime => { user => '', pass => '' },
- Maintenance => {},
- #IRC => { user => 'Multi'},
-];
-
-our %VNDBopts = (
- CookieDomain => '.vndb.org',
- root_url => 'http://vndb.org',
- static_url => 'http://static.vndb.org',
- tplopts => {
- filename => 'main',
- searchdir => '/www/vndb/data/tpl',
- compiled => '/www/vndb/data/tplcompiled.pm',
- namespace => 'VNDB::Util::Template::tpl',
- pre_chomp => 1,
- post_chomp => 1,
- rm_newlines => 0,
- deep_reload => 1,
- },
- ranks => [
- [ [ qw| visitor loser user mod admin | ], [] ],
- {map{$_,1}qw| hist |}, # 0 - visitor (not logged in)
- {map{$_,1}qw| hist |}, # 1 - loser
- {map{$_,1}qw| hist board edit |}, # 2 - user
- {map{$_,1}qw| hist board boardmod edit mod lock del |}, # 3 - mod
- {map{$_,1}qw| hist board boardmod edit mod lock del usermod |}, # 4 - admin
- ],
- postsperpage => 25,
- imgpath => '/www/vndb/static/cv', # cover images
- sfpath => '/www/vndb/static/sf', # full-size screenshots
- stpath => '/www/vndb/static/st', # screenshot thumbnails
- docpath => '/www/vndb/data/docs',
-);
-$VNDBopts{ranks}[0][1] = { (map{$_,1} map { keys %{$VNDBopts{ranks}[$_]} } 1..5) };
-
-
-# I wonder why I even made this hash, almost everything is still hardcoded anyway...
-our $DTAGS = {
- an => 'Announcements', # 0 - usage restricted to boardmods
- db => 'VNDB Discussions', # 0
- v => 'Visual novels', # vid
- p => 'Producers', # pid
- u => 'Users', # uid
-};
-
-
-our $PLAT = {
- win => 'Windows',
- lin => 'Linux',
- mac => 'Mac OS',
- dvd => 'DVD Player',
- gba => 'Game Boy Advance',
- msx => 'MSX',
- nds => 'Nintendo DS',
- nes => 'Famicom',
- psp => 'Playstation Portable',
- ps1 => 'Playstation 1',
- ps2 => 'Playstation 2',
- ps3 => 'Playstation 3',
- drc => 'Dreamcast',
- sfc => 'Super Nintendo',
- wii => 'Nintendo Wii',
- xb3 => 'Xbox 360',
- oth => 'Other'
-};
-
-
-# NOTE: don't forget to update dyna.js
-our $MED = {
- cd => 'CD',
- dvd => 'DVD',
- gdr => 'GD-ROM',
- blr => 'Blu-Ray disk',
- in => 'Internet download',
- pa => 'Patch',
- otc => 'Other (console)',
-};
-
-
-our $PROT = {
- co => 'Company',
- in => 'Individual',
- ng => 'Amateur group',
-};
-
-
-our $RTYP = [
- 'Complete',
- 'Partial',
- 'Trial'
-];
-
-
-# Yes, this is the category list. No, changing something here may
-# not change it on the entire site - many things are still hardcoded
-our $CAT = {
- g => [ 'Gameplay', {
- aa => 'NVL', # 0..1
- ab => 'ADV', # 0..1
- ac => "Act\x{200B}ion", # Ugliest. Hack. Ever.
- rp => 'RPG',
- st => 'Strategy',
- si => 'Simulation',
- }, 2 ],
- p => [ 'Plot', { # 0..1
- li => 'Linear',
- br => 'Branching',
- }, 3 ],
- e => [ 'Elements', {
- ac => 'Action',
- co => 'Comedy',
- dr => 'Drama',
- fa => 'Fantasy',
- ho => 'Horror',
- my => 'Mystery',
- ro => 'Romance',
- sc => 'School Life',
- sf => 'SciFi',
- sj => 'Shoujo Ai',
- sn => 'Shounen Ai',
- }, 1 ],
- t => [ 'Time', { # 0..1
- fu => 'Future',
- pa => 'Past',
- pr => 'Present',
- }, 4 ],
- l => [ 'Place', { # 0..1
- ea => 'Earth',
- fa => "Fant\x{200B}asy world",
- sp => 'Space',
- }, 5 ],
- h => [ 'Protagonist', { # 0..1
- fa => 'Male',
- fe => "Fem\x{200B}ale",
- }, 6 ],
- s => [ 'Sexual content', {
- aa => 'Sexual content',
- be => 'Bestiality',
- in => 'Incest',
- lo => 'Lolicon',
- sh => 'Shotacon',
- ya => 'Yaoi',
- yu => 'Yuri',
- ra => 'Rape',
- }, 7 ],
-};
-
-
-our $RSTAT = [
- 'Unknown',
- 'Pending',
- 'Obtained', # hardcoded
- 'On loan',
- 'Deleted',
-];
-our $VSTAT = [
- 'Unknown',
- 'Playing',
- 'Finished', # hardcoded
- 'Stalled',
- 'Dropped',
-];
-
-our $WSTAT = [
- 'High',
- 'Medium',
- 'Low',
- 'Blacklist',
-];
-
-
-# OLD
-our $LSTAT = [
- 'Wishlist',
- 'Blacklist',
- 'Playing',
- 'Finished',
- 'Stalled',
- 'Dropped',
- 'Other', # XXX: hardcoded at 6
-];
-
-
-our $VREL = [
- 'Sequel',
- 'Prequel', # 1
- 'Same setting',
- 'Alternative setting',
- 'Alternative version',
- 'Same characters',
- 'Side story',
- 'Parent story',# 7
- 'Summary',
- 'Full story', # 9
- 'Other',
-];
-# these reverse relations need a [relation]-1
-our $VRELW = {map{$_=>1}qw| 1 7 9 |};
-
-
-# users.flags
-our $UFLAGS = {
- list => 4,
- nsfw => 8,
-};
-
-
-our $VNLEN = [
- [ 'Unkown', '', '' ],
- [ 'Very short', '< 2 hours', 'OMGWTFOTL, A Dream of Summer' ],
- [ 'Short', '2 - 10 hours', 'Narcissu, Planetarian' ],
- [ 'Medium', '10 - 30 hours', 'Kana: Little Sister' ],
- [ 'Long', '30 - 50 hours', 'Tsukihime' ],
- [ 'Very long', '> 50 hours', 'Clannad' ],
-];
-
-
-our $VRAGES = {
- -1 => 'Unknown',
- 0 => 'All ages',
- map { $_ => $_.'+' } 6..18
-};
-
-
-our $ANITYPE = [
- # VNDB AniDB
- [ 'unknown', 'unknown', ],
- [ 'TV', 'TV Series' ],
- [ 'OVA', 'OVA' ],
- [ 'Movie', 'Movie' ],
- [ 'unknown', 'Other' ],
- [ 'unknown', 'Web' ],
- [ 'TV Special', 'TV Special' ],
- [ 'unknown', 'Music Video' ],
-];
-# AniDB defines:
-# id="1", name="unknown
-# id="2", name="TV Series
-# id="3", name="OVA
-# id="4", name="Movie
-# id="5", name="Other
-# id="6", name="Web
-# id="7", name="TV Special
-# id="8", name="Music Video
-
-
-
-
-
-our $LANG = {
-# 'aa' => q|Afar|,
-# 'ab' => q|Abkhazian|,
-# 'ace' => q|Achinese|,
-# 'ach' => q|Acoli|,
-# 'ada' => q|Adangme|,
-# 'ady' => q|Adyghe|,
-# 'ae' => q|Avestan|,
-# 'af' => q|Afrikaans|,
-# 'afh' => q|Afrihili|,
-# 'ak' => q|Akan|,
-# 'akk' => q|Akkadian|,
-# 'ale' => q|Aleut|,
-# 'alg' => q|Algonquian languages|,
-# 'am' => q|Amharic|,
-# 'an' => q|Aragonese|,
-# 'apa' => q|Apache languages|,
-# 'ar' => q|Arabic|,
-# 'arc' => q|Aramaic|,
-# 'arn' => q|Araucanian|,
-# 'arp' => q|Arapaho|,
-# 'arw' => q|Arawak|,
-# 'as' => q|Assamese|,
-# 'ast' => q|Asturian|,
-# 'ath' => q|Athapascan languages|,
-# 'aus' => q|Australian languages|,
-# 'av' => q|Avaric|,
-# 'awa' => q|Awadhi|,
-# 'ay' => q|Aymara|,
-# 'az' => q|Azerbaijani|,
-# 'ba' => q|Bashkir|,
-# 'bad' => q|Banda|,
-# 'bai' => q|Bamileke languages|,
-# 'bal' => q|Baluchi|,
-# 'ban' => q|Balinese|,
-# 'bas' => q|Basa|,
-# 'be' => q|Belarusian|,
-# 'bej' => q|Beja|,
-# 'bem' => q|Bemba|,
-# 'bg' => q|Bulgarian|,
-# 'bh' => q|Bihari|,
-# 'bho' => q|Bhojpuri|,
-# 'bi' => q|Bislama|,
-# 'bik' => q|Bikol|,
-# 'bin' => q|Bini|,
-# 'bla' => q|Siksika|,
-# 'bm' => q|Bambara|,
-# 'bn' => q|Bengali|,
-# 'bo' => q|Tibetan|,
-# 'br' => q|Breton|,
-# 'bra' => q|Braj|,
-# 'bs' => q|Bosnian|,
-# 'btk' => q|Batak (Indonesia)|,
-# 'bua' => q|Buriat|,
-# 'bug' => q|Buginese|,
-# 'ca' => q|Catalan|,
-# 'cad' => q|Caddo|,
-# 'car' => q|Carib|,
-# 'ce' => q|Chechen|,
-# 'ceb' => q|Cebuano|,
-# 'ch' => q|Chamorro|,
-# 'chb' => q|Chibcha|,
-# 'chg' => q|Chagatai|,
-# 'chk' => q|Chuukese|,
-# 'chm' => q|Mari|,
-# 'chn' => q|Chinook Jargon|,
-# 'cho' => q|Choctaw|,
-# 'chp' => q|Chipewyan|,
-# 'chr' => q|Cherokee|,
-# 'chy' => q|Cheyenne|,
-# 'cmc' => q|Chamic languages|,
-# 'co' => q|Corsican|,
-# 'cop' => q|Coptic|,
-# 'cr' => q|Cree|,
-# 'crh' => q|Crimean Turkish|,
- 'cs' => q|Czech|,
-# 'csb' => q|Kashubian|,
-# 'cu' => q|Church Slavic|,
-# 'cv' => q|Chuvash|,
-# 'cy' => q|Welsh|,
- 'da' => q|Danish|,
-# 'dak' => q|Dakota|,
-# 'dar' => q|Dargwa|,
-# 'day' => q|Dayak|,
- 'de' => q|German|,
-# 'del' => q|Delaware|,
-# 'dgr' => q|Dogrib|,
-# 'din' => q|Dinka|,
-# 'doi' => q|Dogri|,
-# 'dua' => q|Duala|,
-# 'dv' => q|Divehi|,
-# 'dyu' => q|Dyula|,
-# 'dz' => q|Dzongkha|,
-# 'ee' => q|Ewe|,
-# 'efi' => q|Efik|,
-# 'eka' => q|Ekajuk|,
-# 'el' => q|Modern Greek|,
-# 'elx' => q|Elamite|,
- 'en' => q|English|,
-# 'eo' => q|Esperanto|,
- 'es' => q|Spanish|,
-# 'et' => q|Estonian|,
-# 'eu' => q|Basque|,
-# 'ewo' => q|Ewondo|,
-# 'fa' => q|Persian|,
-# 'fan' => q|Fang|,
-# 'fat' => q|Fanti|,
-# 'ff' => q|Fulah|,
- 'fi' => q|Finnish|,
-# 'fj' => q|Fijian|,
-# 'fo' => q|Faroese|,
-# 'fon' => q|Fon|,
- 'fr' => q|French|,
-# 'fur' => q|Friulian|,
-# 'fy' => q|Frisian|,
-# 'ga' => q|Irish|,
-# 'gaa' => q|Ga|,
-# 'gay' => q|Gayo|,
-# 'gba' => q|Gbaya|,
-# 'gd' => q|Scots Gaelic|,
-# 'gez' => q|Geez|,
-# 'gil' => q|Gilbertese|,
-# 'gl' => q|Gallegan|,
-# 'gn' => q|Guarani|,
-# 'gon' => q|Gondi|,
-# 'gor' => q|Gorontalo|,
-# 'got' => q|Gothic|,
-# 'grb' => q|Grebo|,
-# 'grc' => q|Ancient Greek|,
-# 'gu' => q|Gujarati|,
-# 'gv' => q|Manx|,
-# 'gwi' => q|Gwich'in|,
-# 'ha' => q|Hausa|,
-# 'hai' => q|Haida|,
-# 'haw' => q|Hawaiian|,
-# 'he' => q|Hebrew|,
-# 'hi' => q|Hindi|,
-# 'hil' => q|Hiligaynon|,
-# 'him' => q|Himachali|,
-# 'hit' => q|Hittite|,
-# 'hmn' => q|Hmong|,
-# 'ho' => q|Hiri Motu|,
-# 'hr' => q|Croatian|,
-# 'ht' => q|Haitian|,
-# 'hu' => q|Hungarian|,
-# 'hup' => q|Hupa|,
-# 'hy' => q|Armenian|,
-# 'hz' => q|Herero|,
-# 'i-ami' => q|Ami|,
-# 'i-bnn' => q|Bunun|,
-# 'i-klingon' => q|Klingon|,
-# 'i-mingo' => q|Mingo|,
-# 'i-pwn' => q|Paiwan|,
-# 'i-tao' => q|Tao|,
-# 'i-tay' => q|Tayal|,
-# 'i-tsu' => q|Tsou|,
-# 'iba' => q|Iban|,
-# 'id' => q|Indonesian|,
-# 'ie' => q|Interlingue|,
-# 'ig' => q|Igbo|,
-# 'ii' => q|Sichuan Yi|,
-# 'ijo' => q|Ijo|,
-# 'ik' => q|Inupiaq|,
-# 'ilo' => q|Iloko|,
-# 'inh' => q|Ingush|,
-# 'io' => q|Ido|,
-# 'iro' => q|Iroquoian languages|,
-# 'is' => q|Icelandic|,
- 'it' => q|Italian|,
-# 'iu' => q|Inuktitut|,
- 'ja' => q|Japanese|,
-# 'jpr' => q|Judeo-Persian|,
-# 'jrb' => q|Judeo-Arabic|,
-# 'jv' => q|Javanese|,
-# 'ka' => q|Georgian|,
-# 'kaa' => q|Kara-Kalpak|,
-# 'kab' => q|Kabyle|,
-# 'kac' => q|Kachin|,
-# 'kam' => q|Kamba|,
-# 'kar' => q|Karen|,
-# 'kaw' => q|Kawi|,
-# 'kbd' => q|Kabardian|,
-# 'kg' => q|Kongo|,
-# 'kha' => q|Khasi|,
-# 'kho' => q|Khotanese|,
-# 'ki' => q|Kikuyu|,
-# 'kj' => q|Kuanyama|,
-# 'kk' => q|Kazakh|,
-# 'kl' => q|Kalaallisut|,
-# 'km' => q|Khmer|,
-# 'kmb' => q|Kimbundu|,
-# 'kn' => q|Kannada|,
- 'ko' => q|Korean|,
-# 'kok' => q|Konkani|,
-# 'kos' => q|Kosraean|,
-# 'kpe' => q|Kpelle|,
-# 'kr' => q|Kanuri|,
-# 'krc' => q|Karachay-Balkar|,
-# 'kro' => q|Kru|,
-# 'kru' => q|Kurukh|,
-# 'ks' => q|Kashmiri|,
-# 'ku' => q|Kurdish|,
-# 'kum' => q|Kumyk|,
-# 'kut' => q|Kutenai|,
-# 'kv' => q|Komi|,
-# 'kw' => q|Cornish|,
-# 'ky' => q|Kirghiz|,
-# 'la' => q|Latin|,
-# 'lad' => q|Ladino|,
-# 'lah' => q|Lahnda|,
-# 'lam' => q|Lamba|,
-# '#lb' => q|Letzeburgesch|,
-# 'lez' => q|Lezghian|,
-# 'lg' => q|Ganda|,
-# 'li' => q|Limburgish|,
-# 'ln' => q|Lingala|,
-# 'lo' => q|Lao|,
-# 'lol' => q|Mongo|,
-# 'loz' => q|Lozi|,
-# 'lt' => q|Lithuanian|,
-# 'lu' => q|Luba-Katanga|,
-# 'lua' => q|Luba-Lulua|,
-# 'lui' => q|Luiseno|,
-# 'lun' => q|Lunda|,
-# 'luo' => q|Luo (Kenya and Tanzania)|,
-# 'lus' => q|Lushai|,
-# 'lv' => q|Latvian|,
-# 'mad' => q|Madurese|,
-# 'mag' => q|Magahi|,
-# 'mai' => q|Maithili|,
-# 'mak' => q|Makasar|,
-# 'man' => q|Mandingo|,
-# 'mas' => q|Masai|,
-# 'mdf' => q|Moksha|,
-# 'mdr' => q|Mandar|,
-# 'men' => q|Mende|,
-# 'mg' => q|Malagasy|,
-# 'mh' => q|Marshall|,
-# 'mi' => q|Maori|,
-# 'mic' => q|Micmac|,
-# 'min' => q|Minangkabau|,
-# 'mk' => q|Macedonian|,
-# 'ml' => q|Malayalam|,
-# 'mn' => q|Mongolian|,
-# 'mnc' => q|Manchu|,
-# 'mni' => q|Manipuri|,
-# 'mno' => q|Manobo languages|,
-# 'mo' => q|Moldavian|,
-# 'moh' => q|Mohawk|,
-# 'mos' => q|Mossi|,
-# 'mr' => q|Marathi|,
-# 'ms' => q|Malay|,
-# 'mt' => q|Maltese|,
-# 'mul' => q|Multiple languages|,
-# 'mun' => q|Munda languages|,
-# 'mus' => q|Creek|,
-# 'mwr' => q|Marwari|,
-# 'my' => q|Burmese|,
-# 'myn' => q|Mayan languages|,
-# 'myv' => q|Erzya|,
-# 'na' => q|Nauru|,
-# 'nah' => q|Nahuatl|,
-# 'nap' => q|Neapolitan|,
-# 'nb' => q|Norwegian Bokmal|,
-# 'nd' => q|North Ndebele|,
-# 'ne' => q|Nepali|,
-# 'new' => q|Newari|,
-# 'ng' => q|Ndonga|,
-# 'nia' => q|Nias|,
-# 'niu' => q|Niuean|,
- 'nl' => q|Dutch|,
- 'no' => q|Norwegian|,
-# 'nog' => q|Nogai|,
-# 'non' => q|Old Norse|,
-# 'nr' => q|South Ndebele|,
-# 'nso' => q|Northern Sotho|,
-# 'nub' => q|Nubian languages|,
-# 'nv' => q|Navajo|,
-# 'ny' => q|Chichewa|,
-# 'nym' => q|Nyamwezi|,
-# 'nyn' => q|Nyankole|,
-# 'nyo' => q|Nyoro|,
-# 'nzi' => q|Nzima|,
-# 'oj' => q|Ojibwa|,
-# 'om' => q|Oromo|,
-# 'or' => q|Oriya|,
-# 'os' => q|Ossetian; Ossetic|,
-# 'osa' => q|Osage|,
-# 'oto' => q|Otomian languages|,
-# 'pa' => q|Panjabi|,
-# 'pag' => q|Pangasinan|,
-# 'pal' => q|Pahlavi|,
-# 'pam' => q|Pampanga|,
-# 'pap' => q|Papiamento|,
-# 'pau' => q|Palauan|,
-# 'phn' => q|Phoenician|,
-# 'pi' => q|Pali|,
- 'pl' => q|Polish|,
-# 'pon' => q|Pohnpeian|,
-# 'pra' => q|Prakrit languages|,
-# 'ps' => q|Pushto|,
- 'pt' => q|Portuguese|,
-# 'pt-br' => q|Brazilian Portuguese|,
-# 'pt-pt' => q|Portugal Portuguese|,
-# 'qu' => q|Quechua|,
-# 'raj' => q|Rajasthani|,
-# 'rap' => q|Rapanui|,
-# 'rar' => q|Rarotongan|,
-# 'rm' => q|Raeto-Romance|,
-# 'rn' => q|Rundi|,
-# 'ro' => q|Romanian|,
-# 'rom' => q|Romany|,
- 'ru' => q|Russian|,
-# 'rw' => q|Kinyarwanda|,
-# 'sa' => q|Sanskrit|,
-# 'sad' => q|Sandawe|,
-# 'sah' => q|Yakut|,
-# 'sal' => q|Salishan languages|,
-# 'sam' => q|Samaritan Aramaic|,
-# 'sas' => q|Sasak|,
-# 'sat' => q|Santali|,
-# 'sc' => q|Sardinian|,
-# 'sco' => q|Scots|,
-# 'sd' => q|Sindhi|,
-# 'se' => q|Northern Sami|,
-# 'sel' => q|Selkup|,
-# 'sg' => q|Sango|,
-# 'shn' => q|Shan|,
-# 'si' => q|Sinhalese|,
-# 'sid' => q|Sidamo|,
-# 'sio' => q|Siouan languages|,
-# 'sk' => q|Slovak|,
-# 'sl' => q|Slovenian|,
-# 'sm' => q|Samoan|,
-# 'sma' => q|Southern Sami|,
-# 'smj' => q|Lule Sami|,
-# 'smn' => q|Inari Sami|,
-# 'sms' => q|Skolt Sami|,
-# 'sn' => q|Shona|,
-# 'snk' => q|Soninke|,
-# 'so' => q|Somali|,
-# 'sog' => q|Sogdian|,
-# 'son' => q|Songhai|,
-# 'sq' => q|Albanian|,
-# 'sr' => q|Serbian|,
-# 'srr' => q|Serer|,
-# 'ss' => q|Swati|,
-# 'st' => q|Southern Sotho|,
-# 'su' => q|Sundanese|,
-# 'suk' => q|Sukuma|,
-# 'sus' => q|Susu|,
-# 'sux' => q|Sumerian|,
- 'sv' => q|Swedish|,
-# 'sw' => q|Swahili|,
-# 'syr' => q|Syriac|,
-# 'ta' => q|Tamil|,
-# 'te' => q|Telugu|,
-# 'tem' => q|Timne|,
-# 'ter' => q|Tereno|,
-# 'tet' => q|Tetum|,
-# 'tg' => q|Tajik|,
-# 'th' => q|Thai|,
-# 'ti' => q|Tigrinya|,
-# 'tig' => q|Tigre|,
-# 'tiv' => q|Tiv|,
-# 'tk' => q|Turkmen|,
-# 'tkl' => q|Tokelau|,
-# 'tl' => q|Tagalog|,
-# 'tli' => q|Tlingit|,
-# 'tmh' => q|Tamashek|,
-# 'tn' => q|Tswana|,
-# 'to' => q|Tonga (Tonga Islands)|,
-# 'tog' => q|Tonga (Nyasa)|,
-# 'tpi' => q|Tok Pisin|,
- 'tr' => q|Turkish|,
-# 'ts' => q|Tsonga|,
-# 'tsi' => q|Tsimshian|,
-# 'tt' => q|Tatar|,
-# 'tum' => q|Tumbuka|,
-# 'tup' => q|Tupi languages|,
-# 'tvl' => q|Tuvalu|,
-# 'tw' => q|Twi|,
-# 'ty' => q|Tahitian|,
-# 'tyv' => q|Tuvinian|,
-# 'udm' => q|Udmurt|,
-# 'ug' => q|Uighur|,
-# 'uga' => q|Ugaritic|,
-# 'uk' => q|Ukrainian|,
-# 'umb' => q|Umbundu|,
-# 'ur' => q|Urdu|,
-# 'uz' => q|Uzbek|,
-# 'vai' => q|Vai|,
-# 've' => q|Venda|,
-# 'vi' => q|Vietnamese|,
-# 'vo' => q|Volapuk|,
-# 'vot' => q|Votic|,
-# 'wa' => q|Walloon|,
-# 'wak' => q|Wakashan languages|,
-# 'wal' => q|Walamo|,
-# 'war' => q|Waray|,
-# 'was' => q|Washo|,
-# 'wen' => q|Sorbian languages|,
-# 'wo' => q|Wolof|,
-# 'xal' => q|Kalmyk|,
-# 'xh' => q|Xhosa|,
-# 'yao' => q|Yao|,
-# 'yap' => q|Yapese|,
-# 'yi' => q|Yiddish|,
-# 'yo' => q|Yoruba|,
-# 'ypk' => q|Yupik languages|,
-# 'za' => q|Zhuang|,
-# 'zap' => q|Zapotec|,
-# 'zen' => q|Zenaga|,
- 'zh' => q|Chinese|,
-# 'znd' => q|Zande|,
-# 'zu' => q|Zulu|,
-# 'zun' => q|Zuni|,
-};
-
-
-# override config vars
-require '/www/vndb/data/config.pl' if -e '/www/vndb/data/config.pl';
-
-
-1;
-
diff --git a/static/files/blank.css b/static/files/blank.css
deleted file mode 100644
index e69de29b..00000000
--- a/static/files/blank.css
+++ /dev/null
diff --git a/static/files/def.js b/static/files/def.js
deleted file mode 100644
index 4928cb84..00000000
--- a/static/files/def.js
+++ /dev/null
@@ -1,479 +0,0 @@
-
-
-/* G L O B A L S T U F F */
-
-function x(y){return document.getElementById(y)}
-function cl(o,f){if(x(o))x(o).onclick=f}
-function DOMLoad(y){var d=0;var f=function(){if(d++)return;y()};
-if(document.addEventListener)document.addEventListener("DOMCont"
-+"entLoaded",f,false);document.write("<script id=_ie defer src="
-+"javascript:void(0)><\/script>");document.getElementById('_ie')
-.onreadystatechange=function(){if(this.readyState=="complete")f()
-};if(/WebKit/i.test(navigator.userAgent))var t=setInterval(
-function(){if(/loaded|complete/.test(document.readyState)){
-clearInterval(t);f()}},10);window.onload=f;}
-
-
-
-
-/* F O R M S U B S */
-
-var formsubs = [];
-function formhid() {
- var i;
- var j;
- var l = document.forms[1].getElementsByTagName('a');
- for(i=0; i<l.length; i++)
- if(l[i].className.indexOf('s_') != -1) {
- formsubs[ l[i].className.substr(l[i].className.indexOf('s_')+2) ] = 0;
- l[i].onclick = function() {
- formtoggle(this.className.substr(this.className.indexOf('s_')+2));
- return false;
- };
- }
-
- if(x('_hid') && x('_hid').value.length > 1) {
- l = x('_hid').value.split(/,/);
- for(i in formsubs) {
- var inz=0;
- for(j=0; j<l.length; j++)
- if(l[j] == i)
- inz = 1;
- if(!inz)
- formsubs[i] = !formsubs[i];
- }
- }
- if(x('screenshots') && !formsubs['scr'])
- scrLoad();
-}
-function formtoggle(n) {
- formsubs[n] = !formsubs[n];
- if(x('screenshots') && !formsubs['scr'] && !x('scrTbl'))
- scrLoad();
-
- var i;
- var l = document.forms[1].getElementsByTagName('a');
- for(i=0; i<l.length; i++)
- if(l[i].className.indexOf('s_'+n) != -1)
- l[i].innerHTML = (formsubs[n] ? '&#9656;' : '&#9662;') + l[i].innerHTML.substr(1);
-
- l = document.forms[1].getElementsByTagName('li');
- for(i=0; i<l.length; i++)
- if(l[i].className.indexOf('sf_'+n) != -1) {
- if(formsubs[n])
- l[i].className += ' formhid';
- else
- l[i].className = l[i].className.replace(/formhid/g, '');
- }
-
- if(x('_hid')) {
- l = [];
- for(i in formsubs)
- if(!formsubs[i])
- l[l.length] = i;
- x('_hid').value = l.toString();
- }
-}
-
-
-
-
-/* D R O P D O W N M E N U S */
-
-var ddx;var ddy;var dds=null;
-function dropDown(e) {
- e = e || window.event;
- var tg = e.target || e.srcElement;
- while(tg && (tg.nodeType == 3 || tg.nodeName.toLowerCase() != 'a'))
- tg = tg.parentNode;
-
- if(tg && tg.rel)
- tg.rel = tg.rel.replace(/ *nofollow */,"");
- if(!dds && (!tg || !tg.rel || tg.className.indexOf('dropdown') < 0))
- return;
-
- if(!dds) {
- var obj=tg;
- ddx = ddy = 0;
- do {
- ddx += obj.offsetLeft;
- ddy += obj.offsetTop;
- } while(obj = obj.offsetParent);
- if(tg.className.indexOf('above') >= 0) {
- ddx += 30;
- ddy -= x(tg.rel).offsetHeight - 20;
- }
- else
- ddy += 16;
- obj = x(tg.rel);
- obj.style.left = ddx+'px';
- obj.style.top = ddy+'px';
- dds = tg;
- }
-
- if(dds) {
- var mouseX = e.pageX || (e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft);
- var mouseY = e.pageY || (e.clientY + document.body.scrollTop + document.documentElement.scrollTop);
- var obj = x(dds.rel);
- if((mouseX < ddx-25 || mouseX > ddx+obj.offsetWidth+5 || mouseY < ddy-20 || mouseY > ddy + obj.offsetHeight)
- || (tg && tg.className.indexOf('dropdown') >= 0 && tg != dds)) {
- obj.style.left = '-500px';
- dds = null;
- }
- }
-}
-
-
-
-
-/* A D V A N C E D S E A R C H */
-
-var ad_cats = {};
-var ad_lang = {};
-var ad_plat = {};
-
-function adsearch() {
- x('vsearch').onsubmit = ad_dosearch;
- x('vsearch_sub').onclick = ad_dosearch;
- x('q').onkeyup = ad_update;
-
- x('adsearchclick').onclick = function() {
- if(x('adsearch').style.display == 'none') {
- x('adsearch').style.display = 'block';
- x('adsearchclick').innerHTML = '&#9662; advanced options';
- } else {
- x('adsearch').style.display = 'none';
- x('adsearchclick').innerHTML = '&#9656; advanced options';
- }
- };
-
- var l = x('cat').getElementsByTagName('li');
- for(i=0;i<l.length;i++)
- if(l[i].id.indexOf('cat_') != -1) {
- ad_cats[ l[i].id.substr(l[i].id.indexOf('cat_')+4, 3) ] = l[i].innerHTML.substring(0, l[i].innerHTML.indexOf('(')-1).toLowerCase();
- l[i].onclick = function () {
- try { document.selection.empty() } catch(e) { try { window.getSelection().collapse(this, 0) } catch(e) {} };
- ad_update(1, this.innerHTML.substring(0, this.innerHTML.indexOf('(')-1));
- };
- }
-
- l = x('lfilter').getElementsByTagName('input');
- for(i=0;i<l.length;i++) {
- ad_lang[ l[i].name.substring(5) ] = l[i].value.toLowerCase();
- l[i].onclick = function() { ad_update(0, this.value) };
- }
-
- l = x('pfilter').getElementsByTagName('input');
- for(i=0;i<l.length;i++) {
- ad_plat[ l[i].name.substring(5) ] = l[i].value.toLowerCase();
- l[i].onclick = function() { ad_update(0, this.value) };
- }
-
- ad_update();
-}
-
-function ad_update(add, term) {
- var q = x('q').value;
- var i;
-
- if(add == 0 || add === 1) {
- var qn = q;
- if(!add)
- eval('qn = qn.replace(/'+term+'/gi, "")');
- else {
- eval('qn = qn.replace(/(^|[^-])'+term+'/gi, "$1-'+term+'")');
- if(qn == q)
- eval('qn = qn.replace(/-'+term+'/gi, "")');
- }
- if(qn == q)
- q += ' '+term;
- else
- q = qn;
-
- q = q.replace(/^ +/, "");
- q = q.replace(/ +$/, "");
- q = q.replace(/ +/g, " ");
-
- x('q').value = q;
- }
-
- q = q.toLowerCase();
- for (i in ad_lang)
- x('lang_'+i).checked = q.indexOf(ad_lang[i]) >= 0 || q.indexOf('l:'+i) >= 0 ? true : false;
- for (i in ad_plat)
- x('plat_'+i).checked = q.indexOf(ad_plat[i]) >= 0 || q.indexOf('p:'+i) >= 0 ? true : false;
- for (i in ad_cats)
- x('cat_'+i).className = q.indexOf('-'+ad_cats[i]) >= 0 || q.indexOf('-c:'+i) >= 0 ? 'exc' : q.indexOf(ad_cats[i]) >= 0 || q.indexOf('c:'+i) >= 0 ? 'inc' : '';
-}
-
-function ad_dosearch() {
- location.href = '?q='+x('q').value;
- return false;
-}
-
-
-
-/* S C R E E N S H O T S */
-
-var scrNsfwEnabled = null;
-function scrNsfwHid() {
- var l=x('screenshots').getElementsByTagName('a');
- var i;
- if(scrNsfwEnabled == null)
- scrNsfwEnabled = 0;
- else {
- for(i=0;i<l.length;i++)
- if(l[i].className.indexOf('scr_nsfw')>=0)
- l[i].style.display = scrNsfwEnabled ? 'block' : 'none';
- scrNsfwEnabled = scrNsfwEnabled ? 0 : 1;
- }
-
- var t=0;var n=0;
- for(i=0;i<l.length;i++) {
- if(l[i].className.indexOf('shot')<0)
- continue;
- t++;
- if(l[i].className.indexOf('scr_nsfw')>=0)
- n++;
- if(l[i].style.display == 'none')
- scrNsfwEnabled = 1;
- }
- x('scrNsfwHid').innerHTML = 'Showing '+(t-(scrNsfwEnabled?n:0))+' out of '+t+' items. '
- +(scrNsfwEnabled ? '<a href="javascript:scrNsfwHid()">Show</a> / hide' : 'Show / <a href="javascript:scrNsfwHid()">hide</a>')
- +' nsfw.';
-}
-function scrView(what) {
- what = what && what.rel ? what : this;
- var u=what.href;
- var r=what.rel;
- d = x('scrView');
-
- // fix prev/next links (if any)
- var ol=x('screenshots').getElementsByTagName('a');
- if(ol.length > 0) {
- var l=[];
- for(i=0;i<ol.length;i++)
- if(ol[i].className.indexOf('shot')>=0 && (!scrNsfwEnabled || ol[i].className.indexOf('scr_nsfw')<0))
- l[l.length] = ol[i];
-
- ol=0;
- for(i=0;i<l.length;i++)
- if(l[i].href == u) {
- ol=1;
- x('scrnext').style.visibility = l[i+1] ? 'visible' : 'hidden';
- x('scrnext').href = l[i+1] ? l[i+1].href : '#';
- x('scrnext').rel = l[i+1] ? l[i+1].rel : '';
- x('scrprev').style.visibility = l[i-1] ? 'visible' : 'hidden';
- x('scrprev').href = l[i-1] ? l[i-1].href : '#';
- x('scrprev').rel = l[i-1] ? l[i-1].rel : '';
- }
- } else
- ol=0;
- if(!ol)
- x('scrnext').style.visibility = x('scrprev').style.visibility = 'hidden';
-
- // calculate dimensions
- var w = Math.floor(r.split('x')[0]);
- var h = Math.floor(r.split('x')[1]);
- var ww = typeof(window.innerWidth) == 'number' ? window.innerWidth : document.documentElement.clientWidth;
- var wh = typeof(window.innerHeight) == 'number' ? window.innerHeight : document.documentElement.clientHeight;
- var st = typeof(window.pageYOffset) == 'number' ? window.pageYOffset : document.body && document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
- if(w+100 > ww || h+70 > wh) {
- x('scrfull').href = u;
- x('scrfull').innerHTML = w+'x'+h;
- x('scrfull').style.visibility = 'visible';
- if(w/h > ww/wh) { // width++
- h *= (ww-100)/w;
- w = ww-100;
- } else { // height++
- w *= (wh-70)/h;
- h = wh-70;
- }
- } else
- x('scrfull').style.visibility = 'hidden';
- var dw = w;
- var dh = h+20;
- dw = dw < 200 ? 200 : dw;
-
- // update document
- d.style.display = 'block';
- x('scrimg').innerHTML = '<img src="'+u+'" onclick="scrClose()" onload="document.getElementById(\'scrimgload\').style.top=\'-400px\'" style="width: '+w+'px; height: '+h+'px" />';
- d.style.width = dw+'px';
- d.style.height = dh+'px';
- d.style.left = ((ww - dw) / 2 - 10)+'px';
- d.style.top = ((wh - dh) / 2 + st - 20)+'px';
- x('scrimgload').style.left = ((ww - 100) / 2 - 10)+'px';
- x('scrimgload').style.top = ((wh - 20) / 2 + st)+'px';
- return false;
-}
-function scrClose() {
- x('scrView').style.display = 'none';
- x('scrView').style.top = '-5000px';
- x('scrimg').innerHTML = '';
- return false;
-}
-
-
-
-
-/* O N L O A D */
-
-DOMLoad(function() {
- var i;
-
- // search box
- i = x('searchfield');
- i.onfocus = function () {
- if(this.value == 'search') {
- this.value = '';
- this.style.color = '#000'; } };
- i.onblur = function () {
- if(this.value.length < 1) {
- this.value = 'search';
- this.style.color = '#999';} };
-
- // advanced search
- if(x('adsearch'))
- adsearch();
-
- // userdel
- cl('userdel', function() { return confirm("Completely remove this account from the site?") });
-
- // vote warnings
- cl('dovote_10', function() { return confirm(
- "You are about to give this visual novel a 10 out of 10. This is a rather extreme rating, "
- +"meaning this is one of the best visual novels you've ever played and it's unlikely "
- +"that any other game could ever be better than this one.\n"
- +"It is generally a bad idea to have more than three games in your vote list with this rating, choose carefully!") });
- cl('dovote_1', function() { return confirm(
- "You are about to give this visual novel a 1 out of 10. This is a rather extreme rating, "
- +"meaning this game has absolutely nothing to offer, and that it's the worst game you have ever played.\n"
- +"Are you really sure this visual novel matches that description?") });
-
- // NSFW
- cl('nsfw', function () {
- this.src = this.className;
- this.id = '';
- });
-
- // rlists
- i = x('rli');
- if(i) {
- var l=i.getElementsByTagName('td');
- for(i=0;i<l.length;i++)
- if(l[i].className.indexOf('relhid')>=0)
- l[i].onclick = function() {
- var id=this.id.substr(2);
- var j=0;var o;
- var op=x('rr'+id+'-1').style.display == 'none' ? 1 : 0;
- while((o=x('rr'+id+'-'+(++j))) != null)
- o.style.display = op ? '' : 'none';
- x('rhd'+id).innerHTML = op ? '&#9662;' : '&#9656;';
- };
- var l=x('rli').getElementsByTagName('tr');
- for(i=0;i<l.length;i++)
- if(l[i].className.indexOf('relhid')>=0)
- l[i].style.display = 'none';
- var allhid=1;
- cl('relhidpar', function() {
- allhid=!allhid;
- l=x('rli').getElementsByTagName('tr');
- for(i=0;i<l.length;i++)
- if(l[i].className.indexOf('relhid')>=0)
- l[i].style.display = allhid ? 'none' : '';
- l=x('rli').getElementsByTagName('b');
- for(i=0;i<l.length;i++)
- if(l[i].id.substr(0,3) == 'rhd')
- l[i].innerHTML = !allhid ? '&#9662;' : '&#9656;';
- x('relhidparb').innerHTML = !allhid ? '&#9662;' : '&#9656;';
- });
- }
-
- // mass-change rlist or wlist status
- if(x('vnlistchange')) {
- x('vnlistchange').onchange = function() {
- var val = this.options[this.selectedIndex].value;
- if(val == 'n')
- return;
- var l = (x('rli')||x('twl')).getElementsByTagName('input');
- var y; var ch=0;
- for(y=0;y<l.length;y++)
- if(l[y].type == 'checkbox' && l[y].checked)
- ch++;
- if(!ch)
- return alert('Nothing selected...');
- if(val == 'd' && !confirm('Are you sure you want to remove the selected items from your list?'))
- return;
- document.forms[1].submit();
- }
- }
-
- // screenshots
- if(x('scrNsfwHid'))
- scrNsfwHid();
- if(x('screenshots')) {
- l=x('screenshots').getElementsByTagName('a');
- for(i=0;i<l.length;i++)
- l[i].onclick=scrView;
- var d = document.createElement('div');
- d.id = 'scrView';
- d.innerHTML = '<b id="scrimg"></b><br />'
- +'<a href="#" id="scrfull">&nbsp;</a>'
- +'<a href="#" onclick="return scrClose()" id="scrclose">close</a>'
- +'<a href="#" onclick="return scrView(this)" id="scrprev">&lt;- previous</a>'
- +'<a href="#" onclick="return scrView(this)" id="scrnext">next -&gt;</a>';
- document.body.appendChild(d);
- d = document.createElement('b');
- d.id = 'scrimgload';
- d.innerHTML = 'Loading...';
- document.body.appendChild(d);
- }
-
- // spam protection on all forms
- if(document.forms.length > 1)
- for(i=1; i<document.forms.length; i++)
- document.forms[i].action = document.forms[i].action.replace(/\/nospam\?/,'');
-
- // dropdown menus
- var z = document.getElementsByTagName('a');
- for(i=0;i<z.length;i++)
- if(z[i].rel && z[i].className.indexOf('dropdown') >= 0) {
- document.onmousemove = dropDown;
- break;
- }
-
- // form-stuff
- if(document.forms.length > 1) {
- formhid();
- // edit summary warning
- if(x('comm'))
- document.forms[1].onsubmit = function () {
- var z = x('comm');
- if(z.value.length > 5) return true;
- var y = prompt("Edit summary field is empty,\nPlease explain your edits and cite all sources!", z.value);
- if(y == null) return false;
- z.value = y;
- return true;
- };
- }
-
- // init dyna
- if(window.dInit)
- dInit();
-
- // zebra-striped tables (client side!? yes... client side :3)
- var sub = document.getElementsByTagName('tr');
- for(i=1; i<sub.length; i+=2)
- if(!sub[i].style.backgroundColor)
- sub[i].style.backgroundColor = '#f5f5f5';
-});
-
-
-
-
-// small hack because the mozilla -moz-inline-stack display hack sucks
-// (so we're counter-hacking a CSS hack using JS... right)
-if(navigator.userAgent.indexOf('Gecko') >= 0 && navigator.userAgent.indexOf('like Gecko') < 0 && navigator.userAgent.indexOf('3.0') < 0)
- document.write('<style type="text/css">.icons.lang { width: 15px; height: 13px; }</style>');
-
-
diff --git a/static/files/dyna.js b/static/files/dyna.js
deleted file mode 100644
index fd0411d2..00000000
--- a/static/files/dyna.js
+++ /dev/null
@@ -1,815 +0,0 @@
-var med = {
- cd: 'CD',
- dvd: 'DVD',
- gdr: 'GD-ROM',
- blr: 'Blu-Ray disk',
- 'in':'Internet download',
- pa: 'Patch',
- otc: 'Other (console)'
-};
-var vrel = [
- 'Sequel',
- 'Prequel',
- 'Same setting',
- 'Alternative setting',
- 'Alternative version',
- 'Same characters',
- 'Side story',
- 'Parent story',
- 'Summary',
- 'Full story',
- 'Other'
-];
-
-var md;var pd;var rl;var vn;var ct;
-
-function dInit() {
- md = x('md_select');
- if(md) {
- md.onclick = mdChangeSel;
- mdLoad();
- md.selectedIndex = 0;
- mdChangeSel();
- }
-
- pd = x('pd_select');
- if(pd) {
- pd.onclick = pdChangeSel;
- pdLoad();
- pd.selectedIndex = 0;
- pdChangeSel();
- }
-
- rl = x('rl_select');
- if(rl) {
- rl.onclick = rlChangeSel;
- rlLoad();
- rl.selectedIndex = 0;
- rlChangeSel();
- }
-
- vn = x('vn_select');
- if(vn) {
- vn.onclick = vnChangeSel;
- vnLoad();
- vn.selectedIndex = 0;
- vnChangeSel();
- }
-
- ct = x('categories');
- if(ct)
- catLoad();
-
-/* scrLoad() is called by the form sub functions in def.js
- if(x('scrfrm'))
- scrLoad();*/
-}
-
-function qq(v) {
- return v.replace(/&/g,"&amp;").replace(/</,"&lt;").replace(/>/,"&gt;").replace(/'/g,/*'*/ "\\'").replace(/"/g,/*"*/'&quot;');
-}
-
-// small AJAX wapper
-var hr = false;
-function ajax(url, func) {
- if(hr)
- hr.abort();
- hr = (window.ActiveXObject) ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();
- if(hr == null) {
- alert("Your browse does not support the functionality this website requires.");
- return;
- }
- hr.onreadystatechange = func;
- hr.open('GET', url, true);
- hr.send(null);
-}
-
-
-
-
- /************************\
- * M E D I A *
- \************************/
-
-
-function mdChangeSel() {
- var sel = md.options[md.selectedIndex || 0];
- var o = x('md_conts');
- var i;
- if(sel.value == '0_new') {
- var l = ''; var q = '<option value="0">Qty</option>';
- for(i in med)
- l += '<option value="'+i+'">'+med[i]+'</option>';
- for(i=1;i<10;i++)
- q += '<option value="'+i+'">'+i+'</option>';
- o.innerHTML = '<select id="md_Q" name="md_Q" style="width: 50px;">'+q+'</select>'
- + '<select id="md_S" name="md_S" style="width: 150px;">'+l+'</select>'
- + '<br style="clear: both" />'
- + '<button type="button" onclick="mdAddRem()">add/remove</button>'
- + '<br />Qty is only required for CD & DVD';
- } else {
- o.innerHTML = 'Selected "' + sel.text + '"<br />'
- + '<button type="button" onclick="mdAddRem(\'' + sel.value + '\')">remove</button>';
- }
-}
-
-function mdAddRem(id) {
- var i;
- var d = 0;
- var o = id ? null : x('md_S').options[x('md_S').selectedIndex];
- var qty = id ? null : x('md_Q').options[x('md_Q').selectedIndex].value;
- var v = id ? id : (o.value != 'cd' && o.value != 'dvd' && o.value != 'gdr' && o.value != 'blr' ? o.value : (o.value + '_' + qty));
- for(i=0;i<md.options.length;i++)
- if(md.options[i].value == v) {
- md.options[i] = null;
- d = 1;
- }
- if(!d && !id) {
- if(v.indexOf('_') >= 0 && qty == 0) {
- alert('Please specify the quantity');
- return;
- }
- md.options[md.options.length] = new Option(mdString(qty, o.value), v);
- }
- else if(id) {
- md.options[0].selected = true;
- mdChangeSel();
- }
- mdSerialize();
-}
-
-function mdSerialize() {
- var dest = x('media');
- var str = '';
- var i;
- for(i=0;i<md.options.length;i++)
- md.options[i].value != '0_new' && (str += (str.length>0 ? ',' : '') + md.options[i].value);
- dest.value = str;
-}
-
-function mdLoad() {
- var me = x('media').value.split(',');
- var i, j;
- for(i=0;i<me.length;i++) {
- var m = me[i].split('_');
- if(med[m[0]])
- md.options[md.options.length] = new Option(mdString(m[1], m[0]), me[i]);
- }
-}
-
-function mdString(qty, medium) {
- if(medium != 'cd' && medium != 'dvd' && medium != 'gdr' && medium != 'blr')
- return med[medium];
- else
- return qty + ' ' + med[medium] + (qty > 1 ? 's' : '');
-}
-
-
-
-
-
-
- /************************\
- * P R O D U C E R S *
- \************************/
-
-
-function pdChangeSel() {
- var sel = pd.options[pd.selectedIndex || 0];
- var o = x('pd_conts');
- var i;
- if(sel.value == '0_new') {
- o.innerHTML = '<input type="text" name="pd_S" id="pd_S" onkeyup="pdDoSearch(0)" onkeydown="return pdEnter(event)" style="width: 150px;" />'
- + '<button type="button" onclick="pdDoSearch(1)" style="width: 55px;">Search!</button><br style="clear: both" />'
- + '<span id="pd_R" style="display: block; width: 220px; height: 70px; overflow: auto"></span>'
- + '<a href="/p/add" target="_blank">Add new producer</a>';
- pdDoSearch('');
- } else {
- o.innerHTML = 'Selected "' + sel.text + '"<br />'
- + '<button type="button" onclick="pdAddRem(\'' + qq(sel.value) + '\')">remove</button>';
- }
-}
-
-function pdEnter(ev) {
- var c = document.layers ? ev.which : document.all ? event.keyCode : ev.keyCode;
- if(c == 13) {
- pdDoSearch(0);
- return false;
- }
- return true;
-}
-
-function pdDoSearch(f) {
- var v = x('pd_S').value;
- var d = x('pd_R');
- if(v.length < 1)
- d.innerHTML = 'Hint: type pX if you know the producer id.';
- else {
- if(f)
- d.innerHTML = '...searching...';
- ajax('/xml/producers.xml?q='+encodeURIComponent(v)+'&r='+(Math.floor(Math.random()*999)+1), function () {
- if(!hr || hr.readyState != 4 || !hr.responseText)
- return;
- if(hr.status != 200)
- return alert('Whoops, error! :(');
- var items = hr.responseXML.getElementsByTagName('item');
- if(!items || items.length < 1) {
- d.innerHTML = 'No results';
- return false;
- }
- var res = '';
- var i,j;
- for(i=0; i<items.length; i++) {
- var id = items[i].getElementsByTagName('id')[0].firstChild.nodeValue;
- var name = items[i].getElementsByTagName('name')[0].firstChild.nodeValue;
- var cid = id + ',' + name;
- var s = '';
- for(j=0; j<pd.options.length; j++)
- if(pd.options[j].value == cid)
- s = ' checked="checked"';
- res += '<input type="checkbox" id="pd_I'+id+'"'+s+' onclick="pdAddRem(\''+qq(cid)+'\', \''+qq(name)+'\')" />'
- + '<label style="width: auto" for="pd_I'+id+'">'+name+'</label><br style="clear: left" />';
- }
- d.innerHTML = res;
- });
- }
-}
-
-function pdAddRem(id, name) {
- var i;
- var d = 0;
- for(i=0;i<pd.options.length;i++)
- if(pd.options[i].value == id) {
- pd.options[i] = null;
- d = 1;
- }
- if(!d && name)
- pd.options[pd.options.length] = new Option(name, id);
- else if(!name) {
- pd.options[0].selected = true;
- pdChangeSel();
- }
- pdSerialize();
-}
-
-// id,name|||id,name
-function pdSerialize() {
- var dest = x('producers');
- var str = '';
- var i;
- for(i=0;i<pd.options.length;i++)
- pd.options[i].value != '0_new' && (str += (str.length>0 ? '|||' : '') + pd.options[i].value);
- dest.value = str;
-}
-
-function pdLoad() {
- var pds = x('producers').value.split('|||');
- if(!pds[0])
- return;
- var i;
- for(i=0;i<pds.length;i++)
- pd.options[pd.options.length] = new Option(pds[i].split(',',2)[1], pds[i]);
-}
-
-
-
-
-
-
-
-
- /************************\
- * R E L A T I O N S *
- \************************/
-
-
-var rlsel = ''; var rlname = '';
-function rlChangeSel() {
- var sel = rl.options[rl.selectedIndex || 0];
- var o = x('rl_conts');
- var i;
- rlsel = '';
- var ops='';
- for(i=0;i<vrel.length;i++)
- ops += '<option value="'+i+'">'+vrel[i]+'</option>';
- if(sel.value == '0_new') {
- o.innerHTML = '<input type="text" name="rl_S" id="rl_S" onkeyup="rlDoSearch(0)" onkeydown="return rlEnter(event)" style="width: 150px;" />'
- + '<button type="button" onclick="rlDoSearch(1)" style="width: 60px;">Search!</button><br style="clear: both" />'
- + '<span id="rl_R" style="display: block; width: 250px; height: 70px; overflow: auto"></span>'
- + '<select id="rl_L" name="rl_L" onchange="rlAddRem(0)"><option value="-1">...is a [..] of this visual novel</option>'+ops+'</select>';
- rlDoSearch('');
- } else {
- o.innerHTML = sel.value.split(',', 3)[2] + '<br />'
- + '<select id="rl_L" name="rl_L" onchange="rlAddRem(\''+qq(sel.value)+'\')">'
- + '<option value="-1"> - change - </option>'+ops+'<option value="-2"> - remove relation - </option></select>';
- }
-}
-
-function rlEnter(ev) {
- var c = document.layers ? ev.which : document.all ? event.keyCode : ev.keyCode;
- if(c == 13) {
- rlDoSearch(0);
- return false;
- }
- return true;
-}
-
-function rlDoSearch(f) {
- var v = x('rl_S').value;
- var d = x('rl_R');
- if(v.length < 1)
- d.innerHTML = 'Search for a visual novel to add a relation.<br /><br />'
- + 'Hint: type vX if you know the VN id.';
- else {
- if(f)
- d.innerHTML = '...searching...';
- ajax('/xml/vn.xml?q='+encodeURIComponent(v)+'&r='+(Math.floor(Math.random()*999)+1), function () {
- if(!hr || hr.readyState != 4 || !hr.responseText)
- return;
- if(hr.status != 200)
- return alert('Whoops, error! :(');
- rlsel = '';
- var items = hr.responseXML.getElementsByTagName('item');
- if(!items || items.length < 1) {
- d.innerHTML = 'No results';
- return false;
- }
- var res = '';
- var i,j;
- for(i=0; i<items.length; i++) {
- var id = items[i].getElementsByTagName('id')[0].firstChild.nodeValue;
- var title = items[i].getElementsByTagName('title')[0].firstChild.nodeValue;
- var cid = id + ',' + title;
- res += '<input type="radio" name="rl_rad" id="pd_I'+id+'" value="rl_I'+id+'" onclick="rlAddRem(\''+qq(cid)+'\', \''+qq(title)+'\')" />'
- + '<label style="width: auto" for="rl_I'+id+'">'+title+'</label><br style="clear: left" />';
- }
- d.innerHTML = res;
- });
- }
-}
-
-function rlAddRem(id, name) {
- var i;
- var rs = x('rl_L').selectedIndex;
- if(id && name) {
- rlsel = id;
- rlname = name;
- } else if(id) {
- if(!rs)
- return;
- if(rs == x('rl_L').options.length-1) { // remove
- for(i=0;i<rl.options.length;i++)
- if(rl.options[i].value == id)
- rl.options[i] = null;
- rl.options[0].selected = true;
- } else {
- var cur = id.split(',', 3);
- i = rl.selectedIndex;
- rs--;
- rl.options[i] = new Option(vrel[rs]+': '+cur[2], (rs)+','+cur[1]+','+cur[2]);
- rl.options[i].selected = true;
- }
- rlChangeSel();
- rlSerialize();
- return;
- } else if(!rlsel) {
- alert('No visual novel selected');
- return;
- }
-
- if(!id && rlsel && !rs) { // remove
- for(i=0;i<rl.options.length;i++)
- if(rl.options[i].value.indexOf(rlsel) != -1)
- rl.options[i] = null;
- rlSerialize();
- return;
- }
- if(!rs)
- return;
-
- // add/edit
- var mod = rl.options.length;
- rs--;
- for(i=0;i<rl.options.length;i++)
- if(rl.options[i].value.indexOf(rlsel) != -1)
- mod = i;
- rl.options[mod] = new Option(vrel[rs]+': '+rlname, rs+','+rlsel);
-
- rlSerialize();
-}
-
-// rel,id,name|||rel,id,name
-function rlSerialize() {
- var dest = x('relations');
- var str = '';
- var i;
- for(i=0;i<rl.options.length;i++)
- rl.options[i].value != '0_new' && (str += (str.length>0 ? '|||' : '') + rl.options[i].value);
- dest.value = str;
-}
-
-function rlLoad() {
- var rls = x('relations').value.split('|||');
- if(!rls[0])
- return;
- var i;
- for(i=0;i<rls.length;i++)
- rl.options[rl.options.length] = new Option(vrel[rls[i].split(',',3)[0]]+': '+rls[i].split(',',3)[2], rls[i]);
-}
-
-
-
-
-
-
-
-
- /************************\
- * VISUAL NOVELS *
- \************************/
-
-
-function vnChangeSel() {
- var sel = vn.options[vn.selectedIndex || 0];
- var o = x('vn_conts');
- var i;
- var ops='';
- for(i=0;i<vrel.length;i++)
- ops += '<option value="'+i+'">'+vrel[i]+'</option>';
- if(sel.value == '0_new') {
- o.innerHTML = '<input type="text" name="vn_S" id="vn_S" onkeyup="vnDoSearch(0)" onkeydown="return vnEnter(event)" style="width: 150px;" />'
- + '<button type="button" onclick="vnDoSearch(1)" style="width: 60px;">Search!</button><br style="clear: both" />'
- + '<span id="vn_R" style="display: block; width: 250px; height: 90px; overflow: auto"></span>';
- vnDoSearch('');
- } else {
- o.innerHTML = 'Selected "' + sel.text + '"<br />'
- + '<button type="button" onclick="vnAddRem(\'' + sel.value + '\')">remove</button>';
- }
-}
-
-function vnEnter(ev) {
- var c = document.layers ? ev.which : document.all ? event.keyCode : ev.keyCode;
- if(c == 13) {
- vnDoSearch(0);
- return false;
- }
- return true;
-}
-
-function vnDoSearch(f) {
- var v = x('vn_S').value;
- var d = x('vn_R');
- if(v.length < 1)
- d.innerHTML = 'Hint: type vX if you know the visual novel id.';
- else {
- if(f)
- d.innerHTML = '...searching...';
- ajax('/xml/vn.xml?q='+encodeURIComponent(v)+'&r='+(Math.floor(Math.random()*999)+1), function () {
- if(!hr || hr.readyState != 4 || !hr.responseText)
- return;
- if(hr.status != 200)
- return alert('Whoops, error! :(');
- var items = hr.responseXML.getElementsByTagName('item');
- if(!items || items.length < 1) {
- d.innerHTML = 'No results';
- return false;
- }
- var res = '';
- var i,j;
- for(i=0; i<items.length; i++) {
- var id = items[i].getElementsByTagName('id')[0].firstChild.nodeValue;
- var title = items[i].getElementsByTagName('title')[0].firstChild.nodeValue;
- var s = '';
- for(j=0; j<vn.options.length; j++)
- if(vn.options[j].value == id)
- s = ' checked="checked"';
- res += '<input type="checkbox" id="vn_I'+id+'"'+s+' onclick="vnAddRem(\''+qq(id)+'\', \''+qq(title)+'\')" />'
- + '<label style="width: auto" for="vn_I'+id+'">'+title+'</label><br style="clear: left" />';
- }
- d.innerHTML = res;
- });
- }
-}
-
-function vnAddRem(id, title) {
- var i;
- var d = 0;
- for(i=0;i<vn.options.length;i++)
- if(vn.options[i].value == id) {
- vn.options[i] = null;
- d = 1;
- }
- if(!d && title)
- vn.options[vn.options.length] = new Option(title, id);
- else if(!title) {
- vn.options[0].selected = true;
- vnChangeSel();
- }
- vnSerialize();
-}
-
-// id,title|||id,title
-function vnSerialize() {
- var dest = x('vn');
- var str = '';
- var i;
- for(i=0;i<vn.options.length;i++)
- vn.options[i].value != '0_new' && (str += (str.length>0 ? '|||' : '') + vn.options[i].value + ',' + vn.options[i].text);
- dest.value = str;
-}
-
-function vnLoad() {
- var vns = x('vn').value.split('|||');
- if(!vns[0])
- return;
- var i;
- for(i=0;i<vns.length;i++)
- vn.options[vn.options.length] = new Option(vns[i].split(',',2)[1], vns[i].split(',',2)[0]);
-}
-
-
-
-
-
-
- /************************\
- * C A T E G O R I E S *
- \************************/
-
-
-function catLoad() {
- var i;var cats=[];
- var l = ct.value.split(',');
- for(i=0;i<l.length;i++)
- cats[l[i].substr(0,3)] = Math.floor(l[i].substr(3,1));
-
- var l=x('cat').getElementsByTagName('a');
- for(i=0;i<l.length;i++) {
- if(l[i].id.substr(0, 4) != 'cat_')
- continue;
- catSet(l[i].id.substr(4), cats[l[i].id.substr(4)]||0);
- l[i].onclick = function() {
- var c = this.id.substr(4);
- if(!cats[c]) cats[c] = 0;
- if(c.substr(0,1) == 'p' || c == 'gaa' || c == 'gab' || c.substr(0,1) == 'h' || c.substr(0,1) == 'l' || c.substr(0,1) == 't') {
- if(cats[c]++)
- cats[c] = 0;
- } else if(++cats[c] == 4)
- cats[c] = 0;
- catSet(c, cats[c]);
-
- // has to be ordered before serializing!
- var r;l=[];i=0;
- for(r in cats)
- l[i++] = r;
- l = l.sort();
- r='';
- for(i=0;i<l.length;i++)
- if(cats[l[i]] > 0)
- r+=(r?',':'')+l[i]+cats[l[i]];
- ct.value = r;
- return false;
- };
- }
-}
-
-function catSet(id, rnk) {
- var c = rnk == 0 ? '#000' :
- rnk == 1 ? '#090' :
- rnk == 2 ? '#990' : '#900';
- x('b_'+id).style.color = c;
- x('cat_'+id).style.color = c;
- x('b_'+id).innerHTML = rnk;
-}
-
-
-
-
-
-
-
- /***************************\
- * S C R E E N S H O T S *
- \***************************/
-
-
-var scrL = []; // id, load, nsfw, obj, rid
-function scrLoad() {
- // 'screenshots' format: id,nsfw id,nsfw ..
- var l=x('screenshots').value.split(' ');
- for(var i=0;i<l.length;i++)
- if(l[i].length > 2)
- scrL[i] = { load: 2, id: l[i].split(',')[0], nsfw: l[i].split(',')[1]>0?1:0, rid: l[i].split(',')[2] };
-
- // <tbody> because IE can't operate on <table>
- x('scrfrm').innerHTML = '<table><tbody id="scrTbl"></tbody></table>';
- for(i=0;i<scrL.length;i++)
- scrGenerateTR(i);
- scrGenerateTR(i);
-
- setTimeout(scrSetSubmit, 1000);
- scrCheckStatus();
-}
-
-// give an error when submitting the form while still uploading an image
-function scrSetSubmit() {
- var o=document.forms[1].onsubmit;
- document.forms[1].onsubmit = function() {
- var c=0;var r=0;
- for(var i=0;i<scrL.length;i++) {
- if(scrL[i] && scrL[i].load)
- c=1;
- if(scrL[i] && scrL[i].rid == 0)
- r=1;
- }
- if(c) {
- alert('Please wait for the screenshots to be uploaded before submitting the form.');
- return false;
- } else if(r) {
- alert('Please select the appropriate release for every screenshot');
- return false;
- } else
- return o();
- };
-}
-
-function scrURL(id, t) {
- return x('scrfrm').className+'/s'+t+'/'+(id%100<10?'0':'')+(id%100)+'/'+id+'.jpg';
-}
-
-function scrGenerateTR(i) {
- if(!scrL[i])
- scrL[i] = { id: 0, load: 0 };
- var r = '<b style="width: auto; float: none;margin: 0; padding: 0; font-weight: bold">';
- if(!scrL[i].id && !scrL[i].load) {
- var c=0;
- for(var j=0,c=0; j<scrL.length; j++)
- if(scrL[j] && (scrL[j].load || scrL[j].id))
- c++;
- if(c >= 10)
- r += 'Enough screenshots</b>'
- +'The limit of 10 screenshots per visual novel has been reached. '
- +'If you want to add a new screenshot, please remove an existing one first.';
- else
- r += 'Add screenshot</b>'
- +'<input type="file" name="scrAddFile'+i+'" id="scrAddFile'+i+'" style="float: none; height: auto; width: auto;" />'
- +'<input type="button" value="Upload!" style="float: none; height: auto; width: auto; display: inline;" onclick="scrUpload('+i+')" /><br />'
- +'Image must be smaller than 5MB and in PNG or JPEG format.';
- }
- if(scrL[i].load && scrL[i].load == 1)
- r += 'Uploading...</b>This could take a while, depending on the file size and your upload speed.<br />'
- +'<a href="javascript:scrDel('+i+')">cancel</a>';
- if(scrL[i].load && scrL[i].load == 2)
- r += 'Generating thumbnail...</b>Note: if this takes longer than 30 seconds, there\'s probably something wrong on our side.'
- +'Please try again later or report a bug if that is the case.';
- if(scrL[i].id && !scrL[i].load)
- r += 'Screenshot #'+scrL[i].id+'</b>'
- +'<input type="checkbox" name="scrNSFW'+i+'" id="scrNSFW'+i+'"'+(scrL[i].nsfw?' checked="checked"':'')+' style="float: left" onclick="scrSer()" /> '
- +'<label for="scrNSFW'+i+'" class="checkbox">&nbsp;This screenshot is NSFW.</label>'
- +'<input type="button" value="remove" onclick="scrDel('+i+')" style="float: right; width: auto; height: auto" />'
- +'<br /><b style="float: left; width: auto; margin-right: 5px">Release:</b>'
- +'<select style="width: 350px; float: none; height: auto;" onchange="scrSer()" id="scrRel'+i+'">'+scrRelList(scrL[i].rid)+'</select>'
- +'<br />Full size: '+scrL[i].width+'x'+scrL[i].height+'px';
-
- if(scrL[i].obj) {
- x('scrTr'+i).getElementsByTagName('td')[1].innerHTML = r;
- return;
- }
-
- // the slow and tedious way, because we need to use DOM functions to manipulate the table contents...
- var o = document.createElement('tr');
- o.setAttribute('id', 'scrTr'+i);
- o.style.cssText = 'border-top: 1px solid #ccc';
- var d = document.createElement('td');
- d.style.cssText = 'width: 141px; height: 102px; padding: 0;';
- d.innerHTML = scrL[i].id && !scrL[i].load ? '<img src="'+scrURL(scrL[i].id, 't')+'" style="margin: 0; padding: 0; border: 0" />' : '&nbsp;';
- var e = document.createElement('td');
- e.innerHTML = r;
- o.appendChild(d);
- o.appendChild(e);
- x('scrTbl').appendChild(o);
- scrL[i].obj = o;
- scrStripe();
-}
-
-function scrUpload(i) {
- scrL[i].load = 1;
- // move the file selection box into a temporary form and post it into a temporary iframe
- var d = document.createElement('div');
- d.id = 'scrUpl'+i;
- d.style.cssText = 'visibility: hidden; overflow: hidden; width: 1px; height: 1px; position: absolute; left: -500px; top: -500px';
- d.innerHTML = '<iframe name="scrIframe'+i+'" id="scrIframe'+i+'" style="height: 0px; width: 0px; visibility: hidden"'
- +' src="about:blank" onload="scrUploadComplete('+i+')"></iframe>'
- +'<form method="post" action="/xml/screenshots.xml" target="scrIframe'+i+'" enctype="multipart/form-data" id="scrUplFrm'+i+'" name="scrUplFrm'+i+'">'
- +'<input type="hidden" name="itemnumber" value="'+i+'" />'
- +'</form>';
- document.body.appendChild(d);
- x('scrUplFrm'+i).appendChild(x('scrAddFile'+i));
- x('scrUplFrm'+i).submit();
- scrGenerateTR(i);
- scrGenerateTR(i+1);
- return false;
-}
-
-function scrStripe() {
- var l = x('scrTbl').getElementsByTagName('tr');
- for(var j=0; j<l.length; j++)
- l[j].style.backgroundColor = j%2==0 ? '#fff' : '#f5f5f5';
-}
-
-function scrRelLine(rid, sel) {
- var r;
- for(var i=0;i<scrRel.length;i++)
- if(scrRel[i][0] == rid)
- r = scrRel[i];
- return '<option value="'+r[0]+'"'+(sel?' selected="selected"':'')+'>['+r[1]+'] '+r[2]+'</option>';
-}
-
-function scrRelList(rid) {
- var r='<option value="0">-- select release --</option>';
- for(var i=0;i<scrRel.length;i++)
- r += scrRelLine(scrRel[i][0], rid == scrRel[i][0] ? 1 : 0);
- return r;
-}
-
-function scrUploadComplete(i) {
- if(window.frames['scrIframe'+i].location.href.indexOf('screenshots') > 0) {
- try {
- scrL[i].id = window.frames['scrIframe'+i].window.document.getElementsByTagName('image')[0].getAttribute('id');
- } catch(e) {
- scrL[i].id = -10;
- }
- if(scrL[i].id < 0) {
- alert(
- scrL[i].id == -10 ?
- 'Oops! Seems like something went wrong...\n'
- +'Make sure the file you\'re uploading doesn\'t exceed 5MB in size.\n'
- +'If that isn\'t the problem, then please report a bug.' :
- scrL[i].id == -1 ?
- 'Upload failed!\nOnly JPEG or PNG images are accepted.' :
- 'Upload failed!\nNo file selected, or an empty file?');
- return scrDel(i);
- }
- scrL[i].load = 2;
- scrGenerateTR(i);
- scrImageFail(i);
- }
-}
-
-function scrCheckStatus() {
- var ids='';
- for(var i=0;i<scrL.length;i++)
- if(scrL[i] && scrL[i].load == 2)
- ids+=(ids?';':'')+'id='+scrL[i].id;
- if(!ids)
- return setTimeout(scrCheckStatus, 1000);
- var ti = setTimeout(scrCheckStatus, 10000);
- ajax('/xml/screenshots.xml?'+ids+';r='+(Math.floor(Math.random()*999)+1), function () {
- if(!hr || hr.readyState != 4 || !hr.responseText)
- return;
- if(hr.status != 200)
- return alert('Whoops, error! :(');
- var l = hr.responseXML.getElementsByTagName('image');
- for(var s=0;s<l.length;s++) {
- for(i=0;i<scrL.length;i++)
- if(scrL[i] && scrL[i].id == l[s].getAttribute('id') && l[s].getAttribute('status') > 0) {
- scrL[i].load = 0;
- scrL[i].width = l[s].getAttribute('width');
- scrL[i].height = l[s].getAttribute('height');
- x('scrTr'+i).getElementsByTagName('td')[0].innerHTML =
- '<a href="'+scrURL(scrL[i].id, 'f')+'" rel="'+scrL[i].width+'x'+scrL[i].height+'" onclick="return scrView(this)">'
- +'<img src="'+scrURL(scrL[i].id, 't')+'" style="margin: 0; padding: 0; border: 0" /></a>';
- scrGenerateTR(i);
- scrSer();
- }
- }
- clearTimeout(ti);
- setTimeout(scrCheckStatus, 1000);
- });
-}
-
-function scrDel(i) {
- x('scrTbl').removeChild(x('scrTr'+i));
- if(scrL[i].load)
- document.body.removeChild(x('scrUpl'+i));
- scrL[i]=null;
- scrGenerateTR(scrL.length-1);
- scrSer();
- scrStripe();
-}
-
-function scrSer() {
- var r='';
- for(var i=0;i<scrL.length;i++) {
- if(scrL[i] && scrL[i].id && !scrL[i].load) {
- scrL[i].nsfw = x('scrNSFW'+i).checked ? '1' : '0';
- scrL[i].rid = x('scrRel'+i).options[x('scrRel'+i).selectedIndex].value;
- r += ' '+scrL[i].id+','+scrL[i].nsfw+','+scrL[i].rid;
- }
- }
- x('screenshots').value = r;
-}
-
-
-
-
diff --git a/static/files/footer.gif b/static/files/footer.gif
deleted file mode 100644
index c87fb121..00000000
--- a/static/files/footer.gif
+++ /dev/null
Binary files differ
diff --git a/static/files/graph.png b/static/files/graph.png
deleted file mode 100644
index bb56f758..00000000
--- a/static/files/graph.png
+++ /dev/null
Binary files differ
diff --git a/static/files/headerbg.jpg b/static/files/headerbg.jpg
deleted file mode 100644
index 81f4dd75..00000000
--- a/static/files/headerbg.jpg
+++ /dev/null
Binary files differ
diff --git a/static/files/headerbot.png b/static/files/headerbot.png
deleted file mode 100644
index 6e04ab05..00000000
--- a/static/files/headerbot.png
+++ /dev/null
Binary files differ
diff --git a/static/files/icons.png b/static/files/icons.png
deleted file mode 100644
index 4cb1a180..00000000
--- a/static/files/icons.png
+++ /dev/null
Binary files differ
diff --git a/static/files/rss.png b/static/files/rss.png
deleted file mode 100644
index 923c3822..00000000
--- a/static/files/rss.png
+++ /dev/null
Binary files differ
diff --git a/static/files/select.png b/static/files/select.png
deleted file mode 100644
index ac219e05..00000000
--- a/static/files/select.png
+++ /dev/null
Binary files differ
diff --git a/static/files/sidebarbg.jpg b/static/files/sidebarbg.jpg
deleted file mode 100644
index 00eb5697..00000000
--- a/static/files/sidebarbg.jpg
+++ /dev/null
Binary files differ
diff --git a/static/files/sidebarbot.jpg b/static/files/sidebarbot.jpg
deleted file mode 100644
index 49884ded..00000000
--- a/static/files/sidebarbot.jpg
+++ /dev/null
Binary files differ
diff --git a/static/files/sidebg.jpg b/static/files/sidebg.jpg
deleted file mode 100644
index 65fd3306..00000000
--- a/static/files/sidebg.jpg
+++ /dev/null
Binary files differ
diff --git a/static/files/style.css b/static/files/style.css
deleted file mode 100644
index 6c51bacf..00000000
--- a/static/files/style.css
+++ /dev/null
@@ -1,923 +0,0 @@
-
-body {
- margin: 15px 0 0 0;
- padding: 0 0 60px 0;
- background: #fff;
- font-family: Arial, Helvetica, sans-serif;
- font-size: 13px;
- color: #203C36;
-}
-
-form {
- margin: 0;
- padding: 0;
-}
-
-fieldset {
- margin: 0;
- padding: 0;
- border: none;
-}
-
-legend {
- display: none;
-}
-
-input, textarea {
- padding: 2px 5px;
- border: 1px solid #B8E0D7;
- font: normal 1em Arial, Helvetica, sans-serif;
- color: #203C36;
-}
-
-h1, h2 {
- color: #203C36;
- margin: 0;
-}
-
-h1 {
- text-transform: lowercase;
- letter-spacing: -1px;
- font-size: 3em;
-}
-
-h2 {
- font-size: 1.7em;
- clear: right;
-}
-
-h3 {
- font-size: 1.1em;
- margin: 0;
-}
-h3.alttitle {
- margin: 0 0 0 20px;
-}
-
-p, ul, ol {
- margin: 0;
-}
-a {
- color: #69A89A;
-}
-a:hover {
- text-decoration: none;
-}
-
-img {
- border: none;
-}
-
-/* Header */
-
-#header {
- width: 960px;
- height: 80px;
- margin: 0 auto;
- background: url(/files/headerbg.jpg);
-}
-
-#header h1 {
- margin: 0;
- padding: 15px 0 0 20px;
- letter-spacing: normal;
- font-size: 1em;
- color: #FFFFFF;
-}
-
-#header h1 a {
- text-decoration: none;
- color: #FFFFFF;
-}
-
-#header h1 a:hover {
- text-decoration: underline;
-}
-
-#header b {
- display: block;
- letter-spacing: -2px;
- font-size: 2.4em;
-}
-
-/* Search */
-
-#search {
- float: right;
- width: 180px;
- padding-top: 30px;
-}
-
-#searchfield {
- width: 150px;
-}
-
-#searchsubmit {
- display: none;
-}
-
-/* Login */
-
-#loginform {
- padding: 0;
- margin: 0 0 0 20px;
-}
-#loginform input {
- width: 40px;
- margin: 0;
- padding: 1px;
- position: relative;
-}
-#loginform #usrname, #loginform #usrpass {
- width: 70px;
- border: 0;
-}
-
-/* Page */
-
-#page {
- width: 960px;
- margin: 0 auto;
- padding: 40px 0;
- background: url(/files/headerbot.png) no-repeat;
-}
-
-#content {
- float: left;
- width: 700px;
-}
-
-/* Side */
-
-#side {
- float: right;
- padding: 0;
- background: url(/files/sidebg.jpg);
- color: #fff;
-}
-#side div {
- background: url(/files/sidebarbg.jpg) no-repeat;
-}
-#side div div {
- width: 240px;
- padding: 0 0 60px 0;
- background: url(/files/sidebarbot.jpg) no-repeat left bottom;
-}
-
-#side a {
- color: #fff;
-}
-
-#side h2 {
- padding: 20px 20px 0 15px;
- text-transform: uppercase;
- font-family: "Arial Black", Arial, Helvetica, sans-serif;
- font-size: .8em;
- color: #fff;
-}
-
-#side ul {
- margin: 0;
- padding: 0 20px 0 20px;
- list-style: none;
-}
-
-#side li {
- padding: 0;
-}
-
-#side p {
- margin: 0;
- padding: 0 0 0 20px;
-}
-#side li.more {
- font-style: italic;
-}
-
-/* Footer */
-
-#footer {
- clear: both;
- padding: 10px 0;
-}
-
-#footer p {
- margin: 0;
- text-align: center;
- color: #999999;
- font-size: 0.8em;
-}
-
-#footer a {
- color: #999999;
-}
-
-/* Forms */
-#content form {
- display: block;
- margin: 20px 0 10px 0;
- padding: 0;
-}
-#content form.tblf {
- margin: 0;
-}
-form ul {
- margin: 0;
- padding: 0;
-}
-form li {
- display: block;
- clear: left;
- list-style-type: none;
- margin: 0;
- padding: 0;
-}
-form ul ul {
- margin: 0; padding: 0;
- clear: left;
-}
-form li.nolabel, form ul ul {
- padding: 0 0 0 110px;
-}
-form li.nextpart {
- padding: 10px 0 0 0;
-}
-#content label, #content input, #content textarea, #content select, form li b, form li p {
- display: block;
- float: left;
-}
-form li label i, form p.formnotice i {
- display: inline;
- color: #f00;
-}
-input.text, select {
- width: 200px;
-}
-select, input.text, textarea {
- border: 1px solid #B8E0D7;
- font: normal 1em Arial, Helvetica, sans-serif;
- color: #203C36;
-}
-form label.checkbox {
- width: auto;
-}
-select.multiple {
- height: 120px;
- width: 230px;
-}
-#md_conts, #pd_conts, #rl_conts, #vn_conts {
- display: block;
- float: left;
- background-color: #e3ecff;
- border: 1px dashed #b4b4ff;
- padding: 2px;
-}
-#rl_select {
- width: 280px;
-}
-form li.longopts select {
- width: 350px;
-}
-form li.shortopts input {
- width: 50px;
-}
-form li i {
- float: left;
-}
-input.hidden {
- display: none;
- position: absolute;
- top: -30px;
-}
-label, form li b {
- width: 110px;
- font-weight: normal;
-}
-form li.nolabel b {
- display: inline;
- width: auto;
- font-weight: bold;
- float: none;
-}
-form li.subform {
- padding: 10px 0 0 0;
- clear: both;
-}
-form li.subform a {
- display: block;
- margin: 0;
- padding: 0;
- width: 100%;
- background-color: #f0f0f0;
- text-decoration: none;
- font-weight: bold;
- color: #7AB9AB;
-}
-li.formhid {
- float: none;
- position: absolute;
- top: -2000px;
- left: -2000px;
- width: 10px;
-}
-form li.date select {
- width: 100px;
-}
-
-/* Platform selecter */
-form ul.platforms {
- clear: none;
- padding: 0;
- margin: 0 0 0 110px;
-}
-form ul.platforms li {
- float: left;
- clear: none;
-}
-form ul.platforms li label {
- width: 150px;
-}
-form ul.platforms input {
- padding: 0;
- margin: 0 2px 0 2px;
- border: 0;
- height: 14px;
-}
-
-/* Warning & msg box */
-span.warning {
- display: block;
- margin: 5px 10% 5px 10%;
- padding: 3px 5px 3px 60px;
- background: #ffece3 url('/files/warning.png') no-repeat;
- border: 1px dashed #ffb4b4;
- min-height: 57px;
-}
-* html span.warning { height: 57px; }
-span.msg {
- display: block;
- margin: 5px 10% 5px 10%;
- padding: 3px 5px 3px 5px;
- border: 1px dashed #3cb700;
- background: #bfffb5;
-}
-span.warning ul, span.msg ul {
- padding: 0 0 0 15px;
-}
-a.help {
- vertical-align: super;
- font-size: 10px;
- text-decoration: none;
- font-weight: bold;
- padding-left: 1px;
- /*background: #eee;*/
-}
-
-
-/* VN page header, general dl and list markup */
-p.nsfw { color: #999; font-size: 10px; font-style: italic; }
-dt {
- float: left;
- font-style: italic;
-}
-dd {
- padding: 0 0 0 50px;
-}
-dl.vnrel dd, dl.vncat dd {
- padding: 0 0 0 75px;
-}
-ul.vnani i { color: #999 }
-ul.vnani b { color: #999; font-weight: normal; font-size: 10px; }
-ul.vnani acronym { border: 0 }
-ul {
- padding: 0 0 0 17px;
-}
-p.actions {
- display: inline;
- margin: 0 0 0 5px;
- font-weight: normal;
- font-size: 12px;
- color: #999;
-}
-#vnheader div {
- width: 256px;
- float: left;
- text-align: center;
-}
-#vnheader div img {
- margin: 0 auto 0 auto;
-}
-#vnheader #nsfw {
- cursor: pointer;
-}
-#vnheader dl, #vnheader ul {
- margin: 0 0 0 270px;
- padding: 0;
-}
-#vnheader li { list-style-type: none; margin: 0; padding: 0; }
-#vnheader h3 {
- margin: 10px 0 0 260px;
- font-size: 13px;
-}
-#vnheader p.mod {
- margin: 0;
-}
-
-
-/* producer search */
-
-form#psearch fieldset {
- display: block;
- width: 700px;
- text-align: center;
-}
-form#psearch input { margin: 0 auto; float: none; position: relative; display: inline }
-
-
-ul.home {
- float: left;
- list-style-type: none;
- width: 210px;
- margin-top: 30px;
-}
-ul.home li { padding: 0; }
-ul.home.break { clear: left; }
-h3.home {
- clear: left;
- padding-top: 30px;
-}
-
-
-/* edit links and stuff */
-
-p.mod {
- float: right;
- color: #999;
-}
-div.dropdown {
- width: 100px;
- position: absolute;
- left: -500px;
- top: 0;
- border: 1px solid #d0d0d0;
- border-bottom: none;
-}
-div.dropdown ul, div.dropdown ul li {
- list-style-type: none;
- margin: 0;
- padding: 0;
- width: 100px;
- background-color: #f0f0f0;
- border-bottom: 1px solid #d0d0d0;
-}
-div.dropdown a, div.dropdown b {
- display: block;
- width: 90px;
- margin: 0;
- padding: 2px 5px;
- text-decoration: none;
-}
-div.dropdown b {
- font-weight: normal;
- font-style: italic;
- color: #666;
-}
-div.dropdown li.center a, div.dropdown li.center b {
- text-align: center;
-}
-div.dropdown a:hover {
- background-color: #e0e0e0;
-}
-div.rlistdd {
- width: 200px;
-}
-div.rlistdd ul, div.rlistdd ul li {
- float: left;
-}
-div.rlistdd a, div.rlistdd b {
- padding: 0px 5px;
-}
-div.dropdown ul.full a, div.dropdown ul.full b {
- width: 190px;
- padding: 1px 5px;
-}
-div.dropdown ul.full, div.dropdown ul.full li {
- clear: left;
- width: 200px;
-}
-
-
-/* paragraph markups... */
-
-p#relations {
- margin: 20px 0 0 0;
- width: 100%;
- text-align: center;
-}
-p.desc {
- padding: 0 10px 0 10px;
-}
-p.chr {
- width: 100%;
- text-align: center;
- font-size: 1.1em;
-}
-p.browse {
- width: 100%;
- text-align: center;
-}
-b.mod, a.mod {
- color: #f00;
-}
-
-
-/* vn search */
-
-form#vsearch fieldset {
- display: block;
- width: 700px;
- text-align: center;
-}
-form#vsearch input { margin: 0 auto; float: none; position: relative; display: inline }
-form#vsearch input.text { width: 400px; }
-b#adsearchclick { cursor: pointer }
-
-ul.filter { margin: 0 0 0 15px; padding: 0; list-style-type: none }
-ul.filter li { float: left; padding: 4px 10px 0 0; }
-ul.filter label { width: auto; color: #666; font-size: 11px; margin: 0; padding: 0 0 0 1px;}
-ul.filter input { border: 0; margin: 0; }
-
-
-
-/* categories */
-
-ul#cat {
- margin: 0 0 0 15px;
- padding: 0;
-}
-ul#cat ul {
- list-style-type: none;
- padding: 0;
-}
-ul#cat input {
- padding: 0;
- margin: 0 2px 0 2px;
- border: 0;
- height: 14px;
-}
-ul#cat li, form ul#cat li {
- display: block;
- width: 170px;
- float: left;
- clear: none;
- font-weight: bold;
-}
-ul#cat li li {
- display: list-item;
- width: auto;
- float: none;
- clear: left;
- font-weight: normal;
- padding: 0 0 0 20px;
- margin: 0;
- cursor: pointer;
- list-style-type: none;
- background: url(/files/select.png) no-repeat;
-}
-form ul#cat li li {
- padding: 0;
- background: none;
-}
-form ul#cat li li b { width: 13px; font-weight: bold; }
-form ul#cat li li a { color: #000; text-decoration: none; display: block; width: 160px; }
-ul#cat li li.inc { background-position: 0px -16px; color: #090; }
-ul#cat li li.exc { background-position: 0px -33px; color: #900; }
-i.crgn0 { font-style: normal; }
-i.crgn1 { font-style: normal; color: #bbb; }
-i.crgn2 { font-style: normal; }
-i.crgn3 { font-style: normal; font-weight: bold; }
-
-
-
-/* DOCUMENTATION PAGES */
-#dpage h3 { margin-top: 25px; }
-#dpage h3 a { color: #203C36; text-decoration: none; }
-#dpage dd { padding-bottom: 5px; margin-left: 70px; }
-#dpage ul.index { display: block; float: right; width: 150px; padding: 2px; margin: 0 0 10px 5px; background-color: #f1f1f1; border: 1px solid #ccc; }
-#dpage ul.index li { list-style-type: none; }
-#dpage ul.index li a { margin: 0 0 0 10px; }
-#dpage .retired { text-decoration: line-through; }
-#dpage dt b { color: #999; font-weight: normal; font-style: normal; font-size: 12px; }
-
-/* Screenshots */
-div#screenshots {
- display: block;
- width: 700px;
- margin: 0;
- padding: 0;
-}
-div#screenshots b {
- display: block;
- margin: 0;
- padding: 0;
- width: 100%;
- background-color: #f5f5f5;
- font-weight: normal;
-}
-div#screenshots a.shot {
- display: block;
- float: left;
- width: 136px;
- height: 102px;
- margin: 0;
- padding: 2px;
- text-decoration: none;
- text-align: center;
-}
-div#screenshots a.shot:hover {
- background-color: #ccc;
-}
-div#screenshots a.shot b {
- display: block;
- margin: -16px 0 0 0;
- padding: 0;
- height: 14px;
- width: 136px;
- text-align: right;
- font-size: 12px;
- color: #f00;
-}
-div#screenshots img { border: 0; padding: 0; }
-div#scrView {
- position: absolute;
- display: none;
- top: -5000px;
- left: -5000px;
- background-color: #fff;
- border: 2px solid #ccc;
- padding: 10px;
- text-align: center;
-}
-#scrView img { cursor: pointer }
-#scrclose { float: right; padding-left: 10px; }
-#scrnext { padding-left: 5px; }
-#scrprev { padding-right: 5px; }
-#scrfull { float: left; padding-right: 10px; }
-#scrimgload {
- display: block;
- position: absolute;
- left: -500px;
- top: -50px;
- width: 100px;
- padding: 3px;
- background-color: #f5f5f5;
- text-align: center;
- border: 1px solid #ccc;
- color: #000;
-}
-
-
-
-#content input.right, #content select.right {
- float: right;
-}
-#vnlistchange { width: 130px; }
-p.opts {
- clear: left;
- text-align: center;
- width: 100%;
- background-color: #f0f0f0;
- margin-bottom: 10px;
- margin-top: 10px;
- padding: 1px 0;
-}
-ul#stats {
- clear: left;
- list-style-type: none;
- padding: 0px 0 0 5px;
-}
-ul#stats li {
- padding: 0;
- display: block;
- width: 345px;
- float: left;
- margin: 0 0 20px 0;
-}
-ul#stats li.break {
- clear: left;
-}
-
-acronym {
- border-bottom: 1px dotted #999;
-}
-acronym.date {
- border: 0;
-}
-b.future { font-weight: normal; color: #900; }
-
-
-/* icon image sprites */
-
-a.rss {
- display: block;
- height: 16px;
- width: 16px;
- background: url(/files/rss.png) no-repeat;
- text-indent: -9999px;
- overflow: hidden;
- float: right;
-}
-.icons, .uicons {
- background: url(/files/icons.png) no-repeat;
- width: 16px;
- height: 14px;
- margin: 0 2px 0 0;
- overflow: hidden;
- display:-moz-inline-stack;
- display: inline-block;
- padding: 0;
- border: 0;
- text-decoration: none;
-}
-.uicons {
- width: 14px;
- margin: 0;
- background: url(/files/uicons.png) no-repeat;
-}
-.icons.lang {
- width: 13px;
- height: 11px;
- border: 1px solid #999;
- /* see def.js for an ugly FF hack */
-}
-.icons.par, .icons.tri, .icons.com { width: 11px; }
-acronym.icons, acronym.uicons { cursor: default; }
-.icons.oth { background: none; }
-.icons.drc { background-position: 0px 0px; }
-.icons.lin { background-position: 0px -14px; }
-.icons.nds { background-position: 0px -28px; }
-.icons.ps2 { background-position: 0px -42px; }
-.icons.sfc { background-position: 0px -56px; }
-.icons.gba { background-position: 0px -70px; }
-.icons.ps3 { background-position: 0px -84px; }
-
-.icons.dvd { background-position: -16px 0px; }
-.icons.mac { background-position: -16px -14px; }
-.icons.ps1 { background-position: -16px -28px; }
-.icons.psp { background-position: -16px -42px; }
-.icons.win { background-position: -16px -56px; }
-.icons.wii { background-position: -16px -70px; }
-.icons.xb3 { background-position: -16px -84px; }
-
-.icons.com { background-position: -32px 0px; }
-.icons.par { background-position: -32px -14px; }
-.icons.tri { background-position: -32px -28px; }
-.icons.ext { background-position: -32px -42px; }
-.icons.msx { background-position: -32px -56px; }
-.icons.nes { background-position: -32px -70px; }
-
-.icons.cs { background-position: -48px 0px; }
-.icons.da { background-position: -48px -11px; }
-.icons.de { background-position: -48px -22px; }
-.icons.en { background-position: -48px -33px; }
-.icons.es { background-position: -48px -44px; }
-.icons.fi { background-position: -48px -55px; }
-.icons.fr { background-position: -48px -66px; }
-.icons.it { background-position: -48px -77px; }
-.icons.ja { background-position: -48px -88px; }
-
-.icons.nl { background-position: -61px 0px; }
-.icons.no { background-position: -61px -11px; }
-.icons.pl { background-position: -61px -22px; }
-.icons.pt { background-position: -61px -33px; }
-.icons.ru { background-position: -61px -44px; }
-.icons.sv { background-position: -61px -55px; }
-.icons.tr { background-position: -61px -66px; }
-.icons.zh { background-position: -61px -77px; }
-.icons.ko { background-position: -61px -88px; }
-
-.uicons.no { background-position: 0px 0px; }
-.uicons.r0 { background-position: 0px -14px; }
-.uicons.v0 { background-position: 0px -14px; }
-.uicons.r1 { background-position: 0px -28px; }
-.uicons.r2 { background-position: 0px -42px; }
-.uicons.r3 { background-position: 0px -56px; }
-
-.uicons.r4 { background-position: -14px 0px; }
-.uicons.v1 { background-position: -14px -14px; }
-.uicons.v2 { background-position: -14px -28px; }
-.uicons.v3 { background-position: -14px -42px; }
-.uicons.v4 { background-position: -14px -56px; }
-
-
-/* tables */
-
-table td { vertical-align: top; }
-table { width: 100%; border-collapse: collapse; }
-thead tr td { font-weight: bold; }
-thead tr td a { text-decoration: none; }
-#content table input {
- width: 13px;
- height: 13px;
- margin: 0;
- float: right;
-}
-
-/* revisions */
-#tmc { width: 650px; margin: 0 0 30px 30px; border: 1px solid #ddd; background-color: #fbfbfb; clear: both; }
-#tmc thead tr td { font-weight: normal; text-align: center; }
-#tmc .tc1, #tmc .tc2 { border-right: 1px solid #ddd; }
-#tmc .tc1 { font-weight: bold; padding-right: 10px; }
-#tmc .tc1 { width: 100px; }
-#tmc .tc2, #tmc .tc3 { width: 275px; }
-div#tmc { text-align: center; }
-div#revbrowse { margin: 20px 0 0 30px; width: 650px; text-align: center; } /* position: relative; top: 17px; left: 30px; */
-a#revnext { float: right }
-a#revprev { float: left; }
-b.diff_add { font-weight: normal; background-color: #cfc; }
-b.diff_del { font-weight: normal; background-color: #fcc; }
-
-#tvg tr, #tus tr { background-color: #fff!important }
-#tvg .tc1, #tus .tc1 { width: 25px; text-align: right; padding-right: 3px; }
-#tvg .tc2 div, #tus .tc2 div { margin: 0 5px 0 0; padding: 0; float: left; background: url(/files/graph.png); height: 13px; }
-#tus .tc1 { width: 60px }
-
-#tvr .tc3, #tvl .tc5, #tur .tc3, #tul .tc8, #thi .tc6 { text-align: right }
-
-#tvl .tc1, #tvl .tc2, #tvl .tc3 { white-space: nowrap; padding-right: 10px; }
-
-#thi { clear: both }
-#thi .tc1_1 { text-align: right; padding-right: 0; width: 10px; }
-#thi .tc1_2 { padding-left: 0; padding-right: 10px; }
-#thi .tc1_1 a, #thi .tc1_2 a { text-decoration: none }
-#thi .tc1 { width: 10px }
-#thi .tc2 { width: 110px; }
-
-#rli tr.relhid { background-color: #fff!important; }
-#rli td.relhid, #relhidpar { cursor: pointer; }
-#rli td.relnone { color: #aaa }
-#rli .tc1 { width: 560px; }
-#rli .tc2 { width: 80px; }
-#rli .tc3 { width: 50px; }
-#rli .tc1_1 { width: 70px; padding-left: 20px }
-#rli .tc1_2 { width: 40px; padding:0; text-align: right; }
-#rli .tc1_3 { width: 430px; }
-#rli .tc1_3 a { color: #203c36; }
-#rli .tc1_5 { text-align: right }
-
-#tre tr { background-color: #fff!important; }
-#tre tr.lang { background-color: #f5f5f5!important; font-style: italic; }
-
-#tre .tc1 { width: 75px; padding-left: 10px; }
-#tre .tc2 { width: 50px; text-align: center; white-space: nowrap; }
-#tre .tc3, #tre .tc6 { width: 16px; margin: 0; padding: 0; white-space: nowrap; text-align: right }
-#tre .tc3 { width: 70px; }
-#tre .tc5 { width: 30px; text-align: right; padding: 0 10px 0 0; }
-#tre .tc5 a { display: block; width: 30px; text-align: right;text-decoration: none; }
-
-#tbv .tc2 acronym, #tbv .tc3 acronym {
- zoom: 1;
- opacity: 0.7;
- filter:alpha(opacity=70);
- -moz-opacity: 0.7;
-}
-#tbv .tc2, #tbv .tc3 { margin: 0; padding: 0; white-space: nowrap }
-#tbv .tc2 { text-align: right; padding-right: 3px; }
-
-#tpd .tc1 { margin: 0; padding: 0; }
-
-
-/* message board */
-
-#tth tr { border-top: 1px solid #999 }
-#tth .tc1 { width: 150px; border-right: 1px solid #999; padding: 5px; }
-#tth .tc2 { padding: 5px }
-#tth p.mod { margin: -5px; font-size: 10px; }
-#tth .tc2 i { font-size: 10px; float: right; }
-#tth .tc2 b.hidden { font-size: 10px; color: #888; font-weight: normal; }
-#tin .tc1 { width: 400px; }
-#tin .tc2 { width: 25px; }
-#tin .tc4 { text-align: right }
-#tin .tc1 b { font-weight: normal; color: #888; }
-#qreply { display: block; width: 100%; text-align: center }
-#qreply textarea, #qreply input { float: none; margin: auto; }
-a.right { float: right }
-b.spoiler { font-weight: normal; color: #ccc; background-color: #ccc }
-b.spoiler:hover { color: #000; background-color: #eee }
-
-
-
-#debug {
- border-top: 1px solid #ffb4b4;
- background-color: #ffece3;
- height: 70px;
- overflow: auto;
- position: fixed;
- left: 0;
- bottom: 0;
- width: 100%;
- font-size: 10px;
- margin: 0;
- padding: 0;
-}
-
diff --git a/static/files/uicons.png b/static/files/uicons.png
deleted file mode 100644
index 09f8da17..00000000
--- a/static/files/uicons.png
+++ /dev/null
Binary files differ
diff --git a/static/files/warning.png b/static/files/warning.png
deleted file mode 100644
index b8af1a53..00000000
--- a/static/files/warning.png
+++ /dev/null
Binary files differ
diff --git a/util/fcgi.pl b/util/fcgi.pl
deleted file mode 100644
index 6a391386..00000000
--- a/util/fcgi.pl
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/perl
-
-package FCGI::Handler;
-
-use strict;
-use warnings;
-use lib '/www/vndb/lib';
-
-use strict;
-use warnings;
-use FCGI;
-use CGI::Minimal ();
-use CGI::Cookie::XS;
-use Time::HiRes;
-use VNDB;
-
-my $elog = "/www/err.log";
-
-our $req = FCGI::Request();
-our $c;
-our $outputted = 0;
-
-my $VNDB = VNDB->new(%VNDB::VNDBopts);
-
-our @WRN;
-$SIG{__WARN__} = sub { push @FCGI::Handler::WRN, @_; };
-
-while($req->Accept() >= 0) {
- # lighty doesn't always split the query string from REQUEST_URI
- ($ENV{REQUEST_URI}, $ENV{QUERY_STRING}) = split /\?/, $ENV{REQUEST_URI}
- if ($ENV{REQUEST_URI}||'') =~ /\?/;
-
- # re-init CGI::Minimal (can die())
- eval {
- CGI::Minimal::reset_globals;
- CGI::Minimal::allow_hybrid_post_get(1);
- CGI::Minimal::max_read_size(5*1024*1024); # allow 5MB of POST data
- $c = CGI::Minimal->new();
- };
- if($@) {
- send500();
- $req->Finish();
- next;
- }
-
- # figure out some required variables
- my $o = $VNDB;
- my $start = [ Time::HiRes::gettimeofday ] if $o->{debug};
-
- # call appropriate functions in VNDB.pm
- my $e = eval {
- if($c->truncated) {
- send500();
- warn "Truncated post request!\n";
- } else {
- $o->DBCheck;
- $o->get_page; # automatically calls DBCommit on success
- }
- 1;
- };
-
- # Error handling
- if(@WRN && $e && !$@ && open(my $F, '>>', $elog)) {
- for (@WRN) {
- chomp;
- printf $F "[%s] %s: %s\n", scalar localtime(), $ENV{HTTP_HOST}.$ENV{REQUEST_URI}.'?'.$ENV{QUERY_STRING}, $_;
- }
- close $F;
- }
- if(!defined $e && $@ && open(my $F, '>>', $elog)) {
- printf $F "[%s] %s: FATAL ERROR!\n", scalar localtime(), $ENV{HTTP_HOST}.$ENV{REQUEST_URI}.'?'.$ENV{QUERY_STRING};
- print $F " ENV-dump:\n";
- printf $F " %s: %s\n", $_, $ENV{$_} for (sort keys %ENV);
- print $F " PARAM-dump:\n";
- printf $F " %s: %s\n", $_, $c->param($_) for (sort $c->param());
- my $err = $@; chomp($err);
- printf $F " ERROR:\n %s\n", $err;
- if(@WRN) {
- print $F " WARNINGS:\n";
- for (@WRN) {
- chomp;
- printf $F " %s\n", $_;
- }
- }
- print $F "\n";
- close $F;
- eval { $o->DBRollBack; };
- send500() if !$outputted;
- }
-
- # Debug info
- if($o->{debug} && open(my $F, '>>', $elog)) {
- my($sqlt, $sqlc) = (0, 0);
- for (@{$o->{_DB}->{Queries}}) {
- if($_->[0]) {
- $sqlc++;
- $sqlt += $_->[1];
- }
- }
- my $time = Time::HiRes::tv_interval($start);
- my $tpl = $o->{_Res}->{_tpltime} ? $o->{_Res}->{_tpltime}/$time*100 : 0;
- my $gzip = 0;
- $gzip = 100 - $o->{_Res}->{_gzip}->[1]/$o->{_Res}->{_gzip}->[0]*100
- if($o->{_Res}->{_gzip} && ref($o->{_Res}->{_gzip}) eq 'ARRAY' && $o->{_Res}->{_gzip}->[0] > 0);
- printf $F "Took %3dms (SQL/TPL/perl: %4.1f%% %4.1f%% %4.1f%%) (GZIP: %4.1f%%) to parse %s\n",
- $time*1000, $sqlt/$time*100, $tpl, 100-($sqlt/$time*100)-$tpl, $gzip, $ENV{REQUEST_URI};
- close $F;
- }
-
- # reset vars
- @WRN = ();
- $outputted = 0;
- undef $o->{_Res};
- undef $o->{_Req};
-
- $req->Finish();
-}
-
-sub send500 {
- print "Status: 500 Internal Server Error\n";
- print "Content-Type: text/html\n";
- print "X-Sendfile: /www/vndb/www/files/err.html\n\n";
-}
-