diff options
author | Yorhel <git@yorhel.nl> | 2019-10-16 10:31:24 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2019-10-16 15:29:38 +0200 |
commit | 678f511619708ba893cb2414eead90cdae685708 (patch) | |
tree | 2c79c111805f38454e07d96645f3fdc31fe75860 /lib/VNDB | |
parent | 1fb8a234cf5a455af6d78c893320b21de8347bc4 (diff) |
v2rw: Convert staff adding/editing form
This is the first major editing form to be converted, so I'm expecting a
little breakage. A good chunk of this code has been copied from v3.
In terms of the UI there has been a small change: aliases that are still
referenced do not have the 'remove' link and instead have a flag that
shows that they are still referenced. This ought to be a bit friendlier
than throwing an error message after the user has submitted the form.
Some other things I'd like to improve in this form:
- BBCode preview
- Pasting in external links and letting the form figure out the Pixiv
ID, etc.
- Or perhaps even: Integrate AniDB/Wikidata search/autocompletion.
Diffstat (limited to 'lib/VNDB')
-rw-r--r-- | lib/VNDB/BBCode.pm | 51 | ||||
-rw-r--r-- | lib/VNDB/DB/Misc.pm | 1 | ||||
-rw-r--r-- | lib/VNDB/DB/Staff.pm | 42 | ||||
-rw-r--r-- | lib/VNDB/Handler/Staff.pm | 120 | ||||
-rw-r--r-- | lib/VNDB/Util/CommonHTML.pm | 54 | ||||
-rw-r--r-- | lib/VNDB/Util/Misc.pm | 49 |
6 files changed, 55 insertions, 262 deletions
diff --git a/lib/VNDB/BBCode.pm b/lib/VNDB/BBCode.pm index c1de1f7f..6ef72cdc 100644 --- a/lib/VNDB/BBCode.pm +++ b/lib/VNDB/BBCode.pm @@ -1,11 +1,11 @@ package VNDB::BBCode; -use strict; +use v5.26; use warnings; use Exporter 'import'; use TUWF::XML 'xml_escape'; -our @EXPORT = qw/bb2html bb2text/; +our @EXPORT = qw/bb2html bb2text bb_subst_links/; # Supported BBCode: # [spoiler] .. [/spoiler] @@ -249,4 +249,51 @@ sub bb2text { } +# Turn (most) 'dblink's into [url=..] links. This function relies on TUWF to do +# the database querying, so can't be used from Multi. +# Doesn't handle: +# - d+, t+, r+ and u+ links +# - item revisions +sub bb_subst_links { + my $msg = shift; + + # Parse a message and create an index of links to resolve + my %lookup; + parse $msg, sub { + my($code, $tag) = @_; + $lookup{$1}{$2} = 1 if $tag eq 'dblink' && $code =~ /^(.)(\d+)/; + 1; + }; + return $msg unless %lookup; + + # Now resolve the links + state $types = { # Query must return 'id' and 'name' columns, list of IDs will be appended to it. + v => 'SELECT id, title AS name FROM vn WHERE id IN', + c => 'SELECT id, name FROM chars WHERE id IN', + p => 'SELECT id, name FROM producers WHERE id IN', + g => 'SELECT id, name FROM tags WHERE id IN', + i => 'SELECT id, name FROM traits WHERE id IN', + s => 'SELECT s.id, sa.name FROM staff_alias sa JOIN staff s ON s.aid = sa.id WHERE s.id IN', + }; + my %links; + for my $type (keys %$types) { + next if !$lookup{$type}; + my $lst = $TUWF::OBJ->dbAlli($types->{$type}, [keys %{$lookup{$type}}]); + $links{$type . $_->{id}} = $_->{name} for @$lst; + } + return $msg unless %links; + + # Now substitute + my $result = ''; + parse $msg, sub { + my($code, $tag) = @_; + $result .= $tag eq 'dblink' && $links{$code} + ? sprintf '[url=/%s]%s[/url]', $code, $links{$code} + : $code; + 1; + }; + return $result; +} + + 1; diff --git a/lib/VNDB/DB/Misc.pm b/lib/VNDB/DB/Misc.pm index 27494380..cd290d61 100644 --- a/lib/VNDB/DB/Misc.pm +++ b/lib/VNDB/DB/Misc.pm @@ -40,7 +40,6 @@ sub dbItemEdit { $self->dbProducerRevisionInsert(\%o) if $type eq 'p'; $self->dbReleaseRevisionInsert( \%o) if $type eq 'r'; $self->dbCharRevisionInsert( \%o) if $type eq 'c'; - $self->dbStaffRevisionInsert( \%o) if $type eq 's'; return $self->dbRow('SELECT * FROM edit_!s_commit()', $type); } diff --git a/lib/VNDB/DB/Staff.pm b/lib/VNDB/DB/Staff.pm index b8995d04..87dbef43 100644 --- a/lib/VNDB/DB/Staff.pm +++ b/lib/VNDB/DB/Staff.pm @@ -5,7 +5,7 @@ use strict; use warnings; use Exporter 'import'; -our @EXPORT = qw|dbStaffGet dbStaffGetRev dbStaffRevisionInsert dbStaffAliasIds|; +our @EXPORT = qw|dbStaffGet dbStaffGetRev|; # options: results, page, id, aid, search, exact, truename, role, gender # what: extended changes roles aliases @@ -153,44 +153,4 @@ sub _enrich { return wantarray ? ($r, $np) : $r; } - -# Updates the edit_* tables, used from dbItemEdit() -# Arguments: { columns in staff_rev and staff_alias}, -sub dbStaffRevisionInsert { - my($self, $o) = @_; - - $self->dbExec('DELETE FROM edit_staff_alias'); - if($o->{aid}) { - $self->dbExec(q| - INSERT INTO edit_staff_alias (aid, name, original) VALUES (?, ?, ?)|, - $o->{aid}, $o->{name}, $o->{original}); - } else { - $o->{aid} = $self->dbRow(q| - INSERT INTO edit_staff_alias (name, original) VALUES (?, ?) RETURNING aid|, - $o->{name}, $o->{original})->{aid}; - } - - my %staff = map exists($o->{$_}) ? (qq|"$_" = ?|, $o->{$_}) : (), - qw|aid gender lang desc l_wp l_site l_twitter l_anidb l_wikidata l_pixiv|; - $self->dbExec('UPDATE edit_staff !H', \%staff) if %staff; - for my $a (@{$o->{aliases}}) { - if($a->{aid}) { - $self->dbExec('INSERT INTO edit_staff_alias (aid, name, original) VALUES (!l)', [ @{$a}{qw|aid name orig|} ]); - } else { - $self->dbExec('INSERT INTO edit_staff_alias (name, original) VALUES (?, ?)', $a->{name}, $a->{orig}); - } - } -} - - -# returns alias IDs that are and were related to the given staff ID -sub dbStaffAliasIds { - my($self, $sid) = @_; - return $self->dbAll(q| - SELECT DISTINCT sa.aid - FROM changes c - JOIN staff_alias_hist sa ON sa.chid = c.id - WHERE c.type = 's' AND c.itemid = ?|, $sid); -} - 1; diff --git a/lib/VNDB/Handler/Staff.pm b/lib/VNDB/Handler/Staff.pm index bcdbb08f..1eb2f927 100644 --- a/lib/VNDB/Handler/Staff.pm +++ b/lib/VNDB/Handler/Staff.pm @@ -10,8 +10,6 @@ use List::Util qw(first); TUWF::register( qr{s([1-9]\d*)(?:\.([1-9]\d*))?} => \&page, - qr{s(?:([1-9]\d*)(?:\.([1-9]\d*))?/edit|/new)} - => \&edit, qr{s/([a-z0]|all)} => \&list, qr{xml/staff\.xml} => \&staffxml, ); @@ -178,124 +176,6 @@ sub _cast { } -sub edit { - my($self, $sid, $rev) = @_; - - my $s = $sid && $self->dbStaffGetRev(id => $sid, what => 'extended aliases roles', $rev ? (rev => $rev) : ())->[0]; - return $self->resNotFound if $sid && !$s->{id}; - $rev = undef if !$s || $s->{lastrev}; - - return $self->htmlDenied if !$self->authCan('edit') - || $sid && (($s->{locked} || $s->{hidden}) && !$self->authCan('dbmod')); - - my %b4 = !$sid ? () : ( - (map { $_ => $s->{$_} } qw|name original gender lang desc l_site l_wikidata l_twitter l_anidb l_pixiv ihid ilock|), - primary => $s->{aid}, - aliases => [ - map +{ aid => $_->{aid}, name => $_->{name}, orig => $_->{original} }, - sort { $a->{name} cmp $b->{name} || $a->{original} cmp $b->{original} } @{$s->{aliases}} - ], - ); - my $frm; - - if ($self->reqMethod eq 'POST') { - return if !$self->authCheckCode; - $frm = $self->formValidate ( - { post => 'name', maxlength => 200 }, - { post => 'original', required => 0, maxlength => 200, default => '' }, - { post => 'primary', required => 0, template => 'id', default => 0 }, - { post => 'desc', required => 0, maxlength => 5000, default => '' }, - { post => 'gender', required => 0, default => 'unknown', enum => [qw|unknown m f|] }, - { post => 'lang', enum => [ keys %LANGUAGE ] }, - { post => 'l_site', required => 0, template => 'weburl', maxlength => 250, default => '' }, - { post => 'l_wikidata', required => 0, template => 'wikidata' }, - { post => 'l_twitter', required => 0, maxlength => 16, default => '', regex => [ qr/^\S+$/, 'Invalid twitter username' ] }, - { post => 'l_anidb', required => 0, template => 'id', default => undef }, - { post => 'l_pixiv', required => 0, default => 0, template => 'uint' }, - { post => 'aliases', template => 'json', json_sort => ['name','orig'], json_fields => [ - { field => 'name', required => 1, maxlength => 200 }, - { field => 'orig', required => 0, maxlength => 200, default => '' }, - { field => 'aid', required => 0, template => 'id', default => 0 }, - ]}, - { post => 'editsum', template => 'editsum' }, - { post => 'ihid', required => 0 }, - { post => 'ilock', required => 0 }, - ); - - if(!$frm->{_err}) { - my %old_aliases = $sid ? ( map +($_->{aid} => 1), @{$self->dbStaffAliasIds($sid)} ) : (); - $frm->{primary} = 0 unless exists $old_aliases{$frm->{primary}}; - - # reset aid to zero for newly added aliases. - $_->{aid} *= $old_aliases{$_->{aid}} ? 1 : 0 for(@{$frm->{aliases}}); - - # Make sure no aliases that have been linked to a VN are removed. - my %new_aliases = map +($_, 1), grep $_, $frm->{primary}, map $_->{aid}, @{$frm->{aliases}}; - $frm->{_err} = [ "Can't remove an alias that is still linked to a VN." ] - if grep !$new_aliases{$_->{aid}}, @{$s->{roles}}, @{$self->{cast}}; - } - - if(!$frm->{_err}) { - $frm->{ihid} = $frm->{ihid} ?1:0; - $frm->{ilock} = $frm->{ilock}?1:0; - $frm->{aid} = $frm->{primary} if $sid; - $frm->{desc} = $self->bbSubstLinks($frm->{desc}); - return $self->resRedirect("/s$sid", 'post') if $sid && !form_compare(\%b4, $frm); - - my $nrev = $self->dbItemEdit(s => $sid ? ($s->{id}, $s->{rev}) : (undef, undef), %$frm); - return $self->resRedirect("/s$nrev->{itemid}.$nrev->{rev}", 'post'); - } - } - - $frm->{$_} //= $b4{$_} for keys %b4; - $frm->{editsum} //= sprintf 'Reverted to revision s%d.%d', $sid, $rev if $rev; - $frm->{lang} = 'ja' if !$sid && !defined $frm->{lang}; - - my $title = $s ? "Edit $s->{name}" : 'Add staff member'; - $self->htmlHeader(title => $title, noindex => 1); - $self->htmlMainTabs('s', $s, 'edit') if $s; - $self->htmlEditMessage('s', $s, $title); - $self->htmlForm({ frm => $frm, action => $s ? "/s$sid/edit" : '/s/new', editsum => 1 }, - staffe_geninfo => [ 'General info', - [ hidden => short => 'name' ], - [ hidden => short => 'original' ], - [ hidden => short => 'primary' ], - [ json => short => 'aliases' ], - $sid && @{$s->{aliases}} ? - [ static => content => 'You may choose a different primary name.' ] : (), - [ static => label => 'Names', content => sub { - table id => 'names'; - thead; Tr; - td class => 'tc_id'; end; - td class => 'tc_name', 'Name (romaji)'; - td class => 'tc_original', 'Original'; td; end; - end; end; - tbody id => 'alias_tbl'; - # filled with javascript - end; - end; - }], - [ static => content => '<br />' ], - [ text => name => 'Staff note<br /><b class="standout">English please!</b>', short => 'desc', rows => 4 ], - [ select => name => 'Gender',short => 'gender', options => [ - map [ $_, $GENDER{$_} ], qw(unknown m f) ] ], - [ select => name => 'Primary language', short => 'lang', - options => [ map [ $_, "$LANGUAGE{$_} ($_)" ], sort { $LANGUAGE{$a} cmp $LANGUAGE{$b} } keys %LANGUAGE ] ], - [ input => name => 'Official page', short => 'l_site' ], - [ input => short => 'l_wikidata',name => 'Wikidata ID', - value => $frm->{l_wikidata} ? "Q$frm->{l_wikidata}" : '', - post => qq{ (<a href="$self->{url_static}/f/wikidata.png">How to find this</a>)} - ], - [ input => name => 'Twitter username', short => 'l_twitter' ], - [ input => name => 'AniDB creator ID', short => 'l_anidb' ], - [ input => name => 'Pixiv ID', short => 'l_pixiv' ], - [ static => content => '<br />' ], - ]); - - $self->htmlFooter; -} - - sub list { my ($self, $char) = @_; diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm index 81309325..b56a7c74 100644 --- a/lib/VNDB/Util/CommonHTML.pm +++ b/lib/VNDB/Util/CommonHTML.pm @@ -268,59 +268,9 @@ sub revdiff { # Generates a generic message to show as the header of the edit forms -# Arguments: v/r/p, obj +# Arguments: v/r/p, obj, title, copy sub htmlEditMessage { - my($self, $type, $obj, $title, $copy) = @_; - my $typename = {v => 'visual novel', r => 'release', p => 'producer', c => 'character', s => 'person'}->{$type}; - my $guidelines = {v => 2, r => 3, p => 4, c => 12, 's' => 16}->{$type}; - - div class => 'mainbox'; - h1 $title; - if($copy) { - div class => 'warning'; - h2 'You\'re not editing an entry!'; - p; - txt 'You\'re about to insert a new entry into the database with information based on '; - a href => "/$type$obj->{id}", $obj->{title}||$obj->{name}; - txt '.'; - br; - txt 'Hit the \'edit\' tab on the right-top if you intended to edit the entry instead of creating a new one.'; - end; - end; - } - div class => 'notice'; - h2 'Before editing:'; - ul; - li; - txt "Read the "; - a href=> "/d$guidelines", 'guidelines'; - txt '!'; - end; - if($obj) { - li; - txt 'Check for any existing discussions on the '; - a href => $type =~ /[cs]/ ? '/t/db' : $type eq 'r' ? "/t/v$obj->{vn}[0]{vid}" : "/t/$type$obj->{id}", 'discussion board'; - end; - li; - txt 'Browse the '; - a href => "/$type$obj->{id}/hist", 'edit history'; - txt ' for any recent changes related to what you want to change.'; - end; - } elsif($type ne 'r') { - li; - a href => "/$type/all", 'Search the database'; - txt " to see if we already have information about this $typename."; - end; - } - end; - end; - if($obj && !$obj->{lastrev}) { - div class => 'warning'; - h2 'Reverting'; - p "You are editing an old revision of this $typename. If you save it, all changes made after this revision will be reverted!"; - end; - } - end 'div'; + shift; VNWeb::HTML::editmsg_(@_); } diff --git a/lib/VNDB/Util/Misc.pm b/lib/VNDB/Util/Misc.pm index 9cfb8210..394003ae 100644 --- a/lib/VNDB/Util/Misc.pm +++ b/lib/VNDB/Util/Misc.pm @@ -7,7 +7,7 @@ use Exporter 'import'; use TUWF ':html'; use VNDB::Func; use VNDB::Types; -use VNDB::BBCode (); +use VNDB::BBCode; our @EXPORT = qw|filFetchDB filCompat bbSubstLinks entryLinks|; @@ -114,54 +114,11 @@ sub filCompat { sub bbSubstLinks { - my ($self, $msg) = @_; - - # Parse a message and create an index of links to resolve - my %lookup; - VNDB::BBCode::parse $msg, sub { - my($code, $tag) = @_; - $lookup{$1}{$2} = 1 if $tag eq 'dblink' && $code =~ /^(.)(\d+)/; - 1; - }; - return $msg unless %lookup; - - # Now resolve the links - my %links; - my @opt = (results => 50); - - if ($lookup{v}) { - $links{"v$_->{id}"} = $_->{title} for (@{$self->dbVNGet(id => [keys %{$lookup{v}}], @opt)}); - } - if ($lookup{c}) { - $links{"c$_->{id}"} = $_->{name} for (@{$self->dbCharGet(id => [keys %{$lookup{c}}], @opt)}); - } - if ($lookup{p}) { - $links{"p$_->{id}"} = $_->{name} for (@{$self->dbProducerGet(id => [keys %{$lookup{p}}], @opt)}); - } - if ($lookup{g}) { - $links{"g$_->{id}"} = $_->{name} for (@{$self->dbTagGet(id => [keys %{$lookup{g}}], @opt)}); - } - if ($lookup{i}) { - $links{"i$_->{id}"} = $_->{name} for (@{$self->dbTraitGet(id => [keys %{$lookup{i}}], @opt)}); - } - if ($lookup{s}) { - $links{"s$_->{id}"} = $_->{name} for (@{$self->dbStaffGet(id => [keys %{$lookup{s}}], @opt)}); - } - return $msg unless %links; - - # Now substitute - my $result = ''; - VNDB::BBCode::parse $msg, sub { - my($code, $tag) = @_; - $result .= $tag eq 'dblink' && $links{$code} - ? sprintf '[url=/%s]%s[/url]', $code, $links{$code} - : $code; - 1; - }; - return $result; + shift; bb_subst_links @_; } + # Returns an arrayref of links, each link being [$title, $url, $price] sub entryLinks { my($self, $type, $obj) = @_; |