diff options
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | data/style.css | 2 | ||||
-rw-r--r-- | lib/VNDB/DB/VN.pm | 7 | ||||
-rw-r--r-- | lib/VNDB/Handler/VNBrowse.pm | 64 | ||||
-rw-r--r-- | lib/VNDB/Util/CommonHTML.pm | 2 |
5 files changed, 61 insertions, 15 deletions
@@ -6,6 +6,7 @@ - Copy-add release feature - Automatically fill out title & original title when adding a release - Separated VN search filters from search box + - Tag filers on VN search 2.4 - 2009-06-07 - Release search + browser + filters diff --git a/data/style.css b/data/style.css index 2f2038aa..13f3f863 100644 --- a/data/style.css +++ b/data/style.css @@ -810,6 +810,8 @@ a.help { /****** VN browse ********/ +.vnbrowse thead .tc_s { padding-left: 30px } +.vnbrowse .tc_s { width: 65px } .vnbrowse .tc2 { text-align: right; padding: 0; } .vnbrowse .tc3 { padding: 0; } .vnbrowse .tc5 { text-align: right; padding-right: 10px; } diff --git a/lib/VNDB/DB/VN.pm b/lib/VNDB/DB/VN.pm index d0a38ced..5058c367 100644 --- a/lib/VNDB/DB/VN.pm +++ b/lib/VNDB/DB/VN.pm @@ -9,7 +9,7 @@ use VNDB::Func 'gtintype'; our @EXPORT = qw|dbVNGet dbVNAdd dbVNEdit dbVNImageId dbVNCache dbScreenshotAdd dbScreenshotGet dbScreenshotRandom|; -# Options: id, rev, char, search, lang, platform, results, page, order, what +# Options: id, rev, char, search, lang, platform, tags_include, results, page, order, what # What: extended categories anime relations screenshots relgraph ranking changes sub dbVNGet { my($self, %o) = @_; @@ -31,6 +31,8 @@ sub dbVNGet { '('.join(' OR ', map "v.c_languages ILIKE '%%$_%%'", @{$o{lang}}).')' => 1 ) : (), $o{platform} && @{$o{platform}} ? ( '('.join(' OR ', map "v.c_platforms ILIKE '%%$_%%'", @{$o{platform}}).')' => 1 ) : (), + $o{tags_include} && @{$o{tags_include}} ? ( + 'v.id IN(SELECT vid FROM tags_vn_bayesian WHERE tag IN(!l) GROUP BY vid HAVING COUNT(tag) = ?)' => [ $o{tags_include}, $#{$o{tags_include}}+1 ]) : (), # don't fetch hidden items unless we ask for an ID !$o{id} && !$o{rev} ? ( 'v.hidden = FALSE' => 0 ) : (), @@ -73,6 +75,7 @@ sub dbVNGet { 'JOIN relgraph rg ON rg.id = v.rgraph' : (), ); + my $tag_ids = $o{tags_include} && join ',', @{$o{tags_include}}; my @select = ( qw|v.id v.locked v.hidden v.c_released v.c_languages v.c_platforms vr.title vr.original v.rgraph v.c_popularity|, 'vr.id AS cid', $o{what} =~ /extended/ ? ( @@ -81,6 +84,8 @@ sub dbVNGet { qw|c.added c.requester c.comments v.latest u.username c.rev c.causedby|) : (), $o{what} =~ /relgraph/ ? 'rg.cmap' : (), $o{what} =~ /ranking/ ? '(SELECT COUNT(*)+1 FROM vn iv WHERE iv.hidden = false AND iv.c_popularity > v.c_popularity) AS ranking' : (), + $tag_ids ? + qq|(SELECT AVG(tvb.rating) FROM tags_vn_bayesian tvb WHERE tvb.tag IN($tag_ids) AND tvb.vid = v.id GROUP BY tvb.vid) AS tagscore| : (), ); my($r, $np) = $self->dbPage(\%o, q| diff --git a/lib/VNDB/Handler/VNBrowse.pm b/lib/VNDB/Handler/VNBrowse.pm index 1e02337d..d4b5c2d8 100644 --- a/lib/VNDB/Handler/VNBrowse.pm +++ b/lib/VNDB/Handler/VNBrowse.pm @@ -16,13 +16,14 @@ sub list { my($self, $char) = @_; my $f = $self->formValidate( - { name => 's', required => 0, default => 'title', enum => [ qw|title rel pop| ] }, - { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] }, + { name => 's', required => 0, default => 'tagscore', enum => [ qw|title rel pop tagscore| ] }, + { name => 'o', required => 0, enum => [ 'a','d' ] }, { name => 'p', required => 0, default => 1, template => 'int' }, { name => 'q', required => 0, default => '' }, { name => 'sq', required => 0, default => '' }, { name => 'ln', required => 0, multi => 1, enum => [ keys %{$self->{languages}} ], default => '' }, { name => 'pl', required => 0, multi => 1, enum => [ keys %{$self->{platforms}} ], default => '' }, + { name => 'ti', required => 0, default => '', maxlength => 200 }, ); return 404 if $f->{_err}; $f->{q} ||= $f->{sq}; @@ -37,39 +38,60 @@ sub list { $f->{ln} = $f->{ln}[0] ? [ @{$f->{ln}}, @lang ] : \@lang; } + my @ignored; + my @ti = map { + my $i = $self->dbTagGet(name => $_)->[0]; + push @ignored, [$_, 0] if !$i; + push @ignored, [$_, 1] if $i && $i->{meta}; + $i && !$i->{meta} ? $i->{id} : (); + } grep $_, split /\s*,\s*/, $f->{ti}; + $f->{s} = 'title' if !@ti && $f->{s} eq 'tagscore'; + $f->{o} = $f->{s} eq 'tagscore' ? 'd' : 'a' if !$f->{o}; + my($list, $np) = $self->dbVNGet( $char ne 'all' ? ( char => $char ) : (), $f->{q} ? ( search => $f->{q} ) : (), results => 50, page => $f->{p}, - order => ($f->{s} eq 'rel' ? 'c_released' : $f->{s} eq 'pop' ? 'c_popularity' : 'title').($f->{o} eq 'a' ? ' ASC' : ' DESC'), + order => ($f->{s} eq 'rel' ? 'c_released' : $f->{s} eq 'pop' ? 'c_popularity' : $f->{s}).($f->{o} eq 'a' ? ' ASC' : ' DESC'), $f->{pl}[0] ? ( platform => $f->{pl} ) : (), $f->{ln}[0] ? ( lang => $f->{ln} ) : (), + tags_include => \@ti, ); $self->resRedirect('/v'.$list->[0]{id}, 'temp') if $f->{q} && @$list == 1; $self->htmlHeader(title => 'Browse visual novels', search => $f->{q}); - _filters($self, $f, $char); + _filters($self, $f, $char, \@ignored); + + my $url = "/v/$char?q=$f->{q};ti=$f->{ti}"; + $_ and $url .= ";pl=$_" for @{$f->{pl}}; + $_ and $url .= ";ln=$_" for @{$f->{ln}}; $self->htmlBrowse( class => 'vnbrowse', items => $list, options => $f, nextpage => $np, - pageurl => "/v/$char?o=$f->{o};s=$f->{s};q=$f->{q}", - sorturl => "/v/$char?q=$f->{q}", + pageurl => "$url;o=$f->{o};s=$f->{s}", + sorturl => $url, header => [ - [ 'Title', 'title' ], - [ '', 0 ], - [ '', 0 ], - [ 'Released', 'rel' ], - [ 'Popularity', 'pop' ], + @ti ? [ 'Score', 'tagscore', undef, 'tc_s' ] : (), + [ 'Title', 'title', undef, @ti ? 'tc_t' : 'tc1' ], + [ '', 0, undef, 'tc2' ], + [ '', 0, undef, 'tc3' ], + [ 'Released', 'rel', undef, 'tc4' ], + [ 'Popularity', 'pop', undef, 'tc5' ], ], row => sub { my($s, $n, $l) = @_; Tr $n % 2 ? (class => 'odd') : (); - td class => 'tc1'; + if(@ti) { + td class => 'tc_s'; + tagscore $l->{tagscore}, 0; + end; + } + td class => @ti ? 'tc_t' : 'tc1'; a href => '/v'.$l->{id}, title => $l->{original}||$l->{title}, shorten $l->{title}, 100; end; td class => 'tc2'; @@ -92,7 +114,7 @@ sub list { sub _filters { - my($self, $f, $char) = @_; + my($self, $f, $char, $ign) = @_; form action => '/v/all', 'accept-charset' => 'UTF-8', method => 'get'; div class => 'mainbox'; @@ -103,10 +125,26 @@ sub _filters { a href => "/v/$_", $_ eq $char ? (class => 'optselected') : (), $_ ? uc $_ : '#'; } end; + + if(@$ign) { + div class => 'warning'; + h2 'The following tags were ignored:'; + ul; + li $_->[0].' ('.($_->[1]?"can't filter on meta tags":"no such tag found").')' for @$ign; + end; + end; + } + a id => 'advselect', href => '#'; lit '<i>▸</i> advanced search'; end; div id => 'advoptions', class => 'hidden vnoptions'; + + h2 'Tag filters'; + table class => 'formtable', style => 'margin-left: 0'; + $self->htmlFormPart($f, [ input => short => 'ti', name => 'Tags to include', width => 350 ]); + end; + h2; lit 'Languages <b>(boolean or, selecting more gives more results)</b>'; end; diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm index 2f0a3274..646c052a 100644 --- a/lib/VNDB/Util/CommonHTML.pm +++ b/lib/VNDB/Util/CommonHTML.pm @@ -189,7 +189,7 @@ sub htmlBrowse { if(ref $opt{header}[$_] eq 'CODE') { $opt{header}[$_]->($self, $_+1); } else { - td class => 'tc'.($_+1), $opt{header}[$_][2] ? (colspan => $opt{header}[$_][2]) : (); + td class => $opt{header}[$_][3]||'tc'.($_+1), $opt{header}[$_][2] ? (colspan => $opt{header}[$_][2]) : (); lit $opt{header}[$_][0]; if($opt{header}[$_][1]) { lit ' '; |