summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authormorkt <>2015-01-02 10:22:25 +0100
committerYorhel <git@yorhel.nl>2015-01-02 10:22:25 +0100
commit228cb96969a33a60c40dd4991a394460652010af (patch)
tree9d69e00562ae545b79ca8a899d2439c4800133d7 /lib
parent03585d77637a7052d0af2cdb1e4be66358412b6a (diff)
staff: Fix deleting of staff + use JSON to pass data + minor fixes
Diffstat (limited to 'lib')
-rw-r--r--lib/VNDB/DB/Chars.pm7
-rw-r--r--lib/VNDB/DB/VN.pm4
-rw-r--r--lib/VNDB/Func.pm24
-rw-r--r--lib/VNDB/Handler/Staff.pm35
-rw-r--r--lib/VNDB/Handler/VNEdit.pm73
-rw-r--r--lib/VNDB/Handler/VNPage.pm4
-rw-r--r--lib/VNDB/Util/CommonHTML.pm1
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};