diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ChangeLog | 366 | ||||
-rw-r--r-- | lib/Multi/Maintenance.pm | 14 | ||||
-rw-r--r-- | lib/VNDB/DB/Producers.pm | 1 | ||||
-rw-r--r-- | lib/VNDB/DB/Releases.pm | 9 | ||||
-rw-r--r-- | lib/VNDB/DB/Users.pm | 13 | ||||
-rw-r--r-- | lib/VNDB/DB/VN.pm | 15 | ||||
-rw-r--r-- | lib/VNDB/Func.pm | 2 | ||||
-rw-r--r-- | lib/VNDB/Handler/Misc.pm | 6 | ||||
-rw-r--r-- | lib/VNDB/Handler/Releases.pm | 47 | ||||
-rw-r--r-- | lib/VNDB/Handler/Users.pm | 25 | ||||
-rw-r--r-- | lib/VNDB/Handler/VNBrowse.pm | 6 | ||||
-rw-r--r-- | lib/VNDB/Handler/VNPage.pm | 85 | ||||
-rw-r--r-- | lib/VNDB/Util/CommonHTML.pm | 9 | ||||
-rw-r--r-- | lib/VNDB/Util/FormHTML.pm | 3 | ||||
-rw-r--r-- | lib/VNDB/Util/LayoutHTML.pm | 25 | ||||
-rw-r--r-- | lib/VNDB/Util/Misc.pm | 24 |
16 files changed, 183 insertions, 467 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog deleted file mode 100644 index 92532247..00000000 --- a/lib/ChangeLog +++ /dev/null @@ -1,366 +0,0 @@ -2.1 - 2008-12-29 - - Skin support - - 'show all items' tab to large forms - - Allow items to be selected using the mouse on the dropdown search - - [spoiler] tag produces mouseover-style spoilers instead of ROT13 - - Fixed tiny timezone-related bug - - Re-added release list dropdown on VN pages - - Added [quote] tag to bb2html - - fixed URL parser in bb2html - -2.0 - 2008-12-20 - - New layout - - Massive code rewrite: - - Switched to YAWF - - Removed template system - - Split DB functions in several files - - Converted absolute paths to be relative to the root directory - - Database changes: - - Added caching of edit and vote counts in users.c_votes and .c_changes - - Split users.flags into users.show_nsfw and .show_list (boolean type) - - Global statistics are cached in stats_cache - - URL changes: - - /p and /v don't work anymore, use /[pv]/all - - /u/list/* -> /u/* and /u/list -> /u/list/all - - Revert URL changed from /x99/edit?rev=1 to /x99.1/edit - - /v+/stats and /v+/scr moved into /v+ - - Functionality changes: - - Ability to sort the userlist on vote and change counts - - Added threads and posts counts to the global statistics - - Improved diff calculation - - Whitespace around input fields are removed - - Automated edits filter to history browser - - Number of threads is shown in the discussion tab for each item - - Boardmods can edit threads without updating the last edited field - - No more RSS feeds for changes (will be replaced with a notification - system in the future) - - Improved formsub interface - - Improved VN relation editor interface - - Voted/non-voted filter to user's VNLists - - VNList status can only be changed from release pages - - More stats + recent changes on user pages - -1.23 - 2008-10-22 (r117) - - Removed redirects for old revision URLs (the code wasn't very secure...) - - Fixed bug when using unicode in the AJAX vn/producers/release search box - - Added original title field to VN entries - - Fixed incorrect quoting in producer select form - - Improved display of original titles - -1.22 - 2008-08-29 (r106) - - Inverted vote graph - - Relation graph image maps are now stored in the DB - - Properly fixed the command synchronisation issues with Multi - - Fixed display of wrong ID in the screenshot diff - - Fixed bug with the infinite thumbnail generation message when the server - doesn't respond within one second. - - Rewrote VNDB::Util::DB::sqlprint to use server-side prepared statements - - Added two new foreign key constraints: - changes (causedby) -> changes (id) - threads (id, count) -> threads_posts (tid, num) - - Converted relation graphs to PNG - - Added link between screenshots and releases - -1.21 - 2008-08-16 (r90) - - Added !vn and !uptime commands to Multi::IRC - - Added realtime IRC notifications for actions on the site - - Added screenshots to VNs - - Rewrote Multi::Image - - Renamed the 'anime check' command to 'anime' for consistency - - Moved to PostgreSQL's boolean data type to store boolean data - -1.20 - 2008-08-06 (r79) - - Admins can change someone's username - - Fixed the automatic relogin after changing password - - Added lock indicator when browsing threads on a tag - - Re-added the vote stats to VN pages - - Searching for 'Chinese' doesn't select 'NES' - - Place/time category order on VN pages is now consistent - - Admins can delete users from the DB - - Added small NSFW indication for users who have disabled the warning - - Added noindex tag to iid-ttag browser - - Replaced last poster with age of last post on home page - - Added release list feature and removed the old VNList - - Merged user vote list into the new release list (and removed 'hide my - votes' option) - - Merged Votes.pm into VNLists.pm - - Auto-expand edit summary form when adding a release - - Added wishlist - -1.19 - 2008-07-08 (r62) - - Integrated discussion board - - Colored diff for alies field - - 'ttabs' for user entries - - Removed the rating system - -1.18 - 2008-07-02 (r51) - - Releases, producers and visual novel items can't be fully deleted anymore - - Hidden vote and vnlist items from the 'recent' lists on VN stat pages for - users who don't want that to be seen - - 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 - - Relation graph generation improvements: Unicode, anti-aliassing, async - - Removed all passwords from the main code, and created a seperate config - file to override all options - not available on SVN - - Dynamic loading, several bugfixes, and code cleanup for Multi - - Added 'School Life' and 'Protagonist' categories - - Time and Place categories are now boolean - - Added GTIN field to releases - - Added links to encubed and renai.us - -1.16 - 2008-05-22 - - Release dates in the current year or month without a specified day will - be considered as not yet released - - Added platform and language icons to the VN browser - - Grouped producers, user stats and general information on the VN page - - Added language icons to producer browser - - A little CSS cleanup - - Grouped category browser and search into one advanced search - - Updated sitemap generator - - Pattern matching bug fixes in Multi::IRC, and better handling of commands - - Added .xml extention to all RSS URLs - -1.15 - 2008-05-04 - - Relation graph now also updated on VN title change - - Anime relations - - [js] Position of the dropdown box is now relative to the link element - - Used inline-block for icon image sprites (to avoid stupid float hacks) - - Used icons to indicate the release status type on VN pages - - Give a 'not logged in' dropdown edit box when the user isn't logged in - - Fixed the redirects for old URLs - - Designed a better system to handle documentation - - Created a centralised system for site errors within the same layout - - Wrote some more documentation - - Multi::IRC now also handles d[0-9] IDs - - Multi::Maintenance automatically rotates Multi's logs - -1.14 - 2008-04-26 - - Removed the ID gap prevention method - - Moved static content to static.vndb.org (and rely on lighty for js/css - compression) - - relation graphs and cover images now get an ID instead of MD5-sum - - Added Nintendo Wii to platforms - - Added 'hidden' flag, which should now be used instead of the delete option - - Fixed the ordering of nodes in the relation graphs - - Used global.pl as the central location of the PgSQL login info - - Wrote a daemon which handles several tasks: - - Generation of relation graphs - - Generation of the sitemap.xml.gz - - The IRC bot - - scaling/compressing of cover images - - General maintenance - - Fixed bug with categories not being re-selected after an error submitting - a new VN - - Relation graphs are now automatically updated when a change in a related - release causes information in the graph to be outdated - -1.13 - 2008-04-04 - - Fixed update_prev - - Split revision insert queries into a seperate function for code reuse - - Fixed wiki links - - Fixed search for VN's without releases - - Fixed bug with accepting zero-padded VNDB ID's - - Fixed bug with V-N.net link getting lost after reverse relation update - - Added .xml extension to AJAX requests - - Switched to ';' seperator instead of '&' for some URL's (=cleaner) - - Added language filter to category browser - - Stored release dates as integers and added NOT NULL constraint - - Used a newline to seperate multiple relations on a VN page - - Multi will get credits for a reverse relation edit - - Going to an edit-page without logging in will redirect - - Added rankings to the categories - - Fixed automated relation graph updates - - Added /nospam page - - Changed vote treshold to 3 - -1.12 - 2008-03-09 - - Color coded diffs - - Added noindex on ?ref= pages - - Added TBA to release dates - - Possibility to change vote without revoking first - - Added VN/ADV categories - - Replaced the Release summary with Producers on VN pages - - Added foreign key constrains - -1.11 - 2008-02-29 - - [bug] Home page layout got screwed up when line wrapping occurs - - [bug] Multiple revisions got counted at the category browser - - Added GBA platform - - Added Gameplay and Plot categories - - Added link to V-N.net review - - Added vote count to the global statistics in the main menu - - [hidden] Added language filter to category browser - - Created user pages - - Redirect to VN page if someone visits an rX page from google/yahoo - - Added link to latest revision in the diff-browser - - Renamed "comments" to "Personal note" at VN List - -1.10 - 2008-02-09 - - [bug] Long revision summaries incorrectly chopped - - Added GD-ROM and Blu-ray disk to media - - Platform icons will be kept in a consistent order - - ?rev= pages now show information about the change + diffs + links to - previous/next revisions - - Removed diff and revert links on history pages - - Added rel="nofollow" to edit links - - Changed lowest selectable year at releases to 1990 - - Use Bayesian ratings and added extra char to c_votes - - A few small internal DB changes - - Allowed [url]-tag in edit summary, and used same function to parse vn/p/r - descriptions - - Added line wrapping on long words at diff-viewer - - VN search matches on release titles again - - Added producer search - - [bug] Releases in the future don't count as new language - - Release dates in the future are now red - - multiple vns for releases - - Redirect to specific revision after editing - - Redirect to the page you were at after logging in - - Added "Other" status and "comments" field to VN lists - -1.9 - 2008-02-01 - - Redirect to VN when changing VN List status - - [bug] All ages was not automatically selected - - [bug] Description field ignored when adding or requesting edit of producer - - Rewrote diff calculation - - Added wildcard support to URI-mappings - - Changed some URI's: - /vn/* -> /v/* - /u/_* -> /u/* - /u/[username] -> /u[uid] - - id-gaps for producers and releases are now also filled automatically - - Switched producers name and romaji - - Added visitor as rank for non-logged in visitors, and losers for banned - users - - Added history pages & feeds - - Removed everything related to "pending changes" - - Producers are lockable - - Combined DBGetVN and DBGetVNs - - Moved code for releases from VN.pm to Releases.pm - - Denormalized vn_categories - - Added "tabs" to visual novels, releases & producers - - Made several changes to the visual novel page layout - - Added mass-change/delete option to vnlists - - Renamed vnr* to releases* - - Fixed relation graphs generator to work with the new DB structure, and to - delete graphs for VN's where the relation was deleted - - Removed option to hide a user from the userlist - - ResDenied will show the regiser-new-account-page - - Usernames linkified at history and vn-stats pages - - Added noindex tag on pages that include usernames - - Swapped title <-> romaji for releases - - Removed relation field and added type field for releases - - Also allow [url]-bbcode tag for the notes field for releases and producers - - [bug] Self-refering vn relations are not possible anymore - - Wrote update_vncache as a plpgsql function - - Updated homepage layout: added a few lists - - Added filters to recent changes pages - - Added platform icons to releases - - Added user menu to vn pages - - De-JS'ed the platform select form, used checkboxes instead - - Updated FAQ - -1.8 - 2007-12-05 - - Added [url]-tag to vn description field - - Changed category input to checkboxes - - Used image sprites for category browser icons - - Fixed bug with media-select-form - - Fixed bug with pending producer changes showing up in the producer search - - Added hack to exclude trial versions in the release dates - - Removed audience category and added age rating field to releases - - Fixed typo: "game hes either" -> "game has either" - - Added Wikipedia & CISVisual link - - Added small vertical padding between releases - - Added length of visual novel - - Renamed continues back to Sequel/Prequel - -1.7 - 2007-11-25 - - Bugfix: The visual novel itself is now also listed at the Pending Changes - under the releases - - Bugfix: Comments and Moderation subforms cannot be automatically hidden - - Made release and vn-links in the edit-dropdown clickable, to edit all - - Added "show all pending changes" option for moderators - - Removed official (japanese) titles from producer list - - Added description field for producers - - Added a red asterisk for fields that are required - - Combined 4 flag-columns in the users table to one - - Added cronjob to delete unused relation graphs - -1.6 - 2007-11-11 - - vnr.released accepts NULL - - vn.c_years renamed to vn.c_released, and only stores year+month of first - release - - Removed vn_releases.lastmod - - Fixed CSS bug in releases layout - - Renamed Sequel/Prequel to Continuation/continues... - - Added relation graphs (/vX/rg) - -1.5 - 2007-11-04 - - Automatically hiding form parts is now done server-side - - Release id's are hidden for not logged in visitors - - Added cron job to compress images and remove Exif information - - Possibility to add planned releases to 5 years in the future - - Bugfix: When editing a VN that's waiting for moderation, the 'added' - column won't be updated - - Added NSFW-option to VN-images - - Added small edit-dropdown when clicked on release-id - - Pending changes tab for VN removed and contents moved to relations tab - - Added Visual Novel Relations - -1.4 - 2007-10-28 - - 'Mina' category renamed to 'All Ages' - - Added 'Clear selection' button to the category browser - - New visual novels will get unused/lower ID's - - Added notes-field to releases - - Subforms can be dynamically hidden/shown - - Bugfix: user stats will always stay under the votes at /vX/stats - - Bugfix: syntax error in dyna.js in Opera - - Combined all the add/edit/del-buttons into one menu - - Changed VN page layout: description moved to relations page and categories - have their own sub-item - -1.3 - 2007-10-21 - - Bugfix: checkbox at producer-search now works - - VN ratings don't count of only one user has voted - - Added VN list size and number of votes to user list - - Added categories 'Drama' & 'Mystery' - - Added exclude filters to the category browser - - Added a few statistics to the right bottom of the page - -1.2 - 2007-10-14 - - Bugfix: vnr_producers rows weren't deleted when deleting a release - - Added number of pending changes at "Pending changes" menu item - - Long items (>30 chars) at the top 5's (right bottom) will be shortened - - Added visual novel descriptions to the RSS feed - - Bugfix: fixed msg when browsing votes of someone who hasn't voted yet - - Bugfix: Voting now also works when viewing the vote stats of a VN - - Added user VN lists - - Added profile option to hide VN list - - Changed 'votes' tab on VN page to 'stats' and added user stats. - -1.1 - 2007-10-07 - - Bugfix: you can now empty columns of the vn table - - Japanese is automatically selected when adding a release or producer - - User list has been made public - - Possible to browse other people's votes - - Added two options to "my account" to hide in user list and votes - - Bugfix: username is now shown when accepting a producer - - Bugfix: variable typo in tpl->pedit - - Bugfix: c_*-update-function wasn't called correctly when changing/deleting - releases - - Bugfix: 'added' column in releases, vn and vnr is now updated at accepting - - Added "Most Popular" vns to every page, and added "More..."-links. - - Added RSS feed for recent additions - - Changes visual novel page layout - - Added vote graph + latest votes to the visual novel pages - - Added compression on javascript files - - Replaced relation-selection-box with an input field - -1.0 - 2007-09-30 - - First release diff --git a/lib/Multi/Maintenance.pm b/lib/Multi/Maintenance.pm index 2fb7b2bd..e9c9b337 100644 --- a/lib/Multi/Maintenance.pm +++ b/lib/Multi/Maintenance.pm @@ -9,6 +9,7 @@ use strict; use warnings; use POE; use PerlIO::gzip; +use Time::HiRes 'gettimeofday', 'tv_interval'; sub spawn { @@ -17,7 +18,7 @@ sub spawn { my $p = shift; POE::Session->create( package_states => [ - $p => [qw| _start cmd_maintenance vncache usercache statscache revcache integrity unkanime logrotate |], + $p => [qw| _start cmd_maintenance vncache usercache statscache revcache integrity unkanime logrotate vnpopularity |], ], ); } @@ -25,10 +26,10 @@ sub spawn { sub _start { $_[KERNEL]->alias_set('maintenance'); - $_[KERNEL]->call(core => register => qr/^maintenance((?: (?:vncache|revcache|usercache|statscache|integrity|unkanime|logrotate))+)$/, 'cmd_maintenance'); + $_[KERNEL]->call(core => register => qr/^maintenance((?: (?:vncache|revcache|usercache|statscache|integrity|unkanime|logrotate|vnpopularity))+)$/, 'cmd_maintenance'); # Perform some maintenance functions every day on 0:00 - $_[KERNEL]->post(core => addcron => '0 0 * * *', 'maintenance vncache integrity unkanime'); + $_[KERNEL]->post(core => addcron => '0 0 * * *', 'maintenance vncache integrity unkanime vnpopularity'); # update caches and rotate logs every 1st day of the month at 0:05 $_[KERNEL]->post(core => addcron => '5 0 1 * *' => 'maintenance usercache statscache revcache logrotate'); } @@ -169,6 +170,13 @@ sub logrotate { } +sub vnpopularity { + my $S = [gettimeofday]; + $Multi::SQL->do(q|SELECT update_vnpopularity()|); + $_[KERNEL]->call(core => log => 3 => '(Re)calculated vn.c_popularity in %.2fs', tv_interval($S)); +} + + 1; diff --git a/lib/VNDB/DB/Producers.pm b/lib/VNDB/DB/Producers.pm index edee4a8a..c7abd765 100644 --- a/lib/VNDB/DB/Producers.pm +++ b/lib/VNDB/DB/Producers.pm @@ -69,6 +69,7 @@ sub dbProducerGet { JOIN vn_rev vr ON vr.id = v.latest WHERE vp.pid IN(!l) AND v.hidden = FALSE + AND r.hidden = FALSE GROUP BY v.id ORDER BY date|, [ keys %r ] diff --git a/lib/VNDB/DB/Releases.pm b/lib/VNDB/DB/Releases.pm index 6af2f736..52fea2b0 100644 --- a/lib/VNDB/DB/Releases.pm +++ b/lib/VNDB/DB/Releases.pm @@ -41,7 +41,7 @@ sub dbReleaseGet { ); my @select = ( - qw|r.id r.locked r.hidden rr.title rr.original rr.gtin rr.language rr.website rr.released rr.notes rr.minage rr.type|, 'rr.id AS cid', + qw|r.id r.locked r.hidden rr.title rr.original rr.gtin rr.language rr.website rr.released rr.notes rr.minage rr.type rr.patch|, 'rr.id AS cid', $o{what} =~ /changes/ ? qw|c.added c.requester c.comments r.latest u.username c.rev| : (), ); @@ -69,7 +69,8 @@ sub dbReleaseGet { FROM releases_vn rv JOIN vn v ON v.id = rv.vid JOIN vn_rev vr ON vr.id = v.latest - WHERE rv.rid IN(!l)|, + WHERE rv.rid IN(!l) + ORDER BY vr.title|, [ keys %r ] )}); } @@ -135,9 +136,9 @@ sub insert_rev { my($self, $cid, $rid, $o) = @_; $self->dbExec(q| - INSERT INTO releases_rev (id, rid, title, original, gtin, language, website, released, notes, minage, type) + INSERT INTO releases_rev (id, rid, title, original, gtin, language, website, released, notes, minage, type, patch) VALUES (!l)|, - [ $cid, $rid, @$o{qw| title original gtin language website released notes minage type|} ]); + [ $cid, $rid, @$o{qw| title original gtin language website released notes minage type patch|} ]); $self->dbExec(q| INSERT INTO releases_producers (rid, pid) diff --git a/lib/VNDB/DB/Users.pm b/lib/VNDB/DB/Users.pm index 6f1a13c6..3a327197 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 what } +# %options->{ username passwd mail order uid ip registered results page what } # what: stats sub dbUserGet { my $s = shift; @@ -35,6 +35,10 @@ sub dbUserGet { 'id = ?' => $o{uid} ) : (), !$o{uid} && !$o{username} ? ( 'id > 0' => 1 ) : (), + $o{ip} ? ( + 'ip = ?' => $o{ip} ) : (), + $o{registered} ? ( + 'registered > ?' => $o{registered} ) : (), ); my @select = ( @@ -64,7 +68,7 @@ sub dbUserEdit { my %h; defined $o{$_} && ($h{$_.' = ?'} = $o{$_}) - for (qw| username mail rank show_nsfw show_list skin |); + for (qw| username mail rank show_nsfw show_list skin customcss |); $h{'passwd = decode(?, \'hex\')'} = $o{passwd} if defined $o{passwd}; @@ -77,10 +81,11 @@ sub dbUserEdit { } -# username, md5(pass), mail +# username, md5(pass), mail, [ip] sub dbUserAdd { my($s, @o) = @_; - $s->dbExec(q|INSERT INTO users (username, passwd, mail, registered) VALUES(?, decode(?, 'hex'), ?, ?)|, @o, time); + $s->dbExec(q|INSERT INTO users (username, passwd, mail, ip, registered) VALUES(?, decode(?, 'hex'), ?, ?, ?)|, + @o[0..2], $o[3]||$s->reqIP, time); } diff --git a/lib/VNDB/DB/VN.pm b/lib/VNDB/DB/VN.pm index df2e0a03..368657fc 100644 --- a/lib/VNDB/DB/VN.pm +++ b/lib/VNDB/DB/VN.pm @@ -10,7 +10,7 @@ our @EXPORT = qw|dbVNGet dbVNAdd dbVNEdit dbVNImageId dbVNCache dbScreenshotAdd # Options: id, rev, char, search, cati, cate, lang, platform, results, page, order, what -# What: extended categories anime relations screenshots relgraph changes +# What: extended categories anime relations screenshots relgraph ranking changes sub dbVNGet { my($self, %o) = @_; $o{results} ||= 10; @@ -50,16 +50,18 @@ sub dbVNGet { ); if($o{search}) { - my @w; - for (split /[ -,]/, $o{search}) { + my @w = ( + '(irr.id IS NULL OR ir.latest = irr.id)' => 1 + ); + for (split /[ -,._]/, $o{search}) { s/%//g; next if length($_) < 2; if(/^\d+$/ && gtintype($_)) { push @w, 'irr.gtin = ?', $_; } else { $_ = "%$_%"; - push @w, '(ivr.title ILIKE ? OR ivr.alias ILIKE ? OR irr.title ILIKE ? OR irr.original ILIKE ?)', - [ $_, $_, $_, $_ ]; + push @w, '(ivr.title ILIKE ? OR ivr.original ILIKE ? OR ivr.alias ILIKE ? OR irr.title ILIKE ? OR irr.original ILIKE ?)', + [ $_, $_, $_, $_, $_ ]; } } $where{ q| @@ -87,12 +89,13 @@ sub dbVNGet { ); my @select = ( - qw|v.id v.locked v.hidden v.c_released v.c_languages v.c_platforms vr.title vr.original v.rgraph|, 'vr.id AS cid', + qw|v.id v.locked v.hidden v.c_released v.c_languages v.c_platforms vr.title vr.original v.rgraph v.c_popularity|, 'vr.id AS cid', $o{what} =~ /extended/ ? ( qw|vr.alias vr.image vr.img_nsfw vr.length vr.desc vr.l_wp vr.l_encubed vr.l_renai vr.l_vnn| ) : (), $o{what} =~ /changes/ ? ( qw|c.added c.requester c.comments v.latest u.username c.rev c.causedby|) : (), $o{what} =~ /relgraph/ ? 'rg.cmap' : (), + $o{what} =~ /ranking/ ? '(SELECT COUNT(*) FROM vn iv WHERE iv.c_popularity >= v.c_popularity) AS ranking' : (), ); my($r, $np) = $self->dbPage(\%o, q| diff --git a/lib/VNDB/Func.pm b/lib/VNDB/Func.pm index 330dad7d..4c71d061 100644 --- a/lib/VNDB/Func.pm +++ b/lib/VNDB/Func.pm @@ -70,7 +70,7 @@ sub monthstr { return 'TBA' if $y == 9999; return 'unknown' if $y == 0; return $y if $m == 99; - return strftime '%b %Y', 0, 0, 0, 0, $m-1, $y-1900, 0, 0, 0; + return sprintf '%s %d', [qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)]->[$m-1], $y; } diff --git a/lib/VNDB/Handler/Misc.pm b/lib/VNDB/Handler/Misc.pm index 5a9b9a2a..39af8155 100644 --- a/lib/VNDB/Handler/Misc.pm +++ b/lib/VNDB/Handler/Misc.pm @@ -326,12 +326,16 @@ sub itemmod { 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] : + $type eq 'r' ? $self->dbReleaseGet(id => $iid, what => 'vn')->[0] : $self->dbProducerGet(id => $iid)->[0]; return 404 if !$obj->{id}; $self->dbItemMod($type, $iid, $act eq 'hide' ? (hidden => !$obj->{hidden}) : (locked => !$obj->{locked})); + # update cached vn info when hiding an r+ page + $self->vnCacheUpdate(map $_->{vid}, @{$obj->{vn}}) + if $type eq 'r' && $act eq 'hide'; + $self->resRedirect("/$type$iid", 'temp'); } diff --git a/lib/VNDB/Handler/Releases.pm b/lib/VNDB/Handler/Releases.pm index ff28c64b..38a1fa02 100644 --- a/lib/VNDB/Handler/Releases.pm +++ b/lib/VNDB/Handler/Releases.pm @@ -40,6 +40,7 @@ sub page { map sprintf('<a href="/v%d" title="%s">%s</a>', $_->{vid}, $_->{original}||$_->{title}, shorten $_->{title}, 50), @{$_[0]}; } ], [ type => 'Type', serialize => sub { $self->{release_types}[$_[0]] } ], + [ patch => 'Patch', serialize => sub { $_[0] ? 'Patch' : 'Not a patch' } ], [ title => 'Title (romaji)', diff => 1 ], [ original => 'Original title', diff => 1 ], [ gtin => 'JAN/UPC/EAN', serialize => sub { $_[0]||'[none]' } ], @@ -82,13 +83,21 @@ sub page { sub _infotable { my($self, $r) = @_; table; - Tr; - td class => 'key', ' '; - td ' '; - end; my $i = 0; Tr ++$i % 2 ? (class => 'odd') : (); + td class => 'key', 'Title'; + td $r->{title}; + end; + + if($r->{original}) { + Tr ++$i % 2 ? (class => 'odd') : (); + td 'Original title'; + td $r->{original}; + end; + } + + Tr ++$i % 2 ? (class => 'odd') : (); td 'Relation'; td; for (@{$r->{vn}}) { @@ -104,6 +113,7 @@ sub _infotable { my $type = $self->{release_types}[$r->{type}]; cssicon lc(substr $type, 0, 3), $type; txt ' '.$type; + txt ' patch' if $r->{patch}; end; end; @@ -229,17 +239,18 @@ sub edit { my $vn = $rid ? $r->{vn} : [{ vid => $vid, title => $v->{title} }]; my %b4 = !$rid ? () : ( - (map { $_ => $r->{$_} } qw|type title original gtin language website notes minage platforms|), + (map { $_ => $r->{$_} } qw|type title original gtin language website notes minage platforms patch|), released => $r->{released} =~ /^([0-9]{4})([0-9]{2})([0-9]{2})$/ ? [ $1, $2, $3 ] : [ 0, 0, 0 ], media => join(',', sort map "$_->{medium} $_->{qty}", @{$r->{media}}), producers => join('|||', map "$_->{id},$_->{name}", sort { $a->{id} <=> $b->{id} } @{$r->{producers}}), ); - $b4{vn} = join('|||', map "$_->{vid},$_->{title}", sort { $a->{vid} <=> $b->{vid} } @$vn); + $b4{vn} = join('|||', map "$_->{vid},$_->{title}", @$vn); my $frm; if($self->reqMethod eq 'POST') { $frm = $self->formValidate( { name => 'type', enum => [ 0..$#{$self->{release_types}} ] }, + { name => 'patch', required => 0, default => 0 }, { name => 'title', maxlength => 250 }, { name => 'original', required => 0, default => '', maxlength => 250 }, { name => 'gtin', required => 0, default => '0', @@ -263,6 +274,7 @@ sub edit { my $producers = [ map { /^([0-9]+)/ ? $1 : () } split /\|\|\|/, $frm->{producers} ]; my $new_vn = [ map { /^([0-9]+)/ ? $1 : () } split /\|\|\|/, $frm->{vn} ]; $frm->{platforms} = [ grep $_, @{$frm->{platforms}} ]; + $frm->{patch} = $frm->{patch} ? 1 : 0; return $self->resRedirect("/r$rid", 'post') if $rid && $released == $r->{released} && @@ -272,7 +284,7 @@ sub edit { !grep !/^(released|platforms|producers|vn)$/ && $frm->{$_} ne $b4{$_}, keys %b4; my %opts = ( - (map { $_ => $frm->{$_} } qw| type title original gtin language website notes minage platforms editsum|), + (map { $_ => $frm->{$_} } qw| type title original gtin language website notes minage platforms editsum patch|), vn => $new_vn, producers => $producers, media => $media, @@ -284,7 +296,7 @@ sub edit { ($rid) = $self->dbReleaseAdd(%opts) if !$rid; $self->multiCmd("ircnotify r$rid.$rev"); - _update_vncache($self, @$new_vn, map $_->{vid}, @$vn); + $self->vnCacheUpdate(@$new_vn, map $_->{vid}, @$vn); return $self->resRedirect("/r$rid.$rev", 'post'); } @@ -310,6 +322,7 @@ sub _form { "General info" => [ [ select => short => 'type', name => 'Type', options => [ map [ $_, $self->{release_types}[$_] ], 0..$#{$self->{release_types}} ] ], + [ check => short => 'patch', name => 'This release is a patch to an other release.' ], [ input => short => 'title', name => 'Title (romaji)', width => 300 ], [ input => short => 'original', name => 'Original title', width => 300 ], [ static => content => 'The original title of this release, leave blank if it already is in the Latin alphabet.' ], @@ -400,23 +413,5 @@ sub _form { } -# Recalculates the vn.c_* columns and regenerates the related relation graphs on any change -sub _update_vncache { - my($self, @vns) = @_; - - my $before = $self->dbVNGet(id => \@vns, order => 'v.id', what => 'relations'); - $self->dbVNCache(@vns); - my $after = $self->dbVNGet(id => \@vns, order => 'v.id'); - - my @upd = map { - @{$before->[$_]{relations}} && ( - $before->[$_]{c_released} != $after->[$_]{c_released} - || $before->[$_]{c_languages} ne $after->[$_]{c_languages} - ) ? $before->[$_]{id} : (); - } 0..$#$before; - $self->multiCmd('relgraph '.join(' ', @upd)) if @upd; -} - - 1; diff --git a/lib/VNDB/Handler/Users.pm b/lib/VNDB/Handler/Users.pm index f2bb0fa6..2b83b4a5 100644 --- a/lib/VNDB/Handler/Users.pm +++ b/lib/VNDB/Handler/Users.pm @@ -88,12 +88,16 @@ sub userpage { Tr ++$i % 2 ? (class => 'odd') : (); td 'List stats'; td !$u->{show_list} ? 'hidden' : - sprintf '%d releases of %d visual novels', $u->{releasecount}, $u->{vncount}; + sprintf '%d release%s of %d visual novel%s', + $u->{releasecount}, $u->{releasecount} != 1 ? 's' : '', + $u->{vncount}, $u->{vncount} != 1 ? 's' : ''; end; Tr ++$i % 2 ? (class => 'odd') : (); td 'Forum stats'; - td sprintf '%d posts, %d new threads', $u->{postcount}, $u->{threadcount}; + td sprintf '%d post%s, %d new thread%s', + $u->{postcount}, $u->{postcount} != 1 ? 's' : '', + $u->{threadcount}, $u->{threadcount} != 1 ? 's' : ''; end; end; end; @@ -239,6 +243,7 @@ sub register { push @{$frm->{_err}}, 'passmatch' if $frm->{usrpass} ne $frm->{usrpass2}; push @{$frm->{_err}}, 'usrexists' if $frm->{usrname} eq 'anonymous' || !$frm->{_err} && $self->dbUserGet(username => $frm->{usrname})->[0]{id}; push @{$frm->{_err}}, 'mailexists' if !$frm->{_err} && $self->dbUserGet(mail => $frm->{mail})->[0]{id}; + push @{$frm->{_err}}, 'oneaday' if !$frm->{_err} && $self->dbUserGet(ip => $self->reqIP, registered => time-24*3600)->[0]{id}; if(!$frm->{_err}) { $self->dbUserAdd($frm->{usrname}, md5_hex($frm->{usrpass}), $frm->{mail}); @@ -299,17 +304,20 @@ sub edit { { name => 'mail', template => 'mail' }, { name => 'usrpass', required => 0, minlength => 4, maxlength => 64, template => 'asciiprint' }, { name => 'usrpass2', required => 0, minlength => 4, maxlength => 64, template => 'asciiprint' }, - { name => 'skin', enum => [ '', keys %{$self->{skins}} ], required => 0, default => '' }, { name => 'flags_list', required => 0, default => 0 }, { name => 'flags_nsfw', required => 0, default => 0 }, + { name => 'skin', enum => [ '', keys %{$self->{skins}} ], required => 0, default => '' }, + { name => 'customcss', required => 0, maxlength => 2000, default => '' }, ); - push @{$frm->{_err}}, 'passmatch' if ($frm->{usrpass} || $frm->{usrpass2}) && $frm->{usrpass} ne $frm->{usrpass2}; + push @{$frm->{_err}}, 'passmatch' + if ($frm->{usrpass} || $frm->{usrpass2}) && (!$frm->{usrpass} || !$frm->{usrpass2} || $frm->{usrpass} ne $frm->{usrpass2}); if(!$frm->{_err}) { my %o; $o{username} = $frm->{usrname} if $frm->{usrname}; $o{rank} = $frm->{rank} if $frm->{rank}; $o{mail} = $frm->{mail}; $o{skin} = $frm->{skin}; + $o{customcss} = $frm->{customcss}; $o{passwd} = md5_hex($frm->{usrpass}) if $frm->{usrpass}; $o{show_list} = $frm->{flags_list} ? 1 : 0; $o{show_nsfw} = $frm->{flags_nsfw} ? 1 : 0; @@ -321,9 +329,7 @@ sub edit { # fill out default values $frm->{usrname} ||= $u->{username}; - $frm->{rank} ||= $u->{rank}; - $frm->{mail} ||= $u->{mail}; - $frm->{skin} ||= $u->{skin}; + $frm->{$_} ||= $u->{$_} for(qw|rank mail skin customcss|); $frm->{flags_list} = $u->{show_list} if !defined $frm->{flags_list}; $frm->{flags_nsfw} = $u->{show_nsfw} if !defined $frm->{flags_nsfw}; @@ -356,12 +362,13 @@ sub edit { [ passwd => short => 'usrpass2', name => 'Confirm pass.' ], [ part => title => 'Options' ], - [ select => short => 'skin', name => 'Prefered skin', options => [ - map [ $_ eq $self->{skin_default} ? '' : $_, $self->{skins}{$_} ], sort { $self->{skins}{$a} cmp $self->{skins}{$b} } keys %{$self->{skins}} ] ], [ check => short => 'flags_list', name => qq|Allow other people to see my visual novel list (<a href="/u$uid/list">/u$uid/list</a>) |. qq|and wishlist (<a href="/u$uid/wish">/u$uid/wish</a>)| ], [ check => short => 'flags_nsfw', name => 'Disable warnings for images that are not safe for work.' ], + [ select => short => 'skin', name => 'Prefered skin', width => 300, options => [ + map [ $_ eq $self->{skin_default} ? '' : $_, $self->{skins}{$_} ], sort { $self->{skins}{$a} cmp $self->{skins}{$b} } keys %{$self->{skins}} ] ], + [ textarea => short => 'customcss', name => 'Additional CSS' ], ]); $self->htmlFooter; } diff --git a/lib/VNDB/Handler/VNBrowse.pm b/lib/VNDB/Handler/VNBrowse.pm index 8af5791e..d7cacaa0 100644 --- a/lib/VNDB/Handler/VNBrowse.pm +++ b/lib/VNDB/Handler/VNBrowse.pm @@ -16,7 +16,7 @@ sub list { my($self, $char) = @_; my $f = $self->formValidate( - { name => 's', required => 0, default => 'title', enum => [ qw|title rel| ] }, + { name => 's', required => 0, default => 'title', enum => [ qw|title rel pop| ] }, { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] }, { name => 'p', required => 0, default => 1, template => 'int' }, { name => 'q', required => 0, default => '' }, @@ -61,7 +61,7 @@ sub list { $q ? ( search => $q ) : (), results => 50, page => $f->{p}, - order => ($f->{s} eq 'rel' ? 'c_released' : 'title').($f->{o} eq 'a' ? ' ASC' : ' DESC'), + order => ($f->{s} eq 'rel' ? 'c_released' : $f->{s} eq 'pop' ? 'c_popularity' : 'title').($f->{o} eq 'a' ? ' ASC' : ' DESC'), @cati ? ( cati => \@cati ) : (), @cate ? ( cate => \@cate ) : (), @lang ? ( lang => \@lang ) : (), @@ -85,6 +85,7 @@ sub list { [ '', 0 ], [ '', 0 ], [ 'Released', 'rel' ], + [ 'Popularity', 'pop' ], ], row => sub { my($s, $n, $l) = @_; @@ -103,6 +104,7 @@ sub list { td class => 'tc4'; lit monthstr $l->{c_released}; end; + td class => 'tc5', sprintf '%.2f', $l->{c_popularity}*100; end; }, ); diff --git a/lib/VNDB/Handler/VNPage.pm b/lib/VNDB/Handler/VNPage.pm index b53b60ee..6c336160 100644 --- a/lib/VNDB/Handler/VNPage.pm +++ b/lib/VNDB/Handler/VNPage.pm @@ -37,7 +37,7 @@ sub page { my $v = $self->dbVNGet( id => $vid, - what => 'extended categories anime relations screenshots'.($rev ? ' changes' : ''), + what => 'extended categories anime relations screenshots ranking'.($rev ? ' changes' : ''), $rev ? (rev => $rev) : (), )->[0]; return 404 if !$v->{id}; @@ -78,15 +78,15 @@ sub page { # general info table; - Tr; - td class => 'key', ' '; - td ' '; - end; my $i = 0; - if($v->{length}) { + Tr ++$i % 2 ? (class => 'odd') : (); + td class => 'key', 'Title'; + td $v->{title}; + end; + if($v->{original}) { Tr ++$i % 2 ? (class => 'odd') : (); - td 'Length'; - td "$self->{vn_lengths}[$v->{length}][0] ($self->{vn_lengths}[$v->{length}][1])"; + td 'Original title'; + td $v->{original}; end; } if($v->{alias}) { @@ -95,6 +95,12 @@ sub page { td $v->{alias}; end; } + if($v->{length}) { + Tr ++$i % 2 ? (class => 'odd') : (); + td 'Length'; + td "$self->{vn_lengths}[$v->{length}][0] ($self->{vn_lengths}[$v->{length}][1])"; + end; + } my @links = ( $v->{l_wp} ? [ 'Wikipedia', 'http://en.wikipedia.org/wiki/%s', $v->{l_wp} ] : (), $v->{l_encubed} ? [ 'Encubed', 'http://novelnews.net/tag/%s/', $v->{l_encubed} ] : (), @@ -117,34 +123,7 @@ sub page { _categories($self, \$i, $v) if @{$v->{categories}}; _relations($self, \$i, $v) if @{$v->{relations}}; _anime($self, \$i, $v) if @{$v->{anime}}; - - # User options - if($self->authInfo->{id}) { - my $vote = $self->dbVoteGet(uid => $self->authInfo->{id}, vid => $v->{id})->[0]; - my $wish = $self->dbWishListGet(uid => $self->authInfo->{id}, vid => $v->{id})->[0]; - Tr ++$i % 2 ? (class => 'odd') : (); - td 'User options'; - td; - Select id => 'votesel'; - option $vote ? "your vote: $vote->{vote}" : 'not voted yet'; - optgroup label => $vote ? 'Change vote' : 'Vote'; - option value => $_, "$_ ($self->{votes}[$_-1])" for (reverse 1..10); - end; - option value => -1, 'revoke' if $vote; - end; - if(!$vote || $wish) { - br; - Select id => 'wishsel'; - option $wish ? "wishlist: $self->{wishlist_status}[$wish->{wstat}]" : 'not on your wishlist'; - optgroup label => $wish ? 'Change status' : 'Add to wishlist'; - option value => $_, $self->{wishlist_status}[$_] for (0..$#{$self->{wishlist_status}}); - end; - option value => -1, 'remove from wishlist'; - end; - } - end; - end; - } + _useroptions($self, \$i, $v) if $self->authInfo->{id}; end; end; @@ -350,6 +329,39 @@ sub _anime { } +sub _useroptions { + my($self, $i, $v) = @_; + + my $vote = $self->dbVoteGet(uid => $self->authInfo->{id}, vid => $v->{id})->[0]; + my $wish = $self->dbWishListGet(uid => $self->authInfo->{id}, vid => $v->{id})->[0]; + + Tr ++$$i % 2 ? (class => 'odd') : (); + td 'User options'; + td; + if($vote || !$wish) { + Select id => 'votesel'; + option $vote ? "your vote: $vote->{vote}" : 'not voted yet'; + optgroup label => $vote ? 'Change vote' : 'Vote'; + option value => $_, "$_ ($self->{votes}[$_-1])" for (reverse 1..10); + end; + option value => -1, 'revoke' if $vote; + end; + br; + } + if(!$vote || $wish) { + Select id => 'wishsel'; + option $wish ? "wishlist: $self->{wishlist_status}[$wish->{wstat}]" : 'not on your wishlist'; + optgroup label => $wish ? 'Change status' : 'Add to wishlist'; + option value => $_, $self->{wishlist_status}[$_] for (0..$#{$self->{wishlist_status}}); + end; + option value => -1, 'remove from wishlist'; + end; + } + end; + end; +} + + sub _releases { my($self, $v, $r) = @_; @@ -395,6 +407,7 @@ sub _releases { end; td class => 'tc4'; a href => "/r$rel->{id}", title => $rel->{original}||$rel->{title}, $rel->{title}; + b class => 'patch', ' (patch)' if $rel->{patch}; end; td class => 'tc5'; if($self->authInfo->{id}) { diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm index 70fdfde3..6b6725c6 100644 --- a/lib/VNDB/Util/CommonHTML.pm +++ b/lib/VNDB/Util/CommonHTML.pm @@ -402,7 +402,7 @@ sub htmlVoteStats { td colspan => 2, 'Vote graph'; end; end; tfoot; Tr; - td colspan => 2, sprintf '%d votes total, average %.2f%s', $count, $total/$count, + td colspan => 2, sprintf '%d vote%s total, average %.2f%s', $count, $count != 1 ? 's' : '', $total/$count, $type eq 'v' ? ' ('.$self->{votes}[sprintf '%.0f', $total/$count-1].')' : ''; end; end; for (reverse 0..$#$stats) { @@ -443,7 +443,14 @@ sub htmlVoteStats { } end; } + clearfloat; + if($type eq 'v') { + div; + h3 'Popularity'; + p sprintf 'Ranked #%d out of %d with a score of %.2f.', $obj->{ranking}, $self->{stats}{vn}, $obj->{c_popularity}*100; + end; + } end; } diff --git a/lib/VNDB/Util/FormHTML.pm b/lib/VNDB/Util/FormHTML.pm index ff23682d..75471830 100644 --- a/lib/VNDB/Util/FormHTML.pm +++ b/lib/VNDB/Util/FormHTML.pm @@ -49,7 +49,8 @@ my %formerr_exeptions = ( usrexists => 'Someone already has this username, please choose something else', mailexists => 'Someone already registered with that email address', noimage => 'Image must be in JPEG or PNG format', - toolarge => 'Image is too large, only 50kB allowed', + toolarge => 'Image is too large, only 500kB allowed', + oneaday => 'You can only register one account from the same IP within 24 hours', ); diff --git a/lib/VNDB/Util/LayoutHTML.pm b/lib/VNDB/Util/LayoutHTML.pm index a8773894..ccf2a9c6 100644 --- a/lib/VNDB/Util/LayoutHTML.pm +++ b/lib/VNDB/Util/LayoutHTML.pm @@ -12,8 +12,8 @@ our @EXPORT = qw|htmlHeader htmlFooter|; sub htmlHeader { # %options->{ title, js, noindex, search } my($self, %o) = @_; - my $skin = $self->authInfo->{skin} || $self->{skin_default}; - $skin = $self->{skin_default} if !-d "$VNDB::ROOT/static/s/$skin"; + my $skin = $self->reqParam('skin') || $self->authInfo->{skin} || $self->{skin_default}; + $skin = $self->{skin_default} if !$self->{skins}{$skin} || !-d "$VNDB::ROOT/static/s/$skin"; # heading html; @@ -27,12 +27,16 @@ sub htmlHeader { # %options->{ title, js, noindex, search } script type => 'text/javascript', src => $self->{url_static}.'/f/script.js?'.$self->{version}; # most browsers don't like a self-closing <script> tag... end; + if($self->authInfo->{customcss}) { + (my $css = $self->authInfo->{customcss}) =~ s/\n/ /g; + style type => 'text/css', $css; + } meta name => 'robots', content => 'noindex, follow', undef if $o{noindex}; end; body; div id => 'bgright', ' '; div id => 'header'; - h1 $self->debug ? (class => 'debug') : (); + h1; a href => '/', lc $self->{site_title}; end; end; @@ -118,14 +122,13 @@ sub _menu { [ threads => 'Threads' ], [ posts => 'Posts' ], ); - my $stats = $self->dbStats; div class => 'menubox'; h2 'Database Statistics'; div; dl; for (@stats) { dt $$_[1]; - dd $stats->{$$_[0]}; + dd $self->{stats}{$$_[0]}; } end; clearfloat; @@ -141,9 +144,19 @@ sub htmlFooter { txt "vndb $self->{version} | "; a href => '/d7', 'about us'; txt ' | '; - a href => 'mailto:contact@vndb.org', 'contact@vndb.org'; + a href => "mailto:$self->{admin_email}", $self->{admin_email}; + txt ' | '; + a href => $self->{source_url}, 'source'; end; end; # /div maincontent + if($self->debug) { + div id => 'debug'; + h2 'This is not VNDB!'; + txt 'The real VNDB is '; + a href => 'http://vndb.org/', 'here'; + txt '.'; + end; + } end; # /body end; # /html diff --git a/lib/VNDB/Util/Misc.pm b/lib/VNDB/Util/Misc.pm index 94cdcd1e..139eb571 100644 --- a/lib/VNDB/Util/Misc.pm +++ b/lib/VNDB/Util/Misc.pm @@ -6,7 +6,7 @@ use warnings; use Exporter 'import'; use Tie::ShareLite ':lock'; -our @EXPORT = qw|multiCmd|; +our @EXPORT = qw|multiCmd vnCacheUpdate|; # Sends a command to Multi @@ -26,3 +26,25 @@ sub multiCmd { $s->unlock(); $self->{_multiCmd} = []; } + + +# Recalculates the vn.c_* columns and regenerates the related relation graphs on any change +# Arguments: list of vids to be updated +sub vnCacheUpdate { + my($self, @vns) = @_; + + my $before = $self->dbVNGet(id => \@vns, order => 'v.id', what => 'relations'); + $self->dbVNCache(@vns); + my $after = $self->dbVNGet(id => \@vns, order => 'v.id'); + + my @upd = map { + @{$before->[$_]{relations}} && ( + $before->[$_]{c_released} != $after->[$_]{c_released} + || $before->[$_]{c_languages} ne $after->[$_]{c_languages} + ) ? $before->[$_]{id} : (); + } 0..$#$before; + $self->multiCmd('relgraph '.join(' ', @upd)) if @upd; +} + + +1; |