summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/js/filter.js24
-rw-r--r--lib/VNDB/DB/Chars.pm8
-rw-r--r--lib/VNDB/Handler/Chars.pm13
-rw-r--r--lib/VNDB/Types.pm9
-rw-r--r--lib/VNDB/Util/Misc.pm2
-rwxr-xr-xutil/jsgen.pl1
-rw-r--r--util/sql/schema.sql7
-rw-r--r--util/updates/update_20191102.sql51
8 files changed, 101 insertions, 14 deletions
diff --git a/data/js/filter.js b/data/js/filter.js
index fcd56c30..501a31a9 100644
--- a/data/js/filter.js
+++ b/data/js/filter.js
@@ -302,7 +302,13 @@ function show() {
var curSlider = null;
-function filFSlider(c, n, min, max, def, unit) {
+function filFSlider(c, n, min, max, def, unit, ser, deser) {
+ // min/max/def/fil_val are in serialized form (i.e. a "value")
+ if(!ser) ser = function(v) { return v }; // integer -> value
+ if(!deser) deser = function(v) { return parseInt(v) }; // value -> integer
+
+ min = deser(min);
+ max = deser(max);
var bw = 200; var pw = 1; // slidebar width and pointer width
var s = tag('p', {fil_val:def, 'class':'slider'});
var b = tag('div', {style:'width:'+(bw-2)+'px;', s:s});
@@ -318,12 +324,12 @@ function filFSlider(c, n, min, max, def, unit) {
if(v) {
s = e;
- x = v[0] == '' ? def : parseInt(v[0]);
+ x = deser(v[0] == '' ? def : v[0]);
x = (x-min)*w/(max-min);
} else {
s = curSlider;
if(!e) e = window.event;
- x = (!e) ? (def-min)*w/(max-min)
+ x = (!e) ? (deser(def)-min)*w/(max-min)
: (e.pageX || e.clientX + document.body.scrollLeft - document.body.clientLeft)-5;
var o = s.childNodes[0];
while(o.offsetParent) {
@@ -333,7 +339,7 @@ function filFSlider(c, n, min, max, def, unit) {
}
if(x<0) x = 0; if(x>w) x = w;
- s.fil_val = min + Math.floor(x*(max-min)/w);
+ s.fil_val = ser(min + Math.floor(x*(max-min)/w));
s.childNodes[1].innerHTML = s.fil_val+' '+unit;
s.childNodes[0].childNodes[0].style.left = x+'px';
return false;
@@ -574,6 +580,14 @@ function filFStaffInput(code, name) {
function filChars() {
var ontraitpage = location.pathname.indexOf('/i') == 0;
+ var cup_ser = function(v) { return VARS.cup_size[parseInt(v)] };
+ var cup_deser = function(v) {
+ for(var i=0; i<VARS.cup_size.length; i++)
+ if(VARS.cup_size[i] == v)
+ return i;
+ return 0;
+ };
+
return [
'Character filters',
[ 'General',
@@ -591,6 +605,8 @@ function filChars() {
filFSlider('height_max', 'Height max', 0, 300, 240, 'cm'),
filFSlider('weight_min', 'Weight min', 0, 400, 80, 'kg'),
filFSlider('weight_max', 'Weight max', 0, 400, 320, 'kg'),
+ filFSlider('cup_min', 'Cup size min', 'AAA', 'Z', 'AAA', '', cup_ser, cup_deser),
+ filFSlider('cup_max', 'Cup size max', 'AAA', 'Z', 'E', '', cup_ser, cup_deser)
],
ontraitpage ? [ 'Traits',
[ '', ' ', tag('Additional trait filters are not available on this page. Use the character browser instead (available from the main menu -> characters).') ],
diff --git a/lib/VNDB/DB/Chars.pm b/lib/VNDB/DB/Chars.pm
index e2581f87..d5078a1d 100644
--- a/lib/VNDB/DB/Chars.pm
+++ b/lib/VNDB/DB/Chars.pm
@@ -24,6 +24,8 @@ sub dbCharFilters {
defined $o{height_max} ? ( 'c.height <= ? AND c.height > 0' => $o{height_max} ) : (),
defined $o{weight_min} ? ( 'c.weight >= ?' => $o{weight_min} ) : (),
defined $o{weight_max} ? ( 'c.weight <= ?' => $o{weight_max} ) : (),
+ defined $o{cup_min} ? ( 'c.cup_size >= ?' => $o{cup_min} ) : (),
+ defined $o{cup_max} ? ( 'c.cup_size <= ?' => $o{cup_max} ) : (),
$o{role} ? (
'EXISTS(SELECT 1 FROM chars_vns cvi WHERE cvi.id = c.id AND cvi.role IN(!l))',
[ ref $o{role} ? $o{role} : [$o{role}] ] ) : (),
@@ -69,7 +71,7 @@ sub dbCharGet {
);
my @select = (qw|c.id c.name c.original c.gender|);
- push @select, qw|c.hidden c.locked c.alias c.desc c.image c.b_month c.b_day c.s_bust c.s_waist c.s_hip c.height c.weight c.bloodt c.main c.main_spoil| if $o{what} =~ /extended/;
+ push @select, qw|c.hidden c.locked c.alias c.desc c.image c.b_month c.b_day c.s_bust c.s_waist c.s_hip c.height c.weight c.bloodt c.cup_size c.main c.main_spoil| if $o{what} =~ /extended/;
my($r, $np) = $self->dbPage(\%o, q|
SELECT !s
@@ -92,7 +94,7 @@ sub dbCharGetRev {
my $select = 'c.itemid AS id, ch.name, ch.original, ch.gender';
$select .= ', extract(\'epoch\' from c.added) as added, c.comments, c.rev, c.ihid, c.ilock, '.VNWeb::DB::sql_user();
$select .= ', c.id AS cid, NOT EXISTS(SELECT 1 FROM changes c2 WHERE c2.type = c.type AND c2.itemid = c.itemid AND c2.rev = c.rev+1) AS lastrev';
- $select .= ', ch.alias, ch.desc, ch.image, ch.b_month, ch.b_day, ch.s_bust, ch.s_waist, ch.s_hip, ch.height, ch.weight, ch.bloodt, ch.main, ch.main_spoil, co.hidden, co.locked' if $o{what} =~ /extended/;
+ $select .= ', ch.alias, ch.desc, ch.image, ch.b_month, ch.b_day, ch.s_bust, ch.s_waist, ch.s_hip, ch.height, ch.weight, ch.bloodt, ch.cup_size, ch.main, ch.main_spoil, co.hidden, co.locked' if $o{what} =~ /extended/;
my $r = $self->dbAll(q|
SELECT !s
@@ -175,7 +177,7 @@ sub dbCharRevisionInsert {
my($self, $o) = @_;
my %set = map exists($o->{$_}) ? (qq|"$_" = ?|, $o->{$_}) : (),
- qw|name original alias desc image b_month b_day s_bust s_waist s_hip height weight bloodt gender main main_spoil|;
+ qw|name original alias desc image b_month b_day s_bust s_waist s_hip height weight bloodt cup_size gender main main_spoil|;
$self->dbExec('UPDATE edit_chars !H', \%set) if keys %set;
if($o->{traits}) {
diff --git a/lib/VNDB/Handler/Chars.pm b/lib/VNDB/Handler/Chars.pm
index 59b365fe..1fb0feb6 100644
--- a/lib/VNDB/Handler/Chars.pm
+++ b/lib/VNDB/Handler/Chars.pm
@@ -56,6 +56,7 @@ sub page {
[ height => 'Height', serialize => sub { $_[0]||'[empty]' } ],
[ weight => 'Weight', serialize => sub { $_[0]//'[empty]' } ],
[ bloodt => 'Blood type', serialize => sub { $BLOOD_TYPE{$_[0]} } ],
+ [ cup_size => 'Cup size', serialize => sub { $CUP_SIZE{$_[0]} } ],
[ main => 'Main character',htmlize => sub { $_[0] ? sprintf '<a href="/c%d">c%d</a>', $_[0], $_[0] : '[empty]' } ],
[ main_spoil=> 'Spoiler', serialize => \&fmtspoil ],
[ image => 'Image', htmlize => sub {
@@ -171,14 +172,15 @@ sub charTable {
td $r->{alias};
end;
}
- if(defined($r->{weight}) || $r->{height} || $r->{s_bust} || $r->{s_waist} || $r->{s_hip}) {
+ if(defined($r->{weight}) || $r->{height} || $r->{s_bust} || $r->{s_waist} || $r->{s_hip} || $r->{cup_size}) {
Tr;
td class => 'key', 'Measurements';
td join ', ',
- $r->{height} ? "Height: $r->{height}cm" : (),
+ $r->{height} ? "Height: $r->{height}cm" : (),
defined($r->{weight}) ? "Weight: $r->{weight}kg" : (),
$r->{s_bust} || $r->{s_waist} || $r->{s_hip} ?
- sprintf 'Bust-Waist-Hips: %s-%s-%scm', $r->{s_bust}||'??', $r->{s_waist}||'??', $r->{s_hip}||'??' : ();
+ sprintf 'Bust-Waist-Hips: %s-%s-%scm', $r->{s_bust}||'??', $r->{s_waist}||'??', $r->{s_hip}||'??' : (),
+ $r->{cup_size} ? "$CUP_SIZE{$r->{cup_size}} cup" : ();
end;
}
if($r->{b_month} && $r->{b_day}) {
@@ -303,7 +305,7 @@ sub edit {
|| $id && (($r->{locked} || $r->{hidden}) && !$self->authCan('dbmod'));
my %b4 = !$id ? () : (
- (map +($_ => $r->{$_}), qw|name original alias desc image ihid ilock s_bust s_waist s_hip height weight bloodt gender main_spoil|),
+ (map +($_ => $r->{$_}), qw|name original alias desc image ihid ilock s_bust s_waist s_hip height weight bloodt cup_size gender main_spoil|),
main => $r->{main}||0,
bday => $r->{b_month} ? sprintf('%02d-%02d', $r->{b_month}, $r->{b_day}) : '',
traits => join(' ', map sprintf('%d-%d', $_->{tid}, $_->{spoil}), sort { $a->{tid} <=> $b->{tid} } @{$r->{traits}}),
@@ -328,6 +330,7 @@ sub edit {
{ post => 'height', required => 0, default => 0, template => 'uint', max => 32767 },
{ post => 'weight', required => 0, default => undef, template => 'uint', max => 32767 },
{ post => 'bloodt', required => 0, default => 'unknown', enum => [ keys %BLOOD_TYPE ] },
+ { post => 'cup_size', required => 0, default => '', enum => [ keys %CUP_SIZE ] },
{ post => 'main', required => 0, default => 0, template => 'id' },
{ post => 'main_spoil', required => 0, default => 0, enum => [ 0..2 ] },
{ post => 'traits', required => 0, default => '', regex => [ qr/^(?:[1-9]\d*-[0-2])(?: +[1-9]\d*-[0-2])*$/, 'Incorrect trait format.' ] },
@@ -414,6 +417,8 @@ sub edit {
[ input => name => 'Weight', short => 'weight', width => 50, post => ' kg', allow0 => 1 ],
[ select => name => 'Blood type',short => 'bloodt', options => [
map [ $_, $BLOOD_TYPE{$_} ], keys %BLOOD_TYPE ] ],
+ [ select => name => 'Cup size', short => 'cup_size', options => [
+ map [ $_, $CUP_SIZE{$_} ], keys %CUP_SIZE ] ],
[ static => content => '<br />' ],
[ input => name => 'Instance of',short => 'main', width => 50, post => ' ID of the main character - the character of which this is an instance of.' ],
[ select => name => 'Spoiler', short => 'main_spoil', options => [
diff --git a/lib/VNDB/Types.pm b/lib/VNDB/Types.pm
index 3d613a08..8e5b26cf 100644
--- a/lib/VNDB/Types.pm
+++ b/lib/VNDB/Types.pm
@@ -324,6 +324,15 @@ hash GENDER =>
+# SQL: ENUM cup_size
+hash CUP_SIZE =>
+ '' => 'Unknown or N/A',
+ AAA => 'AAA',
+ AA => 'AA',
+ map +($_,$_), 'A'..'Z';
+
+
+
# SQL: ENUM char_role
hash CHAR_ROLE =>
main => { txt => 'Protagonist', plural => 'Protagonists' },
diff --git a/lib/VNDB/Util/Misc.pm b/lib/VNDB/Util/Misc.pm
index b7a2a3a7..9227d22a 100644
--- a/lib/VNDB/Util/Misc.pm
+++ b/lib/VNDB/Util/Misc.pm
@@ -15,7 +15,7 @@ our @EXPORT = qw|filFetchDB filCompat bbSubstLinks entryLinks|;
our %filfields = (
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 engine|],
- 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|],
+ 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 cup_min cup_max trait_inc trait_exc tagspoil role|],
staff => [qw|gender role truename lang|],
);
diff --git a/util/jsgen.pl b/util/jsgen.pl
index bc9e75b9..ff5868d5 100755
--- a/util/jsgen.pl
+++ b/util/jsgen.pl
@@ -48,6 +48,7 @@ sub vars {
blood_types => [ map [ $_, $BLOOD_TYPE{$_} ], keys %BLOOD_TYPE ],
genders => [ map [ $_, $GENDER{$_} ], keys %GENDER ],
credit_type => [ map [ $_, $CREDIT_TYPE{$_} ], keys %CREDIT_TYPE ],
+ cup_size => [ grep $_, keys %CUP_SIZE ],
resolutions => scalar resolutions(),
);
JSON::XS->new->encode(\%vars);
diff --git a/util/sql/schema.sql b/util/sql/schema.sql
index a3c65c7b..ff753619 100644
--- a/util/sql/schema.sql
+++ b/util/sql/schema.sql
@@ -51,6 +51,7 @@ CREATE TYPE blood_type AS ENUM ('unknown', 'a', 'b', 'ab', 'o');
CREATE TYPE board_type AS ENUM ('an', 'db', 'ge', 'v', 'p', 'u');
CREATE TYPE char_role AS ENUM ('main', 'primary', 'side', 'appears');
CREATE TYPE credit_type AS ENUM ('scenario', 'chardesign', 'art', 'music', 'songs', 'director', 'staff');
+CREATE TYPE cup_size AS ENUM ('', 'AAA', 'AA', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
CREATE TYPE dbentry_type AS ENUM ('v', 'r', 'p', 'c', 's', 'd');
CREATE TYPE edit_rettype AS (itemid integer, chid integer, rev integer);
CREATE TYPE gender AS ENUM ('unknown', 'm', 'f', 'b');
@@ -119,7 +120,8 @@ CREATE TABLE chars ( -- dbentry_type=c
weight smallint, -- [pub]
bloodt blood_type NOT NULL DEFAULT 'unknown', -- [pub]
main integer, -- [pub] chars.id
- main_spoil smallint NOT NULL DEFAULT 0 -- [pub]
+ main_spoil smallint NOT NULL DEFAULT 0, -- [pub]
+ cup_size cup_size NOT NULL DEFAULT '' -- [pub]
);
-- chars_hist
@@ -140,7 +142,8 @@ CREATE TABLE chars_hist (
weight smallint,
bloodt blood_type NOT NULL DEFAULT 'unknown',
main integer, -- chars.id
- main_spoil smallint NOT NULL DEFAULT 0
+ main_spoil smallint NOT NULL DEFAULT 0,
+ cup_size cup_size NOT NULL DEFAULT ''
);
-- chars_traits
diff --git a/util/updates/update_20191102.sql b/util/updates/update_20191102.sql
new file mode 100644
index 00000000..9afc4379
--- /dev/null
+++ b/util/updates/update_20191102.sql
@@ -0,0 +1,51 @@
+CREATE TYPE cup_size AS ENUM ('', 'AAA', 'AA', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
+
+ALTER TABLE chars ADD COLUMN cup_size cup_size NOT NULL DEFAULT '';
+ALTER TABLE chars_hist ADD COLUMN cup_size cup_size NOT NULL DEFAULT '';
+
+\i util/sql/editfunc.sql
+
+
+
+CREATE OR REPLACE FUNCTION migrate_trait_to_cup(cid integer, cup cup_size) RETURNS void AS $$
+BEGIN
+ PERFORM edit_c_init(cid, (SELECT MAX(rev) FROM changes WHERE itemid = cid AND type = 'c'));
+ UPDATE edit_chars SET cup_size = cup;
+ DELETE FROM edit_chars_traits WHERE tid IN(722, 1182, 1183, 1178, 1184, 723, 2129, 2115);
+ UPDATE edit_revision SET requester = 1, ip = '0.0.0.0', comments = 'Automatic conversion of breast size trait to cup size field.';
+ PERFORM edit_c_commit();
+END;
+$$ LANGUAGE plpgsql;
+
+UPDATE traits SET state = 1 WHERE id IN(722, 1182, 1183, 1178, 1184);
+
+-- This takes a while (slowness is likely due to traits_chars_calc(), can be temporarily disabled, but w/e)
+\timing
+SELECT migrate_trait_to_cup(c.id, 'AA') FROM chars c JOIN chars_traits ct ON ct.id = c.id WHERE NOT c.hidden AND c.cup_size = '' AND ct.tid = 722;
+SELECT migrate_trait_to_cup(c.id, 'A' ) FROM chars c JOIN chars_traits ct ON ct.id = c.id WHERE NOT c.hidden AND c.cup_size = '' AND ct.tid = 1182;
+SELECT migrate_trait_to_cup(c.id, 'B' ) FROM chars c JOIN chars_traits ct ON ct.id = c.id WHERE NOT c.hidden AND c.cup_size = '' AND ct.tid = 1183;
+SELECT migrate_trait_to_cup(c.id, 'C' ) FROM chars c JOIN chars_traits ct ON ct.id = c.id WHERE NOT c.hidden AND c.cup_size = '' AND ct.tid = 1178;
+SELECT migrate_trait_to_cup(c.id, 'D' ) FROM chars c JOIN chars_traits ct ON ct.id = c.id WHERE NOT c.hidden AND c.cup_size = '' AND ct.tid = 1184;
+\timing
+
+DROP FUNCTION migrate_trait_to_cup(integer, cup_size);
+
+
+-- Regex magic by skorpiondeath (with minor changes) - https://query.vndb.org/queries/kKFzwjqvAshONiaf
+CREATE OR REPLACE FUNCTION migrate_desc_to_cup(cid integer) RETURNS void AS $$
+BEGIN
+ PERFORM edit_c_init(cid, (SELECT MAX(rev) FROM changes WHERE itemid = cid AND type = 'c'));
+ UPDATE edit_chars
+ SET cup_size = substring( substring("desc" from '([c|C]up[\s]*(size|Size)?:[\s]*[A-Z][A]*)') from '[A]*.$')::cup_size
+ , "desc" = regexp_replace("desc", '[\s]*(-)?[\s]*?cup[\s]*(size)?:[\s]?[A-Z][A]*[.|\s-]?((cup)|([\s]*-->[\s]*[A-Z]))?[\n\r]*', '', 'gi');
+ DELETE FROM edit_chars_traits WHERE tid IN(722, 1182, 1183, 1178, 1184, 723, 2129, 2115);
+ UPDATE edit_revision SET requester = 1, ip = '0.0.0.0', comments = 'Automatic extraction of cup size field from the description.';
+ PERFORM edit_c_commit();
+END;
+$$ LANGUAGE plpgsql;
+
+\timing
+SELECT migrate_desc_to_cup(id) FROM chars WHERE NOT hidden AND cup_size = '' AND "desc" ~* '.*(cup[\s]*(size)?:[\s]*[A-Z]).*';
+\timing
+
+DROP FUNCTION migrate_desc_to_cup(integer);