svnno****@sourc*****
svnno****@sourc*****
2007年 10月 31日 (水) 14:54:45 JST
Revision: 234 http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi?root=slashdotjp&view=rev&rev=234 Author: tach Date: 2007-10-31 14:54:43 +0900 (Wed, 31 Oct 2007) Log Message: ----------- merged from 2.5.0.181 Modified Paths: -------------- slashjp/trunk/Slash/DB/MySQL/MySQL.pm slashjp/trunk/Slash/Slash.pm slashjp/trunk/Slash/Utility/Display/Display.pm slashjp/trunk/Slash/Utility/Environment/Environment.pm slashjp/trunk/debian/changelog slashjp/trunk/plugins/Admin/admin.pl slashjp/trunk/plugins/Admin/templates/editStory;admin;default slashjp/trunk/plugins/Admin/templates/static_files;admin;default slashjp/trunk/plugins/Ajax/htdocs/ajax.pl slashjp/trunk/plugins/Ajax/htdocs/images/admin.js slashjp/trunk/plugins/Ajax/htdocs/images/common.js slashjp/trunk/plugins/Ajax/htdocs/images/sectionprefs.js slashjp/trunk/plugins/Ajax/templates/data;ajax;default slashjp/trunk/plugins/Ajax/templates/prefs_d2;ajax;default slashjp/trunk/plugins/Blob/Blob.pm slashjp/trunk/plugins/Bookmark/templates/bookmarklink;misc;default slashjp/trunk/plugins/Bookmark/templates/bookmarktext;misc;default slashjp/trunk/plugins/Console/templates/display;console;default slashjp/trunk/plugins/FAQSlashdot/faq/UI.shtml slashjp/trunk/plugins/FireHose/FireHose.pm slashjp/trunk/plugins/FireHose/firehose.css slashjp/trunk/plugins/FireHose/mysql_schema.sql slashjp/trunk/plugins/FireHose/templates/data;firehose;default slashjp/trunk/plugins/FireHose/templates/firehose_options;misc;default slashjp/trunk/plugins/FireHose/templates/list;firehose;default slashjp/trunk/plugins/FireHose/templates/tagsfirehosedivadmin;misc;default slashjp/trunk/plugins/FireHose/templates/tagsfirehosedivtagbox;misc;default slashjp/trunk/plugins/Journal/Journal.pm slashjp/trunk/plugins/Messages/PLUGIN slashjp/trunk/plugins/Messages/messages.pl slashjp/trunk/plugins/Messages/templates/emailsponsor;messages;default slashjp/trunk/plugins/Remarks/Remarks.pm slashjp/trunk/plugins/Remarks/templates/display;remarks;default slashjp/trunk/plugins/Submit/submit.pl slashjp/trunk/plugins/Submit/templates/displayForm;submit;default slashjp/trunk/plugins/Tags/Clout/Describe.pm slashjp/trunk/plugins/Tags/Clout/Moderate.pm slashjp/trunk/plugins/Tags/Clout/Vote.pm slashjp/trunk/plugins/Tags/Clout.pm slashjp/trunk/plugins/Tags/Tags.pm slashjp/trunk/plugins/Tags/tags_updateclouts.pl slashjp/trunk/plugins/Tags/templates/tagsstorydivadmin;misc;default slashjp/trunk/plugins/Tags/templates/tagsstorydivtagbox;misc;default slashjp/trunk/plugins/Tags/templates/tagsurldivadmin;misc;default slashjp/trunk/plugins/Tags/templates/tagsurldivtagbox;misc;default slashjp/trunk/sql/mysql/defaults.sql slashjp/trunk/sql/mysql/slashschema_create.sql slashjp/trunk/sql/mysql/upgrades slashjp/trunk/themes/slashcode/htdocs/comments.css slashjp/trunk/themes/slashcode/htdocs/images/comments.js slashjp/trunk/themes/slashcode/htdocs/images/comments2.js slashjp/trunk/themes/slashcode/tasks/process_file_queue.pl slashjp/trunk/themes/slashcode/templates/dispComment;misc;default slashjp/trunk/themes/slashcode/templates/dispCommentDetails;misc;default slashjp/trunk/themes/slashcode/templates/dispStory;misc;default slashjp/trunk/themes/slashcode/templates/edit_comment;comments;default slashjp/trunk/themes/slashcode/templates/ipid_display;misc;default slashjp/trunk/themes/slashcode/templates/linkComment;misc;default slashjp/trunk/themes/slashcode/templates/messages;users;default slashjp/trunk/themes/slashcode/templates/printCommComments;misc;default slashjp/trunk/themes/slashcode/templates/printCommentsMain;misc;default slashjp/trunk/themes/slashcode/templates/userlogin_cover;misc;default -------------- next part -------------- Modified: slashjp/trunk/Slash/DB/MySQL/MySQL.pm =================================================================== --- slashjp/trunk/Slash/DB/MySQL/MySQL.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/Slash/DB/MySQL/MySQL.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -282,6 +282,8 @@ 'd2_comment_order' => sub { $_[0]->sqlSelectMany('code, name', 'code_param', "type='d2_comment_order'") }, + 'mediatypes' + => sub { $_[0]->sqlSelectMany('code, name', 'string_param', "type='mediatypes'")} ); ######################################################## @@ -6064,7 +6066,7 @@ if ($cid && $one_cid_only) { $where .= "AND cid=$cid"; - } elsif ($user->{hardthresh}) { + } elsif ($user->{hardthresh} && !$options->{discussion2}) { my $threshold_q = $self->sqlQuote($user->{threshold}); $where .= "AND (comments.points >= $threshold_q"; $where .= " OR comments.uid=$user->{uid}" unless $user->{is_anon}; Modified: slashjp/trunk/Slash/Slash.pm =================================================================== --- slashjp/trunk/Slash/Slash.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/Slash/Slash.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -105,6 +105,7 @@ cache_read_only => $cache_read_only, one_cid_only => $options->{one_cid_only}, }; + $gcfu_opt->{discussion2} = $discussion2; if ($options->{force_read_from_master}) { $thisComment = $slashdb->getCommentsForUser($discussion->{id}, $cid, $gcfu_opt); } else { @@ -1212,7 +1213,7 @@ } else { my $pntcmt = @{$comments->{$comment->{pid}}{kids}} > $user->{commentspill}; $return .= $const->{commentbegin} . - linkComment($comment, $pntcmt, 1); + linkComment($comment, $pntcmt, { date => 1 }); $finish_list++; } $return .= $const->{fullcommentend} if ($user->{mode} eq 'flat'); @@ -1220,9 +1221,12 @@ if ($comment->{kids} && ($user->{mode} ne 'parents' || $pid)) { if (my $str = displayThread($sid, $cid, $lvl+1, $comments, $const)) { $return .= $const->{cagebegin} if $cagedkids; - $return .= $const->{indentbegin} if $indent; + if ($indent && $const->{indentbegin}) { + (my $indentbegin = $const->{indentbegin}) =~ s/^(<[^<>]+)>$/$1 id="commtree_$cid">/; + $return .= $indentbegin; + } $return .= $str; - $return .= "$const->{indentend}" if $indent; + $return .= $const->{indentend} if $indent; $return .= $const->{cageend} if $cagedkids; } # in flat or nested mode, all visible kids will @@ -1350,7 +1354,7 @@ vislenify($comment); # create $comment->{ipid_vis} and {subnetid_vis} if ($constants->{comments_hardcoded}) { $comment->{ipid_display} = <<EOT; -<br>IPID: <a href="$constants->{real_rootdir}/users.pl?op=userinfo&userfield=$comment->{ipid}&fieldname=ipid">$comment->{ipid_vis}</a> SubnetID: +IPID: <a href="$constants->{real_rootdir}/users.pl?op=userinfo&userfield=$comment->{ipid}&fieldname=ipid">$comment->{ipid_vis}</a> SubnetID: <a href="$constants->{real_rootdir}/users.pl?op=userinfo&userfield=$comment->{subnetid}&fieldname=subnetid">$comment->{subnetid_vis}</a> EOT } else { @@ -1984,7 +1988,7 @@ $time_to_display = timeCalc($comment->{date}); unless ($user->{noscores}) { - $score_to_display .= "(Score:"; + $score_to_display .= " (Score:"; $score_to_display .= length($comment->{points}) ? $comment->{points} : "?"; if ($reasons && $comment->{reason}) { $score_to_display .= ", $reasons->{$comment->{reason}}{name}"; @@ -1998,7 +2002,7 @@ cid => $comment->{cid}, subject => "#$comment->{cid}", subject_only => 1, - }, 1); + }, 1, { noextra => 1 }); $comment_link_to_display = qq| ($link)|; } else { $comment_link_to_display = " "; @@ -2165,9 +2169,9 @@ my $classattr = $discussion2 ? qq[ class="$class"] : ''; my $head = $discussion2 ? <<EOT1 : <<EOT2; - <h4><a id="comment_link_$comment->{cid}" name="comment_link_$comment->{cid}" href="$gSkin->{rootdir}/comments.pl?sid=$comment->{sid}&cid=$comment->{cid}" onclick="return setFocusComment($comment->{cid})">$comment->{subject}</a></h4> + <h4><a id="comment_link_$comment->{cid}" name="comment_link_$comment->{cid}" href="$gSkin->{rootdir}/comments.pl?sid=$comment->{sid}&cid=$comment->{cid}" onclick="return setFocusComment($comment->{cid})">$comment->{subject}</a> EOT1 - <h4><a name="$comment->{cid}">$comment->{subject}</a></h4> + <h4><a name="$comment->{cid}">$comment->{subject}</a> EOT2 my $return = ''; @@ -2178,11 +2182,11 @@ EOT $return .= <<EOT if !$options->{noshow}; - <div class="commentTop"> + <div id="comment_top_$comment->{cid}" class="commentTop newcomment"> <div class="title"> $head $comment_links - <span id="comment_score_$comment->{cid}" class="score">$score_to_display</span> + <span id="comment_score_$comment->{cid}" class="score">$score_to_display</span></h4> </div> <div class="details"> by $user_nick_to_display$zoosphere_display Modified: slashjp/trunk/Slash/Utility/Display/Display.pm =================================================================== --- slashjp/trunk/Slash/Utility/Display/Display.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/Slash/Utility/Display/Display.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -1082,11 +1082,9 @@ =cut sub linkComment { - my($linkdata, $printcomment, $date) = @_; + my($linkdata, $printcomment, $options) = @_; my $constants = getCurrentStatic(); my $form = getCurrentForm(); - return _hard_linkComment(@_) if $constants->{comments_hardcoded}; - my $user = getCurrentUser(); my $adminflag = $user->{seclev} >= 10000 ? 1 : 0; @@ -1096,17 +1094,21 @@ $linkdata->{$_} = undef unless exists $linkdata->{$_}; } - $linkdata->{pid} = $linkdata->{original_pid} || $linkdata->{pid}; + $linkdata->{pid} = $linkdata->{original_pid} || $linkdata->{pid}; + $linkdata->{comment} = $printcomment; - slashDisplay('linkComment', { - %$linkdata, # defaults - adminflag => $adminflag, - date => $date, - threshold => defined($linkdata->{threshold}) ? $linkdata->{threshold} : $user->{threshold}, - commentsort => $user->{commentsort}, - mode => $user->{mode}, - comment => $printcomment, - }, { Return => 1, Nocomm => 1 }); + if (!$options->{noextra}) { + %$linkdata = (%$linkdata, + adminflag => $adminflag, + date => $options->{date}, + threshold => defined($linkdata->{threshold}) ? $linkdata->{threshold} : $user->{threshold}, + commentsort => $user->{commentsort}, + mode => $user->{mode}, + ); + } + + return _hard_linkComment($linkdata) if $constants->{comments_hardcoded}; + slashDisplay('linkComment', $linkdata, { Return => 1, Nocomm => 1 }); } #======================================================================== @@ -1315,7 +1317,7 @@ ######################################################## # this sucks, but it is here for now sub _hard_linkComment { - my($linkdata, $printcomment, $date) = @_; + my($linkdata) = @_; my $user = getCurrentUser(); my $constants = getCurrentStatic(); my $form = getCurrentForm(); @@ -1324,16 +1326,16 @@ my $subject = $linkdata->{subject}; my $display = qq|<a href="$gSkin->{rootdir}/comments.pl?sid=$linkdata->{sid}|; - $display .= "&op=$linkdata->{op}" if $linkdata->{op}; - $display .= "&threshold=" . (defined($linkdata->{threshold}) ? $linkdata->{threshold} : $user->{threshold}); - $display .= "&commentsort=$user->{commentsort}" if defined $user->{commentsort}; - $display .= "&mode=$user->{mode}" if defined $user->{mode}; + $display .= "&op=$linkdata->{op}" if defined($linkdata->{op}); + $display .= "&threshold=$linkdata->{threshold}" if defined($linkdata->{threshold}); + $display .= "&commentsort=$user->{commentsort}" if defined $linkdata->{commentsort}; + $display .= "&mode=$user->{mode}" if defined $linkdata->{mode}; $display .= "&no_d2=1" if $user->{state}{no_d2} || $linkdata->{no_d2}; $display .= "&startat=$linkdata->{startat}" if $linkdata->{startat}; $display .= "&tid=$user->{state}{tid}" if $constants->{tids_in_urls} && $user->{state}{tid}; - if ($printcomment) { + if ($linkdata->{comment}) { $display .= "&cid=$linkdata->{cid}"; } else { $display .= "&pid=" . ($linkdata->{original_pid} || $linkdata->{pid}); @@ -1347,7 +1349,7 @@ $display .= qq| (Score:$linkdata->{points})| if !$user->{noscores} && $linkdata->{points}; $display .= " " . timeCalc($linkdata->{date}) - if $date; + if $linkdata->{date}; } #$display .= "\n"; Modified: slashjp/trunk/Slash/Utility/Environment/Environment.pm =================================================================== --- slashjp/trunk/Slash/Utility/Environment/Environment.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/Slash/Utility/Environment/Environment.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -3200,7 +3200,7 @@ quoted but rather inserted directly into an SQL request. For example, if passed "123" (a user id), will return "CAST('123' AS UNSIGNED)" (same value, quoted); if passed "200123456789abcd" (an encoded IP), -will return "CAST(CONV('200123456789abcd', 16, 10) AS UNSIGNED" which +will return "CAST(CONV('200123456789abcd', 16, 10) AS UNSIGNED)" which can be used as an assignment into or test against a BIGINT column. For speed, does not do error-checking against the value passed in. Modified: slashjp/trunk/debian/changelog =================================================================== --- slashjp/trunk/debian/changelog 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/debian/changelog 2007-10-31 05:54:43 UTC (rev 234) @@ -1,3 +1,9 @@ +slash (2.5.0.181-0.1) unstable; urgency=low + + * New upstream CVS release + + -- Taku YASUI <tach****@osdn*****> Wed, 31 Oct 2007 14:53:58 +0900 + slash (2.5.0.180-0.1) unstable; urgency=low * New upstream cvs release @@ -18,7 +24,7 @@ * Fix warning: Use of uninitialized value at getDescForTopicsRendered() at plugins/Admin/admin.pl - -- Taku YASUI <tach****@osdn*****> Fri, 26 Oct 2007 15:06:24 +0900 + -- Taku YASUI <tach****@osdn*****> Wed, 31 Oct 2007 14:53:53 +0900 slash (2.5.0.119-17) unstable; urgency=low Modified: slashjp/trunk/plugins/Admin/admin.pl =================================================================== --- slashjp/trunk/plugins/Admin/admin.pl 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Admin/admin.pl 2007-10-31 05:54:43 UTC (rev 234) @@ -1516,7 +1516,9 @@ } my $pending_file_count = 0; my $story_static_files = []; - if ($stoid) { + if ($stoid || $form->{sid}) { + my $story = $slashdb->getStory($form->{sid}); + $stoid ||= $story->{stoid}; $pending_file_count = $slashdb->numPendingFilesForStory($stoid); $story_static_files = $slashdb->getStaticFilesForStory($stoid); } slashDisplay('editStory', { @@ -1722,7 +1724,7 @@ [$val, $_] } @story_nexuses; - my $remove = qq{[<a href="javascript:st_main_add_really(%d,'%s',0,1)" class="nex_remove">x</a>]}; + my $remove = qq{[<a href="#" onclick="st_main_add_really(%d,'%s',0,1); return false" class="nex_remove">x</a>]}; my $desc; if (!@sorted_nexuses) { @@ -2116,28 +2118,53 @@ my($stoid) = @_; my $form = getCurrentForm(); my $slashdb = getCurrentDB(); + my $constants = getCurrentStatic(); + + my $saveblob = $constants->{admin_use_blob_for_upload}; + my $savefile = !$saveblob; + if ($form->{media_file}) { my $upload = $form->{query_apache}->upload; if ($upload) { my $fh = $upload->fh; use File::Path; - mkpath("/tmp/upload", 0, 0755) unless -e "/tmp/upload"; $form->{media_file} =~ s|^.*?([^/:\\]+)$|$1|; my $name = $form->{media_file}; my $suffix; ($suffix) = $name =~ /(\.\w+)$/; - use File::Temp qw(:mktemp); - my ($ofh, $tmpname) = mkstemps("/tmp/upload/fileXXXXXX", $suffix ); + my($ofh, $tmpname, $blobdata); + mkpath("/tmp/upload", 0, 0755) unless -e "/tmp/upload"; + + if ($savefile) { + use File::Temp qw(:mktemp); + ($ofh, $tmpname) = mkstemps("/tmp/upload/fileXXXXXX", $suffix ); + } while (<$fh>) { - print $ofh $_; + print $ofh $_ if $savefile; + $blobdata .= $_ if $saveblob; } - close $ofh; + if ($savefile) { + close $ofh; + } + my $action = $form->{media_action} eq "thumbnails" ? "thumbnails" : "upload"; my $file = { stoid => $stoid, - file => "$tmpname", - action => "upload", + action => $action, }; + if ($savefile) { + $file->{file} = "$tmpname"; + } + if ($saveblob) { + my $data; + my $blob = getObject("Slash::Blob"); + $file->{blobid} = $blob->create({ + data => $blobdata, + seclev => 0, + filename => $name + }); + + } $slashdb->addFileToQueue($file); } } Modified: slashjp/trunk/plugins/Admin/templates/editStory;admin;default =================================================================== --- slashjp/trunk/plugins/Admin/templates/editStory;admin;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Admin/templates/editStory;admin;default 2007-10-31 05:54:43 UTC (rev 234) @@ -248,7 +248,7 @@ <label> Upload an image/audio file for this story [% IF pending_file_count %]([% pending_file_count %] awaiting processing)[% END %] </label> - <input type="file" name="media_file"> + <input type="file" name="media_file"><select name="media_action"><option value="upload">upload</option><option value="thumbnails">thumbnails</option></select> [% IF story_static_files && story_static_files.size %] <label> @@ -259,6 +259,8 @@ [% trunc_name = mfile.name %] [% trunc_name = trunc_name.replace('^\d+',"") %] <tr><td>[% mfile.sfid %]</td><td><a href="[% constants.imagedir %]/articles/[% sid %][% trunc_name %]" style="color:#fff">[% mfile.name %]</td><td>[% constants.imagedir %]/articles/[% sid %][% trunc_name %]</td> + <td>[% mfile.width %]</td> + <td>[% mfile.height %]</td> <td> [% IF mfile.filetype == "image" %] <img src="[% constants.imagedir %]/articles/[% sid %][% trunc_name %]" width="25%" height="25%"> Modified: slashjp/trunk/plugins/Admin/templates/static_files;admin;default =================================================================== --- slashjp/trunk/plugins/Admin/templates/static_files;admin;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Admin/templates/static_files;admin;default 2007-10-31 05:54:43 UTC (rev 234) @@ -17,9 +17,9 @@ [% FOREACH mfile = story_static_files %] [% trunc_name = mfile.name %] [% trunc_name = trunc_name.replace('^\d+',"") %] - <tr><td>[% mfile.sfid %]</td><td><a href="[% constants.imagedir %]/articles/[% sid %][% trunc_name %]">[% mfile.name %]</td><td>[% constants.imagedir %]/articles/[% sid %][% trunc_name %]</td></tr> + <tr><td>[% mfile.sfid %]</td><td><a href="[% constants.imagedir %]/articles/[% sid %][% trunc_name %]">[% mfile.name %]</td><td>[% constants.imagedir %]/articles/[% sid %][% trunc_name %]</td><td>[% mfile.width %]</td><td>[% mfile.height %]</td></tr> [% IF mfile.filetype == "image" %] - <tr><td colspan="3"><img src="[% constants.imagedir %]/articles/[% sid %][% trunc_name %]"></td></tr> + <tr><td colspan="t"><img src="[% constants.imagedir %]/articles/[% sid %][% trunc_name %]"></td></tr> [% END %] [% END %] Modified: slashjp/trunk/plugins/Ajax/htdocs/ajax.pl =================================================================== --- slashjp/trunk/plugins/Ajax/htdocs/ajax.pl 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Ajax/htdocs/ajax.pl 2007-10-31 05:54:43 UTC (rev 234) @@ -524,8 +524,10 @@ my $user_edits_table = { d2_comment_q => $params{'d2_comment_q'} || undef, d2_comment_order => $params{'d2_comment_order'} || undef, - emaildisplay => $params{'emaildisplay'} || undef, nosigs => ($params{'nosigs'} ? 1 : 0), + noscores => ($params{'noscores'} ? 1 : 0), + domaintags => ($params{'domaintags'} != 2 ? $params{'domaintags'} : undef), + m2_with_comm_mod => ($params{'m2_with_mod_on_comm'} ? 1 : undef), }; $slashdb->setUser($params{uid}, $user_edits_table); Modified: slashjp/trunk/plugins/Ajax/htdocs/images/admin.js =================================================================== --- slashjp/trunk/plugins/Ajax/htdocs/images/admin.js 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Ajax/htdocs/images/admin.js 2007-10-31 05:54:43 UTC (rev 234) @@ -87,7 +87,7 @@ var tagshistid = "taghist-" + id; var popupid = "taghistory-" + id; var title = "History "; - var buttons = createPopupButtons("<a href=\"#\">[?]</a></span><span><a href=\"javascript:closePopup('" + popupid + "-popup')\">[X]</a>"); + var buttons = createPopupButtons("<a href=\"#\" onclick=\"return false\">[?]</a></span><span><a href=\"#\" onclick=\"closePopup('" + popupid + "-popup'); return false\">[X]</a>"); title = title + buttons; createPopup(getXYForId(tagshistid), title, popupid); ajax_update(params, "taghistory-" + id + "-contents"); @@ -123,7 +123,7 @@ var params = []; params['op'] = 'remarks_config'; var title = "Remarks Config "; - var buttons = createPopupButtons('<a href="javascript:closePopup(\'remarksconfig-popup\', 1)">[X]</a>'); + var buttons = createPopupButtons('<a href="#" onclick="closePopup(\'remarksconfig-popup\', 1); return false">[X]</a>'); title = title + buttons; createPopup(getXYForId('remarks_table'), title + buttons, 'remarksconfig'); ajax_update(params, 'remarksconfig-contents'); Modified: slashjp/trunk/plugins/Ajax/htdocs/images/common.js =================================================================== --- slashjp/trunk/plugins/Ajax/htdocs/images/common.js 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Ajax/htdocs/images/common.js 2007-10-31 05:54:43 UTC (rev 234) @@ -1226,7 +1226,7 @@ function vendorStoryPopup() { id = vendor_popup_id; var title = "<a href='//intel.vendors.slashdot.org' onclick=\"javascript:urchinTracker('/vendor_intel-popup/intel_popup_title');\">Intel's Opinion Center</a>"; - var buttons = createPopupButtons("<a href=\"javascript:closePopup('vendorStory-" + id + "-popup')\">[X]</a>"); + var buttons = createPopupButtons("<a href=\"#\" onclick=\"closePopup('vendorStory-" + id + "-popup')\">[X]</a>"); title = title + buttons; var closepopup = function (e) { if (!e) var e = window.event; @@ -1251,7 +1251,7 @@ function vendorStoryPopup2() { id = vendor_popup_id; var title = "<a href='//intel.vendors.slashdot.org' onclick=\"javascript:urchinTracker('/vendor_intel-popup/intel_popup_title');\">Intel's Opinion Center</a>"; - var buttons = createPopupButtons("<a href=\"javascript:closePopup('vendorStory-" + id + "-popup')\">[X]</a>"); + var buttons = createPopupButtons("<a href=\"#\" onclick=\"closePopup('vendorStory-" + id + "-popup')\">[X]</a>"); title = title + buttons; var closepopup = function (e) { if (!e) var e = window.event; Modified: slashjp/trunk/plugins/Ajax/htdocs/images/sectionprefs.js =================================================================== --- slashjp/trunk/plugins/Ajax/htdocs/images/sectionprefs.js 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Ajax/htdocs/images/sectionprefs.js 2007-10-31 05:54:43 UTC (rev 234) @@ -1,8 +1,8 @@ // $Id$ function configSectionPopup() { - var title = "<a href=\"javascript:window.location.reload()\" style=\"color:#fff;\">Sectional Display Prefs</a> "; - var buttons = createPopupButtons("<a href=\"/faq/UI.shtml#ui500\">[?]</a>","<a href=\"javascript:window.location.reload()\">[X]</a>"); + var title = "<a href=\"#\" onclick=\"window.location.reload()\" style=\"color:#fff;\">Sectional Display Prefs</a> "; + var buttons = createPopupButtons("<a href=\"/faq/UI.shtml#ui500\">[?]</a>","<a href=\"#\" onclick=\"window.location.reload()\">[X]</a>"); title = title + buttons; createPopup(getXYForId('links-sections-title'), title, "sectionprefs", "", "Loading..."); Modified: slashjp/trunk/plugins/Ajax/templates/data;ajax;default =================================================================== --- slashjp/trunk/plugins/Ajax/templates/data;ajax;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Ajax/templates/data;ajax;default 2007-10-31 05:54:43 UTC (rev 234) @@ -16,5 +16,5 @@ [% SWITCH value %] [% CASE 'set_section_prefs_success_msg' %] - <a href="javascript:window.location.reload();" style="color:#fff;">Close</a> + <a href="#" onclick="window.location.reload(); return false" style="color:#fff;">Close</a> [% END %] Modified: slashjp/trunk/plugins/Ajax/templates/prefs_d2;ajax;default =================================================================== --- slashjp/trunk/plugins/Ajax/templates/prefs_d2;ajax;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Ajax/templates/prefs_d2;ajax;default 2007-10-31 05:54:43 UTC (rev 234) @@ -20,6 +20,8 @@ <table width="100%"> <tr> <td valign="middle"> + <p> + [% IF user.discussion2 && user.discussion2 == "slashdot" %] <blockquote> <div> @@ -36,31 +38,6 @@ </blockquote> [% END %] - <p><b>Email Display</b> - (currently - [%- IF !user.fakeemail; " not displayed"; - ELSE; ": <tt>"; user.fakeemail | strip_literal; "</tt>"; - END %])<br> - [% IF !user.emaildisplay.defined; - IF user.fakeemail %] - <i>(Your current email address was apparently set before - users' email addresses were forced to one of the below - choices. Please pick one and click Save.)</i><br> - [% END; - user.emaildisplay = 0; - END; - IF user.emaildisplay.defined; - emaildisplay.${user.emaildisplay} = constants.markup_checked_attribute; - END %] - <blockquote> - <div> - <input type="radio" name="emaildisplay" [% emaildisplay.0 %] value=0> Do not display an e-mail address.<br> - <input type="radio" name="emaildisplay" [% emaildisplay.1 %] value=1> Show your email address with random SPAM-armoring applied.<br> - [% PROCESS formNote note='This changes weekly' %] - <input type="radio" name="emaildisplay" [% emaildisplay.2 %] value=2> Show your real email address without cowering behind childish anonymity or obfuscation. - </div> - </blockquote> - [% s_check = ''; IF user.nosigs; s_check = constants.markup_checked_attribute; @@ -68,6 +45,37 @@ <label><input type="checkbox" name="nosigs"[% s_check %]> Disable Sigs</label> [% PROCESS formNote note='Strip sig quotes from comments' %] + + <p> + + [% n_check = ''; + IF user.noscores; + n_check = constants.markup_checked_attribute; + END %] + <label><input type="checkbox" name="noscores"[% n_check %]> Do Not Display Scores</label> + [% PROCESS formNote note="Hides score: They still <b>apply</b> you just don't see them." %] + + <p> + + [% UNLESS user.domaintags.defined; user.domaintags = 2; END %] + [% domaintags.${user.domaintags} = constants.markup_checked_attribute -%] + + <b>Display Link Domains?</b> (shows the actual domain of any link in brackets)<br> + <blockquote><div> + <input type="radio" name="domaintags" [% domaintags.0 %] value=0> Never show link domains<br> + <input type="radio" name="domaintags" [% domaintags.1 %] value=1> Show the links domain only in recommended situations<br> + <input type="radio" name="domaintags" [% domaintags.2 %] value=2> Always show link domains + </div></blockquote> + + <p> + + [% IF user.is_admin && constants.m2 %] + [% s_m2c_check = ''; + IF user.m2_with_comm_mod; + s_m2c_check = constants.markup_checked_attribute; + END %] + <label><input type="checkbox" name="m2_with_mod_on_comm" [% s_m2c_check %]> Show Metamoderation in Comment Moderation Listing</label> + [% END %] </td> </tr> </table> Modified: slashjp/trunk/plugins/Blob/Blob.pm =================================================================== --- slashjp/trunk/plugins/Blob/Blob.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Blob/Blob.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -182,6 +182,12 @@ return $self->sqlDelete($self->{_table}, "reference_count < 1"); } +sub get { + my($self, $sig) = @_; + my $sig_q = $self->sqlQuote($sig); + return $self->sqlSelectHashref($self->{_table}, "id = $sig_q"); +} + sub getFilesForStories { my($self) = @_; $self->sqlSelectAllHashrefArray('*', 'story_files', '', "ORDER BY stoid,description"); Modified: slashjp/trunk/plugins/Bookmark/templates/bookmarklink;misc;default =================================================================== --- slashjp/trunk/plugins/Bookmark/templates/bookmarklink;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Bookmark/templates/bookmarklink;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -14,9 +14,9 @@ 10000 __template__ [% IF user.state.ssl %] - <a href="javascript:location.href='[% constants.absolutedir_secure %]/bookmark.pl?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)">[% title || "Post to $constants.sitename" %]</a> + <a href="#" onclick="location.href='[% constants.absolutedir_secure %]/bookmark.pl?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title); return false">[% title || "Post to $constants.sitename" %]</a> [% ELSE %] - <a href="javascript:location.href='[% constants.absolutedir %]/bookmark.pl?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)">[% title || "Post to $constants.sitename" %]</a> + <a href="#" onclick="location.href='[% constants.absolutedir %]/bookmark.pl?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title); return false">[% title || "Post to $constants.sitename" %]</a> [% END %] __version__ $Id$ Modified: slashjp/trunk/plugins/Bookmark/templates/bookmarktext;misc;default =================================================================== --- slashjp/trunk/plugins/Bookmark/templates/bookmarktext;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Bookmark/templates/bookmarktext;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -24,9 +24,9 @@ <br> <p> <xmp><!-- Start [% constants.sitename %] It link --> -<a href="javascript:location.href='[% constants.absolutedir %]/bookmark.pl?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)"> +<a href="#" onclick="location.href='[% constants.absolutedir %]/bookmark.pl?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title); return false"> <img src="[% constants.absolutedir %]/favicon.ico" alt="[% constants.sitename %]" border="0" height="16" width="16"></a> -<a href="javascript:location.href='[% constants.absolutedir %]/bookmark.pl?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)">[% constants.sitename %] It! +<a href="#" onclick="location.href='[% constants.absolutedir %]/bookmark.pl?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title); return false">[% constants.sitename %] It! <!-- End [% constants.sitename %] It link --> </xmp></p> <br> Modified: slashjp/trunk/plugins/Console/templates/display;console;default =================================================================== --- slashjp/trunk/plugins/Console/templates/display;console;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Console/templates/display;console;default 2007-10-31 05:54:43 UTC (rev 234) @@ -34,7 +34,7 @@ [% firehosebox %] </div> [% ELSE %] - <a href="javascript:reloadBin()">Reload Bin</a> + <a href="#" onclick="reloadBin(); return false">Reload Bin</a> <br> <iframe name="submitframe" id="submitiframe" src="[% gSkin.rootdir %]/submit.pl?op=list&nowrapper=1&fromconsole=1" width="100%" height="800"></iframe> [% END %] Modified: slashjp/trunk/plugins/FAQSlashdot/faq/UI.shtml =================================================================== --- slashjp/trunk/plugins/FAQSlashdot/faq/UI.shtml 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/FAQSlashdot/faq/UI.shtml 2007-10-31 05:54:43 UTC (rev 234) @@ -19,13 +19,13 @@ <p>The policy for Slashboxes is as follows:</p> <ol> <li>The remote site gives us permission.</li> - <li>The remote site provides an RDF file for us to parse (here is <a href="/slashdot.rdf">our rdf</a> if you want an example).</li> + <li>The remote site provides an RSS feed URL.</li> <li>We decide that it belongs on Slashdot.</li> </ol> - <p>Currently the grand Slashbox poobah is <a href="mailto:pater****@slash*****">CowboyNeal</a>. Email him a URL to the RDF, as well as a technical contact, and we'll consider your addition to the roster.</p> + <p>Currently the Slashbox contact address is <a href="mailto:help****@slash*****"></a>. Email us your feed URL, as well as a technical contact, and we'll consider your addition to the roster.</p> <p><em><small> Answered by: <a href="mailto:malda****@slash*****">CmdrTaco</a><br> - Last Modified: 6/14/00 + Last Modified: 10/23/2007 </small></em></p> <h2><a name="ui200" id="ui200">What is this little [?] I see in stories?</a></h2> Modified: slashjp/trunk/plugins/FireHose/FireHose.pm =================================================================== --- slashjp/trunk/plugins/FireHose/FireHose.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/FireHose/FireHose.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -53,6 +53,7 @@ $data->{editorpop} ||= 0; $data->{body_length} = $data->{bodytext} ? length($data->{bodytext}) : 0; $data->{word_count} = countWords($data->{introtext}) + countWords($data->{bodytext}); + $data->{mediatype} ||= "none"; my $text_data = {}; $text_data->{title} = delete $data->{title}; @@ -265,6 +266,7 @@ email => $submission->{email}, emaildomain => $submission->{emaildomain}, name => $submission->{name}, + mediatype => $submission->{mediatype} }; $data->{url_id} = $submission->{url_id} if $submission->{url_id}; my $firehose_id = $self->createFireHose($data); @@ -1805,7 +1807,8 @@ $mode = "full"; } } - + + # number of firehose items per page in the normal case if ($mode eq "full") { if ($user->{is_admin}) { $options->{limit} = $pagesize eq "large" ? 50 : 25; @@ -1820,25 +1823,23 @@ } } - if ($constants->{smalldevices_ua_regex}) { + # the non-normal cases: a small device (e.g., iPhone) or an embedded use (e.g., Google Gadget) + my $force_smaller = $form->{embed}; + if (!$force_smaller && $constants->{smalldevices_ua_regex}) { my $smalldev_re = qr($constants->{smalldevices_ua_regex}); if ($ENV{HTTP_USER_AGENT} && $ENV{HTTP_USER_AGENT} =~ $smalldev_re) { - $options->{smalldevices} = 1; - if ($mode eq "full") { - $options->{limit} = $pagesize eq "large" ? 15 : 10; - } else { - $options->{limit} = $pagesize eq "large" ? 20 : 15; - } + $force_smaller = 1; } } - if ($form->{gadget}) { - $options->{smalldevices} = 1; - if ($mode eq "full") { - $options->{limit} = $pagesize eq "large" ? 15 : 10; - } else { - $options->{limit} = $pagesize eq "large" ? 20 : 15; - } + # ...for which we'll have fewer items per page + if ($force_smaller) { + $options->{smalldevices} = 1; + if ($mode eq "full") { + $options->{limit} = $pagesize eq "large" ? 15 : 10; + } else { + $options->{limit} = $pagesize eq "large" ? 20 : 15; + } } if ($user->{is_admin} && $form->{setusermode}) { @@ -2064,7 +2065,7 @@ } } - if ($form->{gadget}) { + if ($form->{embed}) { $#{@$user_tags_top} = 2; } Modified: slashjp/trunk/plugins/FireHose/firehose.css =================================================================== --- slashjp/trunk/plugins/FireHose/firehose.css 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/FireHose/firehose.css 2007-10-31 05:54:43 UTC (rev 234) @@ -447,3 +447,4 @@ .briefarticle .storylinks .comments a:hover {background:transparent url('//images.slashdot.org/sic_icons.png') no-repeat scroll 0px -1498px; color: #fff !important} .briefarticle .storylinks .comments.nocomment, .briefarticle .storylinks .comments span {display: none} +.embed .paginate, .embed .firemenu, .embed + .copyright { display: none; } Modified: slashjp/trunk/plugins/FireHose/mysql_schema.sql =================================================================== --- slashjp/trunk/plugins/FireHose/mysql_schema.sql 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/FireHose/mysql_schema.sql 2007-10-31 05:54:43 UTC (rev 234) @@ -35,6 +35,7 @@ body_length MEDIUMINT UNSIGNED DEFAULT 0 NOT NULL, word_count MEDIUMINT UNSIGNED DEFAULT 0 NOT NULL, srcname VARCHAR(32) NOT NULL DEFAULT '', + mediatype enum("text", "none", "video", "image", "audio") default "none" NOT NULL, PRIMARY KEY (id), UNIQUE globjid (globjid), KEY createtime (createtime), Modified: slashjp/trunk/plugins/FireHose/templates/data;firehose;default =================================================================== --- slashjp/trunk/plugins/FireHose/templates/data;firehose;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/FireHose/templates/data;firehose;default 2007-10-31 05:54:43 UTC (rev 234) @@ -89,7 +89,7 @@ [% IF user.state.firehose_page == "user" %] This user's Firehose page contains no [% IF form.page %]additional [% END %]entries; [% ELSE %] - No matches were found. You may want to try [% IF new_color %]<a href="?[% IF form.gadget %]gadget=1&[% END %]color=[% new_color | strip_paramattr %]">[% END %]lowering your color threshold[% IF new_color %] to [% new_color %][% END %][% IF new_color %]</a>[% END %] or [% IF options.duration != -1 %]<a href="?[% IF form.gadget %]gadget=1&[% END %]startdate=&duration=-1">[% END %]expanding your time window[% IF options.duration != -1 %]</a>[% END %] + No matches were found. You may want to try [% IF new_color %]<a href="?[% IF form.embed %]embed=1&[% END %]color=[% new_color | strip_paramattr %]">[% END %]lowering your color threshold[% IF new_color %] to [% new_color %][% END %][% IF new_color %]</a>[% END %] or [% IF options.duration != -1 %]<a href="?[% IF form.embed %]embed=1&[% END %]startdate=&duration=-1">[% END %]expanding your time window[% IF options.duration != -1 %]</a>[% END %] [% END %] </b> <br><br> Modified: slashjp/trunk/plugins/FireHose/templates/firehose_options;misc;default =================================================================== --- slashjp/trunk/plugins/FireHose/templates/firehose_options;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/FireHose/templates/firehose_options;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -25,8 +25,8 @@ paused = user.firehose_pause; END; %] - <span id="play"[% IF !paused %] class="hide"[% END %]><a href="javascript:firehose_play()" title="Currently paused">Play</a></span> - <span id="pause" [% IF paused %] class="hide"[% END %]><a href="javascript:firehose_pause()" title="Currently playing">Pause</a></span> + <span id="play"[% IF !paused %] class="hide"[% END %]><a href="#" onclick="firehose_play(); return false" title="Currently paused">Play</a></span> + <span id="pause" [% IF paused %] class="hide"[% END %]><a href="#" onclick="firehose_pause(); return false" title="Currently playing">Pause</a></span> [% IF options.orderby == "popularity" || options.orderby == "editorpop" || options.orderby == "popularity2" %] <span id="popularity"><a href="[% gSkin.rootdir %]/firehose.pl?orderby=createtime" title="Toggle sort popularity/time - Currently popularity" onclick="firehose_set_options('orderby','createtime'); return false;">Popularity</a></span> Modified: slashjp/trunk/plugins/FireHose/templates/list;firehose;default =================================================================== --- slashjp/trunk/plugins/FireHose/templates/list;firehose;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/FireHose/templates/list;firehose;default 2007-10-31 05:54:43 UTC (rev 234) @@ -47,7 +47,7 @@ <div id="slashboxes"> [% UNLESS user.noboxes %] - [% IF slashboxes && !(form.smalldevices || form.gadget || (constants.smalldevices_ua_regex && ua.match(constants.smalldevices_ua_regex))); + [% IF slashboxes && !(form.smalldevices || form.embed || (constants.smalldevices_ua_regex && ua.match(constants.smalldevices_ua_regex))); slashboxes %] [% END %] [% END %] Modified: slashjp/trunk/plugins/FireHose/templates/tagsfirehosedivadmin;misc;default =================================================================== --- slashjp/trunk/plugins/FireHose/templates/tagsfirehosedivadmin;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/FireHose/templates/tagsfirehosedivadmin;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -17,7 +17,7 @@ [% PROCESS ajax_reskey_tag reskey_label => 'admin_commands-reskey-' _ id, reskey_name => 'ajax_admin' %] <input type="text" id="tags_admin_commands-[% id %]" name="tags_admin_commands-[% id %]" value="" size=50 maxlength=60 onkeyup="handleEnter(event, adminTagsCommands, '[% id %]','firehose')"> -<input type="button" value="Admin" onclick="adminTagsCommands('[% id %]','firehose')" class="button"> <span id="taghist-[% id %]"><a href="javascript:tagsHistory('[% id %]','firehose')">[History]</a></span> +<input type="button" value="Admin" onclick="adminTagsCommands('[% id %]','firehose')" class="button"> <span id="taghist-[% id %]"><a href="#" onclick="tagsHistory('[% id %]','firehose'); return false">[History]</a></span> <div>[% tags_admin_str %]</div> Modified: slashjp/trunk/plugins/FireHose/templates/tagsfirehosedivtagbox;misc;default =================================================================== --- slashjp/trunk/plugins/FireHose/templates/tagsfirehosedivtagbox;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/FireHose/templates/tagsfirehosedivtagbox;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -17,22 +17,22 @@ <div id="tagbox-[% id %]" class="tags"> [% IF !form.skipvote && !options.nothumbs %] <span id="updown-[% item.id %]" class="vote[% IF vote == "down" %]ddown[% ELSIF vote == "up" %]dup[% END %]"> - <a href="javascript:firehose_up_down('[% item.id %]','+')" class="up" title="Vote this item up" + <a href="#" onclick="firehose_up_down('[% item.id %]','+'); return false" class="up" title="Vote this item up" [% IF !user.is_anon %]onMouseDown="show_nod_menu(this, '[% item.id %]')" onMouseOver="show_nod_menu(this, '[% item.id %]', 1200, 5200)" onMouseOut="dont_show_nodnix_menu()"[% END %]>+</a> - <a href="javascript:firehose_up_down('[% item.id %]','-')" class="down" title="Vote this item down" + <a href="#" onclick="firehose_up_down('[% item.id %]','-'); return false" class="down" title="Vote this item down" [% IF !user.is_anon %]onMouseDown="show_nix_menu(this, '[% item.id %]')" onMouseOver="show_nix_menu(this, '[% item.id %]', 1200, 5200)" onMouseOut="dont_show_nodnix_menu()"[% END %]>-</a> </span> [% END %] <div id="tagbox-title-[% id %]" class="tagtitleclosed"> - [% IF user.tags_canwrite_stories %]<a href="javascript:tagsToggleStoryDiv('[% id %]','[% user.is_admin && !user.firehose_usermode %]','firehose');">[% ELSIF user.is_anon %]<a href="javascript:show_login_box()">[% ELSE %]<a href="[% gSkin.rootdir %]/subscribe.pl">[% END %]<span class="tagsheader" id="toggletags-button-[% id %]">[+]</span></a> + [% IF user.tags_canwrite_stories %]<a href="#" onclick="tagsToggleStoryDiv('[% id %]','[% user.is_admin && !user.firehose_usermode %]','firehose'); return false">[% ELSIF user.is_anon %]<a href="#" onclick="show_login_box(); return false">[% ELSE %]<a href="[% gSkin.rootdir %]/subscribe.pl">[% END %]<span class="tagsheader" id="toggletags-button-[% id %]">[+]</span></a> <span id="tags-top-[% id %]"> [% PROCESS firehose_tags_top id = id tags_top = tags_top item = item -%] </span> [%- IF user.tags_canwrite_stories && (user.firehose_usermode || !user.is_admin) %] - <span class="tagname"><span class="tagmenu">, <a onClick="clickCompleter(this,'[% id %]','[% user.is_admin && !user.firehose_usermode %]','firehose', 4, {action1:completer_setTag})">feedback</a></span></span> + <span class="tagname"><span class="tagmenu">, <a onClick="clickCompleter(this,'[% id %]','[% user.is_admin && !user.firehose_usermode %]','firehose', 4, {action1:completer_setTag}); return false">feedback</a></span></span> [% END %] [% IF user.is_admin && !user.firehose_usermode -%] - <i>(<span id="note-form-[% item.id %]" class="hide"><input type="text" id="note-input-[% item.id %]" value="[% item.note | strip_attribute %]" size="30" onkeyup="handleEnter(event, firehose_save_note, '[% id %]')"> <input type="button" value="note" onclick="firehose_save_note('[% item.id %]')"></span><a id="note-text-[% item.id %]" onclick="firehose_open_note('[% item.id %]')">[% IF !item.note %]Note[% END %][% item.note | strip_literal %]</a>)</i> + <i>(<span id="note-form-[% item.id %]" class="hide"><input type="text" id="note-input-[% item.id %]" value="[% item.note | strip_attribute %]" size="30" onkeyup="handleEnter(event, firehose_save_note, '[% id %]')"> <input type="button" value="note" onclick="firehose_save_note('[% item.id %]')"></span><a id="note-text-[% item.id %]" href="#" onclick="firehose_open_note('[% item.id %]'); return false">[% IF !item.note %]Note[% END %][% item.note | strip_literal %]</a>)</i> [%- END -%] </div> @@ -49,7 +49,7 @@ <div id="tags-user-[% id %]" class="taguser"></div> [% IF user.is_admin && !user.firehose_usermode %] <div id="tags-admin-[% id %]" class="tagadmin"></div> - <div id="admin-extras-[% item.id %]" class="tagadminextra"><a href="javascript:firehose_get_admin_extras('[% item.id %]')">Get extras</a></div> + <div id="admin-extras-[% item.id %]" class="tagadminextra"><a href="#" onclick="firehose_get_admin_extras('[% item.id %]'); return false">Get extras</a></div> [% END %] <div id="toggletags-message-[% id %]" class="message"></div> </div> Modified: slashjp/trunk/plugins/Journal/Journal.pm =================================================================== --- slashjp/trunk/plugins/Journal/Journal.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Journal/Journal.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -60,10 +60,14 @@ $self->sqlUpdate('journals', \%j1, "id=$id") if keys %j1; $self->sqlUpdate('journals_text', \%j2, "id=$id") if $j2{article}; if ($constants->{plugin}{FireHose}) { - my $journal_item = $self->get($id); - my $firehose = getObject("Slash::FireHose"); - if ($journal_item->{promotetype} eq "publicize" || $journal_item->{promotetype} eq "publish") { - $firehose->createUpdateItemFromJournal($id); + my $reskey = getObject('Slash::ResKey'); + my $rkey = $reskey->key('submit', { nostate => 1 }); + if ($rkey && $rkey->createuse) { + my $journal_item = $self->get($id); + my $firehose = getObject("Slash::FireHose"); + if ($journal_item->{promotetype} eq "publicize" || $journal_item->{promotetype} eq "publish") { + $firehose->createUpdateItemFromJournal($id); + } } } } @@ -209,11 +213,15 @@ my $slashdb = getCurrentDB(); $slashdb->setUser($uid, { journal_last_entry_date => $date }); if ($constants->{plugin}{FireHose}) { - my $firehose = getObject("Slash::FireHose"); - my $journal = getObject("Slash::Journal"); - my $j = $journal->get($id); - if ($j->{promotetype} eq "publicize" || $j->{promotetype} eq "publish") { - $firehose->createItemFromJournal($id); + my $reskey = getObject('Slash::ResKey'); + my $rkey = $reskey->key('submit', { nostate => 1 }); + if ($rkey && $rkey->createuse) { + my $firehose = getObject("Slash::FireHose"); + my $journal = getObject("Slash::Journal"); + my $j = $journal->get($id); + if ($j->{promotetype} eq "publicize" || $j->{promotetype} eq "publish") { + $firehose->createItemFromJournal($id); + } } } Modified: slashjp/trunk/plugins/Messages/PLUGIN =================================================================== --- slashjp/trunk/plugins/Messages/PLUGIN 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Messages/PLUGIN 2007-10-31 05:54:43 UTC (rev 234) @@ -14,6 +14,7 @@ template=templates/data;messages;default template=templates/display;messages;default template=templates/display_prefs;messages;default +template=templates/edit;messages;default template=templates/emailsponsor;messages;default template=templates/footer;messages;default template=templates/html_invalid;misc;default Modified: slashjp/trunk/plugins/Messages/messages.pl =================================================================== --- slashjp/trunk/plugins/Messages/messages.pl 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Messages/messages.pl 2007-10-31 05:54:43 UTC (rev 234) @@ -65,70 +65,8 @@ sub edit_message { my($messages, $constants, $user, $form, $error_message) = @_; - my $template = <<EOT; -[% IF preview %] - [% PROCESS titlebar width="100%" title="Preview Message" %] - [% preview %] - <P> -[% END %] - [% PROCESS titlebar width="100%" title="Send Message" %] - -<!-- error message --> -[% IF error_message %][% error_message %][% END %] -<!-- end error message --> - -<FORM ACTION="[% gSkin.rootdir %]/messages.pl" METHOD="POST"> - <INPUT TYPE="HIDDEN" NAME="op" VALUE="send_message"> -[% IF form.formkey %] - <INPUT TYPE="HIDDEN" NAME="formkey" VALUE="[% form.formkey %]"> -[% END %] - - <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> - <TR><TD ALIGN="RIGHT">User: </TD> - <TD><INPUT TYPE="text" NAME="to_user" VALUE="[% form.to_user | strip_attribute %]" SIZE=50 MAXLENGTH=50></TD> - </TR> - <TR><TD ALIGN="RIGHT">Subject: </TD> - <TD><INPUT TYPE="text" NAME="postersubj" VALUE="[% form.postersubj | strip_attribute %]" SIZE=50 MAXLENGTH=50></TD> - </TR> - <TR> - <TD ALIGN="RIGHT" VALIGN="TOP">Comment</TD> - <TD><TEXTAREA WRAP="VIRTUAL" NAME="postercomment" ROWS="[% user.textarea_rows || constants.textarea_rows %]" COLS="[% user.textarea_cols || constants.textarea_cols %]">[% form.postercomment | strip_literal %]</TEXTAREA> - <BR>(Use the Preview Button! Check those URLs! - Don't forget the http://!) - </TD></TR> - - <TR><TD> </TD><TD> - - <INPUT TYPE="SUBMIT" NAME="which" VALUE="Submit"> - <INPUT TYPE="SUBMIT" NAME="which" VALUE="Preview"> - </TD></TR><TR> - <TD VALIGN="TOP" ALIGN="RIGHT">Allowed HTML: </TD><TD><FONT SIZE="1"> - <[% constants.approvedtags.join("> <") %]> - </FONT> - </TD></TR> -</TABLE> - -</FORM> - -<B>Important Stuff:</B> - <LI>Please try to keep posts on topic. - <LI>Try to reply to other people's comments instead of starting new threads. - <LI>Read other people's messages before posting your own to avoid simply duplicating - what has already been said. - <LI>Use a clear subject that describes what your message is about. - <LI>Offtopic, Inflammatory, Inappropriate, Illegal, or Offensive comments might be - moderated. (You can read everything, even moderated posts, by adjusting your - threshold on the User Preferences Page) - -<P><FONT SIZE="2">Problems regarding accounts or comment posting should be sent to - <A HREF="mailto:[% constants.adminmail | strip_attribute %]">[% constants.siteadmin_name %]</A>.</FONT> - - -EOT - header(getData('header')) or return; - # print edit screen - slashDisplay(\$template, {error_message => $error_message}); + slashDisplay('edit', { error_message => $error_message }); footer(); } Modified: slashjp/trunk/plugins/Messages/templates/emailsponsor;messages;default =================================================================== --- slashjp/trunk/plugins/Messages/templates/emailsponsor;messages;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Messages/templates/emailsponsor;messages;default 2007-10-31 05:54:43 UTC (rev 234) @@ -13,9 +13,6 @@ __instructions__ placeholder __template__ -Drink Slurm, in all four delectable varieties! Slurm Classic, -Royal Slurm, Super Slurm, and now New Slurm! -Slurm: It's so delicious, you'll eat it until you explode! __seclev__ 500 Modified: slashjp/trunk/plugins/Remarks/Remarks.pm =================================================================== --- slashjp/trunk/plugins/Remarks/Remarks.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Remarks/Remarks.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -180,7 +180,7 @@ } $slashdb->setUser($user->{uid}, $data) if keys %$data; # this should be in a template -- pudge - return "<a href=\"javascript:closePopup('remarksconfig-popup', 1)\">Close</a>"; + return "<a href=\"#\" onclick=\"closePopup('remarksconfig-popup', 1)\">Close</a>"; } 1; Modified: slashjp/trunk/plugins/Remarks/templates/display;remarks;default =================================================================== --- slashjp/trunk/plugins/Remarks/templates/display;remarks;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Remarks/templates/display;remarks;default 2007-10-31 05:54:43 UTC (rev 234) @@ -27,7 +27,7 @@ <table class="data" width="100%"> <tr class="data_head"> - <th colspan="5">Remarks (Last Updated [% Slash.timeCalc(Slash.db.getTime, '%Y-%m-%d %H:%M:%S %Z', 0) %]) <a href="javascript:remarks_popup()">[Config]</a></th> + <th colspan="5">Remarks (Last Updated [% Slash.timeCalc(Slash.db.getTime, '%Y-%m-%d %H:%M:%S %Z', 0) %]) <a href="#" onclick="remarks_popup(); return false">[Config]</a></th> </tr> [% i = 1; FOREACH remark = remarks_ref; i = i == 1 ? 2 : 1 %] <tr class="data_hl[% i %]"> <!-- remark.id:[% remark.rid %] --> Modified: slashjp/trunk/plugins/Submit/submit.pl =================================================================== --- slashjp/trunk/plugins/Submit/submit.pl 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Submit/submit.pl 2007-10-31 05:54:43 UTC (rev 234) @@ -628,7 +628,8 @@ story => $form->{story}, subj => $form->{subj}, tid => $form->{tid}, - primaryskid => $form->{primaryskid} + primaryskid => $form->{primaryskid}, + mediatype => $form->{mediatype}, }; $submission->{url_id} = $url_id if $url_id; Modified: slashjp/trunk/plugins/Submit/templates/displayForm;submit;default =================================================================== --- slashjp/trunk/plugins/Submit/templates/displayForm;submit;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Submit/templates/displayForm;submit;default 2007-10-31 05:54:43 UTC (rev 234) @@ -86,7 +86,7 @@ [% PROCESS formNote note => "Where users can contact you" %] [% IF constants.plugin.FireHose %] [% PROCESS formLabel value => "Url" %] - <input type="text" name="url" value="[% form.url | strip_attribute %]" size="50"> + <input type="text" name="url" value="[% form.url | strip_attribute %]" size="50"> Url type [% Slash.createSelect('mediiatype', Slash.db.getDescriptions('mediatypes'), { default => form.mediatype || "none" , return => 1 }) %] [% PROCESS formNote note => "Main url of submission (optional but if provided must be unique) " %] [% END %] [% PROCESS formLabel value => "Subject" %] Modified: slashjp/trunk/plugins/Tags/Clout/Describe.pm =================================================================== --- slashjp/trunk/plugins/Tags/Clout/Describe.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/Clout/Describe.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -1,22 +1,30 @@ package Slash::Clout::Describe; +use strict; +use warnings; +use Slash::Utility; +use base 'Slash::Clout'; + use vars qw($VERSION); ($VERSION) = ' $Revision: $ ' =~ /\$Revision:\s+([^\s]+)/; -# Hard-coded constants should be in the vars table. +sub init { + my($self) = @_; + $self->SUPER::init(@_); + # Hard-coded constants should be in the vars table. + # cumfrac is the cumulative fraction of how much weight is propagated + # for each matching tag. E.g. if $cumfrac is 0.5, the first match may + # propagate up to 50% of the weight, the second another 25%, the + # third another 12.5% etc. + $self->{cumfrac} = 0.5; + $self->{debug_uids} = { }; + $self->{debug} = 0; + 1; +} -# cumfrac is the cumulative fraction of how much weight is propagated -# for each matching tag. E.g. if $cumfrac is 0.5, the first match may -# propagate up to 50% of the weight, the second another 25%, the -# third another 12.5% etc. - -my $cumfrac = 0.5; -my $months_back = 4; -my $clid = 1; - sub getUserClout { - my($class, $user_stub) = @_; + my($self, $user_stub) = @_; my $clout = $user_stub->{karma} >= -3 ? log($user_stub->{karma}+10) : 0; @@ -31,15 +39,15 @@ } sub get_nextgen { - my($class, $g) = @_; - my $reader = getObject('Slash::DB', { db_type => 'reader' }); + my($self, $g) = @_; + my $tags_reader = getObject('Slash::Tags', { db_type => 'reader' }); # TODO: # - opposite tags. presumably a separate call that joins # sourcetag to newtag via tagnames AS sourcetn and # tagnames AS newtn and (sourcetn.tagname=CONCAT('!', newtn.tagname) # OR newtn.tagname=CONCAT('!', sourcetn.tagname)) # except that would be a double table scan I think, ugh - my $hr_ar = $reader->sqlSelectAllHashrefArray( + my $hr_ar = $tags_reader->sqlSelectAllHashrefArray( "sourcetag.uid AS sourcetag_uid, UNIX_TIMESTAMP(newtag.created_at)-UNIX_TIMESTAMP(sourcetag.created_at) AS timediff, @@ -59,11 +67,12 @@ "sourcetag.inactivated IS NULL AND sourcetag.globjid=globjs.globjid AND sourcetag.uid=sourcetpc.uid + AND sourcetpc.clid=$self->{clid} AND sourcetag.globjid=newtag.globjid AND sourcetag.tagnameid=newtag.tagnameid - AND sourcetag.tagnameid NOT IN ($nodid, $nixid) + AND sourcetag.tagnameid NOT IN ($self->{nodid}, $self->{nixid}) AND sourcetag.tagid != newtag.tagid - AND newtag.created_at >= DATE_SUB(NOW(), INTERVAL $months_back MONTH) + AND newtag.created_at >= DATE_SUB(NOW(), INTERVAL $self->{months_back} MONTH) AND newtag.uid=users_info.uid AND newtpc.uid IS NULL AND sourcetpc.gen=$g", @@ -72,38 +81,40 @@ } sub process_nextgen { - my($class, $hr_ar) = @_; + my($self, $hr_ar, $tags_peerclout) = @_; my %newtag_uid = ( map { $_->{newtag_uid}, 1 } @$hr_ar ); my @newtag_uid = sort { $a <=> $b } keys %newtag_uid; - my $insert_ar = [ ]; - my $i = 0; + my $insert_ar = [ ]; my $i = 0; for my $newtag_uid (@newtag_uid) { my @match = grep { $_->{newtag_uid} == $newtag_uid } @$hr_ar; my $match0 = $match[0]; my($clout, $created_at, $karma, $tokens) = ($match0->{clout}, $match0->{created_at_ut}, $match0->{karma}, $match0->{tokens}); - if ($debug_uids->{$newtag_uid}) { - slashdLog("$class starting uid=%d", $newtag_uid); + if ($self->{debug_uids}{$newtag_uid}) { + print STDERR ref($self) . sprintf(" starting uid=%d\n", $newtag_uid); + ++$self->{debug}; } - my $uid_mults = $class->get_mults(\@match); - my $weight = $class->get_total_weight($uid_mults, $clout, $created_at, $karma, $tokens); + my $uid_mults = $self->get_mults(\@match); + my $weight = $self->get_total_weight($tags_peerclout, $uid_mults, $clout, $created_at, $karma, $tokens); push @$insert_ar, { uid => $newtag_uid, clout => $weight, }; - if ($debug_uids->{$newtag_uid}) { - $debug = 1; - my $umd = Dumper($uid_mults); $umd =~ s/\s+/ /g; - slashdLog("$class uid=$newtag_uid weight=" - . $class->get_total_weight($uid_mults, $clout, $created_at, $karma, $tokens) - . " mults: $umd"); - $debug = 0; + if ($self->{debug}) { + use Data::Dumper; my $umd = Dumper($uid_mults); $umd =~ s/\s+/ /g; + print STDERR ref($self) . " uid=$newtag_uid weight=" + . $self->get_total_weight($tags_peerclout, $uid_mults, $clout, $created_at, $karma, $tokens) + . " mults: $umd\n"; } ++$i; - if ($i % 1000 == 0) { - slashdLog("$class process_nextgen processed $i (uid $newtag_uid, matched " . scalar(@match) . ")"); + if ($i % 100 == 0) { + print STDERR ref($self) . " process_nextgen processed $i (uid $newtag_uid, matched " . scalar(@match) . ")\n"; } + if ($self->{debug_uids}{$newtag_uid}) { + print STDERR ref($self) . sprintf(" done uid=%d\n", $newtag_uid); + --$self->{debug}; + } Time::HiRes::sleep(0.01); } @@ -111,10 +122,10 @@ } sub get_mults { - my($class, $match_ar) = @_; + my($self, $match_ar) = @_; my $uid_mults = { }; for my $hr (@$match_ar) { - my $mult = $class->get_mult($hr); + my $mult = $self->get_mult($hr); $uid_mults->{ $hr->{sourcetag_uid} } ||= [ ]; push @{$uid_mults->{ $hr->{sourcetag_uid} }}, $mult; } @@ -122,7 +133,7 @@ } sub get_mult { - my($class, $hr) = @_; + my($self, $hr) = @_; my $mult = 1.0; @@ -154,7 +165,8 @@ } # Tagging different types gets different mults. - my $type = $globjtypes->{ $hr->{gtid} }; + my $slashdb = getCurrentDB(); + my $type = $slashdb->getGlobjTypes()->{ $hr->{gtid} }; if ($type eq 'stories') { # full credit for matching tags on stories } elsif ($type eq 'comments') { @@ -169,13 +181,15 @@ sub get_total_weight { # uid_mults is a hashref where the key is the source uid and # the value is an arrayref of mults from that uid - my($class, $uid_mults, $clout, $created_at, $karma, $tokens) = @_; + my($self, $tags_peerclout, $uid_mults, $clout, $created_at, $karma, $tokens) = @_; return 0 if $clout == 0 || $tokens < -1000 || $karma < -10; my @total_mults = ( ); # Start by sorting source uids by decreasing weight. +my @nodef = grep { !defined $tags_peerclout->{$_} } keys %$uid_mults; $#nodef = 20 if $#nodef > 20; print STDERR "nodef: '@nodef', t_p:" . Dumper($tags_peerclout) if @nodef; +#print STDERR "uid_mults: " . Dumper($uid_mults); my @source_uids = sort { $tags_peerclout->{$b} <=> $tags_peerclout->{$a} } keys %$uid_mults; # If all source uids have weight 0, we know the answer quickly. @@ -190,20 +204,20 @@ # Get the mult for each of those for my $uid (@source_uids) { - my @balanced = $class->balance_weight_vectors(@{$uid_mults->{$uid}}); - push @total_mults, $tags_peerclout->{$uid} * $class->sum_weight_vectors(@balanced); - if ($debug) { - my @tm2 = map { sprintf("%.5g", @_) } @total_mults; - slashdLog("$class source_uid=$uid ($tags_peerclout->{$uid}) total_mults='@tm2'"); + my @balanced = $self->balance_weight_vectors(@{$uid_mults->{$uid}}); + push @total_mults, $tags_peerclout->{$uid} * $self->sum_weight_vectors(@balanced); + if ($self->{debug}) { + my @tm2 = map { sprintf("%.5g", $_) } @total_mults; + print STDERR ref($self) . " source_uid=$uid ($tags_peerclout->{$uid}) total_mults='@tm2'\n"; } } # Then (using the same decreasing-multipliers algorithm) get the # total of all those mults. - my @balanced = $class->balance_weight_vectors(@total_mults); - my $total = $class->sum_weight_vectors(@balanced); - if ($debug) { - slashdLog("$class total=$total"); + my @balanced = $self->balance_weight_vectors(@total_mults); + my $total = $self->sum_weight_vectors(@balanced); + if ($self->{debug}) { + print STDERR ref($self) . " total=$total\n"; } # If this user was created recently, less weight for them. @@ -245,11 +259,11 @@ } sub balance_weight_vectors { - my $class = shift @_; - my @w = sort { abs($b) <=> abs($a) || $b > $a } @_; + my($self, @w) = @_; + @w = sort { abs($b) <=> abs($a) || $b > $a } @w; my $w_pos_mag = 0; for my $w (@w) { $w_pos_mag += $w if $w > 0 }; my $w_neg_mag = 0; for my $w (@w) { $w_neg_mag -= $w if $w < 0 }; - return @_ if !$w_pos_mag && !$w_neg_mag; + return @w if !$w_pos_mag && !$w_neg_mag; my @ret; # Swinging more than 60-40% one way or the other reduces the @@ -263,57 +277,40 @@ @ret = map { $_ > 0 ? $_*$pos_reduc_factor : $_ } @_; } else { # No change. - @ret = @_; + @ret = @w; } - if ($debug) { + if ($self->{debug}) { my @w2 = map { sprintf("%5d", @_) } @w; $#w2 = 4 if $#w2 > 4; my @r2 = map { sprintf("%5d", @_) } @ret; $#r2 = 4 if $#r2 > 4; - slashdLog(sprintf("$class balance_weight_vectors pos=%.5g neg=%.5g from '%s' to '%s'", - $w_pos_mag, $w_neg_mag, join(' ', @w2), join(' ', @r2))); + print STDERR sprintf("%s balance_weight_vectors pos=%.5g neg=%.5g from '%s' to '%s'\n", + ref($self), $w_pos_mag, $w_neg_mag, join(' ', @w2), join(' ', @r2)); } return @ret; } sub sum_weight_vectors { - my $class = shift @_; - my @w = sort { abs($b) <=> abs($a) || $b > $a } @_; + my($self, @v) = @_; + my @w = sort { abs($b) <=> abs($a) || $b > $a } @v; $#w = 50 if $#w > 50; # beyond this point contributions are tiny my $weight = 0; my $cur_magnitude = 1; for my $w (@w) { - $cur_magnitude *= $cumfrac; + $cur_magnitude *= $self->{cumfrac}; $weight += $cur_magnitude * $w; } $weight = 0 if $weight < 0; - if ($debug) { - slashdLog("sum_weight_vectors weight='$weight' w='@w'"); + if ($self->{debug}) { + print STDERR ref($self) . " sum_weight_vectors weight='$weight' w='@w'\n"; } return $weight; } -sub insert_nextgen { - my($class, $g, $insert_ar) = @_; - my $slashdb = getCurrentDB(); - # XXX Should turn off autocommit for this loop - for my $hr (@$insert_ar) { - $hr->{gen} = $g; - $slashdb->sqlInsert('tags_peerclout', $hr); - } -} - -sub update_tags_peerclout { - my($class, $insert_ar) = @_; - for my $hr (@$insert_ar) { - $tags_peerclout->{ $hr->{uid} } = $hr->{clout}; - } -} - sub copy_peerclout_sql { - my($class) = @_; + my($self) = @_; my $slashdb = getCurrentDB(); $slashdb->sqlDo("SET AUTOCOMMIT=0"); - $slashdb->sqlDo("UPDATE users_clout SET clout=NULL WHERE clid='$clid'"); - $slashdb->sqlDo("INSERT INTO users_clout (clout_id, uid, clid, clout) SELECT NULL, uid, '$clid', clout FROM tags_peerclout WHERE clid='$clid'"); + $slashdb->sqlDo("UPDATE users_clout SET clout=NULL WHERE clid='$self->{clid}'"); + $slashdb->sqlDo("REPLACE INTO users_clout (clout_id, uid, clid, clout) SELECT NULL, uid, '$self->{clid}', clout FROM tags_peerclout WHERE clid='$self->{clid}'"); $slashdb->sqlDo("COMMIT"); $slashdb->sqlDo("SET AUTOCOMMIT=1"); } Modified: slashjp/trunk/plugins/Tags/Clout/Moderate.pm =================================================================== --- slashjp/trunk/plugins/Tags/Clout/Moderate.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/Clout/Moderate.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -1,13 +1,39 @@ package Slash::Clout::Moderate; +use strict; +use warnings; +use Slash::Utility; +use base 'Slash::Clout'; + use vars qw($VERSION); ($VERSION) = ' $Revision: $ ' =~ /\$Revision:\s+([^\s]+)/; +sub init { + 1; +} + sub getUserClout { my($class, $user_stub) = @_; return 1; } +sub get_nextgen { + return [ ]; +} + +sub process_nextgen { + return [ ]; +} + +sub insert_nextgen { +} + +sub update_tags_peerclout { +} + +sub copy_peerclout_sql { +} + 1; Modified: slashjp/trunk/plugins/Tags/Clout/Vote.pm =================================================================== --- slashjp/trunk/plugins/Tags/Clout/Vote.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/Clout/Vote.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -1,15 +1,30 @@ package Slash::Clout::Vote; +use strict; +use warnings; +use Slash::Utility; +use base 'Slash::Clout'; + use vars qw($VERSION); ($VERSION) = ' $Revision: $ ' =~ /\$Revision:\s+([^\s]+)/; -my $cumfrac = 0.45; -my $months_back = 4; -my $clid = 2; +sub init { + my($self) = @_; + $self->SUPER::init(@_); + # Hard-coded constants should be in the vars table. + # cumfrac is the cumulative fraction of how much weight is propagated + # for each matching tag. E.g. if $cumfrac is 0.5, the first match may + # propagate up to 50% of the weight, the second another 25%, the + # third another 12.5% etc. + $self->{cumfrac} = 0.45; + $self->{debug_uids} = { }; + $self->{debug} = 0; + 1; +} sub getUserClout { - my($class, $user_stub) = @_; + my($self, $user_stub) = @_; my $clout = $user_stub->{karma} >= -3 ? log($user_stub->{karma}+10)/50 : 0; @@ -23,12 +38,13 @@ } sub get_nextgen { - my($class, $g) = @_; + my($self, $g) = @_; # Populate the firehose_ogaspt table with the necessary data. my $constants = getCurrentStatic(); my $subscribe_future_secs = $constants->{subscribe_future_secs}; my $slashdb = getCurrentDB(); + my $globj_types = $slashdb->getGlobjTypes(); $slashdb->sqlDelete('firehose_ogaspt'); # First, the pub dates for submissions that made it into stories. $slashdb->sqlDo("INSERT INTO firehose_ogaspt @@ -37,9 +53,9 @@ WHERE stories.stoid=story_param.stoid AND in_trash='no' AND story_param.name='subid' - AND globjs.gtid='$globjtypes->{submissions}' + AND globjs.gtid='$globj_types->{submissions}' AND story_param.value=globjs.target_id - AND stories.time >= DATE_SUB(NOW(), INTERVAL $months_back MONTH) + AND stories.time >= DATE_SUB(NOW(), INTERVAL $self->{months_back} MONTH) GROUP BY globjid"); # Then, the same for journal entries that made it into stories. $slashdb->sqlDo("INSERT INTO firehose_ogaspt @@ -48,9 +64,9 @@ WHERE stories.stoid=story_param.stoid AND in_trash='no' AND story_param.name='journal_id' - AND globjs.gtid='$globjtypes->{journals}' + AND globjs.gtid='$globj_types->{journals}' AND story_param.value=globjs.target_id - AND stories.time >= DATE_SUB(NOW(), INTERVAL $months_back MONTH) + AND stories.time >= DATE_SUB(NOW(), INTERVAL $self->{months_back} MONTH) GROUP BY globjid"); # Those queries run in under a second each. But, wait a decent # amount of time for them to replicate. @@ -93,16 +109,20 @@ AND tagnames_similar.dest_tnid=newtag.tagnameid AND simil != 0 AND sourcetag.tagid != newtag.tagid - AND newtag.created_at >= DATE_SUB(NOW(), INTERVAL $months_back MONTH) + AND newtag.created_at >= DATE_SUB(NOW(), INTERVAL $self->{months_back} MONTH) AND newtag.uid=users_info.uid AND newtpc.uid IS NULL - AND sourcetpc.gen=$g", + AND sourcetpc.gen=$g + AND sourcetpc.clid=$self->{clid}", "ORDER BY newtag.tagid"); return $hr_ar; } sub process_nextgen { - my($class, $hr_ar) = @_; + my($self, $hr_ar, $tags_peerclout) = @_; + + $self->count_uid_nodnix($hr_ar); + my %newtag_uid = ( map { $_->{newtag_uid}, 1 } @$hr_ar ); my @newtag_uid = sort { $a <=> $b } keys %newtag_uid; my $user_nodnixes_min = 3; @@ -111,45 +131,49 @@ my $insert_ar = [ ]; my $i = 0; for my $newtag_uid (@newtag_uid) { - my $user_nodnixes_count = $nodc->{$newtag_uid} + $nixc->{$newtag_uid}; + ++$self->{debug} if $self->{debug_uids}{$newtag_uid}; + my $user_nodnixes_count = ($self->{nodc}{$newtag_uid} || 0) + ($self->{nixc}{$newtag_uid} || 0); my $user_nodnixes_mult = 0; if ($user_nodnixes_count >= $user_nodnixes_full) { $user_nodnixes_mult = 1; } elsif ($user_nodnixes_count >= $user_nodnixes_min) { - $user_nodnixes_mult = ($user_nodnixes_count+1-$user_nodnixes_min) - / ($user_nodnixes_full+1-$user_nodnixes_min); + $user_nodnixes_mult = ($user_nodnixes_count+1-$user_nodnixes_min) / + ($user_nodnixes_full+1-$user_nodnixes_min); } my $weight = 0; my(@match, $clout, $created_at, $karma, $tokens, $uid_mults); - if ($debug_uids->{$newtag_uid}) { - slashdLog("$class starting uid=%d user_nodnixes_mult=%.3f", $newtag_uid, $user_nodnixes_mult); + if ($self->{debug}) { + print STDERR ref($self) . sprintf(" starting uid=%d user_nodnixes_mult=%.3f\n", + $newtag_uid, $user_nodnixes_mult); } if ($user_nodnixes_mult > 0) { @match = grep { $_->{newtag_uid} == $newtag_uid } @$hr_ar; my $match0 = $match[0]; ($clout, $created_at, $karma, $tokens) = ($match0->{clout}, $match0->{created_at_ut}, $match0->{karma}, $match0->{tokens}); - $uid_mults = $class->get_mults(\@match); - $uid_mults->{'-1'} = $class->get_mult_timebeforepub(\@match); - $weight = $class->get_total_weight($uid_mults, $clout, $created_at, $karma, $tokens) + $uid_mults = $self->get_mults(\@match); + $uid_mults->{'-1'} = $self->get_mult_timebeforepub(\@match); + $weight = $self->get_total_weight($tags_peerclout, $uid_mults, + $clout, $created_at, $karma, $tokens, $newtag_uid) * $user_nodnixes_mult; } push @$insert_ar, { uid => $newtag_uid, clout => $weight, }; - if ($debug_uids->{$newtag_uid}) { - $debug = 1; - slashdLog(sprintf("$class uid=%d user_nodnixes_mult=%.3f weight=%.6f mults: %s", + if ($self->{debug}) { + use Data::Dumper; + print STDERR sprintf("%s uid=%d user_nodnixes_mult=%.3f weight=%.6f mults: %s\n", + ref($self), $newtag_uid, $user_nodnixes_mult, - $class->get_total_weight($uid_mults, $clout, $created_at, $karma, $tokens), - Dumper($uid_mults))); - $debug = 0; + $weight, + Dumper($uid_mults)); } ++$i; - if ($i % 1000 == 0) { - slashdLog("$class process_nextgen processed $i (uid $newtag_uid, matched " . scalar(@match) . ")"); + if ($i % 100 == 0) { + print STDERR scalar(localtime) . " " . ref($self) . " process_nextgen processed $i (uid $newtag_uid, matched " . scalar(@match) . ")\n"; } + --$self->{debug} if $self->{debug_uids}{$newtag_uid}; Time::HiRes::sleep(0.01); } @@ -157,13 +181,14 @@ } sub count_uid_nodnix { - my($class, $hr_ar) = @_; + my($self, $hr_ar) = @_; + $self->{nodc} = $self->{nixc} = { }; my %uid_needed = ( ); for my $hr (@$hr_ar) { my $uid = $hr->{sourcetag_uid}; - $uid_needed{$uid} = 1 if !exists $nodc->{$uid}; + $uid_needed{$uid} = 1 if !exists $self->{nodc}{$uid}; $uid = $hr->{newtag_uid}; - $uid_needed{$uid} = 1 if !exists $nodc->{$uid}; + $uid_needed{$uid} = 1 if !exists $self->{nodc}{$uid}; } return unless keys %uid_needed; my $reader = getObject('Slash::DB', { db_type => 'reader' }); @@ -175,29 +200,29 @@ my $nod_hr = $reader->sqlSelectAllKeyValue( 'uid, COUNT(*)', 'tags', - "tagnameid='$tagnameid->{nod}' AND uid IN ($uid_str) - AND created_at >= DATE_SUB(NOW(), INTERVAL $months_back MONTH)", + "tagnameid='$self->{nodid}' AND uid IN ($uid_str) + AND created_at >= DATE_SUB(NOW(), INTERVAL $self->{months_back} MONTH)", 'GROUP BY uid'); my $nix_hr = $reader->sqlSelectAllKeyValue( 'uid, COUNT(*)', 'tags', - "tagnameid='$tagnameid->{nix}' AND uid IN ($uid_str) - AND created_at >= DATE_SUB(NOW(), INTERVAL $months_back MONTH)", + "tagnameid='$self->{nixid}' AND uid IN ($uid_str) + AND created_at >= DATE_SUB(NOW(), INTERVAL $self->{months_back} MONTH)", 'GROUP BY uid'); for my $uid (@uid_chunk) { - $nodc->{$uid} = $nod_hr->{$uid} || 0; - $nixc->{$uid} = $nix_hr->{$uid} || 0; + $self->{nodc}{$uid} = $nod_hr->{$uid} || 0; + $self->{nixc}{$uid} = $nix_hr->{$uid} || 0; } sleep 1 if @uids_needed; } } sub get_mults { - my($class, $match_ar) = @_; + my($self, $match_ar) = @_; my $uid_mults = { }; for my $hr (@$match_ar) { - my $mult = $class->get_mult($hr); + my $mult = $self->get_mult($hr); $uid_mults->{ $hr->{sourcetag_uid} } ||= [ ]; push @{$uid_mults->{ $hr->{sourcetag_uid} }}, $mult; } @@ -205,15 +230,17 @@ } sub get_mult { - my($class, $hr) = @_; + my($self, $hr) = @_; my $mult = $hr->{simil}; + my $slashdb = getCurrentDB(); + my $globj_types = $slashdb->getGlobjTypes(); # If this tag-match is too old, it earns the new user less credit. my $older_tag = $hr->{sourcetag_created_at_ut}; $older_tag = $hr->{newtag_created_at_ut} if $hr->{newtag_created_at_ut} < $older_tag; my $tag_age = time - $older_tag; - my $max_days = $months_back * 30 + 1; + my $max_days = $self->{months_back} * 30 + 1; if ($tag_age < 7 * 86400) { # tags within the past week get full credit } elsif ($tag_age < 30 * 86400) { @@ -254,7 +281,7 @@ } # Tagging different types gets different mults. - my $type = $globjtypes->{ $hr->{gtid} }; + my $type = $globj_types->{ $hr->{gtid} }; if ($type eq 'comments') { # fair bit of credit for matching mods on comments # XXX may need to adjust this if it turns out that we're @@ -270,18 +297,18 @@ # rare choice (for either user) is considered more indicative. my($su, $nu) = ($hr->{sourcetag_uid}, $hr->{newtag_uid}); my($stn, $ntn) = ($hr->{sourcetag_tagnameid}, $hr->{newtag_tagnameid}); - my($nodid, $nixid) = ($stn == $tagnameid->{nod}, $stn == $tagnameid->{nix}); + my($nodid, $nixid) = ($stn == $self->{nodid}, $stn == $self->{nixid}); if ( ( $stn == $nodid || $stn == $nixid ) && ( $ntn == $nodid || $ntn == $nixid ) ) { my($su, $nu) = ($hr->{sourcetag_uid}, $hr->{newtag_uid}); - my $snod = $nodc->{$su}; - my $snix = $nixc->{$su}; - my $nnod = $nodc->{$nu}; - my $nnix = $nixc->{$nu}; + my $snod = $self->{nodc}{$su}; + my $snix = $self->{nixc}{$su}; + my $nnod = $self->{nodc}{$nu}; + my $nnix = $self->{nixc}{$nu}; my $sfrac = ($stn == $nodid ? $snix : $snod) / ($snod+$snix+1); my $nfrac = ($ntn == $nodid ? $nnix : $nnod) / ($nnod+$nnix+1); - if ($debug) { - slashdLog("$class get_mult su='$su' nu='$nu' sfrac='$sfrac' nfrac='$nfrac'"); + if ($self->{debug}) { + print STDERR ref($self) . " get_mult su='$su' nu='$nu' sfrac='$sfrac' nfrac='$nfrac'\n"; } $mult *= $sfrac * $nfrac; } @@ -290,15 +317,15 @@ } sub get_mult_timebeforepub { - my($class, $match_ar) = @_; + my($self, $match_ar) = @_; my $tbp_mults = [ ]; for my $hr (@$match_ar) { next unless $hr->{duration} == -1 && defined $hr->{timebeforepub}; my $nodnix; - if ($hr->{sourcetag_tagnameid} == $tagnameid->{nod}) { + if ($hr->{sourcetag_tagnameid} == $self->{nodid}) { $nodnix = 1; - } elsif ($hr->{sourcetag_tagnameid} == $tagnameid->{nix}) { + } elsif ($hr->{sourcetag_tagnameid} == $self->{nixid}) { $nodnix = -1; } else { next; @@ -324,7 +351,8 @@ sub get_total_weight { # uid_mults is a hashref where the key is the source uid and # the value is an arrayref of mults from that uid - my($class, $uid_mults, $clout, $created_at, $karma, $tokens) = @_; + my($self, $tags_peerclout, $uid_mults, + $clout, $created_at, $karma, $tokens, $new_uid) = @_; return 0 if $clout == 0 || $tokens < -1000 || $karma < -10; @@ -338,20 +366,22 @@ # correlations with other users' tags. if ($uid_mults->{'-1'}) { if (@{$uid_mults->{'-1'}}) { - my @balanced = $class->balance_weight_vectors(@{$uid_mults->{'-1'}}); + print STDERR "get_total_weight for $new_uid calling balance_weight_vectors -1\n" if $self->{debug}; + my @balanced = $self->balance_weight_vectors(@{$uid_mults->{'-1'}}); push @total_mults, $constants->{tags_tagpeerval_postingbonus} - * $class->sum_weight_vectors(@balanced); + * $self->sum_weight_vectors(@balanced); $any_weight = 1; } delete $uid_mults->{'-1'}; } # Start by sorting source uids by decreasing weight. - my @source_uids = sort { $tags_peerweight->{$b} <=> $tags_peerweight->{$a} } keys %$uid_mults; + my @nodef = grep { !defined $tags_peerclout->{$_} } keys %$uid_mults; $#nodef = 20 if $#nodef > 20; print STDERR "get_total_weight for $new_uid nodef: '@nodef'\n" if @nodef; + my @source_uids = sort { $tags_peerclout->{$b} <=> $tags_peerclout->{$a} } keys %$uid_mults; # If all source uids have weight 0, we know the answer quickly. for my $uid (@source_uids) { - if ($tags_peerweight->{$uid} > 0) { + if ($tags_peerclout->{$uid} > 0) { $any_weight = 1; last; } @@ -360,21 +390,21 @@ # Get the mult for each of those for my $uid (@source_uids) { - my @balanced = $class->balance_weight_vectors(@{$uid_mults->{$uid}}); - push @total_mults, $tags_peerweight->{$uid} * $class->sum_weight_vectors(@balanced); - if ($debug) { - my @t2 = map { sprintf("%.5g", @_) } @total_mults; - slashdLog("$class source_uid=$uid ($tags_peerweight->{$uid}) total_mults='@t2'"); + print STDERR "get_total_weight for $new_uid calling balance_weight_vectors $uid\n" if $self->{debug}; + my @balanced = $self->balance_weight_vectors(@{$uid_mults->{$uid}}); + push @total_mults, $tags_peerclout->{$uid} * $self->sum_weight_vectors(@balanced); + if ($self->{debug}) { + my @t2 = map { sprintf("%.6g", $_) } @total_mults; + print STDERR "get_total_weight for $new_uid source_uid=$uid (clout $tags_peerclout->{$uid}), total_mults='@t2' from balanced '@balanced'\n"; } } # Then (using the same decreasing-multipliers algorithm) get the # total of all those mults. - my @balanced = $class->balance_weight_vectors(@total_mults); - my $total = $class->sum_weight_vectors(@balanced); - if ($debug) { - slashdLog("$class total=$total"); - } + print STDERR "get_total_weight for $new_uid calling balance_weight_vectors total\n" if $self->{debug}; + my @balanced = $self->balance_weight_vectors(@total_mults); + my $total = $self->sum_weight_vectors(@balanced); + print STDERR ref($self) . " total=$total for uid $new_uid\n" if $self->{debug}; # If this user was created recently, less weight for them. my $daysold = (time - $created_at)/86400; @@ -415,11 +445,11 @@ } sub balance_weight_vectors { - my $class = shift @_; - my @w = sort { abs($b) <=> abs($a) || $b > $a } @_; + my($self, @w) = @_; + @w = sort { abs($b) <=> abs($a) || $b > $a } @w; my $w_pos_mag = 0; for my $w (@w) { $w_pos_mag += $w if $w > 0 }; my $w_neg_mag = 0; for my $w (@w) { $w_neg_mag -= $w if $w < 0 }; - return @_ if !$w_pos_mag && !$w_neg_mag; + return @w if !$w_pos_mag && !$w_neg_mag; my @ret; # Swinging more than 60-40% one way or the other reduces the @@ -427,63 +457,53 @@ my $total = $w_pos_mag+$w_neg_mag; if ($w_pos_mag > $total * 0.60) { my $neg_reduc_factor = $w_neg_mag*3/$w_pos_mag; - @ret = map { $_ < 0 ? $_*$neg_reduc_factor : $_ } @_; + @ret = map { $_ < 0 ? $_*$neg_reduc_factor : $_ } @w; } elsif ($w_neg_mag > $total * 0.60) { my $pos_reduc_factor = $w_pos_mag*3/$w_neg_mag; - @ret = map { $_ > 0 ? $_*$pos_reduc_factor : $_ } @_; + @ret = map { $_ > 0 ? $_*$pos_reduc_factor : $_ } @w; } else { # No change. - @ret = @_; + @ret = @w; } - if ($debug) { - my @w2 = map { sprintf("%5d", @_) } @w; $#w2 = 4 if $#w2 > 4; - my @r2 = map { sprintf("%5d", @_) } @ret; $#r2 = 4 if $#r2 > 4; - slashdLog(sprintf("$class balance_weight_vectors pos=%.5g neg=%.5g from '%s' to '%s'", - $w_pos_mag, $w_neg_mag, join(' ', @w2), join(' ', @r2))); + if ($self->{debug} || $w_pos_mag > 10_000 || $w_neg_mag > 10_000) { + my @w2 = @w; $#w2 = 4 if $#w2 > 4; + my @r2 = @ret; $#r2 = 4 if $#r2 > 4; + print STDERR sprintf("%s balance_weight_vectors posmag=%0.5g negmag=%0.5g from '%s' to '%s'\n", + ref($self), $w_pos_mag, $w_neg_mag, join(' ', @w2), join(' ', @r2)); } return @ret; } sub sum_weight_vectors { - my $class = shift @_; - my @w = sort { abs($b) <=> abs($a) || $b > $a } @_; + my($self, @v) = @_; + my @w = sort { abs($b) <=> abs($a) || $b > $a } @v; $#w = 50 if $#w > 50; # beyond this point contributions are tiny my $weight = 0; my $cur_magnitude = 1; for my $w (@w) { - $cur_magnitude *= $cumfrac; + $cur_magnitude *= $self->{cumfrac}; $weight += $cur_magnitude * $w; } $weight = 0 if $weight < 0; - if ($debug) { - slashdLog("$class sum_weight_vectors weight='$weight' w='@w'"); + if ($self->{debug}) { + print STDERR ref($self) . " sum_weight_vectors weight='$weight' w='@w'\n"; } return $weight; } -sub insert_nextgen { - my($class, $g, $insert_ar) = @_; - my $slashdb = getCurrentDB(); - # XXX Should turn off autocommit for this loop - for my $hr (@$insert_ar) { - $hr->{gen} = $g; - $slashdb->sqlInsert('tags_peerclout', $hr); - } -} - sub update_tags_peerclout { - my($class, $insert_ar) = @_; + my($self, $insert_ar, $tags_peerclout) = @_; for my $hr (@$insert_ar) { $tags_peerclout->{ $hr->{uid} } = $hr->{clout}; } } -sub copy_peerweight_sql { - my($class) = $_; +sub copy_peerclout_sql { + my($self) = @_; my $slashdb = getCurrentDB(); $slashdb->sqlDo("SET AUTOCOMMIT=0"); - $slashdb->sqlDo("UPDATE users_clout SET clout=NULL WHERE clid='$clid'"); - $slashdb->sqlDo("INSERT INTO users_clout (clout_id, uid, clid, clout) SELECT NULL, uid, '$clid', clout FROM tags_peerclout WHERE clid='$clid'"); + $slashdb->sqlDo("UPDATE users_clout SET clout=NULL WHERE clid='$self->{clid}'"); + $slashdb->sqlDo("REPLACE INTO users_clout (clout_id, uid, clid, clout) SELECT NULL, uid, '$self->{clid}', clout FROM tags_peerclout WHERE clid='$self->{clid}'"); $slashdb->sqlDo("COMMIT"); $slashdb->sqlDo("SET AUTOCOMMIT=1"); } Modified: slashjp/trunk/plugins/Tags/Clout.pm =================================================================== --- slashjp/trunk/plugins/Tags/Clout.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/Clout.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -6,15 +6,39 @@ package Slash::Clout; use strict; +use warnings; use Slash; -use Slash::Clout::Describe; -use Slash::Clout::Vote; -use Slash::Clout::Moderate; +use Slash::Utility; +use Slash::Tags; +#use Slash::Clout::Describe; +#use Slash::Clout::Vote; +#use Slash::Clout::Moderate; +use base 'Slash::DB::Utility'; +use base 'Slash::DB'; + use vars qw($VERSION); ($VERSION) = ' $Revision: $ ' =~ /\$Revision:\s+([^\s]+)/; +sub init { + my($self) = @_; + + $self->{months_back} = 4; # default + my $slashdb = getCurrentDB(); + my $info = $slashdb->getCloutInfo(); + for my $clid (keys %$info) { + $self->{clid} = $clid if $info->{$clid}{class} eq ref($self); + } + warn "cannot find clid for $self" if !$self->{clid}; + + my $constants = getCurrentStatic(); + my $tags_reader = getObject('Slash::Tags', { db_type => 'reader' }); + $self->{nodid} = $tags_reader->getTagnameidCreate($constants->{tags_upvote_tagname} || 'nod'); + $self->{nixid} = $tags_reader->getTagnameidCreate($constants->{tags_downvote_tagname} || 'nix'); + 1; +} + #sub insert_nextgen { # my($g, $insert_ar) = @_; # my $slashdb = getCurrentDB(); Modified: slashjp/trunk/plugins/Tags/Tags.pm =================================================================== --- slashjp/trunk/plugins/Tags/Tags.pm 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/Tags.pm 2007-10-31 05:54:43 UTC (rev 234) @@ -26,8 +26,7 @@ my($class, $user) = @_; my $self = {}; - my $plugin = getCurrentStatic('plugin'); - return unless $plugin->{Tags}; + return undef unless $class->isInstalled(); bless($self, $class); $self->{virtual_user} = $user; @@ -36,6 +35,12 @@ return $self; } +sub isInstalled { + my($class) = @_; + my $constants = getCurrentStatic(); + return $constants->{plugin}{Tags} || 0; +} + ######################################################## # createTag's first argument is a hashref with four sets of @@ -617,7 +622,8 @@ # XXX this stub is good enough for now but we may # need the whole actual getUser() user at some # future time - $uid_clout_hr->{$uid} = $clout_info->{class}->getUserClout(\%user_stub); + my $clout = getObject($clout_info->{class}, { db_type => 'reader' }); + $uid_clout_hr->{$uid} = $clout->getUserClout(\%user_stub); } } Modified: slashjp/trunk/plugins/Tags/tags_updateclouts.pl =================================================================== --- slashjp/trunk/plugins/Tags/tags_updateclouts.pl 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/tags_updateclouts.pl 2007-10-31 05:54:43 UTC (rev 234) @@ -34,9 +34,12 @@ $globj_types = $slashdb->getGlobjTypes(); $clout_types = $slashdb->getCloutTypes(); $clout_info = $slashdb->getCloutInfo(); + my $total_inserts = 0; for my $clid (sort { $a <=> $b } grep { /^\d+$/ } keys %$clout_types) { my $class = $clout_info->{$clid}{class}; + my $clout = getObject($class); + next unless $clout; sleep 5; $tags_peerclout = $slashdb->sqlSelectAllKeyValue( 'uid, clout', @@ -49,21 +52,38 @@ while (1) { my $lastgen_count = $slashdb->sqlCount('tags_peerclout', "clid=$clid AND gen=$g"); + slashdLog("gen $g for $clout_types->{$clid}: $lastgen_count"); last unless $lastgen_count; - my $hr_ar = $class->get_nextgen($g); - slashdLog("$class gen $g produces " . scalar(@$hr_ar) . " rows"); - my $insert_ar = $class->process_nextgen($hr_ar); + my $hr_ar = $clout->get_nextgen($g); + slashdLog("$class gen $g produces " . scalar(defined($hr_ar) ? @$hr_ar : 0) . " rows"); + my $insert_ar = $clout->process_nextgen($hr_ar, $tags_peerclout); + slashdLog("$class gen $g insert_ar count: " . scalar(@$insert_ar)); + $total_inserts += scalar(@$insert_ar); ++$g; - for my $hr (@$insert_ar) { $hr->{clid} = $clid } - $class->insert_nextgen($g, $insert_ar); - $class->update_tags_peerclout($insert_ar); + my $total_rows = insert_nextgen($tags_peerclout, $clid, $g, $insert_ar); + slashdLog("$class inserted $total_rows rows"); sleep 5; } - $class->copy_peerclout_sql(); + $clout->copy_peerclout_sql(); } } + + return "$total_inserts inserts"; }; +sub insert_nextgen { + my($tags_peerclout, $clid, $gen, $insert_ar) = @_; + my $slashdb = getCurrentDB(); + my $rows = 0; + for my $hr (@$insert_ar) { + ($hr->{clid}, $hr->{gen}) = ($clid, $gen); +if (!$rows) { use Data::Dumper; my $hd = Dumper($hr); $hd =~ s/\s+/ /g; print STDERR "insert hr: $hd\n"; } + $rows += $slashdb->sqlInsert('tags_peerclout', $hr); + $tags_peerclout->{ $hr->{uid} } = $hr->{clout}; + } + return $rows; +} + 1; Modified: slashjp/trunk/plugins/Tags/templates/tagsstorydivadmin;misc;default =================================================================== --- slashjp/trunk/plugins/Tags/templates/tagsstorydivadmin;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/templates/tagsstorydivadmin;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -17,7 +17,7 @@ [% PROCESS ajax_reskey_tag reskey_label => 'admin_commands-reskey-' _ sidenc, reskey_name => 'ajax_admin' %] <input type="text" id="tags_admin_commands-[% sidenc %]" name="tags_admin_commands-[% sidenc %]" value="" size=50 maxlength=60 onkeyup="handleEnter(event, adminTagsCommands, '[% sidenc %]')"> -<input type="button" value="Admin" onclick="adminTagsCommands('[% sidenc %]','stories')" class="button"> <span id="taghist-[% sidenc %]"><a href="javascript:tagsHistory('[% sidenc %]','stories')">[History]</a></span> +<input type="button" value="Admin" onclick="adminTagsCommands('[% sidenc %]','stories')" class="button"> <span id="taghist-[% sidenc %]"><a href="#" onclick="tagsHistory('[% sidenc %]','stories'); return false">[History]</a></span> <div>[% tags_admin_str %]</div> Modified: slashjp/trunk/plugins/Tags/templates/tagsstorydivtagbox;misc;default =================================================================== --- slashjp/trunk/plugins/Tags/templates/tagsstorydivtagbox;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/templates/tagsstorydivtagbox;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -17,13 +17,13 @@ [% IF user.tags_canread_stories %] <div id="tagbox-[% sidenc %]" class="tags"> -<div id="tagbox-title-[% sidenc %]" class="tagtitleclosed"> [% IF user.tags_canwrite_stories %]<a href="javascript:tagsToggleStoryDiv('[% sidenc %]','[% user.is_admin %]');">[% ELSIF user.is_anon %]<a href="[% gSkin.rootdir %]/login.pl">[% ELSE %]<a href="[% gSkin.rootdir %]/subscribe.pl">[% END %]<span class="tagsheader" id="toggletags-button-[% sidenc %]">[+]</span></a> +<div id="tagbox-title-[% sidenc %]" class="tagtitleclosed"> [% IF user.tags_canwrite_stories %]<a href="#" onclick="tagsToggleStoryDiv('[% sidenc %]','[% user.is_admin %]'); return false">[% ELSIF user.is_anon %]<a href="[% gSkin.rootdir %]/login.pl">[% ELSE %]<a href="[% gSkin.rootdir %]/subscribe.pl">[% END %]<span class="tagsheader" id="toggletags-button-[% sidenc %]">[+]</span></a> [% IF tags_top.size %] [% FOR t = tags_top -%] <span class="tagname"><a href="/tags/[% t | strip_html %]">[% t | strip_html %]</a></span>[% IF !loop.last() || story.is_future %], [% END -%] [%- END %] [%- END %] -[%- IF user.tags_canwrite_stories && story.is_future %]<span class="tagmenu"><a onClick="clickCompleter(this, '[% sidenc %]','[% user.is_admin %]','stories', 4, {action1:completer_setTag})">feedback</a></span>[% END %] +[%- IF user.tags_canwrite_stories && story.is_future %]<span class="tagmenu"><a onClick="clickCompleter(this, '[% sidenc %]','[% user.is_admin %]','stories', 4, {action1:completer_setTag}); return false">feedback</a></span>[% END %] <i>(<a href="/faq/tags.shtml">tagging beta</a>)</i> </div> Modified: slashjp/trunk/plugins/Tags/templates/tagsurldivadmin;misc;default =================================================================== --- slashjp/trunk/plugins/Tags/templates/tagsurldivadmin;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/templates/tagsurldivadmin;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -17,7 +17,7 @@ [% PROCESS ajax_reskey_tag reskey_label => 'admin_commands-reskey-' _ id, reskey_name => 'ajax_admin' %] <input type="text" id="tags_admin_commands-[% id %]" name="tags_admin_commands-[% id %]" value="" size=50 maxlength=60> -<input type="button" value="Admin" onclick="adminTagsCommands('[% id %]','urls')" class="button"> <span id="taghist-[% id %]"><a href="javascript:tagsHistory('[% id %]','urls')">[History]</a></span> +<input type="button" value="Admin" onclick="adminTagsCommands('[% id %]','urls')" class="button"> <span id="taghist-[% id %]"><a href="#" onclick="tagsHistory('[% id %]','urls'); return false">[History]</a></span> <div>[% tags_admin_str %]</div> Modified: slashjp/trunk/plugins/Tags/templates/tagsurldivtagbox;misc;default =================================================================== --- slashjp/trunk/plugins/Tags/templates/tagsurldivtagbox;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/plugins/Tags/templates/tagsurldivtagbox;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -17,10 +17,10 @@ <div id="tagbox-[% url_id %]" class="tags"> -<div id="tagbox-title-[% url_id %]" class="tagtitleclosed"> [% IF user.tags_canwrite_stories %]<a href="javascript:tagsToggleStoryDiv('[% url_id %]','[% user.is_admin %]','urls');">[% ELSIF user.is_anon %]<a href="[% gSkin.rootdir %]/login.pl">[% ELSE %]<a href="[% gSkin.rootdir %]/subscribe.pl">[% END %]<span class="tagsheader" id="toggletags-button-[% url_id %]">[+]</span></a> +<div id="tagbox-title-[% url_id %]" class="tagtitleclosed"> [% IF user.tags_canwrite_stories %]<a href="#" onclick="tagsToggleStoryDiv('[% url_id %]','[% user.is_admin %]','urls'); return false">[% ELSIF user.is_anon %]<a href="[% gSkin.rootdir %]/login.pl">[% ELSE %]<a href="[% gSkin.rootdir %]/subscribe.pl">[% END %]<span class="tagsheader" id="toggletags-button-[% url_id %]">[+]</span></a> [% IF tags_top.size %] [% FOR t = tags_top -%] - <span class="tagname">[% IF user.tags_canwrite_stories %]<a href="javascript:tagsOpenAndEnter('[% url_id %]','[% t %]','[% user.is_admin %]','urls')">[% END %][% t | strip_html %][% IF user.tags_canwrite_stories %]</a>[% END %]</span>[% IF !loop.last() %], [% END -%] + <span class="tagname">[% IF user.tags_canwrite_stories %]<a href="#" onclick="tagsOpenAndEnter('[% url_id %]','[% t %]','[% user.is_admin %]','urls'); return false">[% END %][% t | strip_html %][% IF user.tags_canwrite_stories %]</a>[% END %]</span>[% IF !loop.last() %], [% END -%] [%- END %] [% END %] <i>(<a href="/faq/tags.shtml">tagging beta</a>)</i> @@ -32,7 +32,7 @@ [% IF tags_example.size %] <div>Examples: [% FOR t = tags_example -%] - <span class="tagname"><a href="javascript:tagsOpenAndEnter('[% url_id %]','[% t %]','[% user.is_admin %]','urls')">[% t | strip_html %]</a></span>[% IF !loop.last() %], [% END -%] + <span class="tagname"><a href="#" onclick="tagsOpenAndEnter('[% url_id %]','[% t %]','[% user.is_admin %]','urls'); return false">[% t | strip_html %]</a></span>[% IF !loop.last() %], [% END -%] [%- END %] </div> [% END %] Modified: slashjp/trunk/sql/mysql/defaults.sql =================================================================== --- slashjp/trunk/sql/mysql/defaults.sql 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/sql/mysql/defaults.sql 2007-10-31 05:54:43 UTC (rev 234) @@ -737,6 +737,7 @@ INSERT INTO vars (name, value, description) VALUES ('admin_story_lookahead_default', 365*86400, 'In the admin.pl storylist, how many seconds to look into the future for all stories by default (but see skins_admin_story_lookahead_mainpage)'); INSERT INTO vars (name, value, description) VALUES ('admin_story_lookahead_infinite', '0', 'In the admin.pl storylist, always show all future stories no matter how far in the future?'); INSERT INTO vars (name, value, description) VALUES ('admin_story_lookahead_mainpage', 72*3600, 'In the admin.pl storylist, how many seconds to look into the future for stories on the mainpage'); +INSERT INTO vars (name, value, description) VALUES ('admin_use_blob_for_upload', '1', 'Use blobs for fileuploading - 1 for yes, 0 for no or file-based uploading'); INSERT INTO vars (name, value, description) VALUES ('admin_warn_primaryskid', '', 'Warn admin if a story is saved with the following primaryskids (skids delimited by |)'); INSERT INTO vars (name, value, description) VALUES ('admin_timeout','30','time in minutes before idle admin session ends'); INSERT INTO vars (name, value, description) VALUES ('adminmail','admin****@examp*****','All admin mail goes here'); @@ -829,7 +830,7 @@ INSERT INTO vars (name, value, description) VALUES ('cur_performance_stats_lastid', '0', 'accesslogid to start searching at'); INSERT INTO vars (name, value, description) VALUES ('cur_performance_stats_weeks', '8', 'number of weeks back to compare current stats to'); INSERT INTO vars (name, value, description) VALUES ('currentqid',1,'The Current Question on the homepage pollbooth'); -INSERT INTO vars (name, value, description) VALUES ('cvs_tag_currentcode','T_2_5_0_180','The current cvs tag that the code was updated to - this does not affect site behavior but may be useful for your records'); +INSERT INTO vars (name, value, description) VALUES ('cvs_tag_currentcode','T_2_5_0_181','The current cvs tag that the code was updated to - this does not affect site behavior but may be useful for your records'); INSERT INTO vars (name, value, description) VALUES ('datadir','/usr/local/slash/www.example.com','What is the root of the install for Slash'); INSERT INTO vars (name, value, description) VALUES ('db_auto_increment_increment','1','If your master DB uses auto_increment_increment, i.e. multiple master replication, echo its value into this var'); INSERT INTO vars (name, value, description) VALUES ('dbsparklines_disp','0','Display dbsparklines in the currentAdminUsers box?'); Modified: slashjp/trunk/sql/mysql/slashschema_create.sql =================================================================== --- slashjp/trunk/sql/mysql/slashschema_create.sql 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/sql/mysql/slashschema_create.sql 2007-10-31 05:54:43 UTC (rev 234) @@ -520,6 +520,7 @@ fhid mediumint(8) unsigned default NULL, file varchar(255) default NULL, action enum('upload','thumbnails') default NULL, + blobid VARCHAR(32) DEFAULT "" NOT NULL, PRIMARY KEY (fqid) ) ENGINE=InnoDB; @@ -1073,6 +1074,8 @@ stoid mediumint unsigned NOT NULL, filetype ENUM("file", "image", "audio") not null default "file", name varchar(255) default '' NOT NULL, + width smallint unsigned not null default 0, + height smallint unsigned not null default 0, PRIMARY KEY (sfid), INDEX stoid(stoid) ) ENGINE=InnoDB; @@ -1114,6 +1117,7 @@ del tinyint DEFAULT '0' NOT NULL, weight float DEFAULT '0' NOT NULL, signature varchar(32) NOT NULL, + mediatype enum("text", "none", "video", "image", "audio") default "none" NOT NULL, PRIMARY KEY (subid), UNIQUE signature (signature), KEY emaildomain (emaildomain), Modified: slashjp/trunk/sql/mysql/upgrades =================================================================== --- slashjp/trunk/sql/mysql/upgrades 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/sql/mysql/upgrades 2007-10-31 05:54:43 UTC (rev 234) @@ -4877,8 +4877,6 @@ # 2007-09-26 UPDATE vars SET value = 'T_2_5_0_176' WHERE name = 'cvs_tag_currentcode'; -# PUDGE LAST UPDATED HERE - # For plugins/Tags UPDATE tagboxes SET clid=2 WHERE name='FirstMover'; @@ -4903,9 +4901,7 @@ # 2007-10-11 UPDATE vars SET value = 'T_2_5_0_179' WHERE name = 'cvs_tag_currentcode'; -# SLASHDOT LAST UPDATED HERE - # default prefs for new /. accounts INSERT INTO string_param (type, code, name) VALUES ('otherusersparam','discussion2','slashdot'); INSERT INTO string_param (type, code, name) VALUES ('otherusersparam','d2_comment_q','5'); # medium @@ -4943,5 +4939,32 @@ # 2007-10-16 UPDATE vars SET value = 'T_2_5_0_180' WHERE name = 'cvs_tag_currentcode'; +# SLASHDOT LAST UPDATED HERE + +INSERT INTO string_param (type, code, name) VALUES ('mediatypes','none','None'); +INSERT INTO string_param (type, code, name) VALUES ('mediatypes','video','Video'); +INSERT INTO string_param (type, code, name) VALUES ('mediatypes','image','Image'); +INSERT INTO string_param (type, code, name) VALUES ('mediatypes','audio','Audio'); +INSERT INTO string_param (type, code, name) VALUES ('mediatypes','text','Text'); + +ALTER TABLE submissions ADD COLUMN mediatype enum("none", "text", "video","image","audio") default "none" NOT NULL; + +# For plugins/FireHose +ALTER TABLE firehose ADD COLUMN mediatype enum("none", "text", "video","image","audio") default "none" NOT NULL; + +ALTER TABLE file_queue ADD COLUMN blobid VARCHAR(32) DEFAULT "" NOT NULL; +ALTER TABLE story_static_files ADD COLUMN width smallint unsigned not null default 0; +ALTER TABLE story_static_files ADD COLUMN height smallint unsigned not null default 0; + +INSERT INTO vars (name, value, description) VALUES ('admin_use_blob_for_upload', '1', 'Use blobs for fileuploading - 1 for yes, 0 for no or file-based uploading'); + +UPDATE string_param SET name = '9' WHERE type = 'otherusersparam' AND code = 'd2_comment_q'; # large + + +# 2007-10-25 +UPDATE vars SET value = 'T_2_5_0_181' WHERE name = 'cvs_tag_currentcode'; + # SLASHCODE/USEPERL LAST UPDATED HERE +# PUDGE LAST UPDATED HERE + Modified: slashjp/trunk/themes/slashcode/htdocs/comments.css =================================================================== --- slashjp/trunk/themes/slashcode/htdocs/comments.css 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/htdocs/comments.css 2007-10-31 05:54:43 UTC (rev 234) @@ -138,6 +138,16 @@ .hide { display: none } .show { display: inline } +.oldcomment { + opacity: .65; + filter: alpha(opacity=65); +} +.newcomment { +} +.currcomment { + opacity: .50; + filter: alpha(opacity=50); +} .comment > .hidden { display: none; Modified: slashjp/trunk/themes/slashcode/htdocs/images/comments.js =================================================================== --- slashjp/trunk/themes/slashcode/htdocs/images/comments.js 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/htdocs/images/comments.js 2007-10-31 05:54:43 UTC (rev 234) @@ -13,6 +13,8 @@ var update_comments = {}; var root_comments_hash = {}; var last_updated_comments = []; +var last_updated_comments_index = -1; +var current_cid = 0; var more_comments_num; var behaviors = { 'default': { ancestors: 'none', parent: 'none', children: 'none', descendants: 'none', siblings: 'none', sameauthor: 'none' }, @@ -64,6 +66,7 @@ } else if (viewmodevalue[mode] >= viewmodevalue['full']) { var cd = fetchEl('comment_otherdetails_' + cid); if (!cd.innerHTML) { + cd.innerHTML = '<br><b><big>Loading ...</big></b>'; fetch_comments.push(cid); fetch_comments_pieces[cid] = 1; doshort = 1; @@ -72,7 +75,7 @@ } if (doshort) setShortSubject(cid, mode, cl); - existingdiv.className = mode; + existingdiv.className = existingdiv.className.replace(/full|hidden|oneline/, mode); } if (placeholder) @@ -144,6 +147,13 @@ if ((alone && alone == 2) || (!alone && viewmodevalue[displaymode[abscid]] == viewmodevalue['full'])) cid = '-' + abscid; + if (abscid == cid) { // expanding == selecting + setCurrentComment(cid); + if (checkAdTimer(cid)) + adTimerInsert = cid; + } + + // this doesn't work // var statusdiv = $('comment_status_' + abscid); // statusdiv.innerHTML = 'Working ...'; @@ -152,22 +162,24 @@ // if (!user_is_admin) // XXX: for now, admins-only, for testing // mods = 1; - if (!alone && mods) { - if (mods == 1 || ((mods == 3) && (abscid == cid)) || ((mods == 4) && (abscid != cid))) { - shift_down = 0; - alt_down = 0; - } else if (mods == 2 || ((mods == 3) && (abscid != cid)) || ((mods == 4) && (abscid == cid))) { - shift_down = 1; - alt_down = 0; - } else if (mods == 5) { - shift_down = 1; - alt_down = 1; - } - } +// if (!alone && mods) { +// if (mods == 1 || ((mods == 3) && (abscid == cid)) || ((mods == 4) && (abscid != cid))) { +// shift_down = 0; +// alt_down = 0; +// } else if (mods == 2 || ((mods == 3) && (abscid != cid)) || ((mods == 4) && (abscid == cid))) { +// shift_down = 1; +// alt_down = 0; +// } else if (mods == 5) { +// shift_down = 1; +// alt_down = 1; +// } +// } +// +// if (shift_down && alt_down) +// alone = 1; +// +// resetModifiers(); - if (shift_down && alt_down) - alone = 1; - if (alone && alone == 1) { var thismode = abscid == cid ? 'full' : 'oneline'; updateDisplayMode(abscid, thismode, 1); @@ -177,8 +189,6 @@ updateCommentTree(abscid); finishCommentUpdates(); -// resetModifiers(); - // statusdiv.innerHTML = ''; if (!commentIsInWindow(abscid)) { @@ -270,7 +280,7 @@ else return kidhiddens + 1; } else if (kidhiddens) { - var kidstring = '<a href="javascript:revealKids(' + cid + ')">' + kidhiddens; + var kidstring = '<a href="#" onclick="revealKids(' + cid + '); return false">' + kidhiddens; if (kidhiddens == 1) { kidstring += ' hidden comment</a>'; } else { @@ -431,10 +441,12 @@ var parent = comments[pid]; parent['kids'].push(cid); - // XXX: not QUITE right, but works for now ... - // ideally this would stick in a previous </ul> - // rather than adding a new one -- pudge - tree.innerHTML = tree.innerHTML + '<ul>' + html + '</ul>'; + var commtree = $('commtree_' + pid); + if (commtree) { + commtree.innerHTML = commtree.innerHTML + html; + } else { + tree.innerHTML = tree.innerHTML + '<ul id="commtree_' + pid + '">' + html + '</ul>'; + } } } else { @@ -523,7 +535,7 @@ var comment = fetchEl('comment_' + cid); if (!comment) { return } - var defmode = comment.className; + var defmode = comment.className.match(/full|hidden|oneline/); if (!defmode) { return } futuredisplaymode[cid] = prehiddendisplaymode[cid] = displaymode[cid] = defmode; @@ -636,7 +648,7 @@ }).join(';'); } -function ajaxFetchComments(cids, option, thresh) { +function ajaxFetchComments(cids, option, thresh, highlight) { if (cids && !cids.length) return; @@ -645,6 +657,9 @@ var params = []; params['op'] = 'comments_fetch'; + + var newoldstuff = cids ? 0 : 1; + if (cids) { params['cids'] = cids; } else { @@ -689,7 +704,8 @@ } var update = response.update_data; - if (update && update.new_cids_order) { + var do_update = (update && update.new_cids_order) ? 1 : 0; + if (do_update) { var root; var pids = {}; for (var i = 0; i < update.new_cids_order.length; i++) { @@ -737,32 +753,39 @@ loadNamedElement('comment_sig_' + cids[i]); loadNamedElement('comment_otherdetails_' + cids[i]); loadNamedElement('comment_sub_' + cids[i]); + loadNamedElement('comment_top_' + cids[i]); } setShortSubject(cids[i]); } - if (update && update.new_cids_order) { - for (var i = 0; i < last_updated_comments.length; i++) { - var this_cid = last_updated_comments[i]; - var this_id = $('tree_' + this_cid); - if (this_id) - this_id.className = this_id.className.replace('newcomment', ''); + if (do_update) { + if (newoldstuff) { + for (var i = 0; i < last_updated_comments.length; i++) { + var this_cid = last_updated_comments[i]; + var this_id = fetchEl('comment_top_' + this_cid); + if (this_id) + this_id.className = this_id.className.replace(' newcomment', ' oldcomment'); + } + last_updated_comments = []; + last_updated_comments_index = -1; } - last_updated_comments = []; - + for (var i = 0; i < update.new_cids_order.length; i++) { var this_cid = update.new_cids_order[i]; - if (placeholder_no_update[this_cid]) - continue; - var mode = determineMode(this_cid); - updateDisplayMode(this_cid, mode, 1); - currents[displaymode[this_cid]]++; - updateComment(this_cid, mode); + if (!placeholder_no_update[this_cid]) { + var mode = determineMode(this_cid); + updateDisplayMode(this_cid, mode, 1); + currents[displaymode[this_cid]]++; + updateComment(this_cid, mode); + } - var this_id = $('tree_' + this_cid); - this_id.className = this_id.className + ' newcomment'; - last_updated_comments.push(this_cid); + var this_id = fetchEl('comment_top_' + this_cid); + if (this_id) { + this_id.className = this_id.className.replace(' oldcomment', ' newcomment'); + last_updated_comments.push(this_cid); + } } + // later we may need to find a known point and scroll // to it, but for now we don't want to do this -- pudge //if (!commentIsInWindow(update.new_cids_order[0])) { @@ -783,7 +806,25 @@ } updateHiddens(cids); + if (do_update && highlight && last_updated_comments.length) { + last_updated_comments_index = last_updated_comments_index + 1; + setFocusComment(last_updated_comments[0], 1); + } boxStatus(0); + + if (0 && adTimerInsert) { + var tree = $('tree_' + adTimerInsert); + if (tree) { + var commtree = $('commtree_' + adTimerInsert); + var html = '<li id="comment_ad_' + adTimerInsert + '" class="inlinead"> SLASHDOT AD! </li>'; + if (commtree) { + commtree.innerHTML = html + commtree.innerHTML; + } else { + tree.innerHTML = tree.innerHTML + '<ul id="commtree_' + adTimerInsert + '">' + html + '</ul>'; + } + } + adTimerInsert = 0; + } } }; @@ -977,6 +1018,23 @@ //window.onbeforeunload = function () { savePrefs() }; //window.onunload = function () { savePrefs() }; + var noshow_comments_hash = {}; + for (var i = 0; i < noshow_comments.length; i++) { noshow_comments_hash[noshow_comments[i]] = 1 } + for (var cid in comments) { + if (!noshow_comments_hash[cid]) + last_updated_comments.push(cid); + } + last_updated_comments = last_updated_comments.sort(function (a, b) { return (a - b) }); + + if (1 || user_is_admin) { + if (window.addEventListener) // DOM method for binding an event + window.addEventListener('keydown', keyHandler, false); + else if (window.attachEvent) // IE exclusive method for binding an event + window.attachEvent('onkeydown', keyHandler) + else if (document.getElementById) // support older modern browsers + document.body.onkeydown = keyHandler; + } + if (more_comments_num) updateMoreNum(more_comments_num); updateTotals(); @@ -1004,22 +1062,21 @@ alt_down = 0; } -function doModifiers () { - return; - var ev = window.event; +function doModifiers (e) { + e = e || window.event; shift_down = 0; alt_down = 0; - if (ev) { - if (ev.modifiers) { + if (e) { + if (e.modifiers) { if (e.modifiers & Event.SHIFT_MASK) shift_down = 1; if (e.modifiers & Event.ALT_MASK) alt_down = 1; } else { - if (ev.shiftKey) + if (e.shiftKey) shift_down = 1; - if (ev.altKey) + if (e.altKey) alt_down = 1; } } @@ -1541,9 +1598,124 @@ +var adTimerSecs; +var adTimerClicks; +var adTimerInsert; +var adTimerSecsMax = 10; +var adTimerClicksMax = 5; +var adTimerSeen = {}; +resetAdTimer(); +function checkAdTimer (cid) { + clickAdTimer(); + if (cid && adTimerSeen[cid]) + return 0; + + var ad = 0; + if (adTimerClicks >= adTimerClicksMax) + ad = 1; + else { + var secs = getSeconds() - adTimerSecs; + if (secs >= adTimerSecsMax) + ad = 1; + } + + if (!ad) + return 0; + + if (cid) + adTimerSeen[cid] = 1; + + resetAdTimer(); + return 1; +} + +function resetAdTimer () { + adTimerSecs = getSeconds(); + adTimerClicks = 0; +} + +function clickAdTimer () { + adTimerClicks = adTimerClicks + 1; +} + +function getSeconds () { + return new Date().getTime()/1000; +} + + +function setCurrentComment (cid) { + if (current_cid) { + var this_id = fetchEl('comment_top_' + current_cid); + if (this_id) { + this_id.className = this_id.className.replace(' newcomment', ' oldcomment'); + this_id.className = this_id.className.replace(' currcomment', ''); + } + } + + + var this_id = fetchEl('comment_top_' + cid); + if (this_id) { + this_id.className = this_id.className + ' currcomment'; + } + current_cid = cid; +} + + +function keyHandler(e) { + e = e || window.event; + + if (e) { + // don't handle for forms ... "type" should handle all our cases here + if (e.target && e.target.type) + return; + + var c = e.keyCode; + if (c) { + var key = String.fromCharCode(c); + if (key == 'J' || key == 'K' || key == 'W' || key == 'S') { + if (last_updated_comments.length) { + var i = last_updated_comments_index; + var l = last_updated_comments.length - 1; + var update = 0; + if (key == 'J' || key == 'S') { + update = 1; + if (i <= 0) + i = l; + else + i = i - 1; + } else if (key == 'K' || key == 'W') { + if (i >= l) { + update = 2; + ajaxFetchComments(0, 1, '', 1); + } else { + update = 1; + i = i + 1; + } + } + + if (update) { + doModifiers(e); + var this_shift_down = shift_down; + resetModifiers(); + if (this_shift_down && current_cid) { // if shift, collapse previously selected + setFocusComment('-' + current_cid, 1); + } + if (update == 1) { + last_updated_comments_index = i; + setFocusComment(last_updated_comments[i], 1); + } + } + } + } + } + } + +} + + function dummyComment(cid) { var html = '<li id="tree_--CID--" class="comment">\ <div id="comment_status_--CID--" class="commentstatus"></div>\ Modified: slashjp/trunk/themes/slashcode/htdocs/images/comments2.js =================================================================== --- slashjp/trunk/themes/slashcode/htdocs/images/comments2.js 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/htdocs/images/comments2.js 2007-10-31 05:54:43 UTC (rev 234) @@ -81,7 +81,7 @@ function renderCommentOneLine(cid) { var comment = comments[cid]; - var retval = flipLink(cid, 'oneline') + '<a href="javascript:setFocusComment('+cid+');">'; + var retval = flipLink(cid, 'oneline') + '<a href="#" onclick="setFocusComment('+cid+'); return false">'; retval = retval + comment['subject']+'</a> by '+comment['nickname']; @@ -92,7 +92,7 @@ function renderCommentFull(cid) { var comment = comments[cid]; - return '<div class="commentTop"> '+flipLink(cid,'full')+'<div class="title"><h4><a name="14620800">'+comment['subject']+'</a></h4> (Score: '+comment['points']+', XXXXX) </div> <div class="details"> by '+comment['nickname']+ ' on '+comment['date']+' (<a href="javascript:setFocusComment('+cid+');">'+cid+'</a>) </div></div> <div class="commentBody"> '+comment['comment']+' </div>'+ replyTo(cid); + return '<div class="commentTop"> '+flipLink(cid,'full')+'<div class="title"><h4><a name="14620800">'+comment['subject']+'</a></h4> (Score: '+comment['points']+', XXXXX) </div> <div class="details"> by '+comment['nickname']+ ' on '+comment['date']+' (<a href="#" onclick="setFocusComment('+cid+'); return false">'+cid+'</a>) </div></div> <div class="commentBody"> '+comment['comment']+' </div>'+ replyTo(cid); } function renderComment(cid, mode) { Modified: slashjp/trunk/themes/slashcode/tasks/process_file_queue.pl =================================================================== --- slashjp/trunk/themes/slashcode/tasks/process_file_queue.pl 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/tasks/process_file_queue.pl 2007-10-31 05:54:43 UTC (rev 234) @@ -7,6 +7,7 @@ use File::Path; use File::Temp; use File::Copy; +use Image::Size; use Slash::Constants ':slashd'; use strict; @@ -28,6 +29,9 @@ $file_queue_cmds = $slashdb->getNextFileQueueCmds(); } $cmd = shift @$file_queue_cmds; + if ($cmd->{blobid}) { + $cmd->{file} = blobToFile($cmd->{blobid}); + } if($cmd) { handleFileCmd($cmd); } @@ -39,7 +43,36 @@ sub handleFileCmd { my($cmd) = @_; my $slashdb = getCurrentDB(); + if ($cmd->{action} eq "thumbnails") { + slashdLog("Creating Thumbnails"); + my $files = uploadFile($cmd); + $files ||= []; + slashdLog("after upload file"); + foreach (@$files) { + slashdLog("thumbing $_"); + my ($name, $path) = fileparse($_); + my ($namebase, $suffix) = $name =~ /^(\w+\-\d+)\.(\w+)$/; + my $thumb = $namebase . "-thumb." . $suffix; + my $thumbsm = $namebase . "-thumbsm." . $suffix; + slashdLog("About to create thumb $path$thumb"); + system("convert -size 100x100 $path$name $path$thumb"); + my $data = { + stoid => $cmd->{stoid}, + name => $thumb + }; + addStoryFile($data, $path); + + slashdLog("About to create thumbsms $path$thumbsm"); + system("convert -size 50x50 $path$name $path$thumbsm"); + $data = { + stoid => $cmd->{stoid}, + name => $thumbsm + }; + addStoryFile($data, $path); + } + } if ($cmd->{action} eq "upload") { + slashdLog("handling upload\n"); uploadFile($cmd); } $slashdb->deleteFileQueueCmd($cmd->{fqid}); @@ -78,37 +111,57 @@ return $file =~ /^\/tmp\/upload\/\w+(\.\w+)?$/ } +sub blobToFile { + my($blobid) = @_; + my $blob = getObject("Slash::Blob"); + my $blob_ref = $blob->get($blobid); + my($suffix) = $blob_ref->{filename} =~ /(\.\w+$)/; + $suffix = lc($suffix); + my ($ofh, $tmpname) = mkstemps("/tmp/upload/fileXXXXXX", $suffix ); + print $ofh $blob_ref->{data}; + close $ofh; + return $tmpname; +} + sub uploadFile { my($cmd) = @_; my @suffixlist = (); my $slashdb = getCurrentDB(); my $story = $slashdb->getStory($cmd->{stoid}); + my @files; + + my $file = $cmd->{file}; + if ($story->{sid}) { my $destpath = getStoryFileDir($story->{sid}); makeFileDir($destpath); my ($prefix) = $story->{sid} =~ /^\d\d\/\d\d\/\d\d\/(\d+)$/; - my ($name,$path,$suffix) = fileparse($cmd->{file}, @ suffixlist); + my ($name,$path,$suffix) = fileparse($file, @ suffixlist); ($suffix) = $name =~ /(\.\w+)$/; - if (verifyFileLocation($cmd->{file})) { - my $destfile = copyFileToLocation($cmd->{file}, $destpath, $prefix); + if (verifyFileLocation($file)) { + my $destfile = copyFileToLocation($file, $destpath, $prefix); + push @files, $destfile if $destfile; my $name = fileparse($destfile); my $data = { stoid => $cmd->{stoid}, name => $name }; - $slashdb->addStoryStaticFile($data); + addStoryFile($data, "$destpath/"); } + } if ($cmd->{fhid}) { my $destpath = getFireHoseFileDir($cmd->{fhid}); makeFileDir($destpath); my $numdir = sprintf("%09d",$cmd->{fhid}); my ($prefix) = $numdir =~ /\d\d\d\d\d\d(\d\d\d)/; - copyFileToLocation($cmd->{file}, $destpath, $prefix); + my $destfile = copyFileToLocation($cmd->{file}, $destpath, $prefix); + push @files, $destfile if $destfile; } + return \@files; } sub copyFileToLocation { @@ -139,4 +192,16 @@ return $ret_val; } +sub addStoryFile { + my($data, $path) = @_; + print "Add story file\n"; + my $slashdb = getCurrentDB(); + slashdLog("addStoryFile $path $data->{name}"); + if ($data->{name} =~ /\.(png|gif|jpg)$/i && $path) { + ($data->{width}, $data->{height}) = imgsize("$path$data->{name}"); + slashdLog("addStoryFile $data->{width} $data->{height}"); + } + $slashdb->addStoryStaticFile($data); +} + 1; Modified: slashjp/trunk/themes/slashcode/templates/dispComment;misc;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/dispComment;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/dispComment;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -27,14 +27,14 @@ <div id="comment_status_[% cid %]" class="commentstatus"></div> <div id="comment_[% cid %]"[% IF discussion2 %] class="[% class %]"[% END %]> [% END; IF !options.noshow %] - <div class="commentTop"> + <div id="comment_top_[% cid %]" class="commentTop newcomment"> <div class="title"> [% IF discussion2 %] - <h4><a id="comment_link_[% cid %]" name="comment_link_[% cid %]" href="[% gSkin.rootdir %]/comments.pl?sid=[% sid %]&cid=[% cid %]" onclick="return setFocusComment([% cid %])">[% subject %]</a></h4> + <h4><a id="comment_link_[% cid %]" name="comment_link_[% cid %]" href="[% gSkin.rootdir %]/comments.pl?sid=[% sid %]&cid=[% cid %]" onclick="return setFocusComment([% cid %])">[% subject %]</a> [% ELSE %] - <h4><a name="[% cid %]">[% subject %]</a></h4> + <h4><a name="[% cid %]">[% subject %]</a> [%- END %] - [% UNLESS user.noscores %]<span id="comment_score_[% cid %]" class="score">(Score:[% IF points.length; points; ELSE; "?"; END %][% IF reasons && reason %], [% reasons.$reason.name %][% END %])</span>[% END %] + [% UNLESS user.noscores %]<span id="comment_score_[% cid %]" class="score">(Score:[% IF points.length; points; ELSE; "?"; END %][% IF reasons && reason %], [% reasons.$reason.name %][% END %])</span>[% END %]</h4> </div> <div class="details"> by Modified: slashjp/trunk/themes/slashcode/templates/dispCommentDetails;misc;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/dispCommentDetails;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/dispCommentDetails;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -26,7 +26,7 @@ cid => cid, subject => ('#' _ cid), subject_only => 1 - }, 1) %])[% END %] + }, 1, { noextra => 1 }) %])[% END %] <small> [% has_homepage = homepage && homepage.length > 8; has_journal = journal_last_entry_date.search('[1-9]'); Modified: slashjp/trunk/themes/slashcode/templates/dispStory;misc;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/dispStory;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/dispStory;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -151,7 +151,7 @@ [% title %] [% IF story.commentcount %][% IF thresh_commentcount && story.commentcount != thresh_commentcount %][% thresh_commentcount %] of [% END %][% story.commentcount %] comment[% IF story.commentcount > 1 %]s[% END %][% END %] [% IF user.is_admin %]<a href="[% gSkin.rootdir -%]/admin.pl?op=edit&sid=[% story.sid %]">(edit)</a>[% END %] [% IF expandable %] - <a href="javascript:toggleIntro('intro-[% story.stoid %]','togglest-[% story.stoid %]');"><span id="togglest-[% story.stoid %]">[+]</span></a> + <a href="#" onclick="toggleIntro('intro-[% story.stoid %]','togglest-[% story.stoid %]'); return false"><span id="togglest-[% story.stoid %]">[+]</span></a> [% END %] [% IF getintro %] <div class="introhide" id="intro-[% story.stoid %]"> Modified: slashjp/trunk/themes/slashcode/templates/edit_comment;comments;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/edit_comment;comments;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/edit_comment;comments;default 2007-10-31 05:54:43 UTC (rev 234) @@ -237,7 +237,8 @@ </ul> <p> - Problems regarding accounts or comment posting should be sent to <a href="mailto:[% constants.adminmail | strip_attribute %]">[% constants.siteadmin_name %]</a>. + If you are having a problem with accounts or comment posting, + please <a href="mailto:[% constants.adminmail | strip_attribute %]">yell for help</a>. </p> </div> </fieldset> Modified: slashjp/trunk/themes/slashcode/templates/ipid_display;misc;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/ipid_display;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/ipid_display;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -12,7 +12,7 @@ __name__ ipid_display __template__ -<br>IPID: +IPID: <a href="[% gSkin.rootdir %]/users.pl?op=userinfo&userfield=[% data.ipid %]&fieldname=ipid">[% data.ipid_vis %]</a> SubnetID: Modified: slashjp/trunk/themes/slashcode/templates/linkComment;misc;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/linkComment;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/linkComment;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -22,8 +22,8 @@ __name__ linkComment __template__ -<a href="[% gSkin.rootdir %]/comments.pl?sid=[% sid - %]&op=[% op; +<a href="[% gSkin.rootdir %]/comments.pl?sid=[% sid; +IF op.defined %]&op=[% op; END; IF threshold.defined %]&threshold=[% threshold; END; IF commentsort.defined %]&commentsort=[% commentsort; END; IF mode.defined %]&mode=[% mode; END; Modified: slashjp/trunk/themes/slashcode/templates/messages;users;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/messages;users;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/messages;users;default 2007-10-31 05:54:43 UTC (rev 234) @@ -119,8 +119,8 @@ [% CASE 'tilded_box_msg' %] <p>If you find a problem, or have a reasonable suggestion - for new RSS feeds, please contact - <a href="mailto:[% constants.adminmail | strip_attribute %]">[% constants.siteadmin_name %]</a>. + for new RSS feeds, please + <a href="mailto:[% constants.adminmail | strip_attribute %]">email us</a>. <p></td></tr></table> @@ -130,11 +130,8 @@ [% realemail | strip_literal %]. If this is not correct, if you did not request this change, -please contact the site administrator immediately. +please email us immediately at [% constants.adminmail %]. - [% constants.siteadmin_name %] - [% constants.adminmail %] - [% CASE 'saveuseradmin_saveduser' %] Saved [% field %] [% id %] user settings Modified: slashjp/trunk/themes/slashcode/templates/printCommComments;misc;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/printCommComments;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/printCommComments;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -101,7 +101,17 @@ [% lcp %] [% IF discussion2 && !cid %] -<div class="prev-next"><a href="javascript:ajaxFetchComments(0,1)"><span id="more_comments_num_a" class="hide">Check for more</span></a></div> +<div class="prev-next"><a href="#" onclick="ajaxFetchComments(0,1); return false"><span id="more_comments_num_a" class="hide">Check for more</span></a> + [% UNLESS user.state.discussion_archived || user.state.discussion_future_nopost %] + | [% Slash.linkComment({ + sid => sid, + cid => cid, + op => 'reply', + subject => 'Reply', + subject_only => 1 + }); + END %] +</div> [% END %] [% IF moderate_form %] Modified: slashjp/trunk/themes/slashcode/templates/printCommentsMain;misc;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/printCommentsMain;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/printCommentsMain;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -178,9 +178,9 @@ [% END %] <span class="ccw-header-links"> [% IF discussion2 && !cid && !pid %] - <a href="javascript:ajaxFetchComments(0,1)"><span id="more_comments_num_b"></span> More</a> | + <a href="#" onclick="ajaxFetchComments(0,1); return false"><span id="more_comments_num_b"></span> More</a> | [% END; IF user.is_admin && user.d2prefs_debug %] - <a href="javascript:showPrefs('reading')">Prefs</a> + <a href="#" onclick="showPrefs('reading'); return false">Prefs</a> [% ELSIF user.is_anon; PROCESS userlogin_cover return_url = gSkin.rootdir _ '/comments.pl?sid=' _ sid %] @@ -191,14 +191,13 @@ [% UNLESS user.state.discussion_archived || user.state.discussion_future_nopost %] | [% Slash.linkComment({ - sid => sid, - cid => cid, - op => 'reply', - subject => 'Reply', + sid => sid, + cid => cid, + op => 'reply', + subject => 'Reply', subject_only => 1 - }); - %] - [% END %] + }) %] + [% END %] </span> <span title="Toggle window location" onclick="toggleDisplayOptions()" class="close">/</span> </h4> @@ -225,18 +224,18 @@ <div id="ccw-full-panel" class="ccw-panel"> <div class="ccw-panel-border"></div> <div id="ccw-full-count-pos" class="ccw-core-pos ccw-count-pos"> - <span id="ccw-full-count-text" class="ccw-count-text"><span id="currentFull"></span><span id="ccw-full-phrase"> Full</span></span> + <span id="ccw-full-count-text" class="ccw-count-text"><span id="currentFull"></span><span id="ccw-full-phrase"> Full</span></span> </div> </div> <div id="ccw-abbr-panel" class="ccw-panel"> <div class="ccw-panel-border"></div> <div id="ccw-abbr-count-pos" class="ccw-core-pos ccw-count-pos"> - <span id="ccw-abbr-count-text" class="ccw-count-text"><span id="currentOneline"></span><span id="ccw-abbr-phrase"> Abbreviated</span></span> + <span id="ccw-abbr-count-text" class="ccw-count-text"><span id="currentOneline"></span><span id="ccw-abbr-phrase"> Abbreviated</span></span> </div> </div> <div id="ccw-hide-panel" class="ccw-panel"> <div id="ccw-hide-count-pos" class="ccw-core-pos ccw-count-pos"> - <span id="ccw-hide-count-text" class="ccw-count-text"><span id="currentHidden"></span><span id="ccw-hide-phrase"> Hidden</span></span> + <span id="ccw-hide-count-text" class="ccw-count-text"><span id="currentHidden"></span><span id="ccw-hide-phrase"> Hidden</span></span> </div> </div> </div> @@ -264,9 +263,9 @@ </div> <div class="commentControlFooter"> [% IF discussion2 && !cid && !pid %] - <a href="javascript:ajaxFetchComments(0,1)"><span id="more_comments_num_c"></span> More</a> | + <a href="#" onclick="ajaxFetchComments(0,1); return false"><span id="more_comments_num_c"></span> More</a> | [% END; IF user.is_admin && user.d2prefs_debug %] - <a href="javascript:showPrefs('reading')">Prefs</a> + <a href="#" onclick="showPrefs('reading'); return false">Prefs</a> [% ELSIF user.is_anon; PROCESS userlogin_cover return_url = gSkin.rootdir _ '/comments.pl?sid=' _ sid %] @@ -276,13 +275,12 @@ [% END %] [% UNLESS user.state.discussion_archived || user.state.discussion_future_nopost %] | [% Slash.linkComment({ - sid => sid, - cid => cid, - op => 'reply', - subject => 'Reply', + sid => sid, + cid => cid, + op => 'reply', + subject => 'Reply', subject_only => 1 - }); - %] + }) %] [% END %] </div> <div id="commentControlBoxStatus" class="hide"><b>Loading ... Please wait.</b></div> @@ -296,7 +294,7 @@ <div id="modal_cover" style="display:none" onclick="hide_modal_box()"></div> <div id="modal_box" style="display:none"> <div class="generaltitle" > - <div class="title"><h3><div id="preference_title"></div> <a href="javascript:hide_modal_box()"><img src="[% gSkin.imagedir %]/images/sic_close.png" alt="Close"></a></h3></div> + <div class="title"><h3><div id="preference_title"></div> <a href="#" onclick="hide_modal_box(); return false"><img src="[% gSkin.imagedir %]/images/sic_close.png" alt="Close"></a></h3></div> </div> <div id="modal_box_content">Content here</div> </div> Modified: slashjp/trunk/themes/slashcode/templates/userlogin_cover;misc;default =================================================================== --- slashjp/trunk/themes/slashcode/templates/userlogin_cover;misc;default 2007-10-31 05:43:45 UTC (rev 233) +++ slashjp/trunk/themes/slashcode/templates/userlogin_cover;misc;default 2007-10-31 05:54:43 UTC (rev 234) @@ -18,7 +18,7 @@ <div id="login_box" style="display:none"> [% PROCESS titlebar title => "Please Log In to Continue" _ - '<a href="javascript:hide_login_box()" class="close" title="Close this box"><img id="login_box_close" src="' _ + '<a href="#" onclick="hide_login_box(); return false" class="close" title="Close this box"><img id="login_box_close" src="' _ gSkin.imagedir _ '/images/sic_close.png" alt="Close"></a>' %] <div id="login_box_content">