summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2022-10-18 12:26:44 +0200
committerYorhel <git@yorhel.nl>2022-10-18 12:26:44 +0200
commita4d0b59ecd5ed4976b965915887356efbe097549 (patch)
treedab0183eeb6cde7a1397dab20af91f56a04d3b5a
parente51ba62a4213ae42282cfda2f95c51577281ad4e (diff)
API2: Add querying traits
-rw-r--r--data/api-kana.md60
-rw-r--r--lib/VNWeb/API.pm38
-rw-r--r--lib/VNWeb/AdvSearch.pm4
3 files changed, 81 insertions, 21 deletions
diff --git a/data/api-kana.md b/data/api-kana.md
index 8cd693fd..6cd6ed5b 100644
--- a/data/api-kana.md
+++ b/data/api-kana.md
@@ -873,20 +873,11 @@ vns.release.\*
traits
: Array of objects, possibly empty.
-traits.id
-: vndbid
-
traits.spoiler
: Integer, 0, 1 or 2, spoiler level.
-traits.name
-: String
-
-traits.group_id
-: vndbid
-
-traits.group_name
-: String
+traits.\*
+: All [trait fields](#trait-fields) are available here.
*Missing: sex, instances, voice actor*
@@ -946,6 +937,53 @@ vn\_count
efficiently because tags form a DAG rather than a tree.*
+## POST /trait
+
+Accepted values for `"sort"`: `id`, `name`, `char_count`.
+
+### Filters
+
+-----------------------------------------------------------------------------
+Name [F] Description
+------------------ ---- -------------------------------------------------------
+`id` o vndbid
+
+`search` m String search.
+-----------------------------------------------------------------------------
+
+### Fields {#trait-fields}
+
+id
+: vndbid
+
+name
+: String. Trait names are not necessarily self-describing, so they should
+ always be displayed together with their "group" (see below), which is the
+ top-level parent that the trait belongs to.
+
+aliases
+: Array of strings.
+
+description
+: String, may contain [formatting codes](https://vndb.org/d9#4).
+
+searchable
+: Bool.
+
+applicable
+: Bool.
+
+group_id
+: vndbid
+
+group_name
+: String
+
+char\_count
+: Integer, number of characters this trait has been applied to, including
+ child traits.
+
+
## POST /ulist
Fetch a user's list. This API is very much like `POST /vn`, except it requires
diff --git a/lib/VNWeb/API.pm b/lib/VNWeb/API.pm
index 8e8542f1..83cfaf77 100644
--- a/lib/VNWeb/API.pm
+++ b/lib/VNWeb/API.pm
@@ -457,7 +457,7 @@ api_query '/vn',
},
},
tags => {
- enrich => sub { sql 'SELECT tv.vid, t.id', $_[0], 'FROM tags_vn_direct tv JOIN tags t ON t.id = tv.tag', $_[1], 'WHERE tv.vid IN', $_[2] },
+ enrich => sub { sql 'SELECT tv.vid, t.id', $_[0], 'FROM tags_vn_direct tv JOIN tags t ON t.id = tv.tag', $_[1], 'WHERE NOT t.hidden AND tv.vid IN', $_[2] },
key => 'id', col => 'vid', num => 50,
inherit => '/tag',
fields => {
@@ -604,17 +604,11 @@ api_query '/character',
},
},
traits => {
- enrich => sub { sql 'SELECT ct.id AS cid', $_[0], 'FROM chars_traits ct JOIN traits t ON t.id = ct.tid', $_[1], 'WHERE NOT t.hidden AND ct.id IN', $_[2] },
+ enrich => sub { sql 'SELECT ct.id AS cid, t.id', $_[0], 'FROM chars_traits ct JOIN traits t ON t.id = ct.tid', $_[1], 'WHERE NOT t.hidden AND ct.id IN', $_[2] },
key => 'id', col => 'cid', num => 30,
- joins => {
- group => 'LEFT JOIN traits g ON g.id = t.group',
- },
+ inherit => '/trait',
fields => {
- id => { select => 'ct.tid AS id' },
spoiler => { select => 'ct.spoil AS spoiler' },
- name => { select => 't.name' },
- group_id => { join => 'group', select => 't."group" AS group_id' },
- group_name=>{ join => 'group', select => 'g.name AS group_name' },
},
},
},
@@ -626,7 +620,7 @@ api_query '/character',
api_query '/tag',
filters => 'g',
- sql => sub { sql 'SELECT t.id', $_[0], 'FROM tags t', $_[1], 'WHERE NOT hidden AND (', $_[2], ')' },
+ sql => sub { sql 'SELECT t.id', $_[0], 'FROM tags t', $_[1], 'WHERE NOT t.hidden AND (', $_[2], ')' },
fields => {
id => {},
name => { select => 't.name' },
@@ -644,6 +638,30 @@ api_query '/tag',
];
+api_query '/trait',
+ filters => 'i',
+ sql => sub { sql 'SELECT t.id', $_[0], 'FROM traits t', $_[1], 'WHERE NOT t.hidden AND (', $_[2], ')' },
+ joins => {
+ group => 'LEFT JOIN traits g ON g.id = t.group',
+ },
+ fields => {
+ id => {},
+ name => { select => 't.name' },
+ aliases => { select => 't.alias AS aliases', @MSTR },
+ description => { select => 't.description' },
+ searchable => { select => 't.searchable', @BOOL },
+ applicable => { select => 't.applicable', @BOOL },
+ group_id => { join => 'group', select => 't."group" AS group_id' },
+ group_name => { join => 'group', select => 'g.name AS group_name' },
+ char_count => { select => 't.c_items AS char_count' },
+ },
+ sort => [
+ id => 't.id',
+ name => 't.name',
+ char_count => 't.c_items ?o, t.id',
+ ];
+
+
api_query '/ulist',
filters => 'v',
sql => sub {
diff --git a/lib/VNWeb/AdvSearch.pm b/lib/VNWeb/AdvSearch.pm
index b3d060a8..6cf9a0cc 100644
--- a/lib/VNWeb/AdvSearch.pm
+++ b/lib/VNWeb/AdvSearch.pm
@@ -480,6 +480,10 @@ f g => 3 => 'category', { enum => \%TAG_CATEGORY }, '=' => sub { sql 't.cat ='
f g => 80 => 'search', {}, '=' => sub { sql 't.c_search LIKE ALL (search_query(', \$_, '))' };
+f i => 2 => 'id', { vndbid => 'i' }, sql => sub { sql 't.id', $_[0], \$_ };
+f i => 80 => 'search', {}, '=' => sub { sql 't.c_search LIKE ALL (search_query(', \$_, '))' };
+
+
# Accepts either $tag or [$tag, int($minlevel*5)*3+$maxspoil] (for compact form) or [$tag, $maxspoil, $minlevel]. Normalizes to the latter.
sub _validate_tag {
$_[0] = [$_[0],0,0] if ref $_[0] ne 'ARRAY'; # just a tag id