diff options
author | morkt <> | 2015-01-02 10:22:25 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2015-01-02 10:22:25 +0100 |
commit | 228cb96969a33a60c40dd4991a394460652010af (patch) | |
tree | 9d69e00562ae545b79ca8a899d2439c4800133d7 /lib | |
parent | 03585d77637a7052d0af2cdb1e4be66358412b6a (diff) |
staff: Fix deleting of staff + use JSON to pass data + minor fixes
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VNDB/DB/Chars.pm | 7 | ||||
-rw-r--r-- | lib/VNDB/DB/VN.pm | 4 | ||||
-rw-r--r-- | lib/VNDB/Func.pm | 24 | ||||
-rw-r--r-- | lib/VNDB/Handler/Staff.pm | 35 | ||||
-rw-r--r-- | lib/VNDB/Handler/VNEdit.pm | 73 | ||||
-rw-r--r-- | lib/VNDB/Handler/VNPage.pm | 4 | ||||
-rw-r--r-- | lib/VNDB/Util/CommonHTML.pm | 1 |
7 files changed, 101 insertions, 47 deletions
diff --git a/lib/VNDB/DB/Chars.pm b/lib/VNDB/DB/Chars.pm index 50923941..15f00675 100644 --- a/lib/VNDB/DB/Chars.pm +++ b/lib/VNDB/DB/Chars.pm @@ -119,8 +119,11 @@ sub dbCharGet { JOIN vn_rev vr ON vr.id = vs.vid JOIN vn v ON v.latest = vs.vid !W - ORDER BY v.c_released, sa.name|, - { 'cr.id IN(!l)' => [[ keys %r ]], $o{vid} ? ('v.id = ?' => $o{vid}) : () } + ORDER BY v.c_released, sa.name|, { + 's.hidden = FALSE' => 1, + 'cr.id IN(!l)' => [[ keys %r ]], + $o{vid} ? ('v.id = ?' => $o{vid}) : (), + } )}); } } diff --git a/lib/VNDB/DB/VN.pm b/lib/VNDB/DB/VN.pm index edb55377..9ba27bbd 100644 --- a/lib/VNDB/DB/VN.pm +++ b/lib/VNDB/DB/VN.pm @@ -159,7 +159,7 @@ sub dbVNGet { JOIN staff_alias sa ON vs.aid = sa.id JOIN staff_rev sr ON sr.id = sa.rid JOIN staff s ON sr.id = s.latest - WHERE vs.vid IN(!l) + WHERE s.hidden = FALSE AND vs.vid IN(!l) ORDER BY vs.role ASC, sa.name ASC|, [ keys %r ] )}); @@ -173,7 +173,7 @@ sub dbVNGet { JOIN chars c ON c.id = vs.cid JOIN chars_rev cr ON cr.id = c.latest JOIN chars_vns cv ON cv.cid = cr.id AND cv.vid = vr.vid - WHERE vs.vid IN(!l) + WHERE s.hidden = FALSE AND vs.vid IN(!l) ORDER BY cv.role, cr.name|, [ keys %r ] )}); diff --git a/lib/VNDB/Func.pm b/lib/VNDB/Func.pm index 54acfe4f..3b315c93 100644 --- a/lib/VNDB/Func.pm +++ b/lib/VNDB/Func.pm @@ -6,10 +6,12 @@ use warnings; use TUWF ':html'; use Exporter 'import'; use POSIX 'strftime', 'ceil', 'floor'; +use JSON::XS; use VNDBUtil; our @EXPORT = (@VNDBUtil::EXPORT, qw| clearfloat cssicon tagscore mt minage fil_parse fil_serialize parenttags childtags charspoil imgpath imgurl fmtvote + jsonEncode jsonDecode script_json mtvoiced mtani mtvnlen mtrlstat mtvnlstat mtbloodt |); @@ -202,6 +204,28 @@ sub fmtvote { } +my $JSON; # cache + +# JSON::XS::encode_json converts input to utf8, whereas these functions +# operate on wide character strings. +sub jsonEncode ($) { + ($JSON ||= JSON::XS->new)->encode(@_); +} + +sub jsonDecode ($) { + ($JSON ||= JSON::XS->new)->decode(@_); +} + +# Insert JSON-encoded data as script, arguments: id, object +sub script_json { + script id => $_[0], type => 'application/json'; + my $js = jsonEncode $_[1]; + $js =~ s/</\\u003C/g; # escape HTML tags like </script> and <!-- + lit $js; + end; +} + + # mt() wrappers for data-dependent translation strings that have a special # value for 'unknown'. sub mtvoiced { !$_[0] ? mt '_unknown' : mt '_voiced_'.$_[0]; } diff --git a/lib/VNDB/Handler/Staff.pm b/lib/VNDB/Handler/Staff.pm index 41b4e331..38b280c8 100644 --- a/lib/VNDB/Handler/Staff.pm +++ b/lib/VNDB/Handler/Staff.pm @@ -5,6 +5,7 @@ use strict; use warnings; use TUWF qw(:html :xml xml_escape); use VNDB::Func; +use List::Util qw(first); TUWF::register( qr{s([1-9]\d*)(?:\.([1-9]\d*))?} => \&page, @@ -43,7 +44,7 @@ sub page { # return $_[0] ? sprintf '<img src="%s" />', imgurl(ch => $_[0]) : mt '_stdiff_image_none'; # }], [ aliases => join => '<br />', split => sub { - map sprintf('%s%s', $_->{name}, $_->{original} ? ' ('.$_->{original}.')' : ''), @{$_[0]}; + map xml_escape(sprintf('%s%s', $_->{name}, $_->{original} ? ' ('.$_->{original}.')' : '')), @{$_[0]}; }], ); } @@ -100,7 +101,7 @@ sub page { if (@{$s->{roles}}) { h2 mt '_staff_credits'; - my $has_notes = grep { $_->{note} || $_->{name} ne $s->{name} } @{$s->{roles}}; + my $has_notes = first { $_->{note} || $_->{name} ne $s->{name} } @{$s->{roles}}; table class => 'stripe staffroles'; thead; Tr; @@ -146,7 +147,7 @@ sub page { } if (@{$s->{cast}}) { h2 mt '_staff_voiced'; - my $has_notes = grep { $_->{note} || $_->{name} ne $s->{name} } @{$s->{cast}}; + my $has_notes = first { $_->{note} || $_->{name} ne $s->{name} } @{$s->{cast}}; table class => 'stripe staffroles'; thead; Tr; @@ -195,8 +196,10 @@ sub edit { my %b4 = !$sid ? () : ( (map { $_ => $s->{$_} } qw|aid name original gender lang desc l_wp ihid ilock|), - aliases => join('|||', map sprintf('%d,%s,%s', $_->{id}, $_->{name}, $_->{original}), - sort { $a->{name} <=> $b->{name} } @{$s->{aliases}}), + aliases => jsonEncode [ + map +{ aid => $_->{id}, name => $_->{name}, orig => $_->{original} }, + sort { $a->{name} <=> $b->{name} } @{$s->{aliases}} + ], ); my $frm; @@ -217,25 +220,29 @@ sub edit { { post => 'ilock', required => 0 }, ); push @{$frm->{_err}}, 'badeditsum' if !$frm->{editsum} || lc($frm->{editsum}) eq lc($frm->{desc}); - my @aliases = map { /^(\d+),([^,]*),(.*)$/ ? [ $1, $2, $3 ]: () } split /\|\|\|/, $frm->{aliases}; - for my $a (@aliases) { - # check for empty aliases - if($a->[1] =~ /^\s*$/) { - push @{$frm->{_err}}, ['alias_name', 'required']; - last; + + my $aliases = eval { jsonDecode $frm->{aliases} }; + push @{$frm->{_err}}, [ 'aliases', 'template', 'json' ] if $@; + if(!$frm->{_err}) { + for my $a (@$aliases) { + # check for empty aliases + if($a->{name} =~ /^\s*$/) { + push @{$frm->{_err}}, ['alias_name', 'required']; + last; + } } } if(!$frm->{_err}) { # parse and normalize - $frm->{aliases} = join('|||', map sprintf('%d,%s,%s', @$_), @aliases); + $frm->{aliases} = jsonEncode $aliases; $frm->{ihid} = $frm->{ihid} ?1:0; $frm->{ilock} = $frm->{ilock}?1:0; return $self->resRedirect("/s$sid", 'post') - if $sid && !grep $frm->{$_} ne $b4{$_}, keys %b4; + if $sid && !first { $frm->{$_} ne $b4{$_} } keys %b4; } if(!$frm->{_err}) { - $frm->{aliases} = \@aliases; + $frm->{aliases} = [ map [ @{$_}{qw|aid name orig|} ], @$aliases ]; my $nrev = $self->dbItemEdit ('s' => $sid ? $s->{cid} : undef, %$frm); return $self->resRedirect("/s$nrev->{iid}.$nrev->{rev}", 'post'); } diff --git a/lib/VNDB/Handler/VNEdit.pm b/lib/VNDB/Handler/VNEdit.pm index caf7e8a3..a7900628 100644 --- a/lib/VNDB/Handler/VNEdit.pm +++ b/lib/VNDB/Handler/VNEdit.pm @@ -88,8 +88,14 @@ sub edit { my %b4 = !$vid ? () : ( (map { $_ => $v->{$_} } qw|title original desc alias length l_wp l_encubed l_renai image img_nsfw ihid ilock|), - credits => join('|||', map join('-', $_->{aid}, $_->{role}, $_->{note}), @{$v->{credits}}), - seiyuu => join('|||', map join('-', $_->{aid}, $_->{cid}, $_->{note}), @{$v->{seiyuu}}), + credits => jsonEncode [ + map { my $c = $_; +{ map { $_ => $c->{$_} } qw|aid role note| } } + sort { $a->{aid} <=> $b->{aid} || $a->{role} cmp $b->{role} } @{$v->{credits}} + ], + seiyuu => jsonEncode [ + map { my $c = $_; +{ map { $_ => $c->{$_} } qw|aid cid note| } } + sort { $a->{aid} <=> $b->{aid} || $a->{cid} <=> $b->{cid} } @{$v->{seiyuu}} + ], anime => join(' ', sort { $a <=> $b } map $_->{id}, @{$v->{anime}}), vnrelations => join('|||', map $_->{relation}.','.$_->{id}.','.($_->{official}?1:0).','.$_->{title}, sort { $a->{id} <=> $b->{id} } @{$v->{relations}}), screenshots => join(' ', map sprintf('%d,%d,%d', $_->{id}, $_->{nsfw}?1:0, $_->{rid}), @{$v->{screenshots}}), @@ -124,13 +130,35 @@ sub edit { # handle image upload $frm->{image} = _uploadimage($self, $frm) if !$nosubmit; + my (@credits, @seiyuu); + if(!$nosubmit && !$frm->{_err}) { + eval { # catch json decoding errors + my $raw_c = $frm->{credits} ? jsonDecode $frm->{credits} : []; + my $raw_s = $frm->{seiyuu} ? jsonDecode $frm->{seiyuu} : []; + + # check for duplicate credits + my $last_c; + for my $c (sort { $a->{aid} <=> $b->{aid} || $a->{role} cmp $b->{role} } @$raw_c) { + # discard entries with identical name & role + next if $last_c->{aid} == $c->{aid} && $last_c->{role} eq $c->{role}; + push @credits, $c; + $last_c = $c; + } + + my $last_s; + for my $s (sort { $a->{aid} <=> $b->{aid} || $a->{cid} <=> $b->{cid} } @$raw_s) { + next if $last_s->{aid} == $s->{aid} && $last_s->{cid} == $s->{cid}; + push @seiyuu, $s; + $last_s = $s; + } + }; + push @{$frm->{_err}}, [ 'credits', 'template', 'json' ] if $@; + } if(!$nosubmit && !$frm->{_err}) { # parse and re-sort fields that have multiple representations of the same information my $anime = { map +($_=>1), grep /^[0-9]+$/, split /[ ,]+/, $frm->{anime} }; my $relations = [ map { /^([a-z]+),([0-9]+),([01]),(.+)$/ && (!$vid || $2 != $vid) ? [ $1, $2, $3, $4 ] : () } split /\|\|\|/, $frm->{vnrelations} ]; my $screenshots = [ map /^[0-9]+,[01],[0-9]+$/ ? [split /,/] : (), split / +/, $frm->{screenshots} ]; - my $credits = [ map { /^(\d+)-([^-]+)-(.*)$/ ? [ $1, $2, $3 ]: () } split /\|\|\|/, $frm->{credits} ]; - my $seiyuu = [ map { /^(\d+)-(\d+)-(.*)$/ ? [ $1, $2, $3 ]: () } split /\|\|\|/, $frm->{seiyuu} ]; $frm->{ihid} = $frm->{ihid}?1:0; $frm->{ilock} = $frm->{ilock}?1:0; @@ -139,24 +167,8 @@ sub edit { $frm->{vnrelations} = join '|||', map $_->[0].','.$_->[1].','.($_->[2]?1:0).','.$_->[3], sort { $a->[1] <=> $b->[1]} @{$relations}; $frm->{img_nsfw} = $frm->{img_nsfw} ? 1 : 0; $frm->{screenshots} = join ' ', map sprintf('%d,%d,%d', $_->[0], $_->[1]?1:0, $_->[2]), sort { $a->[0] <=> $b->[0] } @$screenshots; - - # check for duplicate credits - my($checked_c, $last_c) = ([], []); - for my $c (sort { $a->[0] <=> $b->[0] || $a->[1] cmp $b->[1] } @$credits) { - # discard entries with identical name & role - next if $last_c->[0] == $c->[0] && $last_c->[1] eq $c->[1]; - push @$checked_c, $c; - $last_c = $c; - } - $frm->{credits} = join '|||', map sprintf('%d-%s-%s', @$_), @$checked_c; - - my($checked_s, $last_s) = ([], []); - for my $s (sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @$seiyuu) { - next if $last_s->[0] == $s->[0] && $last_s->[1] == $s->[1]; - push @$checked_s, $s; - $last_s = $s; - } - $frm->{seiyuu} = join '|||', map sprintf('%d-%d-%s', @$_), @$checked_s; + $frm->{credits} = jsonEncode \@credits; + $frm->{seiyuu} = jsonEncode \@seiyuu; # weed out duplicate aliases my %alias; @@ -173,8 +185,8 @@ sub edit { # perform the edit/add my $nrev = $self->dbItemEdit(v => $vid ? $v->{cid} : undef, (map { $_ => $frm->{$_} } qw|title original image alias desc length l_wp l_encubed l_renai editsum img_nsfw ihid ilock|), - credits => $checked_c, - seiyuu => $checked_s, + credits => [ map [ @{$_}{qw|aid role note|} ], @credits ], + seiyuu => [ map [ @{$_}{qw|aid cid note|} ], @seiyuu ], anime => [ keys %$anime ], relations => $relations, screenshots => $screenshots, @@ -289,6 +301,13 @@ sub _form { vn_staff => [ mt('_vnedit_staff'), [ hidden => short => 'credits' ], [ static => nolabel => 1, content => sub { + # propagate staff ids and names to javascript + my %staff_data; + for my $c (@{$v->{credits}}, @{$v->{seiyuu}}) { + $staff_data{$c->{aid}} //= { map +($_ => $c->{$_}), qw|id aid name| }; + } + script_json staffdata => \%staff_data if %staff_data; + div class => 'warning'; lit mt '_vnedit_staff_msg'; end; @@ -309,11 +328,11 @@ sub _form { # would be empty anyway. @{$chars} ? (vn_cast => [ mt('_vnedit_cast'), [ hidden => short => 'seiyuu' ], - [ hidden => short => 'castimpdata', value => do { - join '|||', map join('-', $_->{cid}, $_->{sid}, $_->{aid}, $_->{name}), @$import; - }], [ static => nolabel => 1, content => sub { if (@$import) { + script_json castimpdata => [ + map { my $c = $_; +{ map { $_ => $c->{$_} } qw|cid sid aid name| } } @$import + ]; div id => 'cast_import'; a href => '#', title => mt('_vnedit_cast_import_title'), mt '_vnedit_cast_import'; end; diff --git a/lib/VNDB/Handler/VNPage.pm b/lib/VNDB/Handler/VNPage.pm index ddf605f4..89b48a91 100644 --- a/lib/VNDB/Handler/VNPage.pm +++ b/lib/VNDB/Handler/VNPage.pm @@ -710,14 +710,14 @@ sub _revision { }], [ credits => join => '<br />', split => sub { my @r = map sprintf('<a href="/s%d" title="%s">%s</a> [%s]%s', - $_->{id}, xml_escape($_->{original}||$_->{name}), xml_escape($_->{name}), mt("_credit_$_->{role}"), $_->{note} ? ' ['.shorten($_->{note}, 20).']' : ''), sort { $a->{id} <=> $b->{id} } @{$_[0]}; + $_->{id}, xml_escape($_->{original}||$_->{name}), xml_escape($_->{name}), mt("_credit_$_->{role}"), $_->{note} ? ' ['.xml_escape(shorten($_->{note}, 20)).']' : ''), sort { $a->{id} <=> $b->{id} } @{$_[0]}; return @r ? @r : (mt '_revision_empty'); }], [ seiyuu => join => '<br />', split => sub { my @r = map sprintf('<a href="/s%d" title="%s">%s</a> %s%s', $_->{id}, xml_escape($_->{original}||$_->{name}), xml_escape($_->{name}), mt('_staff_as', xml_escape($_->{cname})), - $_->{note} ? ' ['.shorten($_->{note}, 20).']' : ''), + $_->{note} ? ' ['.xml_escape(shorten($_->{note}, 20)).']' : ''), sort { $a->{id} <=> $b->{id} } @{$_[0]}; return @r ? @r : (mt '_revision_empty'); }], diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm index 8474f9c7..d535472d 100644 --- a/lib/VNDB/Util/CommonHTML.pm +++ b/lib/VNDB/Util/CommonHTML.pm @@ -137,6 +137,7 @@ sub htmlHiddenMessage { my $editsum = $type eq 'v' ? $self->dbVNGet(id => $obj->{id}, what => 'changes')->[0]{comments} : $type eq 'r' ? $self->dbReleaseGet(id => $obj->{id}, what => 'changes')->[0]{comments} : $type eq 'c' ? $self->dbCharGet(id => $obj->{id}, what => 'changes')->[0]{comments} + : $type eq 's' ? $self->dbStaffGet(id => $obj->{id}, what => 'changes')->[0]{comments} : $self->dbProducerGet(id => $obj->{id}, what => 'changes')->[0]{comments}; div class => 'mainbox'; h1 $obj->{title}||$obj->{name}; |