summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2009-07-05 18:15:01 +0200
committerYorhel <git@yorhel.nl>2009-07-05 18:15:01 +0200
commitd59124e057e3a10dac0a3a448f4503679810850c (patch)
tree970b2cb381656d6d635cbd4046f30ed685413e62
parentba1d4aed3e9b081a55d306c96c134eee5117284b (diff)
Tag exclude filters on VN search
-rw-r--r--lib/VNDB/DB/VN.pm4
-rw-r--r--lib/VNDB/Handler/VNBrowse.pm22
-rw-r--r--static/f/forms.js4
-rw-r--r--static/f/script.js38
4 files changed, 40 insertions, 28 deletions
diff --git a/lib/VNDB/DB/VN.pm b/lib/VNDB/DB/VN.pm
index 5228a371..76cacf70 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, tags_include, results, page, order, what
+# Options: id, rev, char, search, lang, platform, tags_include, tags_exclude, results, page, order, what
# What: extended categories anime relations screenshots relgraph ranking changes
sub dbVNGet {
my($self, %o) = @_;
@@ -35,6 +35,8 @@ sub dbVNGet {
'v.id IN(SELECT vid FROM tags_vn_bayesian WHERE tag IN(!l) AND spoiler <= ? GROUP BY vid HAVING COUNT(tag) = ?)',
[ $o{tags_include}[1], $o{tags_include}[0], $#{$o{tags_include}[1]}+1 ]
) : (),
+ $o{tags_exclude} && @{$o{tags_exclude}} ? (
+ 'v.id NOT IN(SELECT vid FROM tags_vn_bayesian WHERE tag IN(!l))' => [ $o{tags_exclude} ] ) : (),
# don't fetch hidden items unless we ask for an ID
!$o{id} && !$o{rev} ? (
'v.hidden = FALSE' => 0 ) : (),
diff --git a/lib/VNDB/Handler/VNBrowse.pm b/lib/VNDB/Handler/VNBrowse.pm
index ecb2e235..5a22bccc 100644
--- a/lib/VNDB/Handler/VNBrowse.pm
+++ b/lib/VNDB/Handler/VNBrowse.pm
@@ -24,6 +24,7 @@ sub list {
{ 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 },
+ { name => 'te', required => 0, default => '', maxlength => 200 },
{ name => 'sp', required => 0, default => $self->reqCookie('tagspoil') =~ /^([0-2])$/ ? $1 : 1, enum => [0..2] },
);
return 404 if $f->{_err};
@@ -40,12 +41,17 @@ sub list {
}
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};
+ my $tagfind = sub {
+ return 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*/, $_[0];
+ };
+ my @ti = $tagfind->($f->{ti});
+ my @te = $tagfind->($f->{te});
+
$f->{s} = 'title' if !@ti && $f->{s} eq 'tagscore';
$f->{o} = $f->{s} eq 'tagscore' ? 'd' : 'a' if !$f->{o};
@@ -58,6 +64,7 @@ sub list {
$f->{pl}[0] ? ( platform => $f->{pl} ) : (),
$f->{ln}[0] ? ( lang => $f->{ln} ) : (),
@ti ? (tags_include => [ $f->{sp}, \@ti ]) : (),
+ @te ? (tags_exclude => \@te) : (),
);
$self->resRedirect('/v'.$list->[0]{id}, 'temp')
@@ -66,7 +73,7 @@ sub list {
$self->htmlHeader(title => 'Browse visual novels', search => $f->{q}, js => 'forms');
_filters($self, $f, $char, \@ignored);
- my $url = "/v/$char?q=$f->{q};ti=$f->{ti}";
+ my $url = "/v/$char?q=$f->{q};ti=$f->{ti};te=$f->{te}";
$_ and $url .= ";pl=$_" for @{$f->{pl}};
$_ and $url .= ";ln=$_" for @{$f->{ln}};
$self->htmlBrowse(
@@ -147,6 +154,7 @@ sub _filters {
table class => 'formtable', style => 'margin-left: 0';
$self->htmlFormPart($f, [ input => short => 'ti', name => 'Tags to include', width => 350 ]);
$self->htmlFormPart($f, [ radio => short => 'sp', name => '', options => [[0,'Hide spoilers'],[1,'Show minor spoilers'],[2,'Show major spoilers']]]);
+ $self->htmlFormPart($f, [ input => short => 'te', name => 'Tags to exclude', width => 350 ]);
end;
h2;
diff --git a/static/f/forms.js b/static/f/forms.js
index 96f0d753..4fb02f1e 100644
--- a/static/f/forms.js
+++ b/static/f/forms.js
@@ -56,7 +56,7 @@ function dsKeyDown(ev) {
}
if(obj.selectedId != 0)
- obj.value = obj.serFunc(x('ds_box_'+obj.selectedId).itemData);
+ obj.value = obj.serFunc(x('ds_box_'+obj.selectedId).itemData, obj);
if(obj.returnFunc)
obj.returnFunc();
if(x('ds_box'))
@@ -167,7 +167,7 @@ function dsResults(hr, obj) {
l[i].className = l[i].id == 'ds_box_'+obj.selectedId ? 'selected' : '';
};
tr.onclick = function() {
- obj.value = obj.serFunc(this.itemData);
+ obj.value = obj.serFunc(this.itemData, obj);
if(obj.returnFunc)
obj.returnFunc();
if(x('ds_box'))
diff --git a/static/f/script.js b/static/f/script.js
index 34f654c0..c94d781a 100644
--- a/static/f/script.js
+++ b/static/f/script.js
@@ -456,24 +456,26 @@ DOMLoad(function() {
// auto-complete tag search
if(x('advselect') && x('ti')) {
- dsInit(x('ti'), '/xml/tags.xml?q=',
- function(item, tr) {
- var td = document.createElement('td');
- td.innerHTML = shorten(item.firstChild.nodeValue, 40);
- if(item.getAttribute('meta') == 'yes')
- td.innerHTML += ' <b class="grayedout">meta</b>';
- else if(item.getAttribute('state') == 0)
- td.innerHTML += ' <b class="grayedout">awaiting moderation</b>';
- tr.appendChild(td);
- },
- function(item) {
- var tags = x('ti').value.split(/ *, */);
- tags[tags.length-1] = item.firstChild.nodeValue;
- return tags.join(', ');
- },
- function() { false; },
- function(val) { return (val.split(/, */))[val.split(/, */).length-1]; }
- );
+ var fields=['ti','te'];
+ for(var field=0;field<fields.length;field++)
+ dsInit(x(fields[field]), '/xml/tags.xml?q=',
+ function(item, tr) {
+ var td = document.createElement('td');
+ td.innerHTML = shorten(item.firstChild.nodeValue, 40);
+ if(item.getAttribute('meta') == 'yes')
+ td.innerHTML += ' <b class="grayedout">meta</b>';
+ else if(item.getAttribute('state') == 0)
+ td.innerHTML += ' <b class="grayedout">awaiting moderation</b>';
+ tr.appendChild(td);
+ },
+ function(item, obj) {
+ var tags = obj.value.split(/ *, */);
+ tags[tags.length-1] = item.firstChild.nodeValue;
+ return tags.join(', ');
+ },
+ function() { false; },
+ function(val) { return (val.split(/, */))[val.split(/, */).length-1]; }
+ );
}
// update spoiler cookie on VN search radio button