diff options
-rw-r--r-- | data/js/filter.js | 133 | ||||
-rw-r--r-- | lib/VNDB/DB/Chars.pm | 2 | ||||
-rw-r--r-- | lib/VNDB/DB/Releases.pm | 4 | ||||
-rw-r--r-- | lib/VNDB/DB/Traits.pm | 5 | ||||
-rw-r--r-- | lib/VNDB/DB/VN.pm | 2 | ||||
-rw-r--r-- | lib/VNDB/Handler/Producers.pm | 13 | ||||
-rw-r--r-- | lib/VNDB/Handler/Staff.pm | 13 | ||||
-rw-r--r-- | lib/VNDB/Handler/Tags.pm | 2 | ||||
-rw-r--r-- | lib/VNDB/Handler/Traits.pm | 2 | ||||
-rw-r--r-- | lib/VNDB/Util/Misc.pm | 6 |
10 files changed, 131 insertions, 51 deletions
diff --git a/data/js/filter.js b/data/js/filter.js index 5758aebe..d19892a4 100644 --- a/data/js/filter.js +++ b/data/js/filter.js @@ -412,24 +412,26 @@ function filFOptions(c, n, opts) { ]; } -function filFTagInput(name, label, type) { - var src = type=='tag' ? '/xml/tags.xml' : '/xml/traits.xml'; +// fieldcode -> See <fieldcode> in filter definitions +// fieldname -> See <fieldname> in filter definitions +// src -> The API URL where to get items, must work with dropdownsearch.js and support appending ';q=' and ';id=' to it. +// fmtlist -> Called with item id + XML data, should return an inline element to inject into the list view. +function filFDList(fieldcode, fieldname, src, fmtds, fmtlist) { var visible = false; - var addtag = function(ul, id, name, group) { + var addel = function(ul, id, data) { ul.appendChild( tag('li', { fil_id: id }, - type=='trait' && group ? tag('b', {'class':'grayedout'}, group+' / ') : null, - type=='tag' ? tag('a', {href:'/g'+id}, name||'g'+id) : tag('a', {href:'/i'+id}, name||'i'+id), - ' (', tag('a', {href:'#', - onclick:function () { - // a -> li -> ul -> div - var ul = this.parentNode.parentNode; - ul.removeChild(this.parentNode); - selectField(ul.parentNode); - return false - } - }, 'remove'), ')' + data ? fmtlist(id, data) : null, + ' (', tag('a', {href:'#', + onclick:function () { + // a -> li -> ul -> div + var ul = this.parentNode.parentNode; + ul.removeChild(this.parentNode); + selectField(ul.parentNode); + return false + } + }, 'remove'), ')' )); } var fetch = function(c) { @@ -450,16 +452,16 @@ function filFTagInput(name, label, type) { for(var i=0; i<v.length; i++) { q.push('id='+v[i]); if(!visible) - addtag(ul, v[i]); + addel(ul, v[i]); } txt.value = 'Loading...'; txt.disabled = true; if(visible) - ajax(src+'?'+q.join(';'), function (hr) { + ajax(src+';'+q.join(';'), function (hr) { var items = hr.responseXML.getElementsByTagName('item'); setText(ul, ''); for(var i=0; i<items.length; i++) - addtag(ul, items[i].getAttribute('id'), items[i].firstChild.nodeValue, items[i].getAttribute('groupname')); + addel(ul, items[i].getAttribute('id'), items[i]); txt.value = ''; txt.disabled = false; c.fil_val = null; @@ -467,22 +469,13 @@ function filFTagInput(name, label, type) { }; var input = tag('input', {type:'text', 'class':'text', style:'width:300px', onfocus:selectField}); var list = tag('ul', null); - dsInit(input, src+'?q=', - function(item, tr) { - var g = item.getAttribute('groupname'); - tr.appendChild(tag('td', - type=='trait' && g ? tag('b', {'class':'grayedout'}, g+' / ') : null, - shorten(item.firstChild.nodeValue, 40), - item.getAttribute('searchable') == 'no' ? tag('b', {'class': 'grayedout'}, ' not searchable') : null, - item.getAttribute('state') == 0 ? tag('b', {'class': 'grayedout'}, ' awaiting moderation') : null - )); - }, + dsInit(input, src+';q=', fmtds, function(item, obj) { - if(item.getAttribute('searchable') == 'no') - alert('Can\'t use unsearchable '+type+'s here!'); + if(byName(obj.parentNode, 'li').length >= 10) + alert('Too many items selected'); else { obj.parentNode.fil_val = null; - addtag(byName(obj.parentNode, 'ul')[0], item.getAttribute('id'), item.firstChild.nodeValue, item.getAttribute('groupname')); + addel(byName(obj.parentNode, 'ul')[0], item.getAttribute('id'), item); selectField(obj); } return ''; @@ -491,7 +484,7 @@ function filFTagInput(name, label, type) { ); return [ - name, label, tag('div', list, input), + fieldcode, fieldname, tag('div', list, input), function(c) { var v = []; var l = byName(c, 'li'); for(var i=0; i<l.length; i++) @@ -503,6 +496,59 @@ function filFTagInput(name, label, type) { ]; } +function filFTagInput(code, name) { + return filFDList(code, name, '/xml/tags.xml?searchable=1', + function(item, tr) { + tr.appendChild(tag('td', shorten(item.firstChild.nodeValue, 40))); + }, + function(id, item) { + return tag('span', tag('a', {href:'/g'+id}, item.firstChild.nodeValue||'g'+id)) + } + ) +} + +function filFTraitInput(code, name) { + return filFDList(code, name, '/xml/traits.xml?searchable=1', + function(item, tr) { + var g = item.getAttribute('groupname'); + tr.appendChild(tag('td', + g ? tag('b', {'class':'grayedout'}, g+' / ') : null, + shorten(item.firstChild.nodeValue, 40) + )); + }, + function(id, item) { + var g = item.getAttribute('groupname'); + return tag('span', + g ? tag('b', {'class':'grayedout'}, g+' / ') : null, + tag('a', {href:'/i'+id}, item.firstChild.nodeValue||'i'+id) + ) + } + ) +} + +function filFProducerInput(code, name) { + return filFDList(code, name, '/xml/producers.xml?', + function(item, tr) { + tr.appendChild(tag('td', shorten(item.firstChild.nodeValue, 40))); + }, + function(id, item) { + return tag('span', tag('a', {href:'/p'+id}, item.firstChild.nodeValue||'p'+id)) + } + ) +} + +function filFStaffInput(code, name) { + return filFDList(code, name, '/xml/staff.xml?staffid=1', + function(item, tr) { + tr.appendChild(tag('td', shorten(item.firstChild.nodeValue, 40))); + }, + function(id, item) { + return tag('span', tag('a', {href:'/s'+id}, item.firstChild.nodeValue||'s'+id)) + } + ) +} + + function filChars() { var ontraitpage = location.pathname.indexOf('/i') == 0; @@ -528,11 +574,16 @@ function filChars() { [ '', ' ', tag('Additional trait filters are not available on this page. Use the character browser instead (available from the main menu -> characters).') ], ] : [ 'Traits', [ '', ' ', tag('Boolean and, selecting more gives less results') ], - filFTagInput('trait_inc', 'Traits to include', 'trait'), - filFTagInput('trait_exc', 'Traits to exclude', 'trait'), + filFTraitInput('trait_inc', 'Traits to include'), + filFTraitInput('trait_exc', 'Traits to exclude'), filFOptions('tagspoil', ' ', [[0, 'Hide spoilers'],[1, 'Show minor spoilers'],[2, 'Spoil me!']]), ], - [ 'Roles', filFSelect('role', 'Roles', 4, VARS.char_roles) ] + [ 'Roles', filFSelect('role', 'Roles', 4, VARS.char_roles) ], + [ 'Seiyuu', + [ '', ' ', tag('Boolean or, selecting more gives more results') ], + filFStaffInput('va_inc', 'Seiyuu to include'), + filFStaffInput('va_exc', 'Seiyuu to exclude') + ], ]; } @@ -559,6 +610,11 @@ function filReleases() { [ 'Original language', filFSelect('olang', 'Original language', 20, VARS.languages) ], [ 'Screen resolution', filFSelect('resolution', 'Screen resolution', 15, VARS.resolutions) ], [ 'Platform', filFSelect('plat', 'Platform', 20, plat) ], + [ 'Producer', + [ '', ' ', tag('Boolean or, selecting more gives more results') ], + filFProducerInput('prod_inc', 'Producers to include'), + filFProducerInput('prod_exc', 'Producers to exclude') + ], [ 'Misc', filFSelect('med', 'Medium', 10, med), filFSelect('voiced', 'Voiced', 5, VARS.voiced), @@ -586,13 +642,18 @@ function filVN() { ] : [ 'Tags', [ '', ' ', tag('Boolean and, selecting more gives less results') ], [ '', ' ', byId('pref_code') ? tag('These filters are ignored on tag pages (when set as default).') : null ], - filFTagInput('tag_inc', 'Tags to include', 'tag'), - filFTagInput('tag_exc', 'Tags to exclude', 'tag'), + filFTagInput('tag_inc', 'Tags to include'), + filFTagInput('tag_exc', 'Tags to exclude'), filFOptions('tagspoil', ' ', [[0, 'Hide spoilers'],[1, 'Show minor spoilers'],[2, 'Spoil me!']]) ], [ 'Language', filFSelect('lang', 'Language', 20, VARS.languages) ], [ 'Original language', filFSelect('olang','Original language', 20, VARS.languages) ], [ 'Platform', filFSelect('plat', 'Platform', 20, VARS.platforms) ], + [ 'Staff', + [ '', ' ', tag('Boolean or, selecting more gives more results') ], + filFStaffInput('staff_inc', 'Staff to include'), + filFStaffInput('staff_exc', 'Staff to exclude') + ], !byId('pref_code') ? null : [ 'My lists', filFOptions('ul_notblack', 'Blacklist', [[1, 'Exclude VNs on my blacklist']]), diff --git a/lib/VNDB/DB/Chars.pm b/lib/VNDB/DB/Chars.pm index a3ba0df9..23953028 100644 --- a/lib/VNDB/DB/Chars.pm +++ b/lib/VNDB/DB/Chars.pm @@ -32,6 +32,8 @@ sub dbCharFilters { [ ref $o{trait_inc} ? $o{trait_inc} : [$o{trait_inc}], $o{tagspoil}, ref $o{trait_inc} ? $#{$o{trait_inc}}+1 : 1 ]) : (), $o{trait_exc} ? ( 'c.id NOT IN(SELECT cid FROM traits_chars WHERE tid IN(!l))' => [ ref $o{trait_exc} ? $o{trait_exc} : [$o{trait_exc}] ] ) : (), + $o{va_inc} ? ( 'c.id IN(SELECT ivs.cid FROM vn_seiyuu ivs JOIN staff_alias isa ON isa.aid = ivs.aid WHERE isa.id IN(!l))' => [ ref $o{va_inc} ? $o{va_inc} : [$o{va_inc}] ] ) : (), + $o{va_exc} ? ( 'c.id NOT IN(SELECT ivs.cid FROM vn_seiyuu ivs JOIN staff_alias isa ON isa.aid = ivs.aid WHERE isa.id IN(!l))' => [ ref $o{va_exc} ? $o{va_exc} : [$o{va_exc}] ] ) : (), ) } diff --git a/lib/VNDB/DB/Releases.pm b/lib/VNDB/DB/Releases.pm index a2614ca8..9f164251 100644 --- a/lib/VNDB/DB/Releases.pm +++ b/lib/VNDB/DB/Releases.pm @@ -41,12 +41,14 @@ sub dbReleaseFilters { grep(/^unk$/, @{$o{med}}) ? 'NOT EXISTS(SELECT 1 FROM releases_media irm WHERE irm.id = r.id)' : (), grep(!/^unk$/, @{$o{med}}) ? 'r.id IN(SELECT irm.id FROM releases_media irm WHERE irm.medium IN(!l))' : () ).')', [ [ grep(!/^unk$/, @{$o{med}}) ] ]) : (), + $o{prod_inc} ? ('r.id IN(SELECT irp.id FROM releases_producers irp WHERE irp.pid IN(!l))' => [ ref $o{prod_inc} ? $o{prod_inc} : [$o{prod_inc}] ]) : (), + $o{prod_exc} ? ('r.id NOT IN(SELECT irp.id FROM releases_producers irp WHERE irp.pid IN(!l))' => [ ref $o{prod_exc} ? $o{prod_exc} : [$o{prod_exc}] ]) : (), ); } # Options: id vid pid released page results what med sort reverse date_before date_after -# plat lang olang type minage search resolution freeware doujin voiced uncensored ani_story ani_ero hidden_only +# plat prod_inc prod_exc lang olang type minage search resolution freeware doujin voiced uncensored ani_story ani_ero hidden_only # What: extended vn producers platforms media affiliates # Sort: title released minage sub dbReleaseGet { diff --git a/lib/VNDB/DB/Traits.pm b/lib/VNDB/DB/Traits.pm index 250a7dae..f1c55b24 100644 --- a/lib/VNDB/DB/Traits.pm +++ b/lib/VNDB/DB/Traits.pm @@ -13,7 +13,7 @@ use Exporter 'import'; our @EXPORT = qw|dbTraitGet dbTraitEdit dbTraitAdd|; -# Options: id noid search name state applicable what results page sort reverse +# Options: id noid search name state searchable applicable what results page sort reverse # what: parents childs(n) addedby # sort: id name name added items search sub dbTraitGet { @@ -39,7 +39,8 @@ sub dbTraitGet { '(t.name ILIKE ? OR t.alias ILIKE ?)' => [ "%$o{search}%", "%$o{search}%" ] ) : (), $o{name} ? ( # TODO: This is terribly ugly, use an aliases table. q{(LOWER(t.name) = LOWER(?) OR t.alias ~ ('(!sin)^'||?||'$'))} => [ $o{name}, '?', quotemeta $o{name} ] ) : (), - defined $o{applicable} ? ('t.applicable = ?' => $o{applicable}) : (), + defined $o{applicable} ? ('t.applicable = ?' => $o{applicable}?1:0 ) : (), + defined $o{searchable} ? ('t.searchable = ?' => $o{searchable}?1:0 ) : (), ); my @select = ( diff --git a/lib/VNDB/DB/VN.pm b/lib/VNDB/DB/VN.pm index 2933fbfd..558808d9 100644 --- a/lib/VNDB/DB/VN.pm +++ b/lib/VNDB/DB/VN.pm @@ -58,6 +58,8 @@ sub dbVNGet { 'v.id NOT IN(SELECT vid FROM tags_vn_inherit WHERE tag IN(!l))' => [ ref $o{tag_exc} ? $o{tag_exc} : [$o{tag_exc}] ] ) : (), $o{search} ? ( map +('v.c_search like ?', "%$_%"), normalize_query($o{search})) : (), + $o{staff_inc} ? ( 'v.id IN(SELECT ivs.id FROM vn_staff ivs JOIN staff_alias isa ON isa.aid = ivs.aid WHERE isa.id IN(!l))' => [ ref $o{staff_inc} ? $o{staff_inc} : [$o{staff_inc}] ] ) : (), + $o{staff_exc} ? ( 'v.id NOT IN(SELECT ivs.id FROM vn_staff ivs JOIN staff_alias isa ON isa.aid = ivs.aid WHERE isa.id IN(!l))' => [ ref $o{staff_exc} ? $o{staff_exc} : [$o{staff_exc}] ] ) : (), $uid && $o{ul_notblack} ? ( 'v.id NOT IN(SELECT vid FROM wlists WHERE uid = ? AND wstat = 3)' => $uid ) : (), $uid && defined $o{ul_onwish} ? ( diff --git a/lib/VNDB/Handler/Producers.pm b/lib/VNDB/Handler/Producers.pm index f78d4336..e6517b16 100644 --- a/lib/VNDB/Handler/Producers.pm +++ b/lib/VNDB/Handler/Producers.pm @@ -474,19 +474,22 @@ sub list { sub pxml { my $self = shift; - my $q = $self->formValidate({ get => 'q', maxlength => 500 }); - return $self->resNotFound if $q->{_err}; - $q = $q->{q}; + my $f = $self->formValidate( + { get => 'q', required => 0, maxlength => 500 }, + { get => 'id', required => 0, multi => 1, template => 'id' }, + ); + return $self->resNotFound if $f->{_err} || (!$f->{q} && !$f->{id} && !$f->{id}[0]); my($list, $np) = $self->dbProducerGet( - $q =~ /^p([1-9]\d*)/ ? (id => $1) : (search => $q, sort => 'search'), + !$f->{q} ? () : $f->{q} =~ /^p([1-9]\d*)/ ? (id => $1) : (search => $f->{q}, sort => 'search'), + $f->{id} && $f->{id}[0] ? (id => $f->{id}) : (), results => 10, page => 1, ); $self->resHeader('Content-type' => 'text/xml; charset=UTF-8'); xml; - tag 'producers', more => $np ? 'yes' : 'no', query => $q; + tag 'producers', more => $np ? 'yes' : 'no', query => $f->{q}; for(@$list) { tag 'item', id => $_->{id}, $_->{name}; } diff --git a/lib/VNDB/Handler/Staff.pm b/lib/VNDB/Handler/Staff.pm index 4d583b68..70f78392 100644 --- a/lib/VNDB/Handler/Staff.pm +++ b/lib/VNDB/Handler/Staff.pm @@ -372,11 +372,16 @@ sub list { sub staffxml { my $self = shift; - my $q = $self->formValidate({ get => 'q', required => 0, maxlength => 500 }); - return $self->resNotFound if $q->{_err} || !$q->{q}; + my $f = $self->formValidate( + { get => 'q', required => 0, maxlength => 500 }, + { get => 'id', required => 0, multi => 1, template => 'id' }, + { get => 'staffid', required => 0, default => 0 }, # The returned id = staff id when set, otherwise it's the alias id + ); + return $self->resNotFound if $f->{_err} || (!$f->{q} && !$f->{id} && !$f->{id}[0]); my($list, $np) = $self->dbStaffGet( - $q->{q} =~ /^s([1-9]\d*)/ ? (id => $1) : $q->{q} =~ /^=(.+)/ ? (exact => $1) : (search => $q->{q}, sort => 'search'), + !$f->{q} ? () : $f->{q} =~ /^s([1-9]\d*)/ ? (id => $1) : $f->{q} =~ /^=(.+)/ ? (exact => $1) : (search => $f->{q}, sort => 'search'), + $f->{id} && $f->{id}[0] ? (id => $f->{id}) : (), results => 10, page => 1, ); @@ -384,7 +389,7 @@ sub staffxml { xml; tag 'staff', more => $np ? 'yes' : 'no'; for(@$list) { - tag 'item', sid => $_->{id}, id => $_->{aid}, orig => $_->{original}, $_->{name}; + tag 'item', sid => $_->{id}, id => $f->{staffid} ? $_->{id} : $_->{aid}, orig => $_->{original}, $_->{name}; } end; } diff --git a/lib/VNDB/Handler/Tags.pm b/lib/VNDB/Handler/Tags.pm index 954ea279..90b3e726 100644 --- a/lib/VNDB/Handler/Tags.pm +++ b/lib/VNDB/Handler/Tags.pm @@ -769,6 +769,7 @@ sub tagxml { my $f = $self->formValidate( { get => 'q', required => 0, maxlength => 500 }, { get => 'id', required => 0, multi => 1, template => 'id' }, + { get => 'searchable', required => 0, default => 0 }, ); return $self->resNotFound if $f->{_err} || (!$f->{q} && !$f->{id} && !$f->{id}[0]); @@ -777,6 +778,7 @@ sub tagxml { $f->{id} && $f->{id}[0] ? (id => $f->{id}) : (), results => 15, page => 1, + $f->{searchable} ? (state => 2, searchable => 1) : (), ); $self->resHeader('Content-type' => 'text/xml; charset=UTF-8'); diff --git a/lib/VNDB/Handler/Traits.pm b/lib/VNDB/Handler/Traits.pm index 8d798245..05321988 100644 --- a/lib/VNDB/Handler/Traits.pm +++ b/lib/VNDB/Handler/Traits.pm @@ -426,6 +426,7 @@ sub traitxml { { get => 'q', required => 0, maxlength => 500 }, { get => 'id', required => 0, multi => 1, template => 'id' }, { get => 'r', required => 0, default => 15, template => 'uint', min => 1, max => 200 }, + { get => 'searchable', required => 0, default => 0 }, ); return $self->resNotFound if $f->{_err} || (!$f->{q} && !$f->{id} && !$f->{id}[0]); @@ -434,6 +435,7 @@ sub traitxml { page => 1, sort => 'group', state => 2, + $f->{searchable} ? (searchable => 1) : (), !$f->{q} ? () : $f->{q} =~ /^i([1-9]\d*)/ ? (id => $1) : (search => $f->{q}, sort => 'search'), $f->{id} && $f->{id}[0] ? (id => $f->{id}) : (), ); diff --git a/lib/VNDB/Util/Misc.pm b/lib/VNDB/Util/Misc.pm index 0f6a7448..879dbdf7 100644 --- a/lib/VNDB/Util/Misc.pm +++ b/lib/VNDB/Util/Misc.pm @@ -12,9 +12,9 @@ our @EXPORT = qw|filFetchDB filCompat bbSubstLinks|; our %filfields = ( - vn => [qw|date_before date_after released length hasani hasshot tag_inc tag_exc taginc tagexc tagspoil lang olang plat ul_notblack ul_onwish ul_voted ul_onlist|], - release => [qw|type patch freeware doujin uncensored date_before date_after released minage lang olang resolution plat med voiced ani_story ani_ero|], - char => [qw|gender bloodt bust_min bust_max waist_min waist_max hip_min hip_max height_min height_max weight_min weight_max trait_inc trait_exc tagspoil role|], + vn => [qw|date_before date_after released length hasani hasshot tag_inc tag_exc taginc tagexc tagspoil lang olang plat staff_inc staff_exc ul_notblack ul_onwish ul_voted ul_onlist|], + release => [qw|type patch freeware doujin uncensored date_before date_after released minage lang olang resolution plat prod_inc prod_exc med voiced ani_story ani_ero|], + char => [qw|gender bloodt bust_min bust_max waist_min waist_max hip_min hip_max height_min height_max va_inc va_exc weight_min weight_max trait_inc trait_exc tagspoil role|], staff => [qw|gender role truename lang|], ); |