summaryrefslogtreecommitdiff
path: root/lib/VNDB/Handler/Misc.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VNDB/Handler/Misc.pm')
-rw-r--r--lib/VNDB/Handler/Misc.pm382
1 files changed, 382 insertions, 0 deletions
diff --git a/lib/VNDB/Handler/Misc.pm b/lib/VNDB/Handler/Misc.pm
new file mode 100644
index 00000000..5a9b9a2a
--- /dev/null
+++ b/lib/VNDB/Handler/Misc.pm
@@ -0,0 +1,382 @@
+
+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.<br />
+ 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.<br />
+ 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.<br />
+ <br />
+ Feel free to <a href="/v/all">browse around</a>, <a href="/u/register">register an account</a>
+ or to participate in the discussions about visual novels or VNDB on our <a href="/t">discussion board</a>.
+ |;
+ 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|<h3><a href="#$sec" name="$sec">$sec. $1</a></h3>\n|
+ }eg;
+ s{^:INC:(.+)\r?\n$}{
+ open $F, '<', sprintf('%s/data/docs/%s', $VNDB::ROOT, $1) or die $!;
+ my $ii = join('', <$F>);
+ close $F;
+ $ii;
+ }eg;
+ }
+
+ $self->htmlHeader(title => $title);
+ div class => 'mainbox';
+ h1 $title;
+ div class => 'docs';
+ lit join '', @c;
+ end;
+ end;
+ $self->htmlFooter;
+}
+
+
+sub nospam {
+ my $self = shift;
+ $self->htmlHeader(title => 'Could not send form', noindex => 1);
+
+ div class => 'mainbox';
+ h1 'Could not send form';
+ div class => 'warning';
+ h2 'Error';
+ p 'The form could not be sent, please make sure you have Javascript enabled in your browser.';
+ end;
+ end;
+
+ $self->htmlFooter;
+}
+
+
+# /hide and /lock for v/r/p+ pages
+sub itemmod {
+ my($self, $type, $iid, $act) = @_;
+ return $self->htmlDenied if !$self->authCan($act eq 'hide' ? 'del' : 'lock');
+
+ my $obj = $type eq 'v' ? $self->dbVNGet(id => $iid)->[0] :
+ $type eq 'r' ? $self->dbReleaseGet(id => $iid)->[0] :
+ $self->dbProducerGet(id => $iid)->[0];
+ return 404 if !$obj->{id};
+
+ $self->dbItemMod($type, $iid, $act eq 'hide' ? (hidden => !$obj->{hidden}) : (locked => !$obj->{locked}));
+
+ $self->resRedirect("/$type$iid", 'temp');
+}
+
+
+sub ie6message {
+ my $self = shift;
+
+ if($self->reqParam('i-still-want-access')) {
+ (my $ref = $self->reqHeader('Referer') || '/') =~ s/^\Q$self->{url}//;
+ $ref = '/' if $ref eq '/we-dont-like-ie6';
+ $self->resRedirect($ref, 'temp');
+ $self->resHeader('Set-Cookie', "ie-sucks=1; path=/; domain=$self->{cookie_domain}");
+ return;
+ }
+
+ html;
+ head;
+ title 'Your browser sucks';
+ style type => 'text/css',
+ q|body { background: black }|
+ .q|div { position: absolute; left: 50%; top: 50%; width: 500px; margin-left: -250px; height: 180px; margin-top: -90px; background-color: #012; border: 1px solid #258; text-align: center; }|
+ .q|p { color: #ddd; margin: 10px; font: 9pt "Tahoma"; }|
+ .q|h1 { color: #258; font-size: 14pt; font-family: "Futura", "Century New Gothic", "Arial", Serif; font-weight: normal; margin: 10px 0 0 0; } |
+ .q|a { color: #fff }|;
+ end;
+ body;
+ div;
+ h1 'Oops, we were too lazy support your browser!';
+ p;
+ lit qq|We decided to stop supporting Internet Explorer 6, as it's a royal pain in |
+ .qq|the ass to make our site look good in a browser that doesn't want to cooperate with us.<br />|
+ .qq|You can try one of the following free alternatives: |
+ .qq|<a href="http://www.mozilla.com/firefox/">Firefox</a>, |
+ .qq|<a href="http://www.opera.com/">Opera</a>, |
+ .qq|<a href="http://www.apple.com/safari/">Safari</a>, or |
+ .qq|<a href="http://www.google.com/chrome">Chrome</a>.<br /><br />|
+ .qq|If you're really stubborn about using Internet Explorer, upgrading to version 7 will also work.<br /><br />|
+ .qq|...and if you're mad, you can also choose to ignore this warning and |
+ .qq|<a href="/we-dont-like-ie6?i-still-want-access=1">open the site anyway</a>.|;
+ end;
+ end;
+ end;
+ end;
+}
+
+
+1;
+