r58089 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r58088‎ | r58089 | r58090 >
Date:15:07, 24 October 2009
Author:werdna
Status:deferred
Tags:
Comment:
LiquidThreads: Start to a "Hot Topics" special page, which shows the most actively posted-to threads for the last 10k posts/7 days (whichever is shorter).
Modified paths:
  • /trunk/extensions/LiquidThreads/LiquidThreads.php (modified) (history)
  • /trunk/extensions/LiquidThreads/classes/HotTopics.php (added) (history)
  • /trunk/extensions/LiquidThreads/classes/View.php (modified) (history)
  • /trunk/extensions/LiquidThreads/i18n/Lqt.i18n.php (modified) (history)
  • /trunk/extensions/LiquidThreads/lqt.sql (modified) (history)
  • /trunk/extensions/LiquidThreads/pages/SpecialHotTopics.php (added) (history)

Diff [purge]

Index: trunk/extensions/LiquidThreads/i18n/Lqt.i18n.php
@@ -191,6 +191,7 @@
192192 'lqt-movethread' => 'Move',
193193 'lqt-menu-trigger' => 'More',
194194 'lqt-newmessages-from' => 'From $1',
 195+ 'lqt-hot-topics' => 'Hot Topics',
195196
196197 // Rights
197198 'right-lqt-split' => 'Split threads',
Index: trunk/extensions/LiquidThreads/LiquidThreads.php
@@ -98,6 +98,7 @@
9999 $wgSpecialPages['NewMessages'] = 'SpecialNewMessages';
100100 $wgSpecialPages['SplitThread'] = 'SpecialSplitThread';
101101 $wgSpecialPages['MergeThread'] = 'SpecialMergeThread';
 102+//$wgSpecialPages['HotTopics'] = 'SpecialHotTopics';
102103 $wgSpecialPageGroups['NewMessages'] = 'wiki';
103104
104105 // Classes
@@ -115,6 +116,7 @@
116117 $wgAutoloadClasses['SynchroniseThreadArticleDataJob'] = "$dir/classes/SynchroniseThreadArticleDataJob.php";
117118 $wgAutoloadClasses['ThreadHistoryPager'] = "$dir/classes/ThreadHistoryPager.php";
118119 $wgAutoloadClasses['TalkpageHistoryView'] = "$dir/pages/TalkpageHistoryView.php";
 120+$wgAutoloadClasses['LqtHotTopicsController'] = "$dir/classes/HotTopics.php";
119121
120122 // View classes
121123 $wgAutoloadClasses['TalkpageView'] = $dir . 'pages/TalkpageView.php';
@@ -135,6 +137,7 @@
136138 $wgAutoloadClasses['SpecialNewMessages'] = $dir . 'pages/SpecialNewMessages.php';
137139 $wgAutoloadClasses['SpecialSplitThread'] = $dir . 'pages/SpecialSplitThread.php';
138140 $wgAutoloadClasses['SpecialMergeThread'] = $dir . 'pages/SpecialMergeThread.php';
 141+$wgAutoloadClasses['SpecialHotTopics'] = "$dir/pages/SpecialHotTopics.php";
139142
140143 // Job queue
141144 $wgJobClasses['synchroniseThreadArticleData'] = 'SynchroniseThreadArticleDataJob';
Index: trunk/extensions/LiquidThreads/classes/View.php
@@ -40,6 +40,11 @@
4141 $this->user_colors = array();
4242 $this->user_color_index = 1;
4343 }
 44+
 45+ static function getView() {
 46+ global $wgOut, $wgArticle, $wgTitle, $wgUser, $wgRequest;
 47+ return new LqtView( $wgOut, $wgArticle, $wgTitle, $wgUser, $wgRequest );
 48+ }
