summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/VNDB/DB/Users.pm31
-rw-r--r--lib/VNDB/Handler/Users.pm103
-rw-r--r--lib/VNDB/Util/CommonHTML.pm2
-rw-r--r--static/f/style.css62
m---------yawf0
5 files changed, 194 insertions, 4 deletions
diff --git a/lib/VNDB/DB/Users.pm b/lib/VNDB/DB/Users.pm
index 140b8861..4910b564 100644
--- a/lib/VNDB/DB/Users.pm
+++ b/lib/VNDB/DB/Users.pm
@@ -8,7 +8,7 @@ use Exporter 'import';
our @EXPORT = qw|dbUserGet dbUserEdit dbUserAdd dbUserDel|;
-# %options->{ username passwd mail order uid results page }
+# %options->{ username passwd mail order uid what results page }
sub dbUserGet {
my $s = shift;
my %o = (
@@ -24,6 +24,10 @@ sub dbUserGet {
'username = ?' => $o{username} ) : (),
$o{passwd} ? (
'passwd = decode(?, \'hex\')' => $o{passwd} ) : (),
+ $o{firstchar} ? (
+ 'SUBSTRING(username from 1 for 1) = ?' => $o{firstchar} ) : (),
+ !$o{firstchar} && defined $o{firstchar} ? (
+ 'ASCII(username) < 97 OR ASCII(username) > 122' => 1 ) : (),
$o{mail} ? (
'mail = ?' => $o{mail} ) : (),
$o{uid} ? (
@@ -41,6 +45,31 @@ sub dbUserGet {
$o{order}
);
+ # XXX: cache please...
+ if($o{what} =~ /list/ && $#$r >= 0) {
+ my %r = map {
+ $r->[$_]{votes} = 0;
+ $r->[$_]{changes} = 0;
+ ($r->[$_]{id}, $_)
+ } 0..$#$r;
+
+ $r->[$r{$_->{uid}}]{votes} = $_->{cnt} for (@{$s->dbAll(q|
+ SELECT uid, COUNT(vid) AS cnt
+ FROM votes
+ WHERE uid IN(!l)
+ GROUP BY uid|,
+ [ keys %r ]
+ )});
+
+ $r->[$r{$_->{requester}}]{changes} = $_->{cnt} for (@{$s->dbAll(q|
+ SELECT requester, COUNT(id) AS cnt
+ FROM changes
+ WHERE requester IN(!l)
+ GROUP BY requester|,
+ [ keys %r ]
+ )});
+ }
+
return wantarray ? ($r, $np) : $r;
}
diff --git a/lib/VNDB/Handler/Users.pm b/lib/VNDB/Handler/Users.pm
index 11e88126..aa61b0a7 100644
--- a/lib/VNDB/Handler/Users.pm
+++ b/lib/VNDB/Handler/Users.pm
@@ -5,6 +5,7 @@ use strict;
use warnings;
use YAWF ':html';
use Digest::MD5 'md5_hex';
+use POSIX 'strftime';
YAWF::register(
@@ -16,6 +17,7 @@ YAWF::register(
qr{u/register} => \&register,
qr{u([1-9]\d*)/edit} => \&edit,
qr{u([1-9]\d*)/del(/[od])?} => \&delete,
+ qr{u/list/(all|[0a-z])} => \&list,
);
@@ -308,6 +310,107 @@ sub delete {
}
+sub list {
+ my($self, $char) = @_;
+
+ my $f = $self->formValidate(
+ { name => 's', required => 0, default => 'username', enum => [ qw|username registered| ] },
+ { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] },
+ { name => 'p', required => 0, default => 1, template => 'int' },
+ );
+ return 404 if $f->{_err};
+
+ $self->htmlHeader(title => 'Browse users');
+
+ div class => 'mainbox';
+ h1 'Browse users';
+ p class => 'browseopts';
+ for ('all', 'a'..'z', 0) {
+ a href => "/u/list/$_", $_ eq $char ? (class => 'optselected') : (), $_ ? uc $_ : '#';
+ }
+ end;
+ end;
+
+ my($list, $np) = $self->dbUserGet(
+ order => $f->{s}.($f->{o} eq 'a' ? ' ASC' : ' DESC'),
+ $char ne 'all' ? (
+ firstchar => $char ) : (),
+ results => 50,
+ page => $f->{p},
+ what => 'list',
+ );
+
+ if($f->{p} > 1 || $np) {
+ ul class => 'maintabs notfirst';
+ if($f->{p} > 1) {
+ li class => 'left';
+ a href => "/u/list/$char?o=$f->{o}&s=$f->{s}&p=".($f->{p}-1), '<- previous';
+ end;
+ }
+ if($np) {
+ li;
+ a href => "/u/list/$char?o=$f->{o}&s=$f->{s}&p=".($f->{p}+1), 'next ->';
+ end;
+ }
+ end;
+ }
+
+ div class => 'mainbox browse';
+ table;
+ thead;
+ Tr;
+ td class => 'tc1';
+ txt 'Username ';
+ lit $f->{s} eq 'username' && $f->{o} eq 'a' ? "\x{25B4}" : qq|<a href="/u/list/$char?o=a&s=username">\x{25B4}</a>|;
+ lit $f->{s} eq 'username' && $f->{o} eq 'd' ? "\x{25BE}" : qq|<a href="/u/list/$char?o=d&s=username">\x{25BE}</a>|;
+ end;
+ td class => 'tc2';
+ txt 'Registered ';
+ lit $f->{s} eq 'registered' && $f->{o} eq 'a' ? "\x{25B4}" : qq|<a href="/u/list/$char?o=a&s=registered">\x{25B4}</a>|;
+ lit $f->{s} eq 'registered' && $f->{o} eq 'd' ? "\x{25BE}" : qq|<a href="/u/list/$char?o=d&s=registered">\x{25BE}</a>|;
+ end;
+ td class => 'tc3', 'Votes';
+ td class => 'tc4', 'Edits';
+ end;
+ end;
+ for(0..$#$list) {
+ my $l = $list->[$_];
+ Tr $_ % 2 ? (class => 'odd') : ();
+ td class => 'tc1';
+ a href => '/u'.$l->{id}, $l->{username};
+ end;
+ td class => 'tc2', strftime '%Y-%m-%d', gmtime $l->{registered};
+ td class => 'tc3';
+ lit !($l->{flags} & $self->{user_flags}{list}) ? '-' : !$l->{votes} ? 0 :
+ qq|<a href="/u$l->{id}/list">$l->{votes}</a>|;
+ end;
+ td class => 'tc4';
+ lit !$l->{changes} ? 0 : qq|<a href="/u$l->{id}/hist">$l->{changes}</a>|;
+ end;
+ end;
+ }
+ end;
+ end;
+
+ if($f->{p} > 1 || $np) {
+ ul class => 'maintabs bottom';
+ if($f->{p} > 1) {
+ li class => 'left';
+ a href => "/u/list/$char?o=$f->{o}&s=$f->{s}&p=".($f->{p}-1), '<- previous';
+ end;
+ }
+ if($np) {
+ li;
+ a href => "/u/list/$char?o=$f->{o}&s=$f->{s}&p=".($f->{p}+1), 'next ->';
+ end;
+ }
+ end;
+ }
+
+ $self->htmlFooter;
+}
+
+
1;
diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm
index 735a55cd..1f0c3edb 100644
--- a/lib/VNDB/Util/CommonHTML.pm
+++ b/lib/VNDB/Util/CommonHTML.pm
@@ -50,7 +50,7 @@ sub _menu {
[ '/' => 'Home' ],
[ '#' => 'Visual Novels' ],
[ '#' => 'Producers' ],
- [ '#' => 'Users' ],
+ [ '/u/list/all' => 'Users' ],
[ '#' => 'Recent Changes' ],
[ '#' => 'Discussion Board' ],
[ '#' => 'FAQ' ]) {
diff --git a/static/f/style.css b/static/f/style.css
index cbeca1f4..d492a4a2 100644
--- a/static/f/style.css
+++ b/static/f/style.css
@@ -27,7 +27,7 @@ table td {
padding: 3px;
}
table tr.odd {
- background-color: #112337;
+ background: url(/f/boxbg.png) repeat;
}
#bgright {
@@ -124,6 +124,7 @@ td.field label {
left: 190px;
right: 30px;
margin: 0;
+ padding-bottom: 50px!important;
}
#maincontent h1, #maincontent h2 {
font-family: "Futura", "Century New Gothic", "Arial", Serif;
@@ -141,7 +142,7 @@ td.field label {
}
#maincontent div.mainbox {
border: 1px solid #258;
- margin: 21px 0 10px 0;
+ margin: 21px 0 -10px 0;
padding: 5px;
background: url(/f/boxbg.png) repeat;
}
@@ -223,6 +224,10 @@ p.center {
display: inline;
margin: 0;
}
+#maincontent ul.maintabs.notfirst {
+ display: block;
+ height: 20px;
+}
#maincontent ul.maintabs li {
display: inline;
list-style-type: none;
@@ -237,11 +242,64 @@ p.center {
margin: 0 0 0 10px;
background-color: #012;
}
+#maincontent ul.maintabs.notfirst li a {
+ margin-top: 20px;
+}
+#maincontent ul.maintabs.bottom li a {
+ margin-top: 10px;
+ border-bottom: 1px solid #258;
+ border-top: none;
+ padding: 4px 7px 2px 7px;
+}
+#maincontent ul.maintabs li.left a {
+ float: left;
+ margin-left: 0;
+ margin-right: 10px;
+}
#maincontent ul.maintabs li.tabselected a,
#maincontent ul.maintabs li a:hover {
background-color: #0c1925;
padding-bottom: 6px;
}
+#maincontent ul.maintabs.bottom li.tabselected a,
+#maincontent ul.maintabs.bottom li a:hover {
+ padding-bottom: 2px;
+ padding-top: 5px;
+ margin-top: 9px;
+}
+
+
+
+
+/***** Browsing ******/
+
+p.browseopts {
+ text-align: center;
+}
+p.browseopts a {
+ padding: 1px 3px;
+ color: #fff!important;
+ border: 1px solid #258;
+ margin: 0 2px;
+}
+p.browseopts a.optselected, p.browseopts a:hover {
+ border: 0;
+ padding: 2px 4px;
+}
+#maincontent div.mainbox.browse {
+ padding: 0;
+}
+div.mainbox.browse table {
+ width: 100%;
+}
+div.mainbox.browse table td.tc1 {
+ padding-left: 25px;
+}
+table thead td {
+ font-weight: bold;
+ background-color: #135;
+ /*background-color: #112337;*/
+}
diff --git a/yawf b/yawf
-Subproject 5a71f64b9b030235275e8ce574221ec074b040c
+Subproject 947a4d87107d77f7e5e15d03e1cebbd294acc93