summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryorhel <yorhel@1fe2e327-d9db-4752-bcf7-ef0cb4a1748b>2008-06-30 18:38:42 +0000
committeryorhel <yorhel@1fe2e327-d9db-4752-bcf7-ef0cb4a1748b>2008-06-30 18:38:42 +0000
commit65c9483112ca4a7c5887cd8331326a0e42e49800 (patch)
tree3263a06fc3517eb4d7595054dd882b0863bbd28a
parent5fd0fb77b025faf71946df483296f24e756e3657 (diff)
Revision numers are now local to their item ID and better integrated into VNDBIDs
git-svn-id: svn://vndb.org/vndb@48 1fe2e327-d9db-4752-bcf7-ef0cb4a1748b
-rw-r--r--data/tpl/defs.pl13
-rw-r--r--data/tpl/hist11
-rw-r--r--data/tpl/home2
-rw-r--r--lib/ChangeLog2
-rw-r--r--lib/Multi/IRC.pm103
-rw-r--r--lib/VNDB.pm15
-rw-r--r--lib/VNDB/Producers.pm27
-rw-r--r--lib/VNDB/Releases.pm29
-rw-r--r--lib/VNDB/Util/DB.pm131
-rw-r--r--lib/VNDB/VN.pm41
-rw-r--r--static/files/style.css5
11 files changed, 204 insertions, 175 deletions
diff --git a/data/tpl/defs.pl b/data/tpl/defs.pl
index d3e84b8a..fcc1c443 100644
--- a/data/tpl/defs.pl
+++ b/data/tpl/defs.pl
@@ -87,12 +87,12 @@ sub cdiff { # obj1, obj2, @items->[ short, name, serialise, diff, [parsed_x, par
my $type = defined $$y{minage} ? 'r' : defined $$y{length} ? 'v' : 'p';
my $pre = '<div id="revbrowse">'.
- ($$y{next} ? qq|<a href="/$type$$y{id}?rev=$$y{next}" id="revnext">later revision -&gt;</a>| : '').
- ($x ? qq|<a href="/$type$$y{id}?rev=$$x{cid}" id="revprev">&lt;- earlier revision</a>| : '').
+ ($$y{next} ? qq|<a href="/$type$$y{id}.$$y{next}" id="revnext">later revision -&gt;</a>| : '').
+ ($x ? qq|<a href="/$type$$y{id}.$$x{rev}" id="revprev">&lt;- earlier revision</a>| : '').
qq|<a href="/$type$$y{id}" id="revmain">$type$$y{id}</a>&nbsp;</div>|;
if(!$x) { # just show info about the revision if there is no previous edit
- return $pre.qq|<div id="tmc"><b>Revision $$y{cid}</b> (<a href="/$type$$y{id}/edit?rev=$$y{cid}">edit</a>)<br />By <a href="/u$$y{requester}">$$y{username}</a> on |.
+ return $pre.qq|<div id="tmc"><b>Revision $$y{rev}</b> (<a href="/$type$$y{id}/edit?rev=$$y{rev}">edit</a>)<br />By <a href="/u$$y{requester}">$$y{username}</a> on |.
formatdate('%Y-%m-%d at %R', $$y{added}).'<br /><b>Edit summary:</b><br /><br />'.
summary($$y{comments}, 0, '[no summary]').'</div>';
}
@@ -120,9 +120,9 @@ sub cdiff { # obj1, obj2, @items->[ short, name, serialise, diff, [parsed_x, par
}
}
return $pre.'<table id="tmc"><thead><tr><td class="tc1">&nbsp;</td>'.
- qq|<td class="tc2"><b>Revision $$x{cid}</b> (<a href="/$type$$y{id}/edit?rev=$$x{cid}">edit</a>)<br />By <a href="/u$$x{requester}">$$x{username}</a> on |.formatdate('%Y-%m-%d at %R', $$x{added}).'</td>'.
- qq|<td class="tc3"><b>Revision $$y{cid}</b> (<a href="/$type$$y{id}/edit?rev=$$y{cid}">edit</a>)<br />By <a href="/u$$y{requester}">$$y{username}</a> on |.formatdate('%Y-%m-%d at %R', $$y{added}).'</td>'.
- '</tr><tr></tr><tr><td>&nbsp;</td><td colspan="2"><b>Edit summary of revision '.$$y{cid}.'</b><br /><br />'.summary($$y{comments}, 0, '[no summary]').'<br /><br /></td></tr></thead>'.
+ qq|<td class="tc2"><b>Revision $$x{rev}</b> (<a href="/$type$$y{id}/edit?rev=$$x{rev}">edit</a>)<br />By <a href="/u$$x{requester}">$$x{username}</a> on |.formatdate('%Y-%m-%d at %R', $$x{added}).'</td>'.
+ qq|<td class="tc3"><b>Revision $$y{rev}</b> (<a href="/$type$$y{id}/edit?rev=$$y{rev}">edit</a>)<br />By <a href="/u$$y{requester}">$$y{username}</a> on |.formatdate('%Y-%m-%d at %R', $$y{added}).'</td>'.
+ '</tr><tr></tr><tr><td>&nbsp;</td><td colspan="2"><b>Edit summary of revision '.$$y{rev}.'</b><br /><br />'.summary($$y{comments}, 0, '[no summary]').'<br /><br /></td></tr></thead>'.
join('',map{
'<tr><td class="tc1">'.$_->[1].'</td><td class="tc2">'.$_->[4].'</td><td class="tc3">'.$_->[5].'</td></tr>'
} @c).'</table>';
@@ -148,6 +148,7 @@ sub summary { # cmd, len, def
if(!$as && s/(http|https):\/\/(.+[0-9a-zA-Z=\/])/<a href="$1:\/\/$2" rel="nofollow">link<\/a>/) {
$l = 4;
} elsif(!$as) {
+ s/^(.*[^\w]|)([dvpr][0-9]+)\.([0-9]+)([^\w].*|)$/$1<a href="\/$2.$3">$2.$3<\/a>$4/ ||
s/^(.*[^\w]|)([duvpr][0-9]+)([^\w].*|)$/$1<a href="\/$2">$2<\/a>$3/;
}
while(s/\[\/url\]/<\/a>/i) {
diff --git a/data/tpl/hist b/data/tpl/hist
index 4160ef52..b578d1f5 100644
--- a/data/tpl/hist
+++ b/data/tpl/hist
@@ -62,11 +62,11 @@
[[ } ]]
<table id="thi">
<thead><tr>
- <td class="tc1">Rev.</td>
+ <td class="tc1" colspan="2">Rev.</td>
<td class="tc2">Date</td>
[[ if($d{type} ne 'u' || $d{act}) { ]]-
<td class="tc3">User</td>[[ } ]]-
- [[ if(!$d{type} || $d{type} eq 'u' || $d{act} || ($d{type} eq 'v' && $d{seli})) { ]]-
+ [[ if(!$d{type} || $d{type} eq 'u' || $d{act}) { ]]-
<td class="tc4">Page</td>[[ } ]]-
[[ if($d{type} && !$d{act}) { ]]-
<td class="tc5">Summary</td>[[ } ]]-
@@ -78,14 +78,13 @@
[[ for (@{$d{hist}}) { my $t = (qw|v r p|)[$_->{type}]; ]]-
<tr>
- <td class="tc1"><a href="/[[= $t.$_->{iid} ]]?rev=[[= $_->{id} ]]">[[= $_->{id} ]]</a></td>
+ <td class="tc1_1"><a href="/[[= $t.$_->{iid}.'.'.$_->{rev} ]]">[[= $t.$_->{iid} ]]</td>
+ <td class="tc1_2"><a href="/[[= $t.$_->{iid}.'.'.$_->{rev} ]]">.[[= $_->{rev} == 1 ? '<b>'.$_->{rev}.'</b>' : $_->{rev} ]]</a></td>
<td class="tc2">[[= formatdate('%Y-%m-%d %R', $_->{added}, 'dh') ]]</td>
[[ if($d{type} ne 'u' || $d{act}) { ]]-
<td class="tc3"><a href="/u[[= $_->{requester} ]]">[[: $_->{username} ]]</a></td>[[ } ]]-
[[ if(!$d{type} || $d{type} eq 'u' || $d{act}) { ]]-
- <td class="tc4">[[= $_->{prev} ? $t.$_->{iid} : '<b>'.$t.$_->{iid}.'</b>' ]]:<a href="/[[= $t.$_->{iid} ]]?rev=[[= $_->{id} ]]" title="[[: $_->{ititle} ]]">[[: length($_->{ititle}) > 30 ? substr($_->{ititle},0,27).'...' : $_->{ititle} ]]</a></td>[[ } ]]-
- [[ if($d{type} eq 'v' && $d{seli}) { ]]-
- <td class="tc4"><a href="/[[= $t.$_->{iid} ]]" title="[[: $_->{ititle} ]]">[[= $_->{prev} ? $t.$_->{iid} : '<b>'.$t.$_->{iid}.'</b>' ]]</a></td>[[ } ]]-
+ <td class="tc4"><a href="/[[= $t.$_->{iid} ]].[[= $_->{rev} ]]" title="[[: $_->{ititle} ]]">[[: shorten $_->{ititle}, 30 ]]</a></td>[[ } ]]-
[[ if($d{type} && !$d{act}) { ]]-
<td class="tc5">[[= summary($_->{comments}, $d{type} eq 'u' ? 40 : 60)||'[empty]' ]]</td>[[ } ]]-
[[ if($d{act} eq 'r') { ]]-
diff --git a/data/tpl/home b/data/tpl/home
index b9d19456..f796f8b6 100644
--- a/data/tpl/home
+++ b/data/tpl/home
@@ -25,7 +25,7 @@
<ul class="home">
<li><b>Recent changes</b></li>
[[ for (@{$d{recentedits}}) { my $t = (qw|v r p|)[$_->{type}]; ]]-
- <li>[[= $t ]]:<a href="/[[= $t.$_->{iid}.'?rev='.$_->{id} ]]" title="[[: $_->{ititle} ]]">[[: shorten $_->{ititle}, 30 ]]</a></li>
+ <li>[[= $t ]]:<a href="/[[= $t.$_->{iid}.'.'.$_->{rev} ]]" title="[[: $_->{ititle} ]]">[[: shorten $_->{ititle}, 30 ]]</a></li>
[[ } ]]-
</ul>
diff --git a/lib/ChangeLog b/lib/ChangeLog
index d8815122..2010007d 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -13,6 +13,8 @@ TODO:
- Added warnings for empty edit summary and extreme votes
- Changed earliest release date to 1980
- Added NES and MSX platforms
+ - All revision numbers are now local to their item ID
+ - Rewrote Multi's VNDBID matching
1.17 - 2008-06-21 (r33)
- Added PS3 and Xbox 360 to platforms
diff --git a/lib/Multi/IRC.pm b/lib/Multi/IRC.pm
index 23b476ab..34d4ccd2 100644
--- a/lib/Multi/IRC.pm
+++ b/lib/Multi/IRC.pm
@@ -145,16 +145,36 @@ sub vndbid { # dest, msg
$_[HEAP]{log}{$_} < time-60 and delete $_[HEAP]{log}{$_}
for (keys %{$_[HEAP]{log}});
- my @id;
- push @id, [$1,$2,$3,$4] while $m =~ s/^(.*)([duvpr])([0-9]+)(.*)$/ $1 $4 /i;
- for (reverse @id) {
- next if $$_[0] =~ /[a-z0-9%\/]$/i || $$_[3] =~ /^[a-z]/i || ($$_[1] eq 'v' && $$_[3] =~ /^\.[0-9]/);
- my($t, $id, $ext) = (lc($$_[1]), $$_[2], $$_[3]);
+ # Four possible options:
+ # 1. [vpru]+ -> item page
+ # 2. [vpr]+.+ -> item revision
+ # 3. d+ -> documentation page
+ # 4. d+.+ -> documentation page # section
+
+ my @formats = (
+ BOLD.RED.'['.NORMAL.BOLD.'%s%d' .RED.']'.NORMAL.' %s ' .RED.'@'.NORMAL.LIGHT_GREY.' %s/%1$s%2$d'.NORMAL,
+ BOLD.RED.'['.NORMAL.BOLD.'%s%d.%d'.RED.']'.NORMAL.' %s '.RED.'by'.NORMAL.' %s '.RED.'@'.NORMAL.LIGHT_GREY.' %s/%1$s%2$d.%3$d'.NORMAL,
+ BOLD.RED.'['.NORMAL.BOLD.'d%d' .RED.']'.NORMAL.' %s ' .RED.'@'.NORMAL.LIGHT_GREY.' %s/d%1$d'.NORMAL,
+ BOLD.RED.'['.NORMAL.BOLD.'d%d.%d' .RED.']'.NORMAL.' %s '.RED.'->'.NORMAL.' %s '.RED.'@'.NORMAL.LIGHT_GREY.' %s/d%1$d#%2$d'.NORMAL,
+ );
+
+ # get a list of possible IDs (a la sub summary in defs.pl)
+ my @id; # [ type, id, ref ]
+ for (split /[, ]/, $m) {
+ next if length > 15 or m{[a-z]{3,6}://}i; # weed out URLs and too long things
+ push @id, /^(?:.*[^\w]|)([dvpr])([0-9]+)\.([0-9]+)(?:[^\w].*|)$/ ? [ $1, $2, $3 ] # matches 2 and 4
+ : /^(?:.*[^\w]|)([duvpr])([0-9]+)(?:[^\w].*|)$/ ? [ $1, $2, 0 ] : (); # matches 1 and 3
+ }
- next if $_[HEAP]{log}{$t.$id};
- $_[HEAP]{log}{$t.$id} = time;
+ # loop through the matched IDs and search the database
+ for (@id) {
+ my($t, $id, $rev) = (@$_);
- if($t ne 'd') {
+ next if $_[HEAP]{log}{$t.$id.'.'.$rev};
+ $_[HEAP]{log}{$t.$id.'.'.$rev} = time;
+
+ # option 1: item page
+ if($t =~ /[vpru]/ && !$rev) {
my $s = $Multi::SQL->prepare(
$t eq 'v' ? 'SELECT vr.title FROM vn_rev vr JOIN vn v ON v.latest = vr.id WHERE v.id = ?' :
$t eq 'u' ? 'SELECT u.username AS title FROM users u WHERE u.id = ?' :
@@ -165,43 +185,52 @@ sub vndbid { # dest, msg
my $r = $s->fetchrow_hashref;
$s->finish;
next if !$r || ref($r) ne 'HASH';
- $_[KERNEL]->post(circ => privmsg => $_[ARG0], sprintf
- BOLD.RED.'['.RED.'%s%d'.RED.']'.NORMAL.' %s '.RED.'@'.NORMAL.LIGHT_GREY.' http://vndb.org/%s%d'.NORMAL,
- $t, $id, $r->{title}, $t, $id
- );
+ $_[KERNEL]->post(circ => privmsg => $_[ARG0], sprintf $formats[0],
+ $t, $id, $r->{title}, $VNDB::VNDBopts{root_url});
+
+ # option 2: item revision
+ } elsif($t =~ /[vpr]/) {
+ my $s = $Multi::SQL->prepare(sprintf q|
+ SELECT %s AS title, u.username
+ FROM changes c
+ JOIN %s_rev i ON c.id = i.id
+ JOIN users u ON u.id = c.requester
+ WHERE i.%sid = %d
+ AND c.rev = %d|,
+ $t ne 'p' ? 'i.title' : 'i.name',
+ {qw|v vn r releases p producers|}->{$t},
+ $t, $id, $rev);
+ $s->execute;
+ my $r = $s->fetchrow_hashref;
+ next if !$r || ref($r) ne 'HASH';
+ $_[KERNEL]->post(circ => privmsg => $_[ARG0], sprintf $formats[1],
+ $t, $id, $rev, $r->{title}, $r->{username}, $VNDB::VNDBopts{root_url});
- } else {
+ # option 3: documentation page
+ } elsif($t eq 'd') {
my $f = sprintf '/www/vndb/data/docs/%d', $id;
open my $F, '<', $f or next;
(my $title = <$F>) =~ s/^:TITLE://;
chomp($title);
- my($sub, $sec) = ('', 0);
- if($ext && $ext =~ /^\.([0-9]+)/) {
- my $fs = $1;
- while(<$F>) {
- next if !/^:SUB:/;
- $sec++;
- if($sec == $fs) {
- chomp;
- ($sub = $_) =~ s/^:SUB://;
- last;
- }
- }
+ if(!$rev) {
+ $_[KERNEL]->post(circ => privmsg => $_[ARG0], sprintf $formats[2],
+ $id, $title, $VNDB::VNDBopts{root_url});
+ next;
}
- close $F;
-
- if(!$sub) {
- $_[KERNEL]->post(circ => privmsg => $_[ARG0], sprintf
- BOLD.RED.'['.RED.'d%d'.RED.']'.NORMAL.' %s '.RED.'@'.NORMAL.LIGHT_GREY.' http://vndb.org/d%d'.NORMAL,
- $id, $title, $id
- );
- } else {
- $_[KERNEL]->post(circ => privmsg => $_[ARG0], sprintf
- BOLD.RED.'['.RED.'d%d.%d'.RED.']'.NORMAL.' %s -> %s '.RED.'@'.NORMAL.LIGHT_GREY.' http://vndb.org/d%d#%d'.NORMAL,
- $id, $sec, $title, $sub, $id, $sec
- );
+
+ # option 4: documentation page # section
+ my($sec, $sub);
+ while(<$F>) {
+ if(/^:SUB:/ && ++$sec == $rev) {
+ chomp;
+ ($sub = $_) =~ s/^:SUB://;
+ last;
+ }
}
+ next if !$sub;
+ $_[KERNEL]->post(circ => privmsg => $_[ARG0], sprintf $formats[3],
+ $id, $rev, $title, $sub, $VNDB::VNDBopts{root_url});
}
}
}
diff --git a/lib/VNDB.pm b/lib/VNDB.pm
index 026ef60f..942d38cf 100644
--- a/lib/VNDB.pm
+++ b/lib/VNDB.pm
@@ -65,6 +65,7 @@ my %VNDBuris = ( # wildcards: * -> (.+), + -> ([0-9]+)
hide => sub { shift->VNHide(shift) },
hist => {'*'=> sub { shift->History('v', shift, $_[1]) } },
},
+ 'v+.+' => sub { shift->VNPage($_[0][0], '', $_[0][1]) },
# releases
'r+' => {
'/' => sub { shift->RPage(shift) },
@@ -73,6 +74,7 @@ my %VNDBuris = ( # wildcards: * -> (.+), + -> ([0-9]+)
hide => sub { shift->RHide(shift) },
hist => {'*'=> sub { shift->History('r', shift, $_[1]) } },
},
+ 'r+.+' => sub { shift->RPage($_[0][0], $_[0][1]) },
# producers
p => {
'/' => sub { shift->PBrowse },
@@ -86,6 +88,7 @@ my %VNDBuris = ( # wildcards: * -> (.+), + -> ([0-9]+)
hide => sub { shift->PHide(shift) },
hist => {'*'=> sub { shift->History('p', shift, $_[1]) } },
},
+ 'p+.+' => sub { shift->PPage($_[0][0], $_[0][1]) },
# stuff (.xml extension to make sure they aren't counted as pageviews)
xml => {
'producers.xml' => sub { shift->PXML },
@@ -118,6 +121,11 @@ my %OLDuris = (
'v+' => {
votes => sub { shift->ResRedirect('/v'.(shift).'/stats', 'perm') },
hist=>{rss => sub { shift->ResRedirect('/v'.(shift).'/hist/rss.xml', 'perm') } },
+ '/' => sub {
+ my $r=$_[0]->FormCheck({name=>'rev',required=>0,default=>0,template=>'int'})->{rev};
+ my $i=$_[0]->DBGetHist(cid => [$r])->[0];
+ $i && $i->{rev} ? $_[0]->ResRedirect('/'.((qw|v r p|)[$i->{type}]).$_[1].'.'.$i->{rev}, 'perm') : $_[0]->ResNotFound;
+ },
},
u => {
'*' => {
@@ -142,6 +150,7 @@ my %OLDuris = (
},
hist=>{rss => sub { shift->ResRedirect('/hist/rss.xml', 'perm') } },
);
+$OLDuris{'r+'}{'/'} = $OLDuris{'p+'}{'/'} = $OLDuris{'v+'}{'/'};
@@ -199,9 +208,9 @@ sub uri2page {
$u->[$i] = '/' if !defined $u->[$i];
my $n = $o->{$u->[$i]} ? $u->[$i] : ((map {
if(/[\*\+]/) {
- my $t = "^$_\$";
- /\*/ ? ($t =~ s/\*/(.+)/) : ($t =~ s/\+/([1-9][0-9]*)/);
- $u->[$i] =~ /$t/ ? ($u->[$i] = $1) && $_ : ();
+ (my $t = "^$_\$") =~ s/\./\\./g;
+ /\*/ ? ($t =~ s/\*/(.+)/g) : ($t =~ s/\+/([1-9][0-9]*)/g);
+ $u->[$i] =~ /$t/ ? ($u->[$i] = $2?[$1,$2]:$1) && $_ : ();
} else { () } }
sort { length($b) <=> length($a) } keys %$o)[0] || '*');
ref($o->{$n}) eq 'HASH' && $n ne '/' ?
diff --git a/lib/VNDB/Producers.pm b/lib/VNDB/Producers.pm
index ba800c7c..37cb1ecf 100644
--- a/lib/VNDB/Producers.pm
+++ b/lib/VNDB/Producers.pm
@@ -14,28 +14,23 @@ $VERSION = $VNDB::VERSION;
sub PPage {
my $self = shift;
my $id = shift;
+ my $rev = shift||0;
+ return $self->ResNotFound if $self->ReqParam('rev');
- my $r = $self->FormCheck(
- { name => 'rev', required => 0, default => 0, template => 'int' },
- { name => 'diff', required => 0, default => 0, template => 'int' },
- );
-
my $p = $self->DBGetProducer(
id => $id,
- $r->{rev} ? ( what => 'changes' ) : (),
- $r->{rev} ? ( rev => $r->{rev} ) : ()
+ $rev ? ( what => 'changes', rev => $rev ) : (),
)->[0];
return $self->ResNotFound if !$p->{id};
- $r->{diff} ||= $p->{prev} if $r->{rev};
- my $c = $r->{diff} && $self->DBGetProducer(id => $id, rev => $r->{diff}, what => 'changes')->[0];
- $p->{next} = $self->DBGetHist(type => 'p', id => $id, next => $p->{cid}, showhid => 1)->[0]{id} if $r->{rev};
+ my $c = $rev && $rev > 1 && $self->DBGetProducer(id => $id, rev => $rev-1, what => 'changes')->[0];
+ $p->{next} = $rev && $p->{latest} > $p->{cid} ? $rev+1 : 0;
return $self->ResAddTpl(ppage => {
prod => $p,
prev => $c,
- change => $r->{diff} || $r->{rev},
+ change => $rev,
vn => $self->DBGetProducerVN($id),
});
}
@@ -102,16 +97,16 @@ sub PEdit {
if $id && 6 == scalar grep { $_ ne 'comm' && $b4{$_} eq $frm->{$_} } keys %b4;
if(!$frm->{_err}) {
- my $cid;
- $cid = $self->DBEditProducer($id, %$frm) if $id; # edit
- ($id, $cid) = $self->DBAddProducer(%$frm) if !$id; # add
- return $self->ResRedirect('/p'.$id.'?rev='.$cid, 'post');
+ my $nrev = 1;
+ ($nrev) = $self->DBEditProducer($id, %$frm) if $id; # edit
+ ($id) = $self->DBAddProducer(%$frm) if !$id; # add
+ return $self->ResRedirect('/p'.$id.'.'.$nrev, 'post');
}
}
if($id) {
$frm->{$_} ||= $b4{$_} for (keys %b4);
- $frm->{comm} = sprintf 'Reverted to revision %d by %s.', $p->{cid}, $p->{username} if $p->{cid} != $p->{latest};
+ $frm->{comm} = sprintf 'Reverted to revision p%d.%d', $p->{id}, $p->{rev} if $p->{cid} != $p->{latest};
} else {
$frm->{lang} ||= 'ja';
}
diff --git a/lib/VNDB/Releases.pm b/lib/VNDB/Releases.pm
index bf293647..58270a3f 100644
--- a/lib/VNDB/Releases.pm
+++ b/lib/VNDB/Releases.pm
@@ -14,22 +14,19 @@ $VERSION = $VNDB::VERSION;
sub RPage {
my $self = shift;
my $id = shift;
+ my $rev = shift||0;
+
+ return $self->ResNotFound if $self->ReqParam('rev');
- my $r = $self->FormCheck(
- { name => 'rev', required => 0, default => 0, template => 'int' },
- { name => 'diff', required => 0, default => 0, template => 'int' },
- );
-
my $v = $self->DBGetRelease(
id => $id,
- what => 'producers platforms media vn'.($r->{rev} ? ' changes':''),
- $r->{rev} ? ( rev => $r->{rev} ) : ()
+ what => 'producers platforms media vn'.($rev ? ' changes':''),
+ $rev ? ( rev => $rev ) : ()
)->[0];
return $self->ResNotFound if !$v->{id};
- $r->{diff} ||= $v->{prev} if $r->{rev};
- my $c = $r->{diff} && $self->DBGetRelease(id => $id, rev => $r->{diff}, what => 'changes producers platforms media vn')->[0];
- $v->{next} = $self->DBGetHist(type => 'r', id => $id, next => $v->{cid}, showhid => 1)->[0]{id} if $r->{rev};
+ my $c = $rev && $rev > 1 && $self->DBGetRelease(id => $id, rev => $rev-1, what => 'changes producers platforms media vn')->[0];
+ $v->{next} = $rev && $v->{latest} > $v->{cid} ? $rev+1 : 0;
$self->ResRedirect('/v'.$v->{vn}[0]{vid})
if ($self->ReqHeader('Referer')||'') =~ m{^http://[^/]*(yahoo|google)} && @{$v->{vn}} == 1;
@@ -37,7 +34,7 @@ sub RPage {
return $self->ResAddTpl(rpage => {
rel => $v,
prev => $c,
- change => $r->{diff}||$r->{rev},
+ change => $rev,
});
}
@@ -112,19 +109,19 @@ sub REdit {
media => $media,
producers => $producers,
);
- my $cid;
- $cid = $self->DBEditRelease($rid, %opts) if $rid; # edit
- ($rid, $cid) = $self->DBAddRelease(%opts) if !$rid; # add
+ my $nrev = 1;
+ ($nrev) = $self->DBEditRelease($rid, %opts) if $rid; # edit
+ ($rid) = $self->DBAddRelease(%opts) if !$rid; # add
$self->RVNCache(@$new_vn, (map { $_->{vid} } @$vn));
- return $self->ResRedirect('/r'.$rid.'?rev='.$cid, 'post');
+ return $self->ResRedirect('/r'.$rid.'.'.$nrev, 'post');
}
}
if($rid) {
$frm->{$_} ||= $b4{$_} for (keys %b4);
- $frm->{comm} = sprintf 'Reverted to revision %d by %s.', $r->{cid}, $r->{username} if $r->{cid} != $r->{latest};
+ $frm->{comm} = sprintf 'Reverted to revision r%d.%d', $r->{id}, $r->{rev} if $r->{cid} != $r->{latest};
} else {
$frm->{language} = 'ja';
$frm->{vn} = $b4{vn};
diff --git a/lib/VNDB/Util/DB.pm b/lib/VNDB/Util/DB.pm
index 7329b3f7..a0c851bb 100644
--- a/lib/VNDB/Util/DB.pm
+++ b/lib/VNDB/Util/DB.pm
@@ -171,16 +171,14 @@ sub DBGetHist { # %options->{ type, id, cid, caused, next, page, results, ip, ed
$o{type} eq 'p' ? ( 'c.type = 2' => 1,
$o{id} ? ( 'pr.pid = %d' => $o{id} ) : () ) : (),
- $o{next} ? (
- 'c.id > %d' => $o{next} ) : (),
$o{caused} ? (
'c.causedby = %d' => $o{caused} ) : (),
$o{ip} ? (
'c.ip = !s' => $o{ip} ) : (),
defined $o{edits} && !$o{edits} ? (
- 'c.prev = 0' => 1 ) : (),
+ 'c.rev = 1' => 1 ) : (),
$o{edits} ? (
- 'c.prev > 0' => 1 ) : (),
+ 'c.rev > 1' => 1 ) : (),
# get rid of 'hidden' items
!$o{showhid} ? (
@@ -192,7 +190,7 @@ sub DBGetHist { # %options->{ type, id, cid, caused, next, page, results, ip, ed
my $where = keys %where ? 'WHERE !W' : '';
- my $select = 'c.id, c.type, c.added, c.requester, c.comments, c.prev, c.causedby';
+ my $select = 'c.id, c.type, c.added, c.requester, c.comments, c.rev, c.causedby';
$select .= ', u.username' if $o{what} =~ /user/;
$select .= ', COALESCE(vr.vid, rr.rid, pr.pid) AS iid' if $o{what} =~ /iid/;
$select .= ', COALESCE(vr2.title, rr2.title, pr2.name) AS ititle' if $o{what} =~ /ititle/;
@@ -563,7 +561,7 @@ sub DBGetVN { # %options->{ id rev char search order results page what cati cate
$o{id} && ref($o{id}) ? (
'v.id IN(!l)' => $o{id} ) : (),
$o{rev} ? (
- 'vr.id = %d' => $o{rev} ) : (),
+ 'c.rev = %d' => $o{rev} ) : (),
$o{char} ? (
'LOWER(SUBSTR(vr.title, 1, 1)) = !s' => $o{char} ) : (),
defined $o{char} && !$o{char} ? (
@@ -613,14 +611,14 @@ sub DBGetVN { # %options->{ id rev char search order results page what cati cate
$o{rev} ?
'JOIN vn v ON v.id = vr.vid' :
'JOIN vn v ON vr.id = v.latest',
- $o{what} =~ /changes/ ? (
+ $o{what} =~ /changes/ || $o{rev} ? (
'JOIN changes c ON c.id = vr.id',
'JOIN users u ON u.id = c.requester' ) : (),
);
my $sel = 'v.id, v.locked, v.hidden, v.c_released, v.c_languages, v.c_votes, v.c_platforms, vr.title, vr.id AS cid, v.rgraph';
$sel .= ', vr.alias, vr.image AS image, vr.img_nsfw, vr.length, vr.desc, vr.l_wp, vr.l_encubed, vr.l_renai, vr.l_vnn' if $o{what} =~ /extended/;
- $sel .= ', c.added, c.requester, c.comments, v.latest, u.username, c.prev, c.causedby' if $o{what} =~ /changes/;
+ $sel .= ', c.added, c.requester, c.comments, v.latest, u.username, c.rev, c.causedby' if $o{what} =~ /changes/;
my $r = $s->DBAll(qq|
SELECT $sel
@@ -688,45 +686,45 @@ sub DBGetVN { # %options->{ id rev char search order results page what cati cate
sub DBAddVN { # %options->{ columns in vn_rev + comm + relations + categories + anime }
my($s, %o) = @_;
- $s->DBExec(q|
+ my $id = $s->DBRow(q|
INSERT INTO changes (type, requester, ip, comments)
- VALUES (%d, %d, !s, !s)|,
- 0, $s->AuthInfo->{id}, $s->ReqIP, $o{comm});
-
- my $id = $s->DBLastId('changes');
+ VALUES (%d, %d, !s, !s)
+ RETURNING id|,
+ 0, $s->AuthInfo->{id}, $s->ReqIP, $o{comm}
+ )->{id};
- $s->DBExec(q|
+ my $vid = $s->DBRow(q|
INSERT INTO vn (latest)
- VALUES (%d)|, $id);
- my $vid = $s->DBLastId('vn');
+ VALUES (%d)
+ RETURNING id|, $id
+ )->{id};
_insert_vn_rev($s, $id, $vid, \%o);
- return ($vid, $id);
+ return ($vid, $id); # item id, global revision
}
sub DBEditVN { # id, %options->( columns in vn_rev + comm + relations + categories + anime + uid + causedby }
my($s, $vid, %o) = @_;
- $s->DBExec(q|
- INSERT INTO changes (type, requester, ip, comments, prev, causedby)
+ my $c = $s->DBRow(q|
+ INSERT INTO changes (type, requester, ip, comments, rev, causedby)
VALUES (%d, %d, !s, !s, (
- SELECT c.id
+ SELECT c.rev+1
FROM changes c
JOIN vn_rev vr ON vr.id = c.id
WHERE vr.vid = %d
ORDER BY c.id DESC
LIMIT 1
- ), %d)|,
+ ), %d)
+ RETURNING id, rev|,
0, $o{uid}||$s->AuthInfo->{id}, $s->ReqIP, $o{comm}, $vid, $o{causedby}||0);
- my $id = $s->DBLastId('changes');
+ _insert_vn_rev($s, $c->{id}, $vid, \%o);
- _insert_vn_rev($s, $id, $vid, \%o);
-
- $s->DBExec(q|UPDATE vn SET latest = %d WHERE id = %d|, $id, $vid);
- return $id;
+ $s->DBExec(q|UPDATE vn SET latest = %d WHERE id = %d|, $c->{id}, $vid);
+ return ($c->{rev}, $c->{id}); # local revision, global revision
}
@@ -822,7 +820,7 @@ sub DBGetRelease { # %options->{ id vid results page rev }
$o{id} ? (
'r.id = %d' => $o{id} ) : (),
$o{rev} ? (
- 'rr.id = %d' => $o{rev} ) : (),
+ 'c.rev = %d' => $o{rev} ) : (),
$o{vid} ? (
'rv.vid = %d' => $o{vid} ) : (),
);
@@ -830,12 +828,12 @@ sub DBGetRelease { # %options->{ id vid results page rev }
my $where = scalar keys %where ? 'WHERE !W' : '';
my @join;
push @join, $o{rev} ? 'JOIN releases r ON r.id = rr.rid' : 'JOIN releases r ON rr.id = r.latest';
- push @join, 'JOIN changes c ON c.id = rr.id' if $o{what} =~ /changes/;
+ push @join, 'JOIN changes c ON c.id = rr.id' if $o{what} =~ /changes/ || $o{rev};
push @join, 'JOIN users u ON u.id = c.requester' if $o{what} =~ /changes/;
push @join, 'JOIN releases_vn rv ON rv.rid = rr.id' if $o{vid};
my $select = 'r.id, r.locked, r.hidden, rr.id AS cid, rr.title, rr.original, rr.gtin, rr.language, rr.website, rr.released, rr.notes, rr.minage, rr.type';
- $select .= ', c.added, c.requester, c.comments, r.latest, u.username, c.prev' if $o{what} =~ /changes/;
+ $select .= ', c.added, c.requester, c.comments, r.latest, u.username, c.rev' if $o{what} =~ /changes/;
my $r = $s->DBAll(qq|
SELECT $select
@@ -907,43 +905,43 @@ sub DBGetRelease { # %options->{ id vid results page rev }
sub DBAddRelease { # options -> { columns in releases_rev table + comm + vn + producers + media + platforms }
my($s, %o) = @_;
- $s->DBExec(q|
+ my $id = $s->DBRow(q|
INSERT INTO changes (type, requester, ip, comments)
- VALUES (%d, %d, !s, !s)|,
- 1, $s->AuthInfo->{id}, $s->ReqIP, $o{comm});
+ VALUES (%d, %d, !s, !s)
+ RETURNING id|,
+ 1, $s->AuthInfo->{id}, $s->ReqIP, $o{comm}
+ )->{id};
- my $id = $s->DBLastId('changes');
- $s->DBExec(q|
+ my $rid = $s->DBRow(q|
INSERT INTO releases (latest)
- VALUES (%d)|, $id);
- my $rid = $s->DBLastId('releases');
+ VALUES (%d)
+ RETURNING id|, $id)->{id};
_insert_release_rev($s, $id, $rid, \%o);
- return ($rid, $id);
+ return ($rid, $id); # item id, global revision
}
sub DBEditRelease { # id, %opts->{ columns in releases_rev table + comm + vn + producers + media + platforms }
my($s, $rid, %o) = @_;
- $s->DBExec(q|
- INSERT INTO changes (type, requester, ip, comments, prev)
+ my $c = $s->DBRow(q|
+ INSERT INTO changes (type, requester, ip, comments, rev)
VALUES (%d, %d, !s, !s, (
- SELECT c.id
+ SELECT c.rev+1
FROM changes c
JOIN releases_rev rr ON rr.id = c.id
WHERE rr.rid = %d
ORDER BY c.id DESC
LIMIT 1
- ))|,
+ ))
+ RETURNING id, rev|,
1, $s->AuthInfo->{id}, $s->ReqIP, $o{comm}, $rid);
- my $id = $s->DBLastId('changes');
-
- _insert_release_rev($s, $id, $rid, \%o);
+ _insert_release_rev($s, $c->{id}, $rid, \%o);
- $s->DBExec(q|UPDATE releases SET latest = %d WHERE id = %d|, $id, $rid);
- return $id;
+ $s->DBExec(q|UPDATE releases SET latest = %d WHERE id = %d|, $c->{id}, $rid);
+ return ($c->{rev}, $c->{id}); # local revision, global revision
}
@@ -1018,17 +1016,17 @@ sub DBGetProducer { # %options->{ id search char results page rev }
defined $o{char} && !$o{char} ? (
'(ASCII(pr.name) < 97 OR ASCII(pr.name) > 122) AND (ASCII(pr.name) < 65 OR ASCII(pr.name) > 90)' => 1 ) : (),
$o{rev} ? (
- 'pr.id = %d' => $o{rev} ) : (),
+ 'c.rev = %d' => $o{rev} ) : (),
);
my $where = scalar keys %where ? 'WHERE !W' : '';
my @join;
push @join, $o{rev} ? 'JOIN producers p ON p.id = pr.pid' : 'JOIN producers p ON pr.id = p.latest';
- push @join, 'JOIN changes c ON c.id = pr.id' if $o{what} =~ /changes/;
+ push @join, 'JOIN changes c ON c.id = pr.id' if $o{what} =~ /changes/ || $o{rev};
push @join, 'JOIN users u ON u.id = c.requester' if $o{what} =~ /changes/;
my $select = 'p.id, p.locked, p.hidden, pr.type, pr.name, pr.original, pr.website, pr.lang, pr.desc';
- $select .= ', c.added, c.requester, c.comments, p.latest, pr.id AS cid, u.username, c.prev' if $o{what} =~ /changes/;
+ $select .= ', c.added, c.requester, c.comments, p.latest, pr.id AS cid, u.username, c.rev' if $o{what} =~ /changes/;
my $r = $s->DBAll(qq|
SELECT $select
@@ -1069,44 +1067,45 @@ sub DBGetProducerVN { # pid
sub DBAddProducer { # %opts->{ columns in producers_rev + comm }
my($s, %o) = @_;
- $s->DBExec(q|
+ my $id = $s->DBRow(q|
INSERT INTO changes (type, requester, ip, comments)
- VALUES (%d, %d, !s, !s)|,
- 2, $s->AuthInfo->{id}, $s->ReqIP, $o{comm});
+ VALUES (%d, %d, !s, !s)
+ RETURNING id|,
+ 2, $s->AuthInfo->{id}, $s->ReqIP, $o{comm}
+ )->{id};
- my $id = $s->DBLastId('changes');
- $s->DBExec(q|
+ my $pid = $s->DBRow(q|
INSERT INTO producers (latest)
- VALUES (%d)|, $id);
- my $pid = $s->DBLastId('producers');
+ VALUES (%d)
+ RETURNING id|, $id
+ )->{id};
_insert_producer_rev($s, $id, $pid, \%o);
- return ($pid, $id);
+ return ($pid, $id); # item id, global revision
}
sub DBEditProducer { # id, %opts->{ columns in producers_rev + comm }
my($s, $pid, %o) = @_;
- $s->DBExec(q|
- INSERT INTO changes (type, requester, ip, comments, prev)
+ my $c = $s->DBRow(q|
+ INSERT INTO changes (type, requester, ip, comments, rev)
VALUES (%d, %d, !s, !s, (
- SELECT c.id
+ SELECT c.rev+1
FROM changes c
JOIN producers_rev pr ON pr.id = c.id
WHERE pr.pid = %d
ORDER BY c.id DESC
LIMIT 1
- ))|,
+ ))
+ RETURNING id, rev|,
2, $s->AuthInfo->{id}, $s->ReqIP, $o{comm}, $pid);
- my $id = $s->DBLastId('changes');
-
- _insert_producer_rev($s, $id, $pid, \%o);
+ _insert_producer_rev($s, $c->{id}, $pid, \%o);
- $s->DBExec(q|UPDATE producers SET latest = %d WHERE id = %d|, $id, $pid);
- return $id;
+ $s->DBExec(q|UPDATE producers SET latest = %d WHERE id = %d|, $c->{id}, $pid);
+ return ($c->{rev}, $c->{id}); # local revision, global revision
}
diff --git a/lib/VNDB/VN.pm b/lib/VNDB/VN.pm
index f0727e6a..2b0e6efc 100644
--- a/lib/VNDB/VN.pm
+++ b/lib/VNDB/VN.pm
@@ -16,22 +16,19 @@ sub VNPage {
my $self = shift;
my $id = shift;
my $page = shift || '';
+ my $rev = shift || 0;
- my $r = $self->FormCheck(
- { name => 'rev', required => 0, default => 0, template => 'int' },
- { name => 'diff', required => 0, default => 0, template => 'int' },
- );
+ return $self->ResNotFound if $self->ReqParam('rev');
my $v = $self->DBGetVN(
id => $id,
- what => 'extended relations categories anime'.($r->{rev} ? ' changes' : ''),
- $r->{rev} ? ( rev => $r->{rev} ) : ()
+ what => 'extended relations categories anime'.($rev ? ' changes' : ''),
+ $rev ? ( rev => $rev ) : ()
)->[0];
return $self->ResNotFound if !$v->{id};
- $r->{diff} ||= $v->{prev} if $r->{rev};
- my $c = $r->{diff} && $self->DBGetVN(id => $id, rev => $r->{diff}, what => 'extended changes relations categories anime')->[0];
- $v->{next} = $self->DBGetHist(type => 'v', id => $id, next => $v->{cid}, showhid => 1)->[0]{id} if $r->{rev};
+ my $c = $rev && $rev > 1 && $self->DBGetVN(id => $id, rev => $rev-1, what => 'extended changes relations categories anime')->[0];
+ $v->{next} = $rev && $v->{latest} > $v->{cid} ? $rev+1 : 0;
if($page eq 'rg' && $v->{rgraph}) {
open(my $F, '<:utf8', sprintf '%s/%02d/%d.cmap', $self->{mappath}, $v->{rgraph}%100, $v->{rgraph}) || die $!;
@@ -46,7 +43,7 @@ sub VNPage {
vn => $v,
prev => $c,
page => $page,
- change => $r->{diff}||$r->{rev},
+ change => $rev,
$page eq 'stats' ? (
lists => {
latest => scalar $self->DBGetVNList(vid => $id, results => 7, hide => 1),
@@ -145,15 +142,15 @@ sub VNEdit {
);
if(!$frm->{_err}) {
- my($oid, $cid) = ($id, 0);
- $cid = $self->DBEditVN($id, %args) if $id; # edit
- ($id, $cid) = $self->DBAddVN(%args) if !$id; # add
+ my($oid, $nrev, $cid) = ($id, 1, 0);
+ ($nrev, $cid) = $self->DBEditVN($id, %args) if $id; # edit
+ ($id, $cid) = $self->DBAddVN(%args) if !$id; # add
# update reverse relations and relation graph
if((!$oid && $#$relations >= 0) || ($oid && $frm->{relations} ne $b4{relations})) {
my %old = $oid ? (map { $_->{id} => $_->{relation} } @{$v->{relations}}) : ();
my %new = map { $_->[1] => $_->[0] } @$relations;
- $self->VNUpdReverse(\%old, \%new, $id, $cid);
+ $self->VNUpdReverse(\%old, \%new, $id, $cid, $nrev);
}
# also regenerate relation graph if the title changes
elsif(@$relations && $frm->{title} ne $b4{title}) {
@@ -163,13 +160,13 @@ sub VNEdit {
# check for new anime data
$self->RunCmd('anime check') if $oid && $frm->{anime} ne $b4{anime} || !$oid && $frm->{anime};
- return $self->ResRedirect('/v'.$id.'?rev='.$cid, 'post');
+ return $self->ResRedirect('/v'.$id.'.'.$nrev, 'post');
}
}
if($id) {
$frm->{$_} ||= $b4{$_} for (keys %b4);
- $frm->{comm} = sprintf 'Reverted to revision %d by %s.', $v->{cid}, $v->{username} if $v->{cid} != $v->{latest};
+ $frm->{comm} = sprintf 'Reverted to revision v%d.%d', $v->{id}, $v->{rev} if $v->{cid} != $v->{latest};
}
$self->AddHid($frm);
@@ -205,8 +202,6 @@ sub VNHide {
return $self->ResNotFound() if !$v;
return $self->ResDenied if !$self->AuthCan('del');
$self->DBHideVN($id, $v->{hidden}?0:1);
- #$self->VNUpdReverse({ map { $_->{id} => $_->{relation} } @{$v->{relations}} }, {}, $id, 0)
- # if @{$v->{relations}};
return $self->ResRedirect('/v'.$id, 'perm');
}
@@ -230,8 +225,8 @@ sub VNBrowse {
my $q = $f->{q};
if($chr eq 'search') {
# VNDBID
- return $self->ResRedirect('/'.$1, 'temp')
- if $q =~ /^([vrpud][0-9]+)$/;
+ return $self->ResRedirect('/'.$1.$2.(!$3 ? '' : $1 eq 'd' ? '#'.$3 : '.'.$3), 'temp')
+ if $q =~ /^([vrpud])([0-9]+)(?:\.([0-9]+))?$/;
if(!($q =~ s/^title://)) {
# categories
@@ -310,8 +305,8 @@ sub VNXML {
# Update reverse relations
-sub VNUpdReverse { # old, new, id, cid
- my($self, $old, $new, $id, $cid) = @_;
+sub VNUpdReverse { # old, new, id, cid, rev
+ my($self, $old, $new, $id, $cid, $rev) = @_;
my %upd;
for (keys %$old, keys %$new) {
if(exists $$old{$_} and !exists $$new{$_}) {
@@ -331,7 +326,7 @@ sub VNUpdReverse { # old, new, id, cid
push @newrel, [ $upd{$i}, $id ] if $upd{$i} != -1;
$self->DBEditVN($i,
relations => \@newrel,
- comm => 'Reverse relation update caused by revision '.$cid.' of v'.$id,
+ comm => 'Reverse relation update caused by revision v'.$id.'.'.$rev,
causedby => $cid,
uid => 1, # Multi - hardcoded
anime => [ map $_->{id}, @{$r->{anime}} ],
diff --git a/static/files/style.css b/static/files/style.css
index d656d605..d890a47c 100644
--- a/static/files/style.css
+++ b/static/files/style.css
@@ -741,7 +741,10 @@ b.diff_del { font-weight: normal; background-color: #fcc; }
#tvl .tc1, #tvl .tc2, #tvl .tc3 { white-space: nowrap; padding-right: 10px; }
#thi { clear: both }
-#thi .tc1 { width: 35px; }
+#thi .tc1_1 { text-align: right; padding-right: 0; width: 10px; }
+#thi .tc1_2 { padding-left: 0; padding-right: 10px; }
+#thi .tc1_1 a, #thi .tc1_2 a { text-decoration: none }
+#thi .tc1 { width: 10px }
#thi .tc2 { width: 110px; }
#tre tr { background-color: #fff!important; }