package VNDB::Handler::Misc;
use strict;
use warnings;
use YAWF ':html';
use VNDB::Func;
YAWF::register(
qr{}, \&homepage,
qr{(?:([upvr])([1-9]\d*)/)?hist}, \&history,
qr{d([1-9]\d*)}, \&docpage,
qr{nospam}, \&nospam,
qr{([vrp])([1-9]\d*)/(lock|hide)}, \&itemmod,
qr{we-dont-like-ie6}, \&ie6message,
# redirects for old URLs
qr{(.*[^/]+)/+}, sub { $_[0]->resRedirect("/$_[1]", 'perm') },
qr{([pv])}, sub { $_[0]->resRedirect("/$_[1]/all", 'perm') },
qr{v/search}, sub { $_[0]->resRedirect("/v/all?q=".$_[0]->reqParam('q'), 'perm') },
qr{notes}, sub { $_[0]->resRedirect('/d8', 'perm') },
qr{faq}, sub { $_[0]->resRedirect('/d6', 'perm') },
qr{v([1-9]\d*)/(?:stats|scr|votes)},
sub { $_[0]->resRedirect("/v$_[1]", 'perm') },
qr{u/list(/[a-z0]|/all)?},
sub { my $l = defined $_[1] ? $_[1] : '/all'; $_[0]->resRedirect("/u$l", 'perm') },
qr{d([1-9]\d*)\.([1-9]\d*)},
sub { $_[0]->resRedirect("/d$_[1]#$_[2]", 'perm') },
qr{u([1-9]\d*)/votes},
sub { $_[0]->resRedirect("/u$_[1]/list?v=1", 'perm') },
# rewrite the old category browser to the new-ish search function
qr{v/cat}, sub {
my $f = $_[0]->formValidate(
{name=>'i',required=>0,default=>''},{name=>'e',required=>0,default=>''},{name=>'l',required=>0,default=>''},
{name=>'p',required=>0},{name=>'o',required=>0},{name=>'s',required=>0});
my %f;
$f{$_} = $f->{$_} for (qw|p o s|);
$f{q} = join ' ', (map $_[0]{categories}{substr($_,0,1)}[1]{substr($_,1,2)}, split /,/, $f->{i}),
(map '-'.$_[0]{categories}{substr($_,0,1)}[1]{substr($_,1,2)}, split /,/, $f->{e}),
(map $_[0]{languages}{$_}, split /,/, $f->{l});
!$f{$_} && delete $f{$_} for keys %f;
$_[0]->resRedirect('/v/all'.(!(keys %f)?'':'?'.join(';', map $_.'='.$f{$_}, keys %f) ), 'perm');
},
);
sub homepage {
my $self = shift;
$self->htmlHeader(title => $self->{site_title});
div class => 'mainbox';
h1 $self->{site_title};
p class => 'description';
lit qq|
VNDB.org strives to be a comprehensive database for information about visual novels and
eroge.
This website is built as a wiki, meaning that anyone can freely add and contribute information
to the database, allowing us to create the largest, most accurate and most up-to-date visual novel
database on the web.
Registered users are also able to keep track of a personal list of games they want to play or have finished
and they can vote on all visual novels.
Feel free to browse around, register an account
or to participate in the discussions about visual novels or VNDB on our discussion board.
|;
end;
my $scr = $self->dbScreenshotRandom;
p class => 'screenshots';
for (@$scr) {
a href => "/v$_->{vid}", title => $_->{title};
img src => sprintf("%s/st/%02d/%d.jpg", $self->{url_static}, $_->{scr}%100, $_->{scr}), alt => $_->{title};
end;
}
end;
end;
# Recent changes
div class => 'mainbox threelayout';
h1 'Recent changes';
my $changes = $self->dbRevisionGet(what => 'item user', results => 10, auto => 1, hidden => 1);
ul;
for (@$changes) {
my $t = (qw|v r p|)[$_->{type}];
li;
b "$t:";
a href => "/$t$_->{iid}.$_->{rev}", title => $_->{ioriginal}||$_->{ititle}, shorten $_->{ititle}, 30;
txt ' by ';
a href => "/u$_->{requester}", $_->{username};
end;
}
end;
end;
# Announcements
div class => 'mainbox threelayout';
my $an = $self->dbThreadGet(type => 'an', order => 't.id DESC', results => 2);
a class => 'right', href => '/t/an', 'News archive';
h1 'Announcements';
for (@$an) {
my $post = $self->dbPostGet(tid => $_->{id}, num => 1)->[0];
h2;
a href => "/t$_->{id}", $_->{title};
end;
p;
lit bb2html $post->{msg}, 150;
end;
}
end;
# Recent posts
div class => 'mainbox threelayout last';
h1 'Recent posts';
my $posts = $self->dbThreadGet(what => 'lastpost', results => 10, order => 'tpl.date DESC');
ul;
for (@$posts) {
li;
txt age($_->{ldate}).' ';
a href => "/t$_->{id}.$_->{count}", title => $_->{title}, shorten $_->{title}, 20;
txt ' by ';
a href => "/u$_->{luid}", $_->{lusername};
end;
}
end;
end;
# Random visual novels
div class => 'mainbox threelayout';
h1 'Random visual novels';
my $random = $self->dbVNGet(results => 10, order => 'RANDOM()');
ul;
for (@$random) {
li;
a href => "/v$_->{id}", title => $_->{original}||$_->{title}, shorten $_->{title}, 40;
end;
}
end;
end;
# Upcoming releases
div class => 'mainbox threelayout';
h1 'Upcoming releases';
my $upcoming = $self->dbReleaseGet(results => 10, unreleased => 1);
ul;
for (@$upcoming) {
li;
lit datestr $_->{released};
txt ' ';
a href => "/r$_->{id}", title => $_->{original}||$_->{title}, shorten $_->{title}, 30;
end;
}
end;
end;
# Just released
div class => 'mainbox threelayout last';
h1 'Just released';
my $justrel = $self->dbReleaseGet(results => 10, order => 'rr.released DESC', unreleased => 0);
ul;
for (@$justrel) {
li;
lit datestr $_->{released};
txt ' ';
a href => "/r$_->{id}", title => $_->{original}||$_->{title}, shorten $_->{title}, 30;
end;
}
end;
end;
clearfloat;
$self->htmlFooter;
}
sub history {
my($self, $type, $id) = @_;
$type ||= '';
$id ||= 0;
my $f = $self->formValidate(
{ name => 'p', required => 0, default => 1, template => 'int' },
{ name => 'm', required => 0, default => !$type, enum => [ 0, 1 ] },
{ name => 'h', required => 0, default => 1, enum => [ -1..1 ] },
{ name => 't', required => 0, default => '', enum => [ 'v', 'r', 'p' ] },
{ name => 'e', required => 0, default => 0, enum => [ -1..1 ] },
{ name => 'r', required => 0, default => 0, enum => [ 0, 1 ] },
);
return 404 if $f->{_err};
# get item object and title
my $obj = $type eq 'u' ? $self->dbUserGet(uid => $id)->[0] :
$type eq 'p' ? $self->dbProducerGet(id => $id)->[0] :
$type eq 'r' ? $self->dbReleaseGet(id => $id)->[0] :
$self->dbVNGet(id => $id)->[0];
my $title = $type ? 'Edit history of '.($obj->{title} || $obj->{name} || $obj->{username}) : 'Recent changes';
return 404 if $type && !$obj->{id};
# get the edit history
my($list, $np) = $self->dbRevisionGet(
what => 'item user',
$type && $type ne 'u' ? ( type => $type, iid => $id ) : (),
$type eq 'u' ? ( uid => $id ) : (),
$f->{t} ? ( type => $f->{t} ) : (),
page => $f->{p},
results => 50,
auto => $f->{m},
hidden => $f->{h},
edit => $f->{e},
releases => $f->{r},
);
$self->htmlHeader(title => $title, noindex => 1);
$self->htmlMainTabs($type, $obj, 'hist') if $type;
# url generator
my $u = sub {
my($n, $v) = @_;
$n ||= '';
local $_ = ($type ? "/$type$id" : '').'/hist';
$_ .= '?m='.($n eq 'm' ? $v : $f->{m});
$_ .= ';h='.($n eq 'h' ? $v : $f->{h});
$_ .= ';t='.($n eq 't' ? $v : $f->{t});
$_ .= ';e='.($n eq 'e' ? $v : $f->{e});
$_ .= ';r='.($n eq 'r' ? $v : $f->{r});
};
# filters
div class => 'mainbox';
h1 $title;
if($type ne 'u') {
p class => 'browseopts';
a !$f->{m} ? (class => 'optselected') : (), href => $u->(m => 0), 'Show automated edits';
a $f->{m} ? (class => 'optselected') : (), href => $u->(m => 1), 'Hide automated edits';
end;
}
if(!$type || $type eq 'u') {
if($self->authCan('del')) {
p class => 'browseopts';
a $f->{h} == 1 ? (class => 'optselected') : (), href => $u->(h => 1), 'Hide deleted items';
a $f->{h} == -1 ? (class => 'optselected') : (), href => $u->(h => -1), 'Show deleted items';
end;
}
p class => 'browseopts';
a !$f->{t} ? (class => 'optselected') : (), href => $u->(t => ''), 'Show all items';
a $f->{t} eq 'v' ? (class => 'optselected') : (), href => $u->(t => 'v'), 'Only visual novels';
a $f->{t} eq 'r' ? (class => 'optselected') : (), href => $u->(t => 'r'), 'Only releases';
a $f->{t} eq 'p' ? (class => 'optselected') : (), href => $u->(t => 'p'), 'Only producers';
end;
p class => 'browseopts';
a !$f->{e} ? (class => 'optselected') : (), href => $u->(e => 0), 'Show all changes';
a $f->{e} == 1 ? (class => 'optselected') : (), href => $u->(e => 1), 'Only edits';
a $f->{e} == -1 ? (class => 'optselected') : (), href => $u->(e => -1), 'Only newly created pages';
end;
}
if($type eq 'v') {
p class => 'browseopts';
a !$f->{r} ? (class => 'optselected') : (), href => $u->(r => 0), 'Exclude';
a $f->{r} ? (class => 'optselected') : (), href => $u->(r => 1), 'Include edits of releases';
end;
}
end;
$self->htmlHistory($list, $f, $np, $u->());
$self->htmlFooter;
}
sub docpage {
my($self, $did) = @_;
open my $F, '<', sprintf('%s/data/docs/%d', $VNDB::ROOT, $did) or return 404;
my @c = <$F>;
close $F;
(my $title = shift @c) =~ s/^:TITLE://;
chomp $title;
my $sec = 0;
for (@c) {
s{^:SUB:(.+)\r?\n$}{
$sec++;
qq|