diff options
author | Yorhel <git@yorhel.nl> | 2020-02-13 16:25:09 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2020-02-13 16:37:05 +0100 |
commit | cc9965cc9e081ff1c1c0ff065f9c5ffcc744cb86 (patch) | |
tree | d9b2f997c31c1c7b05392e1f8eaeaa99c1faf43e /lib | |
parent | 23fb02e36defa7660ee871dd9e650906b0d2d616 (diff) |
v2rw: Add instance listing to Chars::Page
I wasn't sure how to handle the fetching of multiple character entries;
whether to extend/re-use db_entry() or write a separate function. Ended
up going with the latter solution, as db_entry() already has other
functionality (and overhead) that we won't be needing in this case. This
overhead will matter when this function is used for the character
listing on VN pages.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VNDB/Handler/Chars.pm | 90 | ||||
-rw-r--r-- | lib/VNWeb/Chars/Page.pm | 45 |
2 files changed, 43 insertions, 92 deletions
diff --git a/lib/VNDB/Handler/Chars.pm b/lib/VNDB/Handler/Chars.pm index 059c7b3f..a7a8d801 100644 --- a/lib/VNDB/Handler/Chars.pm +++ b/lib/VNDB/Handler/Chars.pm @@ -12,102 +12,12 @@ use List::Util 'min'; our @EXPORT = ('charOps', 'charTable', 'charBrowseTable'); TUWF::register( - qr{oc([1-9]\d*)(?:\.([1-9]\d*))?} => \&page, qr{c(?:([1-9]\d*)(?:\.([1-9]\d*))?/(edit|copy)|/new)} => \&edit, qr{c/([a-z0]|all)} => \&list, ); -sub page { - my($self, $id, $rev) = @_; - - my $method = $rev ? 'dbCharGetRev' : 'dbCharGet'; - my $r = $self->$method( - id => $id, - what => 'extended traits vns seiyuu', - $rev ? ( rev => $rev ) : () - )->[0]; - return $self->resNotFound if !$r->{id}; - - my $metadata = { - 'og:title' => $r->{name}, - 'og:description' => bb2text($r->{desc}), - 'og:image' => $r->{image} && imgurl(ch => $r->{image}), - }; - - $self->htmlHeader(title => $r->{name}, noindex => $rev, metadata => $metadata); - $self->htmlMainTabs(c => $r); - return if $self->htmlHiddenMessage('c', $r); - - if($rev) { - my $prev = $rev && $rev > 1 && $self->dbCharGetRev(id => $id, rev => $rev-1, what => 'extended traits vns')->[0]; - $self->htmlRevision('c', $prev, $r, - [ name => 'Name', diff => 1 ], - [ original => 'Original name', diff => 1 ], - [ alias => 'Aliases', diff => qr/[ ,\n\.]/ ], - [ desc => 'Description', diff => qr/[ ,\n\.]/ ], - [ gender => 'Sex', serialize => sub { $GENDER{$_[0]} } ], - [ b_month => 'Birthday/month',serialize => sub { $_[0]||'[empty]' } ], - [ b_day => 'Birthday/day', serialize => sub { $_[0]||'[empty]' } ], - [ s_bust => 'Bust', serialize => sub { $_[0]||'[empty]' } ], - [ s_waist => 'Waist', serialize => sub { $_[0]||'[empty]' } ], - [ s_hip => 'Hip', serialize => sub { $_[0]||'[empty]' } ], - [ 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]} } ], - [ age => 'Age', serialize => sub { $_[0]//'[empty]' } ], - [ 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 { - return $_[0] ? sprintf '<img src="%s" />', imgurl(ch => $_[0]) : 'No image'; - }], - [ traits => 'Traits', join => '<br />', split => sub { - map sprintf('%s<a href="/i%d">%s</a> (%s)', $_->{group}?qq|<b class="grayedout">$_->{groupname} / </b> |:'', - $_->{tid}, $_->{name}, fmtspoil $_->{spoil}), @{$_[0]} - }], - [ vns => 'Visual novels', join => '<br />', split => sub { - map sprintf('<a href="/v%d">v%d</a> %s %s (%s)', $_->{vid}, $_->{vid}, - $_->{rid}?sprintf('[<a href="/r%d">r%d</a>]', $_->{rid}, $_->{rid}):'', - $CHAR_ROLE{$_->{role}}{txt}, fmtspoil $_->{spoil}), @{$_[0]}; - }], - ); - } - - div class => 'charops', id => 'charops'; - $self->charOps(1, 'char'); - - div class => 'mainbox'; - $self->htmlItemMessage('c', $r); - h1 $r->{name}; - h2 class => 'alttitle', $r->{original} if $r->{original}; - $self->charTable($r); - end; - - # TODO: ordering of these instances? - my $inst = []; - if(!$r->{main}) { - $inst = $self->dbCharGet(instance => $r->{id}, what => 'extended traits vns seiyuu'); - } else { - $inst = $self->dbCharGet(instance => $r->{main}, notid => $r->{id}, what => 'extended traits vns seiyuu'); - push @$inst, $self->dbCharGet(id => $r->{main}, what => 'extended traits vns seiyuu')->[0]; - } - if(@$inst) { - my $spoil = sub { local $_=shift; !$r->{main} ? $_->{main_spoil} : $_->{main_spoil} > $r->{main_spoil} ? $_->{main_spoil} : $r->{main_spoil} }; - my $minspoil = min map $spoil->($_), @$inst; - div class => 'mainbox '.charspoil($minspoil); - h1 'Other instances'; - $self->charTable($_, 1, $_ != $inst->[0], 0, $spoil->($_)) for @$inst; - end; - } - - end; - - $self->htmlFooter; -} - - sub charOps { my($self, $sexual, $blockId) = @_; $blockId ||= 'charops_block'; diff --git a/lib/VNWeb/Chars/Page.pm b/lib/VNWeb/Chars/Page.pm index 06493de6..58323bcd 100644 --- a/lib/VNWeb/Chars/Page.pm +++ b/lib/VNWeb/Chars/Page.pm @@ -29,6 +29,37 @@ sub enrich_item { } +# Fetch multiple character entries with a format suitable for chartable_() +sub fetch_chars { + my($vid, $where) = @_; + my $l = tuwf->dbAlli(' + SELECT id, name, original, alias, "desc", gender, b_month, b_day, s_bust, s_waist, s_hip, height, weight, bloodt, cup_size, age, image + FROM chars WHERE NOT hidden AND (', $where, ')' + ); + + enrich vns => id => id => sub { sql ' + SELECT cv.id, cv.vid, cv.rid, cv.spoil, cv.role, v.title, v.original, r.title AS rtitle, r.original AS roriginal + FROM chars_vns cv + JOIN vn v ON v.id = cv.vid + LEFT JOIN releases r ON r.id = cv.rid + WHERE cv.id IN', $_, $vid ? ('AND cv.vid =', \$vid) : (), ' + ORDER BY v.title, cv.vid, cv.rid NULLS LAST' + }, $l; + + enrich traits => id => id => sub { sql ' + SELECT ct.id, ct.tid, ct.spoil, t.name, t.sexual, coalesce(g.id, t.id) AS group, coalesce(g.name, t.name) AS groupname, coalesce(g.order,0) AS order + FROM chars_traits ct + JOIN traits t ON t.id = ct.tid + LEFT JOIN traits g ON t.group = g.id + WHERE ct.id IN', $_, ' + ORDER BY g.order NULLS FIRST, coalesce(g.name, t.name), t.name' + }, $l; + + enrich_seiyuu $vid, $l; + $l +} + + sub _rev_ { my($c) = @_; revision_ c => $c, \&enrich_item, @@ -187,6 +218,7 @@ TUWF::get qr{/$RE{crev}} => sub { enrich_item $c; enrich_seiyuu undef, $c; + my $view = viewget; framework_ title => $c->{name}, index => !tuwf->capture('rev'), type => 'c', dbobj => $c, hiddenmsg => 1, og => { @@ -197,7 +229,6 @@ TUWF::get qr{/$RE{crev}} => sub { div_ class => 'mainbox', sub { itemmsg_ c => $c; p_ class => 'mainopts', sub { - my $view = viewget; a_ mkclass(checked => $view->{spoilers} == 0), href => '?view='.viewset(spoilers=>0), 'Hide spoilers'; a_ mkclass(checked => $view->{spoilers} == 1), href => '?view='.viewset(spoilers=>1), 'Show minor spoilers'; a_ mkclass(standout =>$view->{spoilers} == 2), href => '?view='.viewset(spoilers=>2), 'Spoil me!'; @@ -209,7 +240,17 @@ TUWF::get qr{/$RE{crev}} => sub { chartable_ $c; }; - # TODO: Other instances + my $inst = $c->{main} && $c->{main_spoil} > $view->{spoilers} ? [] + : fetch_chars undef, sql + # If this entry doesn't have a 'main', look for other entries with a 'main' referencing this entry + !$c->{main} ? ('main =', \$c->{id}, 'AND main_spoil <=', \$view->{spoilers}) : + # Otherwise, look for other entries with the same 'main', and also fetch the 'main' entry itself + ('(id <>', \$c->{id}, 'AND main =', \$c->{main}, 'AND main_spoil <=', \$view->{spoilers}, ') OR id =', \$c->{main}); + + div_ class => 'mainbox', sub { + h1_ 'Other instances'; + chartable_ $_, 1, $_ != $inst->[0] for @$inst; + } if @$inst; }; }; |