diff options
author | Yorhel <git@yorhel.nl> | 2011-01-02 14:17:57 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2011-01-02 14:17:57 +0100 |
commit | b4e3c35620916852a6028ab5f6644382553408f9 (patch) | |
tree | 303248a812f6a7dc9c25bec0d8af5836c87fec3f /lib/VNDB/Util | |
parent | 632df9599de8dbb25707b0bf8caea075c55cfa3f (diff) | |
parent | 98f4725013b6d7a65e1fd07f7f02785b12e8a9bd (diff) |
Merge branch 'beta'2.16
Conflicts:
ChangeLog
lib/VNDB/Handler/ULists.pm
Diffstat (limited to 'lib/VNDB/Util')
-rw-r--r-- | lib/VNDB/Util/Auth.pm | 17 | ||||
-rw-r--r-- | lib/VNDB/Util/BrowseHTML.pm | 43 | ||||
-rw-r--r-- | lib/VNDB/Util/CommonHTML.pm | 6 | ||||
-rw-r--r-- | lib/VNDB/Util/FormHTML.pm | 4 | ||||
-rw-r--r-- | lib/VNDB/Util/LayoutHTML.pm | 22 | ||||
-rw-r--r-- | lib/VNDB/Util/Misc.pm | 100 |
6 files changed, 169 insertions, 23 deletions
diff --git a/lib/VNDB/Util/Auth.pm b/lib/VNDB/Util/Auth.pm index 24e316ce..9ad76894 100644 --- a/lib/VNDB/Util/Auth.pm +++ b/lib/VNDB/Util/Auth.pm @@ -14,7 +14,7 @@ use YAWF ':html'; use VNDB::Func; -our @EXPORT = qw| authInit authLogin authLogout authInfo authCan authPreparePass authGetCode authCheckCode |; +our @EXPORT = qw| authInit authLogin authLogout authInfo authCan authPreparePass authGetCode authCheckCode authPref |; # initializes authentication information and checks the vndb_auth cookie @@ -27,7 +27,7 @@ sub authInit { return _rmcookie($self) if length($cookie) < 41; my $token = substr($cookie, 0, 40); my $uid = substr($cookie, 40); - $self->{_auth} = $uid =~ /^\d+$/ && $self->dbUserGet(uid => $uid, session => $token, what => 'extended notifycount')->[0]; + $self->{_auth} = $uid =~ /^\d+$/ && $self->dbUserGet(uid => $uid, session => $token, what => 'extended notifycount prefs')->[0]; # update the sessions.lastused column if lastused < now()'6 hours' $self->dbSessionUpdateLastUsed($uid, $token) if $self->{_auth} && $self->{_auth}{session_lastused} < time()-6*3600; return _rmcookie($self) if !$self->{_auth}; @@ -70,6 +70,10 @@ sub authLogout { $self->resRedirect('/', 'temp'); _rmcookie($self); + + # set l10n cookie if the user has a preferred language set + my $l10n = $self->authPref('l10n'); + $self->resHeader('Set-Cookie', "l10n=$l10n; expires=Sat, 01-Jan-2030 00:00:00 GMT; path=/; domain=$self->{cookie_domain}") if $l10n; } @@ -196,5 +200,14 @@ sub _incorrectcode { } +sub authPref { + my($self, $key, $val) = @_; + my $nfo = $self->authInfo; + return '' if !$nfo->{id}; + return $nfo->{prefs}{$key}||'' if @_ == 2; + $nfo->{prefs}{$key} = $val; + $self->dbUserPrefSet($nfo->{id}, $key, $val); +} + 1; diff --git a/lib/VNDB/Util/BrowseHTML.pm b/lib/VNDB/Util/BrowseHTML.pm index 139ff1b0..62e01fd1 100644 --- a/lib/VNDB/Util/BrowseHTML.pm +++ b/lib/VNDB/Util/BrowseHTML.pm @@ -6,6 +6,7 @@ use warnings; use YAWF ':html', 'xml_escape'; use Exporter 'import'; use VNDB::Func; +use POSIX 'ceil'; our @EXPORT = qw| htmlBrowse htmlBrowseNavigate htmlBrowseHist htmlBrowseVN |; @@ -83,23 +84,39 @@ sub htmlBrowse { # creates next/previous buttons (tabs), if needed -# Arguments: page url, current page (1..n), nextpage (0/1), alignment (t/b), noappend (0/1) +# Arguments: page url, current page (1..n), nextpage (0/1 or [$total, $perpage]), alignment (t/b), noappend (0/1) sub htmlBrowseNavigate { my($self, $url, $p, $np, $al, $na) = @_; - return if $p == 1 && !$np; + my($cnt, $pp) = ref($np) ? @$np : ($p+$np, 1); + return if $p == 1 && $cnt <= $pp; $url .= $url =~ /\?/ ? ';p=' : '?p=' unless $na; - ul class => 'maintabs ' . ($al eq 't' ? 'notfirst' : 'bottom'); - if($p > 1) { - li class => 'left'; - a href => $url.($p-1), '<- '.mt '_browse_previous'; - end; - } - if($np) { - li; - a href => $url.($p+1), mt('_browse_next').' ->'; - end; - } + + my $tab = sub { + my($left, $page, $label) = @_; + li $left ? (class => 'left') : (); + a href => $url.$page; lit $label; end; + end; + }; + my $ell = sub { + use utf8; + li class => 'ellipsis'.(shift() ? ' left' : ''); + b '⋯'; + end; + }; + my $nc = 5; # max. number of buttons on each side + + ul class => 'maintabs browsetabs ' . ($al eq 't' ? 'notfirst' : 'bottom'); + $p > 2 and ref $np and $tab->(1, 1, '« '.mt '_browse_first'); + $p > $nc+1 and ref $np and $ell->(1); + $p > $_ and ref $np and $tab->(1, $p-$_, $p-$_) for (reverse 2..($nc>$p-2?$p-2:$nc-1)); + $p > 1 and $tab->(1, $p-1, '‹ '.mt '_browse_previous'); + + my $l = ceil($cnt/$pp)-$p+1; + $l > 2 and $tab->(0, $l+$p-1, mt('_browse_last').' »'); + $l > $nc+1 and $ell->(0); + $l > $_ and $tab->(0, $p+$_, $p+$_) for (reverse 2..($nc>$l-2?$l-2:$nc-1)); + $l > 1 and $tab->(0, $p+1, mt('_browse_next').' ›'); end; } diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm index c7d67647..a412949a 100644 --- a/lib/VNDB/Util/CommonHTML.pm +++ b/lib/VNDB/Util/CommonHTML.pm @@ -45,11 +45,15 @@ sub htmlMainTabs { end; } - if($type eq 'u' && ($obj->{show_list} || $self->authCan('usermod'))) { + if($type eq 'u' && (!($obj->{hide_list} || $obj->{prefs}{hide_list}) || ($self->authInfo->{id} && $self->authInfo->{id} == $obj->{id}) || $self->authCan('usermod'))) { li $sel eq 'wish' ? (class => 'tabselected') : (); a href => "/$id/wish", mt '_mtabs_wishlist'; end; + li $sel eq 'votes' ? (class => 'tabselected') : (); + a href => "/$id/votes", mt '_mtabs_votes'; + end; + li $sel eq 'list' ? (class => 'tabselected') : (); a href => "/$id/list", mt '_mtabs_list'; end; diff --git a/lib/VNDB/Util/FormHTML.pm b/lib/VNDB/Util/FormHTML.pm index d619754a..41ee0ccc 100644 --- a/lib/VNDB/Util/FormHTML.pm +++ b/lib/VNDB/Util/FormHTML.pm @@ -27,7 +27,7 @@ sub htmlFormError { ul; for my $e (@{$frm->{_err}}) { if(!ref $e) { - li mt '_formerr_e_'.$e; + li; lit mt '_formerr_e_'.$e; end; next; } my($field, $type, $rule) = @$e; @@ -89,7 +89,7 @@ sub htmlFormPart { end; td class => 'field'; input type => 'checkbox', name => $o{short}, id => $o{short}, - value => $o{value}||'true', $frm->{$o{short}} ? ( checked => 'checked' ) : (); + value => $o{value}||1, ($frm->{$o{short}}||0) eq ($o{value}||1) ? ( checked => 'checked' ) : (); label for => $o{short}; lit $o{name}; end; diff --git a/lib/VNDB/Util/LayoutHTML.pm b/lib/VNDB/Util/LayoutHTML.pm index f1a6dc2d..cc34b874 100644 --- a/lib/VNDB/Util/LayoutHTML.pm +++ b/lib/VNDB/Util/LayoutHTML.pm @@ -12,7 +12,7 @@ our @EXPORT = qw|htmlHeader htmlFooter|; sub htmlHeader { # %options->{ title, noindex, search, feeds } my($self, %o) = @_; - my $skin = $self->reqParam('skin') || $self->authInfo->{skin} || $self->{skin_default}; + my $skin = $self->reqParam('skin') || $self->authPref('skin') || $self->{skin_default}; $skin = $self->{skin_default} if !$self->{skins}{$skin} || !-d "$VNDB::ROOT/static/s/$skin"; # heading @@ -22,8 +22,8 @@ sub htmlHeader { # %options->{ title, noindex, search, feeds } Link rel => 'shortcut icon', href => '/favicon.ico', type => 'image/x-icon'; Link rel => 'stylesheet', href => $self->{url_static}.'/s/'.$skin.'/style.css?'.$self->{version}, type => 'text/css', media => 'all'; Link rel => 'search', type => 'application/opensearchdescription+xml', title => 'VNDB VN Search', href => $self->{url}.'/opensearch.xml'; - if($self->authInfo->{customcss}) { - (my $css = $self->authInfo->{customcss}) =~ s/\n/ /g; + if($self->authPref('customcss')) { + (my $css = $self->authPref('customcss')) =~ s/\n/ /g; style type => 'text/css', $css; } Link rel => 'alternate', type => 'application/atom+xml', href => "/feeds/$_.atom", title => $self->{atom_feeds}{$_}[1] @@ -88,6 +88,7 @@ sub _menu { div; a href => "$uid/edit", mt '_menu_myprofile'; br; a href => "$uid/list", mt '_menu_myvnlist'; br; + a href => "$uid/votes",mt '_menu_myvotes'; br; a href => "$uid/wish", mt '_menu_mywishlist'; br; a href => "$uid/notifies", $nc ? (class => 'notifyget') : (), mt('_menu_mynotifications').($nc?" ($nc)":''); br; a href => "$uid/hist", mt '_menu_mychanges'; br; @@ -134,8 +135,8 @@ sub _menu { } -sub htmlFooter { - my $self = shift; +sub htmlFooter { # %options => { prefs => [pref1,..] } + my($self, %o) = @_; div id => 'footer'; my $q = $self->dbRandomQuote; @@ -155,6 +156,17 @@ sub htmlFooter { a href => $self->{source_url}, mt '_footer_source'; end; end; # /div maincontent + + # insert users' preference data when required by JS + if($o{prefs}) { + script type => 'text/javascript'; + txt sprintf "PREF_CODE='%s';", $self->authInfo->{id} ? $self->authGetCode('/xml/prefs.xml') : ''; + txt 'PREFS={'; + # assumes the preference value doesn't contain a ' + txt join ',', map sprintf("'%s':'%s'", $_, $self->authPref($_)), @{$o{prefs}}; + txt '};'; + end; + } script type => 'text/javascript', src => $self->{url_static}.'/f/js/'.$self->{l10n}->language_tag().'.js?'.$self->{version}, ''; end; # /body end; # /html diff --git a/lib/VNDB/Util/Misc.pm b/lib/VNDB/Util/Misc.pm new file mode 100644 index 00000000..71aca7a8 --- /dev/null +++ b/lib/VNDB/Util/Misc.pm @@ -0,0 +1,100 @@ + +package VNDB::Util::Misc; + +use strict; +use warnings; +use Exporter 'import'; +use VNDB::Func; + +our @EXPORT = qw|filFetchDB|; + + +my %filfields = ( + vn => [qw|length hasani tag_inc tag_exc taginc tagexc tagspoil lang olang plat|], + release => [qw|type patch freeware doujin date_before date_after minage lang olang resolution plat med voiced ani_story ani_ero|], +); + + +# Arguments: +# type ('vn' or 'release'), +# filter overwrite (string or undef), +# when defined, these filters will be used instead of the preferences, +# must point to a variable, will be modified in-place with the actually used filters +# options to pass to db*Get() before the filters (hashref or undef) +# these options can be overwritten by the filters or the next option +# options to pass to db*Get() after the filters (hashref or undef) +# these options overwrite all other options (pre-options and filters) + +sub filFetchDB { + my($self, $type, $overwrite, $pre, $post) = @_; + $pre = {} if !$pre; + $post = {} if !$post; + my $dbfunc = $self->can($type eq 'vn' ? 'dbVNGet' : 'dbReleaseGet'); + my $prefname = 'filter_'.$type; + my $pref = $self->authPref($prefname); + + # simply call the DB if we're not applying filters + return $dbfunc->($self, %$pre, %$post) if !$pref && !$overwrite; + + my $filters = fil_parse $overwrite // $pref, @{$filfields{$type}}; + + # compatibility + $self->authPref($prefname => fil_serialize $filters) + if $type eq 'vn' && _fil_vn_compat($self, $filters) && !defined $overwrite; + + # write the definite filter string in $overwrite + $_[2] = fil_serialize({map +( + exists($post->{$_}) ? ($_ => $post->{$_}) : + exists($filters->{$_}) ? ($_ => $filters->{$_}) : + exists($pre->{$_}) ? ($_ => $pre->{$_}) : (), + ), @{$filfields{$type}}}) if defined $overwrite; + + return $dbfunc->($self, %$pre, %$filters, %$post) if defined $overwrite; + + # since incorrect filters can throw a database error, we have to special-case + # filters that originate from a preference setting, so that in case these are + # the cause of an error, they are removed. Not doing this will result in VNDB + # throwing 500's even for non-browse pages. We have to do some low-level + # PostgreSQL stuff with savepoints to ensure that an error won't affect our + # existing transaction. + my $dbh = $self->{_YAWF}{DB}{sql}; + $dbh->pg_savepoint('filter'); + my($r, $np); + my $OK = eval { + ($r, $np) = $dbfunc->($self, %$pre, %$filters, %$post); + 1; + }; + $dbh->pg_rollback_to('filter') if !$OK; + $dbh->pg_release('filter'); + + # error occured, let's try again without filters. if that succeeds we know + # it's the fault of the filter preference, and we should remove it. + if(!$OK) { + ($r, $np) = $dbfunc->($self, %$pre, %$post); + # if we're here, it means the previous function didn't die() (duh!) + $self->authPref($prefname => ''); + warn sprintf "Reset filter preference for userid %d. Old: %s\n", $self->authInfo->{id}||0, $pref; + } + return wantarray ? ($r, $np) : $r; +} + + +sub _fil_vn_compat { + my($self, $fil) = @_; + + # older tag specification (by name rather than ID) + if($fil->{taginc} || $fil->{tagexc}) { + my $tagfind = sub { + return map { + my $i = $self->dbTagGet(name => $_)->[0]; + $i && !$i->{meta} ? $i->{id} : (); + } grep $_, ref $_[0] ? @{$_[0]} : ($_[0]||'') + }; + $fil->{tag_inc} //= [ $tagfind->(delete $fil->{taginc}) ] if $fil->{taginc}; + $fil->{tag_exc} //= [ $tagfind->(delete $fil->{tagexc}) ] if $fil->{tagexc}; + return 1; + } + + return 0; +} + |