4449
4550 function setHeaderLevel( $int ) {
4651 $this->headerLevel = $int;
Index: trunk/extensions/LiquidThreads/classes/HotTopics.php
@@ -0,0 +1,122 @@
 2+<?php
 3+
 4+/* Test
 5+print_r( LqtHotTopicsController::generateHotTopics() )
 6+*/
 7+class LqtHotTopicsController {
 8+ public static function generateHotTopics( $count = 10 ) {
 9+ $dbr = wfGetDB( DB_SLAVE );
 10+
 11+ $now = wfTimestamp( TS_UNIX, wfTimestampNow() );
 12+ $dateCutoff = $dbr->addQuotes( $dbr->timestamp( $now - (7*86400) ) );
 13+
 14+ $conds = array();
 15+// $conds[] ='th_timestamp>'.$dateCutoff;
 16+
 17+ // Grab the ID cutoff
 18+ $idCutoff = $dbr->selectField( 'thread_history', 'th_id',
 19+ array( 'th_timestamp>'.$dateCutoff ),
 20+ __METHOD__,
 21+ array( 'ORDER BY' => 'th_id desc',
 22+ 'OFFSET' => 10000 )
 23+ );
 24+
 25+ if ( $idCutoff ) {
 26+ $idCutoff = $dbr->addQuotes( $idCutoff );
 27+ $conds[] = 'th_id>'.$idCutoff;
 28+ }
 29+
 30+ $res = $dbr->select( array( 'thread_history' ),
 31+ array( 'th_id', 'th_thread', 'th_timestamp' ),
 32+ $conds,
 33+ __METHOD__,
 34+ array( 'LIMIT' => 10000 )
 35+ );
 36+
 37+ $threads = array();
 38+
 39+ foreach( $res as $row ) {
 40+ if ( isset( $threads[$row->th_thread] ) ) {
 41+ $thread =& $threads[$row->th_thread];
 42+ $thread['count']++;
 43+
 44+ if ( $thread['firstpost'] > $row->th_timestamp ) {
 45+ $thread['firstpost'] = $row->th_timestamp;
 46+ }
 47+
 48+ if ( $thread['lastpost'] < $row->th_timestamp ) {
 49+ $thread['lastpost'] = $row->th_timestamp;
 50+ }
 51+ unset($thread);
 52+ } else {
 53+ $thread = array();
 54+
 55+ $thread['id'] = $row->th_thread;
 56+ $thread['count'] = 1;
 57+ $thread['firstpost'] = $row->th_timestamp;
 58+ $thread['lastpost'] = $row->th_timestamp;
 59+
 60+ $threads[$row->th_thread] = $thread;
 61+ }
 62+ }
 63+
 64+ foreach( $threads as &$thread ) {
 65+ $thread['rate'] = self::getThreadPostRate( $thread );
 66+ }
 67+
 68+ // Filter out useless stuff
 69+ $threads = array_filter( $threads, array( __CLASS__, 'threadFilterCallback' ) );
 70+
 71+ // Sort
 72+ usort( $threads, array( __CLASS__, 'threadSortCallback' ) );
 73+
 74+ $threads = array_slice( $threads, 0, $count, true );
 75+
 76+ $outputThreads = array();
 77+
 78+ foreach( $threads as $thread ) {
 79+ $outputThreads[$thread['id']] = $thread['id'];
 80+ }
 81+
 82+ return $outputThreads;
 83+ }
 84+
 85+ public static function getHotThreads( $count = 10 ) {
 86+ $topics = array_values( self::generateHotTopics( $count ) );
 87+
 88+ return Threads::where( array( 'thread_id' => $topics ) );
 89+ }
 90+
 91+ public static function threadFilterCallback( $entry ) {
 92+ return $entry['count'] > 3;
 93+ }
 94+
 95+ public static function threadSortCallback( $a, $b ) {
 96+ $rateA = floatval($a['rate']);
 97+ $rateB = floatval($b['rate']);
 98+
 99+ if ( $rateA == $rateB ) {
 100+ $val = 0;
 101+ } elseif ( $rateA < $rateB ) {
 102+ $val = 1;
 103+ } elseif ( $rateA > $rateB ) {
 104+ $val = -1;
 105+ }
 106+
 107+ return $val;
 108+ }
 109+
 110+ public static function getThreadPostRate( $entry ) {
 111+ if ( $entry['count'] < 2 ) {
 112+ return 0;
 113+ }
 114+
 115+ $startTime = wfTimestamp( TS_UNIX, $entry['firstpost'] );
 116+ $endTime = wfTimestamp( TS_UNIX, wfTimestampNow() );
 117+ $duration = $endTime - $startTime;
 118+
 119+ // Get count over duration, multiply out to give posts per day
 120+
 121+ return ( $entry['count'] / $duration ) * 86400;
 122+ }
 123+}
Index: trunk/extensions/LiquidThreads/lqt.sql
@@ -80,6 +80,6 @@
8181
8282 PRIMARY KEY (th_id),
8383 KEY (th_thread,th_timestamp),
84 - KEY (th_timestamp),
 84+ KEY (th_timestamp,th_thread),
8585 KEY (th_user,th_user_text)
8686 ) /*$wgDBTableOptions*/;
Index: trunk/extensions/LiquidThreads/pages/SpecialHotTopics.php
@@ -0,0 +1,31 @@
 2+<?php
 3+
 4+class SpecialHotTopics extends SpecialPage {
 5+ function __construct() {
 6+ parent::__construct( 'HotTopics' );
 7+ }
 8+
 9+ function execute( $par ) {
 10+ global $wgOut;
 11+
 12+ wfLoadExtensionMessages( 'LiquidThreads' );
 13+
 14+ $this->setHeaders();
 15+
 16+ $wgOut->setPageTitle( wfMsg( 'lqt-hot-topics' ) );
 17+ $view = LqtView::getView();
 18+
 19+ LqtView::addJsAndCss();
 20+
 21+ // Get hot topics
 22+ $topics = LqtHotTopicsController::getHotThreads();
 23+
 24+ foreach( $topics as $thread ) {
 25+ $view->showThread( $thread );
 26+ }
 27+ }
 28+
 29+ function getPageName() {
 30+ return wfMsg( 'lqt-hot-topics' );
 31+ }
 32+}

Follow-up revisions

RevisionCommit summaryAuthorDate
r58091Follow-up r58089: Fix title casing, add new special page to the alias fileraymond18:58, 24 October 2009

Status & tagging log