summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Multi/Feed.pm5
-rw-r--r--lib/Multi/IRC.pm31
-rw-r--r--lib/VNDB/BBCode.pm8
-rw-r--r--lib/VNDB/DB/Docs.pm53
-rw-r--r--lib/VNDB/DB/Misc.pm4
-rw-r--r--lib/VNDB/Handler/Discussions.pm4
-rw-r--r--lib/VNDB/Handler/Docs.pm177
-rw-r--r--lib/VNDB/Handler/Misc.pm84
-rw-r--r--lib/VNDB/Handler/VNEdit.pm2
-rw-r--r--lib/VNDB/Util/CommonHTML.pm10
-rw-r--r--lib/VNDB/Util/FormHTML.pm4
11 files changed, 270 insertions, 112 deletions
diff --git a/lib/Multi/Feed.pm b/lib/Multi/Feed.pm
index 86f0ffa1..b4cddfac 100644
--- a/lib/Multi/Feed.pm
+++ b/lib/Multi/Feed.pm
@@ -44,14 +44,15 @@ sub generate {
# changes
pg_cmd q{
- SELECT '/'||c.type||COALESCE(v.id, r.id, p.id, c.id, s.id)||'.'||c.rev AS id,
- COALESCE(v.title, r.title, p.name, ca.name, sa.name) AS title, extract('epoch' from c.added) AS updated,
+ SELECT '/'||c.type||COALESCE(v.id, r.id, p.id, ca.id, s.id, d.id)||'.'||c.rev AS id,
+ COALESCE(v.title, r.title, p.name, ca.name, sa.name, d.title) AS title, extract('epoch' from c.added) AS updated,
u.username, u.id AS uid, c.comments AS summary
FROM changes c
LEFT JOIN vn v ON c.type = 'v' AND c.itemid = v.id
LEFT JOIN releases r ON c.type = 'r' AND c.itemid = r.id
LEFT JOIN producers p ON c.type = 'p' AND c.itemid = p.id
LEFT JOIN chars ca ON c.type = 'c' AND c.itemid = ca.id
+ LEFT JOIN docs d ON c.type = 'd' AND c.itemid = d.id
LEFT JOIN staff s ON c.type = 's' AND c.itemid = s.id
LEFT JOIN staff_alias sa ON sa.id = s.id AND sa.aid = s.aid
JOIN users u ON u.id = c.requester
diff --git a/lib/Multi/IRC.pm b/lib/Multi/IRC.pm
index ef36bace..b1be1a24 100644
--- a/lib/Multi/IRC.pm
+++ b/lib/Multi/IRC.pm
@@ -218,9 +218,8 @@ sub set_notify {
# type database item in [dvprtug]
# id database id
# title main name or title of the DB entry
-# rev (optional) revision, post number or section number
+# rev (optional) revision, post number
# username (optional) relevant username
-# section (optional, for d+.+) section title
# boards (optional) board titles the thread has been posted in
# comments (optional) edit summary
sub formatid {
@@ -238,6 +237,7 @@ sub formatid {
g => 'tag',
i => 'trait',
t => 'thread',
+ d => 'doc',
);
for (@$res) {
@@ -267,9 +267,6 @@ sub formatid {
length $_->{comments} > 40 ? substr($_->{comments}, 0, 37).'...' : $_->{comments}
) if defined $_->{comments};
- # (for d+.+) -> section title
- push @msg, $c."->$NORMAL $_->{section}" if $_->{section};
-
# (always) @ URL
push @msg, $c."@ $NORMAL$LIGHT_GREY$VNDB::S{url}/$id$NORMAL";
@@ -303,8 +300,9 @@ sub handleid {
$t eq 't' ? 'title, '.$GETBOARDS.' FROM threads t WHERE id = $2' :
$t eq 'g' ? 'name AS title FROM tags WHERE id = $2' :
$t eq 'i' ? 'name AS title FROM traits WHERE id = $2' :
+ $t eq 'd' ? 'title FROM docs WHERE id = $2' :
'r.title FROM releases r WHERE r.id = $2'),
- [ $t, $id ], $c if !$rev && $t =~ /[vprtugics]/;
+ [ $t, $id ], $c if !$rev && $t =~ /[dvprtugics]/;
# edit/insert of vn/release/producer or discussion board post
pg_cmd 'SELECT $1::text AS type, $2::integer AS id, $3::integer AS rev, '.(
@@ -313,23 +311,9 @@ sub handleid {
$t eq 'p' ? 'ph.name AS title, u.username, c.comments FROM changes c JOIN producers_hist ph ON c.id = ph.chid JOIN users u ON u.id = c.requester WHERE c.type = \'p\' AND c.itemid = $2 AND c.rev = $3' :
$t eq 'c' ? 'ch.name AS title, u.username, c.comments FROM changes c JOIN chars_hist ch ON c.id = ch.chid JOIN users u ON u.id = c.requester WHERE c.type = \'c\' AND c.itemid = $2 AND c.rev = $3' :
$t eq 's' ? 'sah.name AS title, u.username, c.comments FROM changes c JOIN staff_hist sh ON c.id = sh.chid JOIN users u ON u.id = c.requester JOIN staff_alias_hist sah ON sah.chid = c.id AND sah.aid = sh.aid WHERE c.type = \'s\' AND c.itemid = $2 AND c.rev = $3' :
+ $t eq 'd' ? 'dh.title, u.username, c.comments FROM changes c JOIN docs_hist dh ON c.id = dh.chid JOIN users u ON u.id = c.requester WHERE c.type = \'d\' AND c.itemid = $2 AND c.rev = $3' :
't.title, u.username, '.$GETBOARDS.' FROM threads t JOIN threads_posts tp ON tp.tid = t.id JOIN users u ON u.id = tp.uid WHERE t.id = $2 AND tp.num = $3'),
- [ $t, $id, $rev], $c if $rev && $t =~ /[vprtcs]/;
-
- # documentation page (need to parse the doc pages manually here)
- if($t eq 'd') {
- my $f = sprintf $VNDB::ROOT.'/data/docs/%d', $id;
- my($title, $sec, $sub) = (undef, 0);
- open my $F, '<', $f or next;
- while(<$F>) {
- chomp;
- $title = $1 if /^:TITLE:(.+)$/;
- $sub = $1 if $rev && /^:SUB:(.+)$/ && ++$sec == $rev;
- }
- close $F;
- next if $rev && !$sub;
- formatid([{type => 'd', id => $id, title => $title, rev => $rev, section => $sub}], $chan, 0);
- }
+ [ $t, $id, $rev], $c if $rev && $t =~ /[dvprtcs]/;
}
@@ -358,7 +342,7 @@ sub notify {
my $q = {
rev => q{
SELECT c.type, c.rev, c.comments, c.id AS lastid, c.itemid AS id,
- COALESCE(vh.title, rh.title, ph.name, ch.name, sah.name) AS title, u.username
+ COALESCE(vh.title, rh.title, ph.name, ch.name, sah.name, dh.title) AS title, u.username
FROM changes c
LEFT JOIN vn_hist vh ON c.type = 'v' AND c.id = vh.chid
LEFT JOIN releases_hist rh ON c.type = 'r' AND c.id = rh.chid
@@ -366,6 +350,7 @@ sub notify {
LEFT JOIN chars_hist ch ON c.type = 'c' AND c.id = ch.chid
LEFT JOIN staff_hist sh ON c.type = 's' AND c.id = sh.chid
LEFT JOIN staff_alias_hist sah ON c.type = 's' AND sah.aid = sh.aid AND sah.chid = c.id
+ LEFT JOIN docs_hist dh ON c.type = 'd' AND c.id = dh.chid
JOIN users u ON u.id = c.requester
WHERE c.id > $1 AND c.requester <> 1
ORDER BY c.id},
diff --git a/lib/VNDB/BBCode.pm b/lib/VNDB/BBCode.pm
index d2f3135d..7ddfcd1b 100644
--- a/lib/VNDB/BBCode.pm
+++ b/lib/VNDB/BBCode.pm
@@ -14,7 +14,7 @@ our @EXPORT = qw/bb2html bb2text/;
# [url=..] [/url]
# [raw] .. [/raw]
# link: http://../
-# dblink: v#, v#.#, d#.#.#
+# dblink: v+, v+.+, d+#+, d+#+.+
#
# Permitted nesting of formatting codes:
# spoiler -> url, raw, link, dblink
@@ -112,9 +112,9 @@ sub parse {
while($raw =~ m{(?:
\[ \/? (?i: spoiler|quote|code|url|raw ) [^\s\]]* \] | # tag
- d[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]* | # d#.#.#
- [tdvprcs][1-9][0-9]*\.[1-9][0-9]* | # v#.#
- [tdvprcsugi][1-9][0-9]* | # v#
+ d[1-9][0-9]* \# [1-9][0-9]* (?: \.[1-9][0-9]* )? | # d+#+[.+]
+ [tdvprcs][1-9][0-9]*\.[1-9][0-9]* | # v+.+
+ [tdvprcsugi][1-9][0-9]* | # v+
(?:https?|ftp)://[^><"\n\s\]\[]+[\d\w=/-] # link
)}xg) {
my $token = $&;
diff --git a/lib/VNDB/DB/Docs.pm b/lib/VNDB/DB/Docs.pm
new file mode 100644
index 00000000..27cabf6e
--- /dev/null
+++ b/lib/VNDB/DB/Docs.pm
@@ -0,0 +1,53 @@
+
+package VNDB::DB::Docs;
+
+use strict;
+use warnings;
+use Exporter 'import';
+
+our @EXPORT = qw|dbDocGet dbDocGetRev dbDocRevisionInsert|;
+
+
+# Can only fetch a single document.
+# $doc = $self->dbDocGet(id => $id);
+sub dbDocGet {
+ my $self = shift;
+ my %o = @_;
+
+ my $r = $self->dbAll('SELECT id, title, content FROM docs WHERE id = ?', $o{id});
+ return wantarray ? ($r, 0) : $r;
+}
+
+
+# options: id, rev
+sub dbDocGetRev {
+ my $self = shift;
+ my %o = @_;
+
+ $o{rev} ||= $self->dbRow('SELECT MAX(rev) AS rev FROM changes WHERE type = \'d\' AND itemid = ?', $o{id})->{rev};
+
+ my $r = $self->dbAll(q|
+ SELECT de.id, d.title, d.content, de.hidden, de.locked,
+ extract('epoch' from c.added) as added, c.requester, c.comments, u.username, c.rev, c.ihid, c.ilock, c.id AS cid,
+ NOT EXISTS(SELECT 1 FROM changes c2 WHERE c2.type = c.type AND c2.itemid = c.itemid AND c2.rev = c.rev+1) AS lastrev
+ FROM changes c
+ JOIN docs de ON de.id = c.itemid
+ JOIN docs_hist d ON d.chid = c.id
+ JOIN users u ON u.id = c.requester
+ WHERE c.type = 'd' AND c.itemid = ? AND c.rev = ?|,
+ $o{id}, $o{rev}
+ );
+ return wantarray ? ($r, 0) : $r;
+}
+
+
+# Updates the edit_* tables, used from dbItemEdit()
+# Arguments: { title content },
+sub dbDocRevisionInsert {
+ my($self, $o) = @_;
+ my %set = map exists($o->{$_}) ? (qq|"$_" = ?|, $o->{$_}) : (), qw|title content|;
+ $self->dbExec('UPDATE edit_docs !H', \%set) if keys %set;
+}
+
+
+1;
diff --git a/lib/VNDB/DB/Misc.pm b/lib/VNDB/DB/Misc.pm
index d6389376..61bb71a2 100644
--- a/lib/VNDB/DB/Misc.pm
+++ b/lib/VNDB/DB/Misc.pm
@@ -21,7 +21,7 @@ sub dbStats {
# Inserts a new revision into the database
-# Arguments: type [vrp], itemid, rev, %options->{ editsum uid ihid ilock + db[item]RevisionInsert }
+# Arguments: type [vrpcsd], itemid, rev, %options->{ editsum uid ihid ilock + db[item]RevisionInsert }
# rev = changes.rev of the revision this edit is based on, undef to create a new DB item
# Returns: { itemid, chid, rev }
sub dbItemEdit {
@@ -41,6 +41,7 @@ sub dbItemEdit {
$self->dbReleaseRevisionInsert( \%o) if $type eq 'r';
$self->dbCharRevisionInsert( \%o) if $type eq 'c';
$self->dbStaffRevisionInsert( \%o) if $type eq 's';
+ $self->dbDocRevisionInsert( \%o) if $type eq 'd';
return $self->dbRow('SELECT * FROM edit_!s_commit()', $type);
}
@@ -98,6 +99,7 @@ sub dbRevisionGet {
UNION ALL SELECT 'r'::dbentry_type, chid, title, original FROM releases_hist
UNION ALL SELECT 'p'::dbentry_type, chid, name, original FROM producers_hist
UNION ALL SELECT 'c'::dbentry_type, chid, name, original FROM chars_hist
+ UNION ALL SELECT 'd'::dbentry_type, chid, title, '' AS original FROM docs_hist
UNION ALL SELECT 's'::dbentry_type, sh.chid, name, original FROM staff_hist sh JOIN staff_alias_hist sah ON sah.chid = sh.chid AND sah.aid = sh.aid
) x(type, id, title, original)
WHERE $w
diff --git a/lib/VNDB/Handler/Discussions.pm b/lib/VNDB/Handler/Discussions.pm
index f7f26a5e..f6b68c36 100644
--- a/lib/VNDB/Handler/Discussions.pm
+++ b/lib/VNDB/Handler/Discussions.pm
@@ -304,7 +304,7 @@ sub edit {
!$tid || $num == 1 ? (
[ input => short => 'title', name => 'Thread title' ],
[ input => short => 'boards', name => 'Board(s)' ],
- [ static => content => 'Read <a href="/d9.2">d9.2</a> for information about how to specify boards.' ],
+ [ static => content => 'Read <a href="/d9#2">d9#2</a> for information about how to specify boards.' ],
$self->authCan('boardmod') ? (
[ check => name => 'Locked', short => 'locked' ],
) : (),
@@ -318,7 +318,7 @@ sub edit {
) : (),
) : (),
[ text => name => 'Message<br /><b class="standout">English please!</b>', short => 'msg', rows => 25, cols => 75 ],
- [ static => content => 'See <a href="/d9.3">d9.3</a> for the allowed formatting codes' ],
+ [ static => content => 'See <a href="/d9#3">d9#3</a> for the allowed formatting codes' ],
(!$tid || $num == 1) ? (
[ static => content => '<br />' ],
[ check => short => 'poll', name => 'Add poll' ],
diff --git a/lib/VNDB/Handler/Docs.pm b/lib/VNDB/Handler/Docs.pm
new file mode 100644
index 00000000..bc1166d5
--- /dev/null
+++ b/lib/VNDB/Handler/Docs.pm
@@ -0,0 +1,177 @@
+
+package VNDB::Handler::Docs;
+
+
+use strict;
+use warnings;
+use TUWF ':html';
+use VNDB::Func;
+use Text::MultiMarkdown 'markdown';
+
+
+TUWF::register(
+ qr{d([1-9]\d*)(?:\.([1-9]\d*))?} => \&page,
+ qr{d([1-9]\d*)(?:\.([1-9]\d*))?/edit} => \&edit,
+);
+
+
+sub _html {
+ my $content = shift;
+
+ $content =~ s{^:MODERATORS:$}{
+ my $l = tuwf->dbUserGet(results => 100, sort => 'id', notperm => tuwf->{default_perm}, what => 'extended');
+ my $admin = 0;
+ $admin |= $_ for values %{ tuwf->{permissions} };
+ '<dl>'.join('', map {
+ my $u = $_;
+ my $p = $u->{perm} >= $admin ? 'admin' : join ', ', sort map +($u->{perm} &~ tuwf->{default_perm}) & tuwf->{permissions}{$_} ? $_ : (), keys %{ tuwf->{permissions} };
+ $p ? sprintf('<dt><a href="/u%d">%s</a></dt><dd>%s</dd>', $_->{id}, $_->{username}, $p) : ()
+ } @$l).'</dl>';
+ }me;
+ $content =~ s{^:SKINCONTRIB:$}{
+ my %users;
+ push @{$users{ tuwf->{skins}{$_}[1] }}, [ $_, tuwf->{skins}{$_}[0] ]
+ for sort { tuwf->{skins}{$a}[0] cmp tuwf->{skins}{$b}[0] } keys %{ tuwf->{skins} };
+ my $u = tuwf->dbUserGet(uid => [ keys %users ]);
+ '<dl>'.join('', map sprintf('<dt><a href="/u%d">%s</a></dt><dd>%s</dd>',
+ $_->{id}, $_->{username}, join(', ', map sprintf('<a href="?skin=%s">%s</a>', $_->[0], $_->[1]), @{$users{$_->{id}}})
+ ), @$u).'</dl>';
+ }me;
+
+ my $html = markdown $content, {
+ strip_metadata => 1,
+ img_ids => 0,
+ disable_footnotes => 1,
+ disable_bibliography => 1,
+ };
+
+ # Number sections and turn them into links
+ my($sec, $subsec) = (0,0);
+ $html =~ s{<h([1-2])[^>]+>(.*?)</h\1>}{
+ if($1 == 1) {
+ $sec++;
+ $subsec = 0;
+ qq{<h3><a href="#$sec" name="$sec">$sec. $2</a></h3>}
+ } elsif($1 == 2) {
+ $subsec++;
+ qq|<h4><a href="#$sec.$subsec" name="$sec.$subsec">$sec.$subsec. $2</a></h4>\n|
+ }
+ }ge;
+
+ # Text::MultiMarkdown doesn't handle fenced code blocks properly. The
+ # following solution breaks inline code blocks, but I don't use those anyway.
+ $html =~ s/<code>/<pre>/g;
+ $html =~ s#</code>#</pre>#g;
+
+ $html
+}
+
+
+sub page {
+ my($self, $id, $rev) = @_;
+
+ my $method = $rev ? 'dbDocGetRev' : 'dbDocGet';
+ my $d = $self->$method(id => $id, $rev ? ( rev => $rev ) : ())->[0];
+ return $self->resNotFound if !$d->{id};
+
+ $self->htmlHeader(title => $d->{title}, noindex => $rev);
+ $self->htmlMainTabs(d => $d);
+ return if $self->htmlHiddenMessage('d', $d);
+
+ if($rev) {
+ my $prev = $rev && $rev > 1 && $self->dbDocGetRev(id => $id, rev => $rev-1)->[0];
+ $self->htmlRevision('d', $prev, $d,
+ [ title => 'Title', diff => 1 ],
+ [ content => 'Content', diff => qr/\s+/ ],
+ );
+ }
+
+ div class => 'mainbox';
+ h1 $d->{title};
+ div class => 'docs';
+ ul class => 'index';
+ li; b 'Guidelines'; end;
+ li; a href => '/d5', 'Editing Guidelines'; end;
+ li; a href => '/d2', 'Visual Novels'; end;
+ li; a href => '/d15', 'Special Games'; end;
+ li; a href => '/d3', 'Releases'; end;
+ li; a href => '/d4', 'Producers'; end;
+ li; a href => '/d16', 'Staff'; end;
+ li; a href => '/d12', 'Characters'; end;
+ li; a href => '/d10', 'Tags & Traits'; end;
+ li; a href => '/d13', 'Capturing Screenshots'; end;
+ li; b 'About VNDB'; end;
+ li; a href => '/d9', 'Discussion Board'; end;
+ li; a href => '/d6', 'FAQ'; end;
+ li; a href => '/d7', 'About Us'; end;
+ li; a href => '/d11', 'Database API'; end;
+ li; a href => '/d14', 'Database Dumps'; end;
+ end;
+ lit _html $d->{content};
+ end;
+ end;
+ $self->htmlFooter;
+}
+
+
+sub edit {
+ my($self, $id, $rev) = @_;
+
+ my $d = $self->dbDocGetRev(id => $id, rev => $rev)->[0];
+ return $self->resNotFound if !$d->{id};
+ $rev = undef if $d->{lastrev};
+
+ return $self->htmlDenied if !$self->authCan('dbmod');
+
+ my %b4 = map { $_ => $d->{$_} } qw|title content ihid ilock|;
+ my $frm;
+
+ if($self->reqMethod eq 'POST') {
+ return if !$self->authCheckCode;
+ $frm = $self->formValidate(
+ { post => 'title', maxlength => 200 },
+ { post => 'content', },
+ { post => 'editsum', template => 'editsum' },
+ { post => 'ihid', required => 0 },
+ { post => 'ilock', required => 0 },
+ { post => 'preview', required => 0 },
+ );
+ if(!$frm->{_err} && !$frm->{preview}) {
+ $frm->{ihid} = $frm->{ihid}?1:0;
+ $frm->{ilock} = $frm->{ilock}?1:0;
+
+ return $self->resRedirect("/d$id", 'post') if !form_compare(\%b4, $frm);
+ my $nrev = $self->dbItemEdit(d => $id, $d->{rev}, %$frm);
+ return $self->resRedirect("/d$nrev->{itemid}.$nrev->{rev}", 'post');
+ }
+ }
+
+ !defined $frm->{$_} && ($frm->{$_} = $b4{$_}) for keys %b4;
+ $frm->{editsum} = sprintf 'Reverted to revision d%d.%d', $id, $rev if $rev && !defined $frm->{editsum};
+ delete $frm->{_err} if $frm->{preview};
+
+ my $title = "Edit $d->{title}";
+ $self->htmlHeader(title => $title, noindex => 1);
+ $self->htmlMainTabs('d', $d, 'edit');
+
+ if($frm->{preview}) {
+ div class => 'mainbox';
+ h1 'Preview';
+ div class => 'docs';
+ lit _html $frm->{content};
+ end;
+ end;
+ }
+
+ $self->htmlForm({ frm => $frm, action => "/d$id/edit", editsum => 1, preview => 1 }, dedit => [ $title,
+ [ input => name => 'Title', short => 'title', width => 300 ],
+ [ static => nolabel => 1, content => q{
+ <br>Contents (HTML and MultiMarkdown supported, which is
+ <a href="https://daringfireball.net/projects/markdown/basics">Markdown</a>
+ with some <a href="http://fletcher.github.io/MultiMarkdown-5/syntax.html">extensions</a>).} ],
+ [ textarea => short => 'content', name => 'Content', rows => 50, cols => 90, nolabel => 1 ],
+ ]);
+ $self->htmlFooter;
+}
+
+1;
diff --git a/lib/VNDB/Handler/Misc.pm b/lib/VNDB/Handler/Misc.pm
index e3b67d52..771c9d83 100644
--- a/lib/VNDB/Handler/Misc.pm
+++ b/lib/VNDB/Handler/Misc.pm
@@ -4,18 +4,16 @@ package VNDB::Handler::Misc;
use strict;
use warnings;
-use TUWF ':html', ':xml', 'xml_escape', 'uri_escape';
+use TUWF ':html', ':xml', 'uri_escape';
use VNDB::Func;
-use POSIX 'strftime';
TUWF::register(
- qr{}, \&homepage,
- qr{(?:([upvrcs])([1-9]\d*)/)?hist},\&history,
- qr{d([1-9]\d*)}, \&docpage,
- qr{nospam}, \&nospam,
- qr{xml/prefs\.xml}, \&prefs,
- qr{opensearch\.xml}, \&opensearch,
+ qr{}, \&homepage,
+ qr{(?:([upvrcsd])([1-9]\d*)/)?hist},\&history,
+ qr{nospam}, \&nospam,
+ qr{xml/prefs\.xml}, \&prefs,
+ qr{opensearch\.xml}, \&opensearch,
# redirects for old URLs
qr{u([1-9]\d*)/tags}, sub { $_[0]->resRedirect("/g/links?u=$_[1]", 'perm') },
@@ -28,8 +26,6 @@ TUWF::register(
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') }
);
@@ -206,7 +202,7 @@ sub history {
{ get => 'p', required => 0, default => 1, template => 'page' },
{ get => 'm', required => 0, default => !$type, enum => [ 0, 1 ] },
{ get => 'h', required => 0, default => 0, enum => [ -1..1 ] },
- { get => 't', required => 0, default => '', enum => [qw|v r p c s a|] },
+ { get => 't', required => 0, default => '', enum => [qw|v r p c s d a|] },
{ get => 'e', required => 0, default => 0, enum => [ -1..1 ] },
{ get => 'r', required => 0, default => 0, enum => [ 0, 1 ] },
);
@@ -218,6 +214,7 @@ sub history {
$type eq 'r' ? $self->dbReleaseGet(id => $id)->[0] :
$type eq 'c' ? $self->dbCharGet(id => $id)->[0] :
$type eq 's' ? $self->dbStaffGet(id => $id)->[0] :
+ $type eq 'd' ? $self->dbDocGet(id => $id)->[0] :
$type eq 'v' ? $self->dbVNGet(id => $id)->[0] : undef;
return $self->resNotFound if $type && !$obj->{id};
my $title = $type ? 'Edit history of '.($obj->{title} || $obj->{name} || $obj->{username}) : 'Recent changes';
@@ -226,7 +223,7 @@ sub history {
my($list, $np) = $self->dbRevisionGet(
$type && $type ne 'u' ? ( type => $type, itemid => $id ) : (),
$type eq 'u' ? ( uid => $id ) : (),
- $f->{t} ? ( type => $f->{t} eq 'a' ? [qw|v r p s|] : $f->{t} ) : (),
+ $f->{t} ? ( type => $f->{t} eq 'a' ? [qw|v r p s d|] : $f->{t} ) : (),
page => $f->{p},
results => 50,
auto => $f->{m},
@@ -273,6 +270,7 @@ sub history {
a $f->{t} eq 'p' ? (class => 'optselected') : (), href => $u->(t => 'p'), 'Only producers';
a $f->{t} eq 's' ? (class => 'optselected') : (), href => $u->(t => 's'), 'Only staff';
a $f->{t} eq 'c' ? (class => 'optselected') : (), href => $u->(t => 'c'), 'Only characters';
+ a $f->{t} eq 'd' ? (class => 'optselected') : (), href => $u->(t => 'd'), 'Only docs';
a $f->{t} eq 'a' ? (class => 'optselected') : (), href => $u->(t => 'a'), 'All except characters';
end;
p class => 'browseopts';
@@ -294,68 +292,6 @@ sub history {
}
-sub docpage {
- my($self, $did) = @_;
-
- my $f = sprintf('%s/data/docs/%d', $VNDB::ROOT, $did);
- my $F;
- open($F, '<:utf8', $f) or return $self->resNotFound;
- my @c = <$F>;
- close $F;
-
- (my $title = shift @c) =~ s/^:TITLE://;
- chomp $title;
-
- my($sec, $subsec) = (0,0);
- for (@c) {
- s{^:SUB:(.+)\r?\n$}{
- $sec++;
- $subsec = 0;
- qq|<h3><a href="#$sec" name="$sec">$sec. $1</a></h3>\n|
- }e;
- s{^:SUBSUB:(.+)\r?\n$}{
- $subsec++;
- qq|<h4><a href="#$sec.$subsec" name="$sec.$subsec">$sec.$subsec. $1</a></h4>\n|
- }e;
- s{^:INC:(.+)\r?\n$}{
- $f = sprintf('%s/data/docs/%s', $VNDB::ROOT, $1);
- open($F, '<:utf8', $f) or die $!;
- my $ii = join('', <$F>);
- close $F;
- $ii;
- }e;
- s{^:MODERATORS:$}{
- my $l = $self->dbUserGet(results => 100, sort => 'id', notperm => $self->{default_perm}, what => 'extended');
- my $admin = 0;
- $admin |= $_ for values %{$self->{permissions}};
- '<dl>'.join('', map {
- my $u = $_;
- my $p = $u->{perm} >= $admin ? 'admin' : join ', ', sort map +($u->{perm} &~ $self->{default_perm}) & $self->{permissions}{$_} ? $_ : (), keys %{$self->{permissions}};
- $p ? sprintf('<dt><a href="/u%d">%s</a></dt><dd>%s</dd>', $_->{id}, $_->{username}, $p) : ()
- } @$l).'</dl>';
- }e;
- s{^:SKINCONTRIB:$}{
- my %users;
- push @{$users{ $self->{skins}{$_}[1] }}, [ $_, $self->{skins}{$_}[0] ]
- for sort { $self->{skins}{$a}[0] cmp $self->{skins}{$b}[0] } keys %{$self->{skins}};
- my $u = $self->dbUserGet(uid => [ keys %users ]);
- '<dl>'.join('', map sprintf('<dt><a href="/u%d">%s</a></dt><dd>%s</dd>',
- $_->{id}, $_->{username}, join(', ', map sprintf('<a href="?skin=%s">%s</a>', $_->[0], $_->[1]), @{$users{$_->{id}}})
- ), @$u).'</dl>';
- }e;
- }
-
- $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);
diff --git a/lib/VNDB/Handler/VNEdit.pm b/lib/VNDB/Handler/VNEdit.pm
index ce10611d..e08925f7 100644
--- a/lib/VNDB/Handler/VNEdit.pm
+++ b/lib/VNDB/Handler/VNEdit.pm
@@ -319,7 +319,7 @@ sub _form {
@alist ? @{$self->dbStaffGet(aid => \@alist, results => 200)} : ()
};
div class => 'warning';
- lit 'Please check the <a href="/d2.3">staff editing guidelines</a>. You can'
+ lit 'Please check the <a href="/d2#3">staff editing guidelines</a>. You can'
.' <a href="/s/new">create a new staff entry</a> if it is not in the database yet,'
.' but please <a href="/s/all">check for aliasses first</a>.';
end;
diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm
index e8561e3c..dd129c18 100644
--- a/lib/VNDB/Util/CommonHTML.pm
+++ b/lib/VNDB/Util/CommonHTML.pm
@@ -18,7 +18,7 @@ our @EXPORT = qw|
# generates the "main tabs". These are the commonly used tabs for
# 'objects', i.e. VN/producer/release entries and users
-# Arguments: u/v/r/p/g/i/c, object, currently selected item (empty=main)
+# Arguments: u/v/r/p/g/i/c/d, object, currently selected item (empty=main)
sub htmlMainTabs {
my($self, $type, $obj, $sel) = @_;
$sel ||= '';
@@ -27,7 +27,7 @@ sub htmlMainTabs {
return if $type eq 'g' && !$self->authCan('tagmod');
ul class => 'maintabs';
- if($type =~ /[uvrpcs]/) {
+ if($type =~ /[uvrpcsd]/) {
li $sel eq 'hist' ? (class => 'tabselected') : ();
a href => "/$id/hist", 'history';
end;
@@ -75,6 +75,7 @@ sub htmlMainTabs {
if( $type eq 'u' && ($self->authInfo->{id} && $obj->{id} == $self->authInfo->{id} || $self->authCan('usermod'))
|| $type =~ /[vrpcs]/ && $self->authCan('edit') && ((!$obj->{locked} && !$obj->{hidden}) || $self->authCan('dbmod'))
|| $type =~ /[gi]/ && $self->authCan('tagmod')
+ || $type eq 'd' && $self->authCan('dbmod')
) {
li $sel eq 'edit' ? (class => 'tabselected') : ();
a href => "/$id/edit", 'edit';
@@ -132,12 +133,13 @@ sub htmlDenied {
sub htmlHiddenMessage {
my($self, $type, $obj) = @_;
return 0 if !$obj->{hidden};
- my $board = $type =~ /[cs]/ ? 'db' : $type eq 'r' ? 'v'.$obj->{vn}[0]{vid} : $type.$obj->{id};
+ my $board = $type =~ /[csd]/ ? 'db' : $type eq 'r' ? 'v'.$obj->{vn}[0]{vid} : $type.$obj->{id};
# fetch edit summary (not present in $obj, requires the db*GetRev() methods)
my $editsum = $type eq 'v' ? $self->dbVNGetRev(id => $obj->{id})->[0]{comments}
: $type eq 'r' ? $self->dbReleaseGetRev(id => $obj->{id})->[0]{comments}
: $type eq 'c' ? $self->dbCharGetRev(id => $obj->{id})->[0]{comments}
: $type eq 's' ? $self->dbStaffGetRev(id => $obj->{id})->[0]{comments}
+ : $type eq 'd' ? $self->dbDocGetRev(id => $obj->{id})->[0]{comments}
: $self->dbProducerGetRev(id => $obj->{id})->[0]{comments};
div class => 'mainbox';
h1 $obj->{title}||$obj->{name};
@@ -156,7 +158,7 @@ sub htmlHiddenMessage {
# Shows a revision, including diff if there is a previous revision.
-# Arguments: v|p|r|c, old revision, new revision, @fields
+# Arguments: v|p|r|c|d, old revision, new revision, @fields
# Where @fields is a list of fields as arrayrefs with:
# [ shortname, displayname, %options ],
# Where %options:
diff --git a/lib/VNDB/Util/FormHTML.pm b/lib/VNDB/Util/FormHTML.pm
index a522599e..11de460b 100644
--- a/lib/VNDB/Util/FormHTML.pm
+++ b/lib/VNDB/Util/FormHTML.pm
@@ -54,7 +54,7 @@ sub htmlFormError {
li "$field: Malformed data or invalid input" if $rule eq 'json';
li 'Invalid release date' if $rule eq 'rdate';
if($rule eq 'editsum') {
- li; lit 'Please read <a href="/d5.4">the guidelines</a> on how to use the edit summary.'; end;
+ li; lit 'Please read <a href="/d5#4">the guidelines</a> on how to use the edit summary.'; end;
}
}
}
@@ -187,6 +187,7 @@ sub htmlFormPart {
# nosubmit => 1/0, hides the submit button
# editsum => 1/0, adds an edit summary field before the submit button
# continue => 2/1/0, replace submit button with continue buttons
+# preview => 1/0, add preview button
# noformcode=> 1/0, remove the formcode field
# The other arguments are a list of subforms in the form
# of (subform-name => [form parts]). Each subform is shown as a
@@ -265,6 +266,7 @@ sub htmlForm {
input type => 'submit', name => 'continue_ign', value => 'Continue and ignore duplicates',
class => 'submit', style => 'width: auto', tabindex => 10 if $options->{continue} == 2;
}
+ input type => 'submit', value => 'Preview', id => 'preview', name => 'preview', class => 'submit', tabindex => 10 if $options->{preview};
end;
end 'div';
}