summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2020-02-13 16:25:09 +0100
committerYorhel <git@yorhel.nl>2020-02-13 16:37:05 +0100
commitcc9965cc9e081ff1c1c0ff065f9c5ffcc744cb86 (patch)
treed9b2f997c31c1c7b05392e1f8eaeaa99c1faf43e /lib
parent23fb02e36defa7660ee871dd9e650906b0d2d616 (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.pm90
-rw-r--r--lib/VNWeb/Chars/Page.pm45
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;
};
};