summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2020-01-23 10:22:36 +0100
committerYorhel <git@yorhel.nl>2020-01-23 10:22:39 +0100
commit95c14cbfeaf92d29827196912b9c7259c3afb89d (patch)
tree6a0ce2c17701ca1c5e60e2c9c5372117e53af3a5
parentb86e1c7744710099d1511598ece7f5c320cd54da (diff)
v2rw: Convert release pages
This removes the user list management functionality, I'll reimplement those in a bit.
-rw-r--r--data/js/misc.js8
-rw-r--r--lib/VNDB/Handler/Releases.pm283
-rw-r--r--lib/VNWeb/DB.pm9
-rw-r--r--lib/VNWeb/HTML.pm2
-rw-r--r--lib/VNWeb/Prelude.pm4
-rw-r--r--lib/VNWeb/Releases/Page.pm217
-rw-r--r--lib/VNWeb/Staff/Page.pm3
7 files changed, 226 insertions, 300 deletions
diff --git a/data/js/misc.js b/data/js/misc.js
index fd042524..ccacd0ee 100644
--- a/data/js/misc.js
+++ b/data/js/misc.js
@@ -72,14 +72,6 @@ if(byId('wishsel'))
};
-// Release & VN list dropdown box (/r+ and /v+)
-if(byId('listsel'))
- byId('listsel').onchange = function() {
- if(this.selectedIndex != 0)
- ulist_redirect('[rv]', '/list', this.name, 'e='+this.options[this.selectedIndex].value);
- };
-
-
// 'more' / 'less' summarization of some boxes on VN pages
(function(){
function set(o, h) {
diff --git a/lib/VNDB/Handler/Releases.pm b/lib/VNDB/Handler/Releases.pm
index 4b850e58..589a685b 100644
--- a/lib/VNDB/Handler/Releases.pm
+++ b/lib/VNDB/Handler/Releases.pm
@@ -3,17 +3,15 @@ package VNDB::Handler::Releases;
use strict;
use warnings;
-use TUWF ':html', ':xml', 'uri_escape', 'xml_escape';
+use TUWF ':html', ':xml', 'uri_escape';
use VNDB::Func;
use VNDB::Types;
-use VNDB::ExtLinks;
use Exporter 'import';
our @EXPORT = ('releaseExtLinks');
TUWF::register(
- qr{r([1-9]\d*)(?:\.([1-9]\d*))?} => \&page,
qr{(v)([1-9]\d*)/add} => \&edit,
qr{r} => \&browse,
qr{r(?:([1-9]\d*)(?:\.([1-9]\d*))?/(edit|copy))}
@@ -24,285 +22,6 @@ TUWF::register(
);
-sub page {
- my($self, $rid, $rev) = @_;
-
- my $method = $rev ? 'dbReleaseGetRev' : 'dbReleaseGet';
- my $r = $self->$method(
- id => $rid,
- what => 'vn extended links producers platforms media',
- $rev ? (rev => $rev) : (),
- )->[0];
- return $self->resNotFound if !$r->{id};
- enrich_extlinks r => $r;
-
- my $metadata = {
- 'og:title' => $r->{title},
- 'og:description' => bb2text $r->{notes},
- };
-
- $self->htmlHeader(title => $r->{title}, noindex => $rev, metadata => $metadata);
- $self->htmlMainTabs('r', $r);
- return if $self->htmlHiddenMessage('r', $r);
-
- if($rev) {
- my $prev = $rev && $rev > 1 && $self->dbReleaseGetRev(
- id => $rid, rev => $rev-1,
- what => 'vn extended links producers platforms media changes'
- )->[0];
- $self->htmlRevision('r', $prev, $r,
- [ vn => 'Relations', join => '<br />', split => sub {
- map sprintf('<a href="/v%d" title="%s">%s</a>', $_->{vid}, $_->{original}||$_->{title}, shorten $_->{title}, 50), @{$_[0]};
- } ],
- [ type => 'Type' ],
- [ patch => 'Patch', serialize => sub { $_[0] ? 'Yes' : 'No' } ],
- [ freeware => 'Freeware', serialize => sub { $_[0] ? 'Yes' : 'No' } ],
- [ doujin => 'Doujin', serialize => sub { $_[0] ? 'Yes' : 'No' } ],
- [ uncensored => 'Uncensored', serialize => sub { $_[0] ? 'Yes' : 'No' } ],
- [ title => 'Title (romaji)', diff => 1 ],
- [ original => 'Original title', diff => 1 ],
- [ gtin => 'JAN/UPC/EAN', serialize => sub { $_[0]||'[empty]' } ],
- [ catalog => 'Catalog number', serialize => sub { $_[0]||'[empty]' } ],
- [ languages => 'Language', join => ', ', split => sub { map $LANGUAGE{$_}, @{$_[0]} } ],
- [ website => 'Website' ],
- [ l_egs => 'ErogameScape', htmlize => sub { $_[0] ? sprintf '<a href="https://erogamescape.dyndns.org/~ap2/ero/toukei_kaiseki/game.php?game=%d">%1$d</a>', $_[0] : '[empty]' } ],
- [ l_erotrail => 'ErogeTrailers', htmlize => sub { $_[0] ? sprintf '<a href="http://erogetrailers.com/soft/%d">%1$d</a>', $_[0] : '[empty]' } ],
- [ l_steam => 'Steam AppId', htmlize => sub { $_[0] ? sprintf '<a href="https://store.steampowered.com/app/%d/">%1$d</a>', $_[0] : '[empty]' } ],
- [ l_dlsite => 'DLsite (jpn)', htmlize => sub { $_[0] ? sprintf '<a href="'.sprintf($self->{dlsite_url}, 'home').'">%1$s</a>', $_[0] : '[empty]' } ],
- [ l_dlsiteen => 'DLsite (eng)', htmlize => sub { $_[0] ? sprintf '<a href="'.sprintf($self->{dlsite_url}, 'eng').'">%1$s</a>', $_[0] : '[empty]' } ],
- [ l_gog => 'GOG.com', htmlize => sub { $_[0] ? sprintf '<a href="https://www.gog.com/game/%s">%1$s</a>', $_[0] : '[empty]' } ],
- [ l_denpa => 'Denpasoft', htmlize => sub { $_[0] ? sprintf qq{<a href="$self->{denpa_url}">%1\$s</a>}, $_[0] : '[empty]' } ],
- [ l_jlist => 'J-List', htmlize => sub { $_[0] ? sprintf qq{<a href="$self->{jlist_url}">%1\$s</a>}, $_[0] : '[empty]' } ],
- [ l_gyutto => 'Gyutto', htmlize => sub { join ', ', map sprintf('<a href="https://gyutto.com/i/item%d">%1$s</a>', xml_escape $_), sort @{$_[0]} } ],
- [ l_digiket => 'Digiket', htmlize => sub { $_[0] ? sprintf '<a href="https://www.digiket.com/work/show/_data/ID=ITM%07d/">%1$d</a>', $_[0] : '[empty]' } ],
- [ l_melon => 'Melonbooks', htmlize => sub { $_[0] ? sprintf '<a href="https://www.melonbooks.com/index.php?main_page=product_info&products_id=IT%010d">%1$d</a>', $_[0] : '[empty]' } ],
- [ l_mg => 'MangaGamer', htmlize => sub { $_[0] ? sprintf qq{<a href="$self->{mg_r18_url}">%1\$d</a>}, $_[0] : '[empty]' } ],
- [ l_getchu => 'Getchu', htmlize => sub { $_[0] ? sprintf '<a href="http://www.getchu.com/soft.phtml?id=%d">%1$d</a>', $_[0] : '[empty]' } ],
- [ l_getchudl => 'DL.Getchu', htmlize => sub { $_[0] ? sprintf '<a href="http://dl.getchu.com/i/item%d">%1$d</a>', $_[0] : '[empty]' } ],
- [ l_dmm => 'DMM', htmlize => sub { join ', ', map sprintf('<a href="https://%s">%1$s</a>', xml_escape $_), sort @{$_[0]} } ],
- [ l_itch => 'Itch.io', htmlize => sub { $_[0] ? sprintf '<a href="https://%s">%1$s</a>', xml_escape $_[0] : '[empty]' } ],
- [ l_jastusa => 'JAST USA', htmlize => sub { $_[0] ? sprintf '<a href="https://jastusa.com/%s">%1$s</a>', xml_escape $_[0] : '[empty]' } ],
- [ released => 'Release date', htmlize => \&fmtdatestr ],
- [ minage => 'Age rating', serialize => \&minage ],
- [ notes => 'Notes', diff => qr/[ ,\n\.]/ ],
- [ platforms => 'Platforms', join => ', ', split => sub { map $PLATFORM{$_}, @{$_[0]} } ],
- [ media => 'Media', join => ', ', split => sub { map fmtmedia($_->{medium}, $_->{qty}), @{$_[0]} } ],
- [ resolution => 'Resolution', serialize => sub { $RESOLUTION{$_[0]}{txt}; } ],
- [ voiced => 'Voiced', serialize => sub { $VOICED{$_[0]}{txt} } ],
- [ ani_story => 'Story animation', serialize => sub { $ANIMATED{$_[0]}{txt} } ],
- [ ani_ero => 'Ero animation', serialize => sub { $ANIMATED{$_[0]}{txt} } ],
- [ engine => 'Engine' ],
- [ producers => 'Producers', join => '<br />', split => sub {
- map sprintf('<a href="/p%d" title="%s">%s</a> (%s)', $_->{id}, xml_escape($_->{original}||$_->{name}), xml_escape(shorten($_->{name}, 50)),
- join(', ', $_->{developer} ? 'developer' :(), $_->{publisher} ? 'publisher' :())
- ), @{$_[0]};
- } ],
- );
- }
-
- div class => 'mainbox release';
- $self->htmlItemMessage('r', $r);
- h1 $r->{title};
- h2 class => 'alttitle', lang_attr($r->{languages}), $r->{original} if $r->{original};
-
- _infotable($self, $r);
-
- if($r->{notes}) {
- p class => 'description';
- lit bb2html $r->{notes};
- end;
- }
-
- end;
- $self->htmlFooter;
-}
-
-
-sub _infotable {
- my($self, $r) = @_;
- table class => 'stripe';
-
- Tr;
- td class => 'key', 'Relation';
- td;
- for (@{$r->{vn}}) {
- a href => "/v$_->{vid}", title => $_->{original}||$_->{title}, shorten $_->{title}, 60;
- br if $_ != $r->{vn}[$#{$r->{vn}}];
- }
- end;
- end;
-
- Tr;
- td 'Title';
- td $r->{title};
- end;
-
- if($r->{original}) {
- Tr;
- td 'Original title';
- td lang_attr($r->{languages}), $r->{original};
- end;
- }
-
- Tr;
- td 'Type';
- td;
- cssicon "rt$r->{type}", $r->{type};
- txt sprintf ' %s%s', $RELEASE_TYPE{$r->{type}}, $r->{patch} ? ', patch' : '';
- end;
- end;
-
- Tr;
- td 'Language';
- td;
- for (@{$r->{languages}}) {
- cssicon "lang $_", $LANGUAGE{$_};
- txt ' '.$LANGUAGE{$_};
- br if $_ ne $r->{languages}[$#{$r->{languages}}];
- }
- end;
- end;
-
- Tr;
- td 'Publication';
- td join ', ',
- $r->{freeware} ? 'Freeware' : 'Non-free',
- $r->{patch} ? () : ($r->{doujin} ? 'doujin' : 'commercial');
- end;
-
- if(@{$r->{platforms}}) {
- Tr;
- td 'Platform'.(@{$r->{platforms}} == 1 ? '' : 's');
- td;
- for(@{$r->{platforms}}) {
- cssicon $_, $PLATFORM{$_};
- txt ' '.$PLATFORM{$_};
- br if $_ ne $r->{platforms}[$#{$r->{platforms}}];
- }
- end;
- end;
- }
-
- if(@{$r->{media}}) {
- Tr;
- td @{$r->{media}} == 1 ? 'Medium' : 'Media';
- td join ', ', map fmtmedia($_->{medium}, $_->{qty}), @{$r->{media}};
- end;
- }
-
- if($r->{resolution} ne 'unknown') {
- Tr;
- td 'Resolution';
- td $RESOLUTION{$r->{resolution}}{txt};
- end;
- }
-
- if($r->{voiced}) {
- Tr;
- td 'Voiced';
- td $VOICED{$r->{voiced}}{txt};
- end;
- }
-
- if($r->{ani_story} || $r->{ani_ero}) {
- Tr;
- td 'Animation';
- td join ', ',
- $r->{ani_story} ? "Story: $ANIMATED{$r->{ani_story}}{txt}" : (),
- $r->{ani_ero} ? "Ero scenes: $ANIMATED{$r->{ani_ero}}{txt}" : ();
- end;
- }
-
- if(length $r->{engine}) {
- Tr;
- td 'Engine';
- td; a href => '/r?fil='.fil_serialize({engine => $r->{engine}}), $r->{engine}; end;
- end;
- }
-
- Tr;
- td 'Released';
- td;
- lit fmtdatestr $r->{released};
- end;
- end;
-
- if($r->{minage} >= 0) {
- Tr;
- td 'Age rating';
- td minage $r->{minage};
- end;
- }
-
- if($r->{minage} == 18) {
- Tr;
- td 'Censoring';
- td $r->{uncensored} ? 'No optical censoring (e.g. mosaics)' : 'May include optical censoring (e.g. mosaics)';
- end;
- }
-
- for my $t (qw|developer publisher|) {
- my @prod = grep $_->{$t}, @{$r->{producers}};
- if(@prod) {
- Tr;
- td ucfirst($t).(@prod == 1 ? '' : 's');
- td;
- for (@prod) {
- a href => "/p$_->{id}", title => $_->{original}||$_->{name}, shorten $_->{name}, 60;
- br if $_ != $prod[$#prod];
- }
- end;
- end;
- }
- }
-
- if($r->{gtin}) {
- Tr;
- td gtintype($r->{gtin}) || 'GTIN';
- td $r->{gtin};
- end;
- }
-
- if($r->{catalog}) {
- Tr;
- td 'Catalog no.';
- td $r->{catalog};
- end;
- }
-
- if($r->{extlinks}->@*) {
- Tr;
- td 'Links';
- td;
- for($r->{extlinks}->@*) {
- a href => $_->[1], $_->[0];
- txt ', ' if $_ ne $r->{extlinks}[$#{$r->{extlinks}}];
- }
- end;
- end;
- }
-
- if($self->authInfo->{id}) {
- my $rl = $self->dbRListGet(uid => $self->authInfo->{id}, rid => $r->{id})->[0];
- Tr;
- td 'User options';
- td;
- Select id => 'listsel', name => $self->authGetCode("/r$r->{id}/list");
- option value => -2, !$rl ? 'not on your list' : "Status: $RLIST_STATUS{$rl->{status}}";
- optgroup label => 'Set status';
- option value => $_, $RLIST_STATUS{$_}
- for (keys %RLIST_STATUS);
- end;
- option value => -1, 'remove from list' if $rl;
- end;
- end;
- end 'tr';
- }
-
- end 'table';
-}
-
-
# rid = \d -> edit/copy release
# rid = 'v' -> add release to VN with id $rev
sub edit {
diff --git a/lib/VNWeb/DB.pm b/lib/VNWeb/DB.pm
index e4905bf0..2e7cf7f6 100644
--- a/lib/VNWeb/DB.pm
+++ b/lib/VNWeb/DB.pm
@@ -224,11 +224,10 @@ my $entry_types = do {
my %types = map +($_->{dbentry_type}, { prefix => $_->{name} }), grep $_->{dbentry_type}, values %$schema;
for my $t (values %$schema) {
my $n = $t->{name};
- my($type) = grep $n =~ s/^$_->{prefix}_//, values %types;
- next if !$type;
- $type->{base} = $t if $n eq 'hist';
- next if $n !~ s/_hist$//;
- $type->{tables}{$n} = $t;
+ my($type) = grep $n =~ /^$_->{prefix}_/, values %types;
+ next if !$type || $n !~ s/^$type->{prefix}_?(.*)_hist$/$1/;
+ if($n eq '') { $type->{base} = $t }
+ else { $type->{tables}{$n} = $t }
}
\%types;
};
diff --git a/lib/VNWeb/HTML.pm b/lib/VNWeb/HTML.pm
index 3231ee7e..17856664 100644
--- a/lib/VNWeb/HTML.pm
+++ b/lib/VNWeb/HTML.pm
@@ -526,7 +526,7 @@ sub _revision_fmtcol_ {
b_ class => 'diff_add', sub { _revision_fmtval_ $opt, $val }
} elsif(@$l > 1 && $i == 1 && ($ch eq '-' || $ch eq 'c')) {
b_ class => 'diff_del', sub { _revision_fmtval_ $opt, $val }
- } elsif($ch eq 'c' || $ch eq 'u') {
+ } elsif($ch eq 'c' || $ch eq 'u' || @$l == 1) {
_revision_fmtval_ $opt, $val;
}
}, @$l;
diff --git a/lib/VNWeb/Prelude.pm b/lib/VNWeb/Prelude.pm
index 3f5d5f67..587e385d 100644
--- a/lib/VNWeb/Prelude.pm
+++ b/lib/VNWeb/Prelude.pm
@@ -14,7 +14,7 @@
# use VNDB::BBCode;
# use VNDB::Types;
# use VNDB::Config;
-# use VNDB::Func 'fmtdate', 'fmtage', 'fmtvote', 'fmtspoil', 'query_encode';
+# use VNDB::Func qw/fmtdate fmtage fmtvote fmtspoil fmtmedia minage query_encode lang_attr/;
# use VNDB::ExtLinks;
# use VNWeb::Auth;
# use VNWeb::HTML;
@@ -58,7 +58,7 @@ sub import {
use VNDB::BBCode;
use VNDB::Types;
use VNDB::Config;
- use VNDB::Func 'fmtdate', 'fmtage', 'fmtvote', 'fmtspoil', 'query_encode';
+ use VNDB::Func qw/fmtdate fmtage fmtvote fmtspoil fmtmedia minage query_encode lang_attr/;
use VNDB::ExtLinks;
use VNWeb::Auth;
use VNWeb::HTML;
diff --git a/lib/VNWeb/Releases/Page.pm b/lib/VNWeb/Releases/Page.pm
new file mode 100644
index 00000000..c6718232
--- /dev/null
+++ b/lib/VNWeb/Releases/Page.pm
@@ -0,0 +1,217 @@
+package VNWeb::Releases::Page;
+
+use VNWeb::Prelude;
+
+
+sub enrich_item {
+ my($r) = @_;
+
+ enrich_merge pid => 'SELECT id AS pid, name, original FROM producers WHERE id IN', $r->{producers};
+ enrich_merge vid => 'SELECT id AS vid, title, original FROM vn WHERE id IN', $r->{vn};
+
+ $r->{lang} = [ sort map $_->{lang}, $r->{lang}->@* ];
+ $r->{platforms} = [ sort map $_->{platform}, $r->{platforms}->@* ];
+ $r->{vn} = [ sort { $a->{title} cmp $b->{title} || $a->{vid} <=> $b->{vid} } $r->{vn}->@* ];
+ $r->{producers} = [ sort { $a->{name} cmp $b->{name} || $a->{pid} <=> $b->{pid} } $r->{producers}->@* ];
+ $r->{media} = [ sort { $a->{medium} cmp $b->{medium} || $a->{qty} <=> $b->{qty} } $r->{media}->@* ];
+}
+
+
+sub _rev_ {
+ my($r) = @_;
+ revision_ r => $r, \&enrich_item,
+ [ vn => 'Relations', fmt => sub { a_ href => "/v$_->{vid}", title => $_->{original}||$_->{title}, $_->{title} } ],
+ [ type => 'Type' ],
+ [ patch => 'Patch', fmt => 'bool' ],
+ [ freeware => 'Freeware', fmt => 'bool' ],
+ [ doujin => 'Doujin', fmt => 'bool' ],
+ [ uncensored => 'Uncensored', fmt => 'bool' ],
+ [ title => 'Title (Romaji)' ],
+ [ original => 'Original title' ],
+ [ gtin => 'JAN/EAN/UPC', empty => 0 ],
+ [ catalog => 'Catalog number' ],
+ [ lang => 'Languages', fmt => \%LANGUAGE ],
+ [ released => 'Release date', fmt => sub { rdate_ $_ } ],
+ [ minage => 'Age rating', fmt => sub { txt_ minage $_ } ],
+ [ notes => 'Notes' ],
+ [ platforms => 'Platforms', fmt => \%PLATFORM ],
+ [ media => 'Media', fmt => sub { txt_ fmtmedia $_->{medium}, $_->{qty}; } ],
+ [ resolution => 'Resolution', fmt => \%RESOLUTION ],
+ [ voiced => 'Voiced', fmt => \%VOICED ],
+ [ ani_story => 'Story animation', fmt => \%ANIMATED ],
+ [ ani_ero => 'Ero animation', fmt => \%ANIMATED ],
+ [ engine => 'Engine' ],
+ [ producers => 'Producers', fmt => sub {
+ a_ href => "/p$_->{pid}", title => $_->{original}||$_->{name}, $_->{name};
+ txt_ ' (';
+ txt_ join ', ', $_->{developer} ? 'developer' : (), $_->{publisher} ? 'publisher' : ();
+ txt_ ')';
+ } ],
+ revision_extlinks 'r'
+}
+
+
+sub _infotable_ {
+ my($r) = @_;
+
+ table_ class => 'stripe', sub {
+ tr_ sub {
+ td_ class => 'key', 'Relation';
+ td_ sub {
+ join_ \&br_, sub {
+ a_ href => "/v$_->{vid}", title => $_->{original}||$_->{title}, $_->{title};
+ }, $r->{vn}->@*
+ }
+ };
+
+ tr_ sub {
+ td_ 'Title';
+ td_ $r->{title};
+ };
+
+ tr_ sub {
+ td_ 'Original title';
+ td_ lang_attr($r->{lang}), $r->{original};
+ } if $r->{original};
+
+ tr_ sub {
+ td_ 'Type';
+ td_ sub {
+ abbr_ class => "icons rt$r->{type}", title => $r->{type}, ' ';
+ txt_ ' '.$RELEASE_TYPE{$r->{type}};
+ txt_ ', patch' if $r->{patch};
+ }
+ };
+
+ tr_ sub {
+ td_ 'Language';
+ td_ sub {
+ join_ \&br_, sub {
+ abbr_ class => "icons lang $_", title => $LANGUAGE{$_}, ' ';
+ txt_ ' '.$LANGUAGE{$_};
+ }, $r->{lang}->@*;
+ }
+ };
+
+ tr_ sub {
+ td_ 'Publication';
+ td_ join ', ',
+ $r->{freeware} ? 'Freeware' : 'Non-free',
+ $r->{patch} ? () : ($r->{doujin} ? 'doujin' : 'commercial');
+ };
+
+ tr_ sub {
+ td_ 'Platform'.($r->{platforms}->@* == 1 ? '' : 's');
+ td_ sub {
+ join_ \&br_, sub {
+ abbr_ class => "icons $_", title => $PLATFORM{$_}, ' ';
+ txt_ ' '.$PLATFORM{$_};
+ }, $r->{platforms}->@*;
+ }
+ } if $r->{platforms}->@*;
+
+ tr_ sub {
+ td_ $r->{media}->@* == 1 ? 'Medium' : 'Media';
+ td_ sub {
+ join_ \&br_, sub { txt_ fmtmedia $_->{medium}, $_->{qty} }, $r->{media}->@*;
+ }
+ } if $r->{media}->@*;
+
+ tr_ sub {
+ td_ 'Resolution';
+ td_ $RESOLUTION{$r->{resolution}}{txt};
+ } if $r->{resolution} ne 'unknown';
+
+ tr_ sub {
+ td_ 'Voiced';
+ td_ $VOICED{$r->{voiced}}{txt};
+ } if $r->{voiced};
+
+ tr_ sub {
+ td_ 'Animation';
+ td_ sub {
+ join_ \&br_, sub { txt_ $_ },
+ $r->{ani_story} ? "Story: $ANIMATED{$r->{ani_story}}{txt}" : (),
+ $r->{ani_ero} ? "Ero scenes: $ANIMATED{$r->{ani_ero}}{txt}" : ();
+ }
+ } if $r->{ani_story} || $r->{ani_ero};
+
+ tr_ sub {
+ td_ 'Engine';
+ td_ sub {
+ # TODO: Should not rely on legacy VNDB::* functions!
+ a_ href => '/r?fil='.VNDB::Util::Misc::fil_serialize({engine => $r->{engine}}), $r->{engine};
+ }
+ } if length $r->{engine};
+
+ tr_ sub {
+ td_ 'Released';
+ td_ sub { rdate_ $r->{released} };
+ };
+
+ tr_ sub {
+ td_ 'Age rating';
+ td_ minage $r->{minage};
+ } if $r->{minage} >= 0;
+
+ tr_ sub {
+ td_ 'Censoring';
+ td_ $r->{uncensored} ? 'No optical censoring (e.g. mosaics)' : 'May include optical censoring (e.g. mosaics)';
+ } if $r->{minage} == 18;
+
+ for my $t (qw|developer publisher|) {
+ my @prod = grep $_->{$t}, @{$r->{producers}};
+ tr_ sub {
+ td_ ucfirst($t).(@prod == 1 ? '' : 's');
+ td_ sub {
+ join_ \&br_, sub {
+ a_ href => "/p$_->{pid}", title => $_->{original}||$_->{name}, $_->{name};
+ }, @prod
+ }
+ } if @prod;
+ }
+
+ tr_ sub {
+ td_ gtintype($r->{gtin}) || 'GTIN';
+ td_ $r->{gtin};
+ } if $r->{gtin};
+
+ tr_ sub {
+ td_ 'Catalog no.';
+ td_ $r->{catalog};
+ } if $r->{catalog};
+
+ tr_ sub {
+ td_ 'Links';
+ td_ sub {
+ join_ ', ', sub { a_ href => $_->[1], $_->[0] }, $r->{extlinks}->@*;
+ }
+ } if $r->{extlinks}->@*;
+ }
+}
+
+
+TUWF::get qr{/$RE{rrev}} => sub {
+ my $r = db_entry r => tuwf->capture('id'), tuwf->capture('rev');
+ return tuwf->resNotFound if !$r;
+
+ enrich_item $r;
+ enrich_extlinks r => $r;
+
+ framework_ title => $r->{title}, index => !tuwf->capture('rev'), type => 'r', dbobj => $r, hiddenmsg => 1,
+ og => {
+ description => bb2text $r->{notes}
+ },
+ sub {
+ _rev_ $r if tuwf->capture('rev');
+ div_ class => 'mainbox release', sub {
+ itemmsg_ r => $r;
+ h1_ sub { txt_ $r->{title}; debug_ $r };
+ h2_ class => 'alttitle', lang_attr($r->{lang}), $r->{original} if length $r->{original};
+ _infotable_ $r;
+ p_ class => 'description', sub { lit_ bb2html $r->{notes} } if $r->{notes};
+ };
+ };
+};
+
+1;
diff --git a/lib/VNWeb/Staff/Page.pm b/lib/VNWeb/Staff/Page.pm
index fe5a5696..12383ba7 100644
--- a/lib/VNWeb/Staff/Page.pm
+++ b/lib/VNWeb/Staff/Page.pm
@@ -1,7 +1,6 @@
package VNWeb::Staff::Page;
use VNWeb::Prelude;
-use VNWeb::Docs::Lib;
sub enrich_item {
@@ -169,7 +168,7 @@ TUWF::get qr{/$RE{srev}} => sub {
enrich_extlinks s => $s;
my($main) = grep $_->{aid} == $s->{aid}, $s->{alias}->@*;
- framework_ title => $main->{name}, index => 1, type => 's', dbobj => $s, hiddenmsg => 1,
+ framework_ title => $main->{name}, index => !tuwf->capture('rev'), type => 's', dbobj => $s, hiddenmsg => 1,
og => {
description => bb2text $s->{desc}
},