diff options
author | yorhel <yorhel@1fe2e327-d9db-4752-bcf7-ef0cb4a1748b> | 2008-05-19 07:01:24 +0000 |
---|---|---|
committer | yorhel <yorhel@1fe2e327-d9db-4752-bcf7-ef0cb4a1748b> | 2008-05-19 07:01:24 +0000 |
commit | 2ce770e7e5817f8838fdaf7bc7eda2a8da972962 (patch) | |
tree | 4aa6306599d38b6af01c8495d6731a838944602e | |
parent | 8b72b6535a553f8751842369a3abc0016d18611e (diff) |
Too many changes to keep track of. See ChangeLog. (I should commit more often -.-)
git-svn-id: svn://vndb.org/vndb@13 1fe2e327-d9db-4752-bcf7-ef0cb4a1748b
-rw-r--r-- | data/tpl/defs.pl | 26 | ||||
-rw-r--r-- | data/tpl/home | 10 | ||||
-rw-r--r-- | data/tpl/main | 5 | ||||
-rw-r--r-- | data/tpl/pbrowse | 16 | ||||
-rw-r--r-- | data/tpl/redit | 2 | ||||
-rw-r--r-- | data/tpl/vnbrowse | 110 | ||||
-rw-r--r-- | data/tpl/vnedit | 2 | ||||
-rw-r--r-- | data/tpl/vnpage | 37 | ||||
-rw-r--r-- | data/tpl/vnpage_rel | 6 | ||||
-rw-r--r-- | data/tpl/vnpage_stats | 6 | ||||
-rw-r--r-- | lib/ChangeLog | 12 | ||||
-rw-r--r-- | lib/Multi/Anime.pm | 3 | ||||
-rw-r--r-- | lib/Multi/IRC.pm | 60 | ||||
-rw-r--r-- | lib/Multi/Maintenance.pm | 20 | ||||
-rw-r--r-- | lib/Multi/RG.pm | 2 | ||||
-rw-r--r-- | lib/VNDB.pm | 7 | ||||
-rw-r--r-- | lib/VNDB/Releases.pm | 2 | ||||
-rw-r--r-- | lib/VNDB/Util/DB.pm | 18 | ||||
-rw-r--r-- | lib/VNDB/VN.pm | 72 | ||||
-rw-r--r-- | lib/global.pl | 15 | ||||
-rw-r--r-- | static/files/16x14.png | bin | 2397 -> 0 bytes | |||
-rw-r--r-- | static/files/def.js | 152 | ||||
-rw-r--r-- | static/files/icons.png | bin | 0 -> 2816 bytes | |||
-rw-r--r-- | static/files/style.css | 177 | ||||
-rw-r--r-- | util/multi.pl | 2 | ||||
-rw-r--r-- | util/updates/update_1.16.sql | 74 |
26 files changed, 519 insertions, 317 deletions
diff --git a/data/tpl/defs.pl b/data/tpl/defs.pl index 6c70a68b..405cc2a5 100644 --- a/data/tpl/defs.pl +++ b/data/tpl/defs.pl @@ -19,14 +19,14 @@ 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 = 0 -> Month + day unknown, year known -# d = 0 -> Day unknown, month + year known +# m = 99 -> Month + day unknown, year known +# d = 99 -> Day unknown, month + year known sub datestr { - my $d = $_[0]||'00000000'; - my @d = map { int } $1, $2, $3 if $d =~ /^([0-9]{4})([0-9]{2})([0-9]{2})$/; + 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] ? '%04d' : !$d[2] ? '%04d-%02d' : '%04d-%02d-%02d', @d; - my $b = $r gt Time::CTime::strftime("%Y-%m-%d", gmtime()); + my $r = sprintf $d[1] == 99 ? '%04d' : $d[2] == 99 ? '%04d-%02d' : '%04d-%02d-%02d', @d; $r = 'TBA' if $d[0] == 9999; return ($b?'<b class="future">':'').$r.($b?'</b>':''); } @@ -134,7 +134,8 @@ sub summary { # cmd, len, def my $res = ''; my $len = 0; my $as = 0; - for (split / /, $_[0]) { + (my $txt = $_[0]) =~ s/\r?\n/\n /g; + for (split / /, $txt) { next if !defined $_ || $_ eq ''; my $l = length; s/\&/&/g; @@ -146,7 +147,7 @@ sub summary { # cmd, len, def } if(!$as && s/(http|https):\/\/(.+[0-9a-zA-Z=\/])/<a href="$1:\/\/$2" rel="nofollow">link<\/a>/) { $l = 4; - } elsif(!$as) { + } elsif($as) { s/^([duvpr][0-9]+)[^\w]*$/<a href="\/$1">$1<\/a>/; } while(s/\[\/url\]/<\/a>/) { @@ -157,8 +158,8 @@ sub summary { # cmd, len, def last if $_[1] && $len > $_[1]; $res .= "$_ "; } - $res =~ y/\r\n/ / if $_[1]; - $res =~ s/\r?\n/<br \/>/g if !$_[1]; + $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]; @@ -179,7 +180,7 @@ sub ttabs { # [vrp], obj, sel '<a href="/%s/del" id="idel">del</a>', sprintf('<a href="/%%s/hide"%s>%s</a>', $t eq 'v' ? ' id="vhide"' : '', $$o{hidden} ? 'unhide' : 'hide') ) : (), - !$$o{locked} || ($p{Authedit} && $p{Authlock}) ? + (!$$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>') : (), $p{Authhist} ? @@ -247,8 +248,7 @@ my %pagetitles = ( 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' ? sprintf 'Search results for "%s"', $p{searchquery} : - $p{vnbrowse}{chr} eq 'cat' ? 'Browse categories' : + 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' : diff --git a/data/tpl/home b/data/tpl/home index 37ada1d8..e8e9158d 100644 --- a/data/tpl/home +++ b/data/tpl/home @@ -13,13 +13,13 @@ or to discuss about the database at our <a href="http://forum.vndb.org/">forums</a>. </p> -<h3 class="home">VNDB 1.14!</h3> +<h3 class="home">VNDB 1.15!</h3> <p class="desc"> - A large update technical-wise, but no major noticable changes: Large cover images will now automatically - get resized, all static content has been moved to a separate domain, the Nintento Wii has been - added to the platform list, and various other small changes and bug fixes. + This update finally implements a new feature I've been wanting to see for a + while now: anime relations! Other than that, it also includes the usual bug + fixes and some other improvements. <br /> - <a href="http://forum.vndb.org/index.php?topic=49.0">Read more...</a> - <a href="http://forum.vndb.org/index.php?board=7.0">news archive</a>. + <a href="http://forum.vndb.org/index.php?topic=50.0">Read more...</a> - <a href="http://forum.vndb.org/index.php?board=7.0">news archive</a>. </p> <ul class="home"> diff --git a/data/tpl/main b/data/tpl/main index cbac2729..5c009297 100644 --- a/data/tpl/main +++ b/data/tpl/main @@ -32,7 +32,7 @@ <form id="search" method="get" action="/v/search"> <fieldset> <legend>Search</legend> - <input id="searchfield" type="text" name="q" value="[[: $p{searchquery} || 'search' ]]"[[= !$p{searchquery} ? ' style="color: #999"': '' ]]- /> + <input id="searchfield" type="text" name="sq" value="search" style="color: #999" /> <input id="searchsubmit" type="submit" value="Search" /> </fieldset> </form> @@ -75,7 +75,7 @@ <li><a href="/">Home</a></li> <li><a href="/v">Visual Novels</a></li> <li><a href="/p">Producers</a></li> - <li><a href="/v/cat">Categories</a></li> + <li><a href="/v/search">Search</a></li> <li><a href="/u/list">Users</a></li> <li><a href="/hist">Recent changes</a></li> <li><a href="/d6">FAQ</a></li> @@ -134,6 +134,7 @@ <div id="footer"> <p> vndb v[[: $VNDB::VERSION ]]- | + <a href="/d7">about us</a> | <a href="mailto:contact@vndb.org">contact@vndb.org</a> | designed by <a href="http://www.freecsstemplates.org/">free css templates</a>. </p> diff --git a/data/tpl/pbrowse b/data/tpl/pbrowse index 71b40c82..8d2604c3 100644 --- a/data/tpl/pbrowse +++ b/data/tpl/pbrowse @@ -6,8 +6,8 @@ [[ } ]]- <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!" /> + <input type="text" name="q" id="q" value="[[: $d{query} ]]" class="text" + /><input type="submit" value="Search!" /> </fieldset> </form> </p> @@ -25,17 +25,17 @@ <thead><tr> <td class="tc1">Name</td> <td class="tc2">Type</td> - <td class="tc3">Main language</td> - <td class="tc4">Website</td> + <td class="tc3">Website</td> </tr></thead> [[ for (@{$d{prods}}) { ]]- <tr> - <td class="tc1"><a href="/p[[= $_->{id} ]]">[[: $_->{name} ]]</a></td> + <td class="tc1"> + <acronym class="icons lang -[[= $_->{lang} ]]" title="[[: $VNDB::LANG->{$_->{lang}} ]]"> </acronym><a + href="/p[[= $_->{id} ]]" title="[[: $_->{original}||$_->{name} ]]">[[: $_->{name} ]]</a></td> <td class="tc2">[[: $VNDB::PROT->{$_->{type}} ]]</td> - <td class="tc3">[[: $VNDB::LANG->{$_->{lang}} ]]</td> - <td class="tc4"> + <td class="tc3"> [[ if($_->{website}) { ]] - <a href="[[: $_->{website} ]]">[[: length($_->{website}) > 30 ? substr($_->{website}, 0, 27).'...' : $_->{website} ]] + <a href="[[: $_->{website} ]]">[[: shorten $_->{website}, 50 ]] [[ } else { ]]---[[ } ]] </td> </tr> diff --git a/data/tpl/redit b/data/tpl/redit index 9567cce0..4bac5e24 100644 --- a/data/tpl/redit +++ b/data/tpl/redit @@ -42,7 +42,7 @@ { 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="plat '.$_.'" title="'.$VNDB::PLAT->{$_}.'"> </acronym>'.$VNDB::PLAT->{$_}.'</label></li>' + '<label for="'.$_.'"><acronym class="icons '.$_.'" title="'.$VNDB::PLAT->{$_}.'"> </acronym>'.$VNDB::PLAT->{$_}.'</label></li>' } sort { $VNDB::PLAT->{$a} cmp $VNDB::PLAT->{$b} } keys %$VNDB::PLAT).'</ul>' }, { type => 'static', text => '<br />' }, diff --git a/data/tpl/vnbrowse b/data/tpl/vnbrowse index 27aa78b7..fef795a3 100644 --- a/data/tpl/vnbrowse +++ b/data/tpl/vnbrowse @@ -1,31 +1,56 @@ <h2>[[: $p{PageTitle} ]]</h2> -[[ if($d{chr} eq 'cat') { ]]- -<ul id="cat"> -[[ for my $c (qw| e g p t l s |) { ]]- - -[[= $c ne 'l' && $c ne 'p' ? '<li>' : '<br />' ]][[: $VNDB::CAT->{$c}[0] ]]- - <ul> - [[ for (sort keys %{$VNDB::CAT->{$c}[1]}) { ]]- - <li class="cat_[[= $c.$_ ]][[= $d{incl} =~ /$c$_/ ? ' inc' : $d{excl} =~ /$c$_/ ? ' exc' : '' ]]"> - [[: $VNDB::CAT->{$c}[1]{$_} ]]- ([[= $d{cat}{$c.$_} || 0 ]])</li> - [[ } ]] - </ul>[[= $c ne 't' && $c ne 'g' ? '</li>' : '' ]]- -[[ } ]]- -</ul> -<div id="lfilter"> - <b>Languages</b> (none selected means all)<br /> -[[ for (sort keys %{$d{lang}}) { next if !$d{lang}{$_}; ]]- - <input type="checkbox" name="lang_[[= $_ ]]" id="lang_[[= $_ ]]" value="1" -[[= $d{slang}=~/$_/?'checked="checked"':'' ]] /> - <label for="lang_[[= $_ ]]">[[: $VNDB::LANG->{$_} ]]- ([[= $d{lang}{$_} ]])</label> -[[ } ]]- -</div> -<br style="clear: left" /> -<input type="button" class="right" id="catsearch" name="catsearch" value="Search!" /> -<br style="clear: left" /> -<br /> -<br /> -[[ } elsif($d{chr} ne 'search') { ]]- +[[ 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} ? '▾' : '▸' ]]- advanced options</b> + </fieldset> + </form> + + <div id="adsearch" [[= !$p{searchquery} ? '' : ' style="display: none"' ]]> + <b>Categories</b> (inclusive, selecting more gives less results) + <ul id="cat"> + [[ for my $c (qw| e g p t l s |) { ]]- + -[[= $c ne 'l' && $c ne 'p' ? '<li>' : '<br />' ]][[: $VNDB::CAT->{$c}[0] ]]- + <ul> + [[ for (sort keys %{$VNDB::CAT->{$c}[1]}) { my $ca = $c.$_; ]]- + <li[[= (grep /$ca/, @{$d{incl}}) ? ' class="inc"' : (grep /$ca/, @{$d{excl}}) ? ' class="exc"' : '' ]]- id="cat_[[= $ca ]]"> + [[: $VNDB::CAT->{$c}[1]{$_} ]]- ([[= $d{cat}{$ca} || 0 ]])</li> + [[ } ]] + </ul>[[= $c ne 't' && $c ne 'g' ? '</li>' : '' ]]- + [[ } ]]- + </ul> + <br style="clear: both" /> + <br /> + + <b>Languages</b> (exclusive, 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} ]]" [[= (grep /$l/, @{$d{lang}}) ? ' checked="checked"' : '' ]]- /> + <label for="lang_[[= $l ]]"><acronym class="icons lang -[[= $l ]]" title="[[: $VNDB::LANG->{$l} ]]"> </acronym>([[= $d{langc}{$l} ]])</label></li> + [[ } ]]- + </ul> + <br style="clear: both" /> + <br /> + + <b>Platforms</b> (exclusive, 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} ]]" [[= (grep /$l/, @{$d{plat}}) ? ' checked="checked"' : '' ]]- /> + <label for="plat_[[= $l ]]"><acronym class="icons -[[= $l ]]" title="[[: $VNDB::PLAT->{$l} ]]"> </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) { ]]- @@ -35,23 +60,16 @@ </p> [[ } ]]- + -[[ if($#{$d{vn}} < 0) { ]] + -[[ if($d{chr} eq 'search' && $p{searchquery} || $d{chr} ne 'search') { ]] <p> - -[[ if($d{chr} eq 'cat' && !$d{scat}[0][0] && !$d{scat}[0][1]) { ]] - Select some categories and hit the "Search" button to get a list of visual novels. Click on a - category again to exclude it.<br /> - Please keep in mind that not all visual novels have the correct categories set, so you - may not always find what you are looking for. - [[ } else { ]] No results again, life sucks... :'( - [[ } ]]- </p> + [[ } ]] [[ } else { my %url = ( $p{searchquery} ? ( q => $p{searchquery} ) : (), - $d{incl} ? ( i => $d{incl} ) : (), - $d{excl} ? ( e => $d{excl} ) : (), - $d{slang} ? ( l => $d{slang} ) : (), ); my %urls = ( %url, $d{order}[0] ne 'title' ? ( s => $d{order}[0] ) : (), @@ -67,19 +85,25 @@ <table id="tbv"> <thead><tr> <td class="tc1">Title [[= sortbut($url, 'title') ]]</td> - <td class="tc2">Released [[= sortbut($url, 'released') ]]</td> - <td class="tc3">Languages</td> - <td class="tc4">Rating [[= sortbut($url, 'votes') ]]</td> + <td class="tc2"> </td> + <td class="tc3"> </td> + <td class="tc4">Released [[= sortbut($url, 'released') ]]</td> + <td class="tc5">Rating [[= sortbut($url, 'votes') ]]</td> </tr></thead> [[ for (@{$d{vn}}) { $_->{c_votes} =~ s#^([0-9]{2}.[0-9]{2})\|([0-9]{4})$#$1 == 0 ? sprintf '- (%d)', $2 : sprintf '%.2f (%d)', $1, $2#e; - $_->{c_released} =~ s#^([0-9]{4})([0-9]{2}).+#$1==0?'N/A':$1==9999?'TBA':(($2&&$2>0?($Time::CTime::MoY[$2-1].' '):'').$1)#e; + $_->{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->{$_}).'"> </acronym>' : () + } split /\//, $_->{c_platforms}; + $_->{c_languages} = join '', map qq|<acronym class="icons lang $_" title="$$VNDB::LANG{$_}"> </acronym>|, reverse sort split /\//, $_->{c_languages}; ]]- <tr> - <td class="tc1"><a href="/v[[= $_->{id} ]]">[[: $_->{title} ]]</a></td> - <td class="tc2">[[: $_->{c_released} ]]</td> - <td class="tc3">[[: $_->{c_languages} || 'N/A' ]]</td> - <td class="tc4">[[: $_->{c_votes} ]]</td> + <td class="tc1"><a href="/v[[= $_->{id} ]]" title="[[: $_->{title} ]]">[[: shorten $_->{title}, 50 ]]</a></td> + <td class="tc2">[[= $_->{c_platforms} ]]</td> + <td class="tc3">[[= $_->{c_languages} ]]</td> + <td class="tc4">[[: $_->{c_released} ]]</td> + <td class="tc5">[[: $_->{c_votes} ]]</td> </tr> [[ } ]]- </table> diff --git a/data/tpl/vnedit b/data/tpl/vnedit index 0e46ba47..b0869b45 100644 --- a/data/tpl/vnedit +++ b/data/tpl/vnedit @@ -45,7 +45,7 @@ { type => 'static', text => '<br />' }, { type => 'input', name => 'External links', short => 'l_wp', pre => 'http://en.wikipedia.org/wiki/' }, { type => 'input', name => ' ', short => 'l_vnn', pre => 'http://visual-novels.net/vn/index.php?option=com_content&task=view&id=', class => 'shortopts' }, - { type => 'input', name => ' ', short => 'l_cisv', pre => 'http://cisvisual.net/title/', class => 'shortopts' }, +# { type => 'input', name => ' ', short => 'l_cisv', pre => 'http://cisvisual.net/title/', class => 'shortopts' }, { type => 'static', text => '<br />' }, { type => 'input', name => 'Related anime', short => 'anime' }, diff --git a/data/tpl/vnpage b/data/tpl/vnpage index 1388fd03..84c00fc2 100644 --- a/data/tpl/vnpage +++ b/data/tpl/vnpage @@ -69,18 +69,32 @@ my @links = ( $d{vn}{l_wp} ? [ 'Wikipedia', 'http://en.wikipedia.org/wiki/%s', $d{vn}{l_wp} ] : (), $d{vn}{l_vnn} ? [ 'V-N.net', 'http://visual-novels.net/vn/index.php?option=com_content&task=view&id=%d', $d{vn}{l_vnn} ] : (), - $d{vn}{l_cisv} ? [ 'CISVisual', 'http://cisvisual.net/title/%d', $d{vn}{l_cisv} ] : (), +# $d{vn}{l_cisv} ? [ 'CISVisual', 'http://cisvisual.net/title/%d', $d{vn}{l_cisv} ] : (), ); -if($d{vn}{length} || $d{vn}{alias} || @links) { ]] + 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($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($_->{name}), _hchar shorten $_->{name}, 30) => 1 + } @{$_->{producers}} )) for (@{$d{rel}}); + if(keys %l) { ]]- + <acronym class="icons lang -[[= $l ]]" title="[[: $VNDB::LANG->{$l} ]]"> </acronym>[[= join(' & ', keys %l) ]]<br /> + [[ } } ]] + </dd>[[ } ]]- [[ if(@links > 0) { ]]- <dt>Links</dt><dd>[[= join(', ', map { '<a href="'.sprintf($_->[1],$_->[2]).'">'.$_->[0].'</a>' } @links) ]]</dd>[[ } ]]- + <dt>Rating</dt><dd>[[: $d{vn}{c_votes} ]]</dd> </dl> [[ } ]]- @@ -129,25 +143,6 @@ if($d{vn}{length} || $d{vn}{alias} || @links) { ]] [[ } ]] </ul> [[ } ]]- - - [[ if(@lang && grep { @{$_->{producers}} } @{$d{rel}}) { ]]- - <h3>Producers</h3> - <dl> - [[ for my $l (@lang) { my %l; - $_->{language} eq $l && (%l = ( %l, map { - sprintf('<a href="/p%d" title="%s">%s</a>', - $_->{id}, _hchar($_->{name}), _hchar shorten $_->{name}, 30) => 1 - } @{$_->{producers}} )) for (@{$d{rel}}); - if(keys %l) { ]]- - <dt>[[: $VNDB::LANG->{$l} ]]</dt><dd>[[= join(' & ', keys %l) ]]</dd> - [[ } } ]] - </dl> - [[ } ]]- - - <h3>[[= $d{page} eq 'stats' ? 'User stats' : '<a href="/v'.$d{vn}{id}.'/stats">User stats</a>' ]]</h3> - <dl> - <dt>Rating</dt><dd>[[: $d{vn}{c_votes} ]]</dd> - </dl> </div> -[[ diff --git a/data/tpl/vnpage_rel b/data/tpl/vnpage_rel index ea5c5235..e213c12f 100644 --- a/data/tpl/vnpage_rel +++ b/data/tpl/vnpage_rel @@ -30,11 +30,11 @@ <td class="tc1">[[= datestr($_->{released}) ]]</td> <td class="tc2">[[= $_->{minage}<0 ? '' : $VNDB::VRAGES->{$_->{minage}} ]]</td> <td class="tc3"> - [[= join('', map { $_ ne 'oth' ? '<acronym class="plat '.$_.'" title="'._hchar($VNDB::PLAT->{$_}).'"> </acronym>' : () } sort @{$_->{platforms}}) ]] - <acronym title="[[= $VNDB::RTYP->[$_->{type}] ]]- release" class="plat -[[= lc substr($VNDB::RTYP->[$_->{type}],0,3) ]]"> </acronym> + [[= join('', map { $_ ne 'oth' ? '<acronym class="icons '.$_.'" title="'._hchar($VNDB::PLAT->{$_}).'"> </acronym>' : () } sort @{$_->{platforms}}) ]] + <acronym title="[[= $VNDB::RTYP->[$_->{type}] ]]- release" class="icons -[[= lc substr($VNDB::RTYP->[$_->{type}],0,3) ]]"> </acronym> </td> <td class="tc4"><a href="/r[[= $_->{id} ]]" title="[[: $_->{original} || $_->{title} ]]">[[: shorten $_->{title},60 ]]</a></td> - <td class="tc5">[[ if($_->{website}) { ]]<a href="[[: $_->{website} ]]" class="plat ext" title="WWW"> </a>[[ } ]]</td> + <td class="tc5">[[ if($_->{website}) { ]]<a href="[[: $_->{website} ]]" class="icons ext" title="WWW"> </a>[[ } ]]</td> </tr> [[ } ]]- [[ } ]]- diff --git a/data/tpl/vnpage_stats b/data/tpl/vnpage_stats index dde9aed3..7108486e 100644 --- a/data/tpl/vnpage_stats +++ b/data/tpl/vnpage_stats @@ -8,8 +8,8 @@ } ]] [[ if(!$d{user} || ($d{pv} && $d{user}{votes})) { ]]- -<li><h3>Vote graph <b class="actions">[[= $total ]]- vote[[= $total==1?'':'s' ]]- total - [[= $total ? sprintf(', average: %.1f.', $sum/$total) : '' ]]</b></h3> +<li><h3>Vote graph <p class="actions">[[= $total ]]- vote[[= $total==1?'':'s' ]]- total + [[= $total ? sprintf(', average: %.1f.', $sum/$total) : '' ]]</p></h3> <table id="tvg"> [[ for (0..$#{$d{votes}{graph}}) { ]]- <tr> @@ -39,7 +39,7 @@ -[[ $max = 1; $total = 0; for (@{$d{lists}{graph}}) { $total += $_; $max = $_ if $_ > $max; } ]] [[ if(!$d{user} || ($d{pl} && $d{user}{vnlist})) { ]]- -<li class="break"><h3>VN List stats <b class="actions">[[= $total ]]- -[[= $d{user}?'visual novel':'user' ]][[= $total==1?'':'s' ]]- total</b></h3> +<li class="break"><h3>VN List stats <p class="actions">[[= $total ]]- -[[= $d{user}?'visual novel':'user' ]][[= $total==1?'':'s' ]]- total</p></h3> <table id="tus"> [[ for (0..$#$VNDB::LSTAT) { ]]- <tr> diff --git a/lib/ChangeLog b/lib/ChangeLog index 3f01492f..a9969ac5 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -10,9 +10,17 @@ TODO: uploaded or not + Use AniDB's daily title dump and implement a search feature to add anime relations without having to visit AniDB. - + Clear up style.css (or wait until the new layout is ready...) -1.15 - ? +1.16 - ? + - Release dates in the current year or month without a specified day will + be considered as not yet released + - Added platform and language icons to the VN browser + - Grouped producers, user stats and general information on the VN page + - Added language icons to producer browser + - A little CSS cleanup + - Grouped category browser into one advanced search + +1.15 - 2008-05-04 - Relation graph now also updated on VN title change - Anime relations - [js] Position of the dropdown box is now relative to the link element diff --git a/lib/Multi/Anime.pm b/lib/Multi/Anime.pm index 44fafb92..0da54e2e 100644 --- a/lib/Multi/Anime.pm +++ b/lib/Multi/Anime.pm @@ -257,7 +257,7 @@ sub updateanime { # aid, data|'notfound' # aid, ANN id, NFO id, year, type, romaji, kanji, lastfetch my @col = $_[ARG1] eq 'notfound' ? ($_[ARG0], 0, 0, 0, 0, '', '', -1) - : (split(/\|/, $_[ARG1]), int time); + : (split(/\|/, $_[ARG1], 7), int time); if($col[7] > 0) { for (@col) { @@ -269,6 +269,7 @@ sub updateanime { # aid, data|'notfound' $col[4] = $_ if lc($VNDB::ANITYPE->[$_][1]) eq lc($col[4]); } $col[4] = 0 if $col[4] !~ /^[0-9]+$/; + $col[2] = '' if $col[2] =~ /^0,/; } # try to UPDATE first diff --git a/lib/Multi/IRC.pm b/lib/Multi/IRC.pm index 984d5d5d..58789675 100644 --- a/lib/Multi/IRC.pm +++ b/lib/Multi/IRC.pm @@ -27,7 +27,7 @@ sub spawn { ); POE::Session->create( package_states => [ - $p => [qw| _start irc_001 irc_public irc_ctcp_action irc_msg vndbid shutdown |], + $p => [qw| _start irc_001 irc_public irc_ctcp_action irc_msg irccmd vndbid shutdown |], ], heap => { irc => $irc, o => { @@ -36,7 +36,8 @@ sub spawn { ircname => 'VNDB.org Multi', channel => '#vndb', @_ - } + }, + log => {}, } ); } @@ -83,9 +84,10 @@ sub irc_001 { sub irc_public { - if($_[ARG2] =~ /^!info/) { - $_[KERNEL]->post(circ => privmsg => $_[ARG1][0], - 'Hello, I am HMX-12 Multi v'.$VNDB::VERSION.' made by the great Yorhel! (Please ask Ayo for more info)'); + if($_[ARG2] =~ /^!/) { + (my $cmd = $_[ARG2]) =~ s/^!//; + my $nick = (split /!/, $_[ARG0])[0]; + $_[KERNEL]->call(irc => irccmd => $_[ARG1][0], $cmd, $nick, $nick.', '); } else { $_[KERNEL]->call(irc => vndbid => $_[ARG1][0], $_[ARG2]); } @@ -99,26 +101,39 @@ sub irc_ctcp_action { sub irc_msg { my $nick = ( split /!/, $_[ARG0] )[0]; + $_[KERNEL]->call(irc => irccmd => $nick => $_[ARG2]); +} - if(!$_[HEAP]{irc}->is_channel_operator($_[HEAP]{o}{channel}, $nick) - && !$_[HEAP]{irc}->is_channel_owner($_[HEAP]{o}{channel}, $nick) - && !$_[HEAP]{irc}->is_channel_admin($_[HEAP]{o}{channel}, $nick)) { - $_[KERNEL]->post(circ => privmsg => $nick, 'You are not my master'); - return; - } - my $m = $_[ARG2]; - if($m =~ /^say (.+)$/) { +sub irccmd { # dest, cmd, [nick], [prep] + my($dest, $cmd, $nick, $prep) = @_[ARG0..$#_]; + $nick ||= $_[ARG0]; + $prep ||= ''; + + if($cmd =~ /^info/) { + return $_[KERNEL]->post(circ => privmsg => $dest, + 'Hello, I am HMX-12 Multi v'.$VNDB::VERSION.' made by the great Yorhel!'); + } + + return $_[KERNEL]->post(circ => privmsg => $dest, + $prep.'You are not my master!') + if !$_[HEAP]{irc}->is_channel_operator($_[HEAP]{o}{channel}, $nick) + && !$_[HEAP]{irc}->is_channel_owner($_[HEAP]{o}{channel}, $nick) + && !$_[HEAP]{irc}->is_channel_admin($_[HEAP]{o}{channel}, $nick); + + if($cmd =~ /^say (.+)$/) { $_[KERNEL]->post(circ => privmsg => $_[HEAP]{o}{channel}, $1); - } elsif($m =~ /^me (.+)$/) { + } elsif($cmd =~ /^me (.+)$/) { $_[KERNEL]->post(circ => ctcp => $_[HEAP]{o}{channel}, "ACTION $1"); - } elsif($m =~ /^cmd (.+)$/) { + } elsif($cmd =~ /^cmd (.+)$/) { $_[KERNEL]->post(core => queue => $1); - } elsif($m =~ /^eval (.+)$/) { - $_[KERNEL]->post(circ => privmsg => $nick, 'eval: '.$_) + $_[KERNEL]->post(circ => privmsg => $dest => sprintf "%sExecuting command '%s'", $prep, $1); + } elsif($cmd =~ /^eval (.+)$/) { + $_[KERNEL]->post(circ => privmsg => $dest, $prep.'eval: '.$_) for (split /\r?\n/, eval($1)||$@); } else { - $_[KERNEL]->post(circ => privmsg => $nick, 'Unkown command'); } + $_[KERNEL]->post(circ => privmsg => $dest, $prep.'Unkown command'); + } # TODO: add command to view the current queue, and a method to send log messages } @@ -126,12 +141,19 @@ sub irc_msg { sub vndbid { # dest, msg my $m = $_[ARG1]; + + $_[HEAP]{log}{$_} < time-60 and delete $_[HEAP]{log}{$_} + for (keys %{$_[HEAP]{log}}); + my @id; push @id, [$1,$2,$3,$4] while $m =~ s/^(.*)([duvpr])([0-9]+)(.*)$/ $1 $4 /i; for (reverse @id) { - next if $$_[0] =~ /(\.org\/|[a-z])$/i || $$_[3] =~ /^[a-z]/i; + next if $$_[0] =~ /[a-z0-9%/]$/i || $$_[3] =~ /^[a-z]/i; my($t, $id, $ext) = (lc($$_[1]), $$_[2], $$_[3]); + next if $_[HEAP]{log}{$t.$id}; + $_[HEAP]{log}{$t.$id} = time; + if($t ne 'd') { my $s = $Multi::SQL->prepare( $t eq 'v' ? 'SELECT vr.title FROM vn_rev vr JOIN vn v ON v.latest = vr.id WHERE v.id = ?' : diff --git a/lib/Multi/Maintenance.pm b/lib/Multi/Maintenance.pm index 1f1a337e..d0aa4dbc 100644 --- a/lib/Multi/Maintenance.pm +++ b/lib/Multi/Maintenance.pm @@ -26,24 +26,18 @@ sub spawn { sub _start { $_[KERNEL]->alias_set('maintenance'); - $_[KERNEL]->call(core => register => qr/^maintenance((?: (?:all|vncache|ratings|prevcache|integrity|unkanime|logrotate))+)$/, 'cmd_maintenance'); + $_[KERNEL]->call(core => register => qr/^maintenance((?: (?:vncache|ratings|prevcache|integrity|unkanime|logrotate))+)$/, 'cmd_maintenance'); - # Perform all maintenance functions every day on 0:00 - $_[KERNEL]->post(core => addcron => '0 0 * * *', 'maintenance all'); - # rotate logs every 1st day of the month at 0:05 - $_[KERNEL]->post(core => addcron => '5 0 1 * *' => 'maintenance logrotate'); + # Perform some maintenance functions every day on 0:00 + $_[KERNEL]->post(core => addcron => '0 0 * * *', 'maintenance ratings integrity unkanime'); + # update caches and rotate logs every 1st day of the month at 0:05 + $_[KERNEL]->post(core => addcron => '5 0 1 * *' => 'maintenance vncache prevcache logrotate'); } sub cmd_maintenance { - local $_ = $_[ARG1]; - - $_[KERNEL]->yield('vncache') if /(?:vncache|all)/; - $_[KERNEL]->yield('ratings') if /(?:ratings|all)/; - $_[KERNEL]->yield('prevcache') if /(?:prevcache|all)/; - $_[KERNEL]->yield('integrity') if /(?:integrity|all)/; - $_[KERNEL]->yield('unkanime') if /(?:unkanime|all)/; - $_[KERNEL]->yield('logrotate') if /logrotate/; + $_[KERNEL]->yield($_) + for (split /\s+/, $_[ARG1]); $_[KERNEL]->post(core => finish => $_[ARG0]); } diff --git a/lib/Multi/RG.pm b/lib/Multi/RG.pm index b32fedba..ebb93013 100644 --- a/lib/Multi/RG.pm +++ b/lib/Multi/RG.pm @@ -130,7 +130,7 @@ sub relscomplete { # heap->nodes and heap->rels are now assumed to contain all n # insert all nodes, ordered by release date for (sort { $a->[2] <=> $b->[2] } values %{$_[HEAP]{nodes}}) { my $date = sprintf '%08d', $_->[2]; - $date =~ s#^([0-9]{4})([0-9]{2}).+#$1==0?'N/A':$1==9999?'TBA':(($2&&$2>0?($_[HEAP]{moy}[$2-1].' '):'').$1)#e; + $date =~ s#^([0-9]{4})([0-9]{2}).+#$1==0?'N/A':$1==9999?'TBA':(($2&&$2<13?($_[HEAP]{moy}[$2-1].' '):'').$1)#e; my $title = unidecode($_->[1]); $title = substr($title, 0, 27).'...' if length($title) > 30; diff --git a/lib/VNDB.pm b/lib/VNDB.pm index 2632a358..93f9e190 100644 --- a/lib/VNDB.pm +++ b/lib/VNDB.pm @@ -79,7 +79,8 @@ my %VNDBuris = ( # wildcards: * -> (.+), + -> ([0-9]+) v => { '/' => sub { shift->VNBrowse }, new => sub { shift->VNEdit(0); }, - '*' => sub { $_[2] =~ /^([a-z0]|all|search|cat)$/ ? shift->VNBrowse($_[1]) : shift->ResNotFound; }, + #search => sub { shift->VNSearch }, + '*' => sub { $_[2] =~ /^([a-z0]|all|search)$/ ? shift->VNBrowse($_[1]) : shift->ResNotFound; }, }, 'v+' => { '/' => sub { shift->VNPage(shift) }, @@ -128,10 +129,14 @@ my %VNDBuris = ( # wildcards: * -> (.+), + -> ([0-9]+) # 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 { }, + }, 'v+' => { votes => sub { shift->ResRedirect('/v'.(shift).'/stats', 'perm') }, }, diff --git a/lib/VNDB/Releases.pm b/lib/VNDB/Releases.pm index 6f642cba..abf3a786 100644 --- a/lib/VNDB/Releases.pm +++ b/lib/VNDB/Releases.pm @@ -87,7 +87,7 @@ sub REdit { my $released = !$frm->{released}[0] ? 0 : $frm->{released}[0] == 9999 ? 99999999 : - sprintf '%04d%02d%02d', $frm->{released}[0]||0, $frm->{released}[1]||0, $frm->{released}[2]||0; + 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} ]; diff --git a/lib/VNDB/Util/DB.pm b/lib/VNDB/Util/DB.pm index e5eba14f..a2b4a035 100644 --- a/lib/VNDB/Util/DB.pm +++ b/lib/VNDB/Util/DB.pm @@ -538,7 +538,7 @@ sub DBDelVNList { # uid, @vid # uid = 0 to delete all #-----------------------------------------------------------------------------# -sub DBGetVN { # %options->{ id rev char search order results page what cati cate lang } +sub DBGetVN { # %options->{ id rev char search order results page what cati cate lang platform } my $s = shift; my %o = ( page => 1, @@ -573,14 +573,10 @@ sub DBGetVN { # %options->{ id rev char search order results page what cati cate JOIN vn iv ON iv.latest = ivc.vid WHERE cat IN(!L) GROUP BY iv.id)| => $o{cate} ) : (), - $o{lang} && @{$o{lang}} ? ( q| - v.id IN(SELECT irv.vid - FROM releases_rev irr - JOIN releases ir ON irr.id = ir.latest - JOIN releases_vn irv ON irv.rid = irr.id - WHERE irr.language IN(!L) - AND irr.type <> 2 - AND irr.released <= TO_CHAR('today'::timestamp, 'YYYYMMDD')::integer)| => $o{lang} ) : (), + $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}) { @@ -613,7 +609,7 @@ sub DBGetVN { # %options->{ id rev char search order results page what cati cate 'JOIN users u ON u.id = c.requester' ) : (), ); - my $sel = 'v.id, v.locked, v.hidden, v.c_released, v.c_languages, v.c_votes, vr.title, vr.id AS cid, v.rgraph'; + my $sel = 'v.id, v.locked, v.hidden, v.c_released, v.c_languages, v.c_votes, v.c_platforms, vr.title, vr.id AS cid, v.rgraph'; $sel .= ', vr.alias, vr.image AS image, vr.img_nsfw, vr.length, vr.desc, vr.l_wp, vr.l_cisv, vr.l_vnn' if $o{what} =~ /extended/; $sel .= ', c.added, c.requester, c.comments, v.latest, u.username, c.prev, c.causedby' if $o{what} =~ /changes/; @@ -909,7 +905,7 @@ sub DBGetRelease { # %options->{ id vid results page rev } )}); } if($o{what} =~ /platforms/) { - ($_->{platform}=~s/\s+//||1)&&push(@{$r->[$r{$_->{rid}}]{platforms}}, $_->{platform}) for (@{$s->DBAll(q| + push(@{$r->[$r{$_->{rid}}]{platforms}}, $_->{platform}) for (@{$s->DBAll(q| SELECT rid, platform FROM releases_platforms WHERE rid IN(!l)|, diff --git a/lib/VNDB/VN.pm b/lib/VNDB/VN.pm index 4732e278..fd46672c 100644 --- a/lib/VNDB/VN.pm +++ b/lib/VNDB/VN.pm @@ -92,7 +92,7 @@ sub VNEdit { { name => 'anime', required => 0, default => '' }, { name => 'img_nsfw', required => 0 }, { name => 'categories', required => 0, default => '' }, - { name => 'relations', required => 0, default => 0 }, + { name => 'relations', required => 0, default => '' }, { name => 'comm', required => 0, default => '' }, ); $frm->{img_nsfw} = $frm->{img_nsfw} ? 1 : 0; @@ -155,8 +155,8 @@ sub VNEdit { $self->VNUpdReverse(\%old, \%new, $id, $cid); } # also regenerate relation graph if the title changes - elsif($frm->{title} ne $b4{title}) { - $self->RunCmd('relraph '.$id); + elsif(@$relations && $frm->{title} ne $b4{title}) { + $self->RunCmd('relgraph '.$id); } # check for new anime data @@ -230,25 +230,49 @@ sub VNBrowse { 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 => 'i', required => 0, default => '' }, - { name => 'e', required => 0, default => '' }, - { name => 'l', required => 0, default => '' }, - { name => 'q', required => 0}, + { name => 'q', required => 0, default => '' }, + { name => 'sq', required => 0, default => '' }, { name => 'p', required => 0, template => 'int', default => 1}, ); - my($r, $np) = $chr ne 'cat' || $f->{e} || $f->{i} || $f->{l} ? ($self->DBGetVN( - $chr =~ /^[a-z0]$/ ? ( - char => $chr ) : (), - $chr eq 'search' && $f->{q} ? ( - search => $f->{q} ) : (), - page => $f->{p}, - $chr eq 'cat' ? ( - cati => [ split /,/, $f->{i} ], - cate => [ split /,/, $f->{e} ], - lang => [ grep { $VNDB::LANG->{$_} } split /,/, $f->{l} ], - ) : (), + $f->{q} ||= $f->{sq}; + + my(@cati, @cate, @plat, @lang); + my $q = $f->{q}; + if($chr eq 'search') { + # VNDBID + return $self->ResRedirect('/'.$1, 'temp') + if $q =~ /^([vrpud][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', votes => 'v.c_votes' }->{$f->{s}}.{a=>' ASC',d=>' DESC'}->{$f->{o}}, )) : ([], 0); @@ -261,12 +285,13 @@ sub VNBrowse { npage => $np, page => $f->{p}, chr => $chr, - $chr eq 'cat' ? ( - incl => $f->{i}, - excl => $f->{e}, + $chr eq 'search' ? ( + incl => \@cati, + excl => \@cate, cat => $self->DBCategoryCount, - lang => $self->DBLanguageCount, - slang => $f->{l}, + langc => $self->DBLanguageCount, + lang => \@lang, + plat => \@plat, ) : (), order => [ $f->{s}, $f->{o} ], }, @@ -336,4 +361,3 @@ sub VNUpdReverse { # old, new, id, cid 1; - diff --git a/lib/global.pl b/lib/global.pl index 890046b2..cf8d02db 100644 --- a/lib/global.pl +++ b/lib/global.pl @@ -3,7 +3,7 @@ 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 = '1.15'; +our $VERSION = '1.16'; our $PLAT = { win => 'Windows', @@ -13,9 +13,9 @@ our $PLAT = { gba => 'Game Boy Advance', nds => 'Nintendo DS', psp => 'Playstation Portable', - ps => 'Playstation', + ps1 => 'Playstation 1', ps2 => 'Playstation 2', - dc => 'Dreamcast', + drc => 'Dreamcast', sfc => 'Super Nintendo', wii => 'Nintendo Wii', oth => 'Other' @@ -54,7 +54,7 @@ our $CAT = { g => [ 'Gameplay', { aa => 'Visual Novel', # 0..1 ab => 'Adventure', # 0..1 - ac => 'Action', + ac => "Act\x{200B}ion", # Ugliest. Hack. Ever. rp => 'RPG', st => 'Strategy', si => 'Simulation', @@ -64,7 +64,7 @@ our $CAT = { br => 'Branching', # 0..1 } ], e => [ 'Elements', { - ac => 'Action', + ac => 'Action', co => 'Comedy', dr => 'Drama', fa => 'Fantasy', @@ -82,7 +82,7 @@ our $CAT = { } ], l => [ 'Place', { ea => 'Earth', - fa => 'Fantasy World', + fa => "Fant\x{200B}asy world", sp => 'Space', } ], s => [ 'Sexual content', { @@ -102,7 +102,6 @@ our $LSTAT = [ 'Wishlist', 'Blacklist', 'Playing', - 'Finished', 'Stalled', 'Dropped', 'Other', # XXX: hardcoded at 6 @@ -291,7 +290,7 @@ our $LANG = { 'fr' => q|French|, # 'fur' => q|Friulian|, # 'fy' => q|Frisian|, - 'ga' => q|Irish|, +# 'ga' => q|Irish|, # 'gaa' => q|Ga|, # 'gay' => q|Gayo|, # 'gba' => q|Gbaya|, diff --git a/static/files/16x14.png b/static/files/16x14.png Binary files differdeleted file mode 100644 index 1cf35c08..00000000 --- a/static/files/16x14.png +++ /dev/null diff --git a/static/files/def.js b/static/files/def.js index 72b5cd80..ed7e1f41 100644 --- a/static/files/def.js +++ b/static/files/def.js @@ -75,7 +75,6 @@ function formtoggle(n) { /* 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; @@ -119,6 +118,92 @@ function dropDown(e) { +/* 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 = '▾ advanced options'; + } else { + x('adsearch').style.display = 'none'; + x('adsearchclick').innerHTML = '▸ 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) }; + } +} + +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; +} + + + + /* O N L O A D */ DOMLoad(function() { @@ -134,41 +219,10 @@ DOMLoad(function() { if(this.value.length < 1) { this.value = 'search'; this.style.color = '#999';} }; - - // browse categories - if(x('catsearch')) { - x('catsearch').onclick = function () { - var u = { i:'',e:'',l:'' }; - var l = x('cat').getElementsByTagName('li'); - var y;var j; - for(y=0;y<l.length;y++) - if((j = l[y].className.indexOf('cat_')) != -1) { - var k = l[y].className.substr(j+4, 3); - if(l[y].className.indexOf(' inc') != -1) - u.i += (u.i?',':'')+k; - if(l[y].className.indexOf(' exc') != -1) - u.e += (u.e?',':'')+k; - } - l = x('lfilter').getElementsByTagName('input'); - for(y=0;y<l.length;y++) - if(l[y].checked) - u.l+=(u.l!=''?',':'')+l[y].name.substr(5); - var url = '/v/cat'; - for (y in u) - if(u[y]) - url+=(url.indexOf('?')<0?'?':';')+y+'='+u[y]; - location.href=url; - return false; - }; - var l = x('cat').getElementsByTagName('li'); - for(i=0;i<l.length;i++) - if(l[i].className.indexOf('cat_') != -1) - l[i].onclick = function () { - try { document.selection.empty() } catch(e) { try { window.getSelection().collapse(this, 0) } catch(e) {} }; - var sel = this.className.substr(this.className.indexOf('cat_'), 7); - this.className = this.className.indexOf(' inc') != -1 ? (sel+' exc') : this.className.indexOf(' exc') != -1 ? sel : (sel + ' inc'); - }; - } + + // advanced search + if(x('adsearch')) + adsearch(); // vnlist cl('askcomment', function() { @@ -197,22 +251,9 @@ DOMLoad(function() { } } - // autocheck - cl('checkall', function () { - var l = document.getElementsByTagName('input'); - var y; - for(y=0;y<l.length;y++) - if(l[y].type == 'checkbox' && l[y].name == this.name) - l[y].checked = this.checked; - }); - - // a few confirm popups + // confirm popup cl('idel', function () { return confirm('Are you sure you want to delete this item?\n\nAll previous edits will be deleted, this action can not be reverted!') }); -// cl('vhide', function () { -// return confirm('!WARNING!\nHiding a visual novel also DELETES the following information:\n - VN Relations of ALL revisions\n - VN lists\n - Votes\nThis is NOT recoverable!'); }); - cl('massdel', function () { - return confirm('Are you sure you want to mass-delete all the selected changes?\n\nThis action can not be reverted!') }); // NSFW cl('nsfw', function () { @@ -238,7 +279,6 @@ DOMLoad(function() { formhid(); // init dyna -// if(x('vn_select') || x('md_select') || x('pd_select') || x('rl_select')) if(window.dInit) dInit(); @@ -247,3 +287,13 @@ DOMLoad(function() { for(i=1; i<sub.length; i+=2) 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('fox/3') < 0) + document.write('<style type="text/css">.icons.lang { width: 15px; height: 13px; }</style>'); + + diff --git a/static/files/icons.png b/static/files/icons.png Binary files differnew file mode 100644 index 00000000..f9cad068 --- /dev/null +++ b/static/files/icons.png diff --git a/static/files/style.css b/static/files/style.css index 5d1996c6..980e0861 100644 --- a/static/files/style.css +++ b/static/files/style.css @@ -54,12 +54,7 @@ h3 { p, ul, ol { margin: 0; } - -blockquote { - font-style: italic; -} a { -/* color: #7AB9AB;*/ color: #69A89A; } a:hover { @@ -367,6 +362,7 @@ span.warning ul, span.msg ul { padding: 0 0 0 15px; } +/* VN page header, general dl and list markup */ dt { float: left; font-style: italic; @@ -383,25 +379,13 @@ ul.vnani acronym { border: 0 } ul { padding: 0 0 0 17px; } -p.actions, #vnheader p.actions, b.actions { +p.actions { display: inline; margin: 0 0 0 5px; font-weight: normal; font-size: 12px; color: #999; } -a.relch { - color: #900; -} -a.rss { - display: block; - height: 16px; - width: 16px; - background: url(/files/rss.png) no-repeat; - text-indent: -9999px; - overflow: hidden; - float: right; -} #vnheader div { width: 256px; float: left; @@ -413,15 +397,6 @@ a.rss { #vnheader #nsfw { cursor: pointer; } -img.left { - float: left; - margin: 0 15px 0 0; -} - -img.right { - float: left; - margin: 0 0 0 15px; -} #vnheader dl, #vnheader ul { margin: 0 0 0 270px; padding: 0; @@ -431,21 +406,6 @@ img.right { margin: 5px 0 0 260px; font-size: 13px; } -#vnheader p { - margin: 0 0 0 270px; -} -#vnheader select { - width: 60px; - height: 16px; - display: inline; - float: none; - text-align: center; -} -#vnheader #vnlist { - width: 150px; - text-align: left; -} - #vnheader p.mod { margin: 0; } @@ -453,11 +413,12 @@ img.right { /* producer search */ -form#psearch { +form#psearch fieldset { display: block; - margin: 10px 0 20px 210px; + width: 700px; + text-align: center; } -* html form#psearch { margin-left: 105px; } +form#psearch input { margin: 0 auto; float: none; position: relative; display: inline } ul.home { @@ -540,10 +501,28 @@ b.mod, a.mod { } +/* 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; + margin: 0 0 0 15px; padding: 0; } ul#cat ul { @@ -589,20 +568,6 @@ i.crgn2 { font-style: normal; } i.crgn3 { font-style: normal; font-weight: bold; } -/* language filter */ - -div#lfilter { - clear: left; - padding: 10px 0 0 0; -} -div#lfilter input { - float: left; margin: 3px 3px 0 10px; -} -div#lfilter label { - float: left; margin-top: 3px; - width: 90px; -} - /* DOCUMENTATION PAGES */ #dpage h3 { margin-top: 25px; } @@ -654,10 +619,19 @@ acronym.date { b.future { font-weight: normal; color: #900; } -/* 16x14 image sprites */ +/* icon image sprites */ -.plat { - background: url(/files/16x14.png) no-repeat; +a.rss { + display: block; + height: 16px; + width: 16px; + background: url(/files/rss.png) no-repeat; + text-indent: -9999px; + overflow: hidden; + float: right; +} +.icons { + background: url(/files/icons.png) no-repeat; width: 16px; height: 14px; margin: 0 2px 0 0; @@ -668,25 +642,49 @@ b.future { font-weight: normal; color: #900; } border: 0; text-decoration: none; } -acronym.plat { cursor: default; } -.plat.oth { background: none; } -.plat.dc { background-position: 0px 0px; } -.plat.lin { background-position: 0px -14px; } -.plat.nds { background-position: 0px -28px; } -.plat.ps2 { background-position: 0px -42px; } -.plat.sfc { background-position: 0px -56px; } -.plat.gba { background-position: 0px -70px; } -.plat.ext { background-position: 0px -84px; } -.plat.par { background-position: 0px -98px; } -.plat.dvd { background-position: -16px 0px; } -.plat.mac { background-position: -16px -14px; } -.plat.ps { background-position: -16px -28px; } -.plat.psp { background-position: -16px -42px; } -.plat.win { background-position: -16px -56px; } -.plat.wii { background-position: -16px -70px; } -.plat.tri { background-position: -16px -84px; } -.plat.com { background-position: -16px -98px; } -.plat.par, .plat.tri, .plat.com { width: 11px; } +.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 { 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.ext { background-position: 0px -84px; } +.icons.par { background-position: 0px -98px; } +.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.tri { background-position: -16px -84px; } +.icons.com { background-position: -16px -98px; } +.icons.cs { background-position: -32px 0px; } +.icons.da { background-position: -32px -11px; } +.icons.de { background-position: -32px -22px; } +.icons.en { background-position: -32px -33px; } +.icons.es { background-position: -32px -44px; } +.icons.fi { background-position: -32px -55px; } +.icons.fr { background-position: -32px -66px; } +.icons.it { background-position: -32px -77px; } +.icons.ja { background-position: -32px -88px; } +.icons.ko { background-position: -32px -99px; } +.icons.nl { background-position: -45px 0px; } +.icons.no { background-position: -45px -11px; } +.icons.pl { background-position: -45px -22px; } +.icons.pt { background-position: -45px -33px; } +.icons.ru { background-position: -45px -44px; } +.icons.sv { background-position: -45px -55px; } +.icons.tr { background-position: -45px -66px; } +.icons.zh { background-position: -45px -77px; } /* tables */ @@ -733,9 +731,20 @@ b.diff_del { font-weight: normal; background-color: #fcc; } #tre tr.lang { background-color: #f5f5f5!important; font-style: italic; } #tre .tc1 { width: 75px; padding-left: 10px; } -#tre .tc2 { width: 60px; text-align: center; } +#tre .tc2 { width: 50px; text-align: center; white-space: nowrap; } #tre .tc3, #tre .tc5 { width: 16px; margin: 0; padding: 0; white-space: nowrap; text-align: right } -#tre .tc3 { width: 60px; } +#tre .tc3 { width: 70px; } + +#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; } #debug { border-top: 1px solid #ffb4b4; diff --git a/util/multi.pl b/util/multi.pl index 3e6e07a7..93c4fe44 100644 --- a/util/multi.pl +++ b/util/multi.pl @@ -80,7 +80,7 @@ Multi::Image->spawn(); Multi::Sitemap->spawn(); Multi::Anime->spawn(); Multi::Maintenance->spawn(); -Multi::IRC->spawn() if !$VNDB::DEBUG; +Multi::IRC->spawn(user => 'Multi_test', channel => '#vndb_test') if !$VNDB::DEBUG; $SIG{__WARN__} = sub {(local$_=shift)=~s/\r?\n//;$poe_kernel->call(core=>log=>1,'__WARN__: '.$_)}; diff --git a/util/updates/update_1.16.sql b/util/updates/update_1.16.sql new file mode 100644 index 00000000..c64e1d49 --- /dev/null +++ b/util/updates/update_1.16.sql @@ -0,0 +1,74 @@ + +-- empty nfo_id +UPDATE anime SET nfo_id = '' WHERE nfo_id = '0,'; + + +-- future release dates +UPDATE releases_rev + SET released = (SUBSTRING(released::text, 1, 4)||'9999')::integer + WHERE SUBSTRING(released::text, 5, 4) = '0000'; + +UPDATE releases_rev + SET released = (SUBSTRING(released::text, 1, 6)||'99')::integer + WHERE SUBSTRING(released::text, 7, 4) = '00'; + + + +-- all platforms are three-letters now +UPDATE releases_platforms SET platform = 'ps1' WHERE platform = 'ps '; +UPDATE releases_platforms SET platform = 'drc' WHERE platform = 'dc '; + + + +-- cache platforms +ALTER TABLE vn ADD COLUMN c_platforms varchar(32) NOT NULL DEFAULT ''; + +CREATE OR REPLACE FUNCTION update_vncache(id integer) RETURNS void AS $$ +DECLARE + w text := ''; +BEGIN + IF id > 0 THEN + w := ' WHERE id = '||id; + END IF; + EXECUTE 'UPDATE vn SET + c_released = COALESCE((SELECT + MIN(rr1.released) + FROM releases_rev rr1 + JOIN releases r1 ON rr1.id = r1.latest + JOIN releases_vn rv1 ON rr1.id = rv1.rid + WHERE rv1.vid = vn.id + AND rr1.type <> 2 + AND r1.hidden = 0 + AND rr1.released <> 0 + GROUP BY rv1.vid + ), 0), + c_languages = COALESCE(ARRAY_TO_STRING(ARRAY( + SELECT language + FROM releases_rev rr2 + JOIN releases r2 ON rr2.id = r2.latest + JOIN releases_vn rv2 ON rr2.id = rv2.rid + WHERE rv2.vid = vn.id + AND rr2.type <> 2 + AND rr2.released <= TO_CHAR(''today''::timestamp, ''YYYYMMDD'')::integer + AND r2.hidden = 0 + GROUP BY rr2.language + ORDER BY rr2.language + ), ''/''), ''''), + c_platforms = COALESCE(ARRAY_TO_STRING(ARRAY( + SELECT rp3.platform + FROM releases_platforms rp3 + JOIN releases_rev rr3 ON rp3.rid = rr3.id + JOIN releases r3 ON rp3.rid = r3.latest + JOIN releases_vn rv3 ON rp3.rid = rv3.rid + WHERE rv3.vid = vn.id + AND rr3.type <> 2 + AND rr3.released <= TO_CHAR(''today''::timestamp, ''YYYYMMDD'')::integer + AND r3.hidden = 0 + GROUP BY rp3.platform + ORDER BY rp3.platform + ), ''/''), '''') + '||w; +END; +$$ LANGUAGE plpgsql; + +SELECT update_vncache(0); |