r89724 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r89723‎ | r89724 | r89725 >
Date:10:26, 8 June 2011
Author:nikerabbit
Status:resolved
Tags:
Comment:
Add some tag cloudiness to Special:SupportedLanguages
Also cache the results, doing it all from scratch takes about 8 seconds (3s for queries, 4s for formatting html)
Modified paths:
  • /trunk/extensions/Translate/Translate.php (modified) (history)
  • /trunk/extensions/Translate/js/ext.translate.special.supportedlanguages.css (added) (history)
  • /trunk/extensions/Translate/specials/SpecialSupportedLanguages.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Translate/js/ext.translate.special.supportedlanguages.css
@@ -0,0 +1,8 @@
 2+.mw-translate-spsl-translators {
 3+ line-height: 200%;
 4+}
 5+
 6+.mw-special-SupportedLanguages h2 {
 7+ font-weight: bold;
 8+ margin-top: 2em;
 9+}
\ No newline at end of file
Property changes on: trunk/extensions/Translate/js/ext.translate.special.supportedlanguages.css
___________________________________________________________________
Added: svn:eol-style
110 + native
Index: trunk/extensions/Translate/Translate.php
@@ -153,6 +153,10 @@
154154 'styles' => 'js/ext.translate.special.translate.css',
155155 ) + $resourcePaths;
156156
 157+$wgResourceModules['ext.translate.special.supportedlanguages'] = array(
 158+ 'styles' => 'js/ext.translate.special.supportedlanguages.css',
 159+) + $resourcePaths;
 160+
157161 $wgResourceModules['jquery.autoresize'] = array(
158162 'scripts' => 'js/jquery.autoresize.js',
159163 ) + $resourcePaths;
Index: trunk/extensions/Translate/specials/SpecialSupportedLanguages.php
@@ -20,27 +20,38 @@
2121 * @ingroup SpecialPage TranslateSpecialPage
2222 */
2323 class SpecialSupportedLanguages extends UnlistedSpecialPage {
 24+ // Whether to skip and regenerate caches
 25+ protected $purge = false;
 26+
2427 public function __construct() {
2528 parent::__construct( 'SupportedLanguages' );
2629 }
2730
2831 public function execute( $par ) {
29 - global $wgLang, $wgOut;
 32+ global $wgLang, $wgOut, $wgRequest;
3033
31 - /**
32 - * Requires NS_PORTAL. If not present, display error text.
33 - */
 34+ // Requires NS_PORTAL. If not present, display error text.
3435 if ( !defined( 'NS_PORTAL' ) ) {
3536 $wgOut->showErrorPage( 'supportedlanguages-noportal-title', 'supportedlanguages-noportal' );
3637 return;
3738 }
3839
39 - $this->outputHeader();
 40+ $this->purge = $wgRequest->getVal( 'action' ) === 'purge';
 41+
4042 $this->setHeaders();
 43+ $wgOut->addModuleStyles( 'ext.translate.special.supportedlanguages' );
4144
42 - /**
43 - * Check if CLDR extension has been installed.
44 - */
 45+ $cache = wfGetCache( CACHE_ANYTHING );
 46+ $cachekey = wfMemcKey( 'translate-supportedlanguages', $wgLang->getCode() );
 47+ $data = $cache->get( $cachekey );
 48+ if ( !$this->purge && is_string( $data ) ) {
 49+ $wgOut->addHtml( $data );
 50+ return;
 51+ }
 52+
 53+ $this->outputHeader();
 54+
 55+ // Check if CLDR extension has been installed.
4556 $cldrInstalled = class_exists( 'LanguageNames' );
4657
4758 if ( $cldrInstalled ) {
@@ -83,14 +94,14 @@
8495 $user = Title::capitalize( $match[1], NS_USER );
8596 $lb->add( NS_USER, $user );
8697 $lb->add( NS_USER_TALK, $user );
87 -
8898 if ( !isset( $users[$code] ) ) $users[$code] = array();
89 - $users[$code][] = $user;
 99+ $users[$code][] = strtr( $user, '_', ' ' );
90100 }
91101 }
92102
93103 $lb->execute();
94104
 105+ list( $editcounts, $lastedits ) = $this->getUserStats();
95106 global $wgUser;
96107
97108 $skin = $wgUser->getSkin();
@@ -106,16 +117,12 @@
107118 $portalTitle = Title::makeTitleSafe( NS_PORTAL, $code );
108119 $portalText = $portalBaseText;
109120
110 - /**
111 - * If CLDR is installed, add localised header and link title.
112 - */
 121+ // If CLDR is installed, add localised header and link title.
113122 if ( $cldrInstalled ) {
114123 $headerText = wfMsg( 'supportedlanguages-portallink', $code, $locals[$code], $natives[$code] );
115124 $portalText .= ' ' . $locals[$code];
116125 } else {
117 - /**
118 - * No CLDR, so a less localised header and link title.
119 - */
 126+ // No CLDR, so a less localised header and link title.
120127 $headerText = wfMsg( 'supportedlanguages-portallink-nocldr', $code, $natives[$code] );
121128 $portalText .= ' ' . $natives[$code];
122129 }
@@ -133,9 +140,7 @@
134141
135142 $wgOut->addHTML( "<h2>" . $portalLink . "</h2>" );
136143
137 - /**
138 - * Add useful links for language stats and recent changes for the language.
139 - */
 144+ // Add useful links for language stats and recent changes for the language.
140145 $links = array();
141146 $links[] = $skin->link(
142147 $linkInfo['stats']['title'],
@@ -160,20 +165,109 @@
161166 $linkList = $wgLang->listToText( $links );
162167
163168 $wgOut->addHTML( "<p>" . $linkList . "</p>\n" );
 169+ $this->makeUserList( $users[$code], $editcounts, $lastedits );
164170
165 - foreach ( $users[$code] as $index => $username ) {
166 - $title = Title::makeTitleSafe( NS_USER, $username );
167 - $users[$code][$index] = $skin->link( $title, $username );
168 - }
169 -
170 - $wgOut->addHTML( "<p>" . wfMsgExt(
171 - 'supportedlanguages-translators',
172 - 'parsemag',
173 - $wgLang->listToText( $users[$code] ),
174 - count( $users[$code] )
175 - ) . "</p>\n" );
176171 }
177172 $wgOut->addHtml( Html::element( 'hr' ) );
178173 $wgOut->addWikiMsg( 'supportedlanguages-count', $wgLang->formatNum( count( $users ) ) );
 174+
 175+ $cache->set( $cachekey, $wgOut->getHTML(), 3600 );
179176 }
 177+
 178+ protected function makeUserList( $users, $editcounts, $lastedits ) {
 179+ global $wgOut, $wgLang, $wgUser;
 180+ $skin = $wgUser->getSkin();
 181+
 182+ $day = 60*60*24;
 183+
 184+ // Scale of the activity colors, anything
 185+ // longer than this is just inactive
 186+ $period = 180;
 187+
 188+ foreach ( $users as $index => $username ) {
 189+ $title = Title::makeTitleSafe( NS_USER, $username );
 190+ $enc = htmlspecialchars( $username );
 191+
 192+ $attribs = array();
 193+ $styles = array();
 194+ if ( isset( $editcounts[$username] ) ) {
 195+ $count = $editcounts[$username];
 196+ $styles['font-size'] = round( log( $count, 10 ) * 30 ) + 70 . '%';
 197+
 198+ $last = wfTimestamp( TS_UNIX ) - $lastedits[$username];
 199+ $last = round( $last / $day );
 200+ $attribs['title'] = wfMsgExt( 'supportedlanguages-activity', 'parsemag',
 201+ $username, $wgLang->formatNum( $count ), $wgLang->formatNum( $last ) );
 202+ $last = max( 1, min( $period, $last ) );
 203+ $styles['border-bottom'] = '3px solid #' . $this->getActivityColour( $period - $last, $period );
 204+ #$styles['color'] = '#' . $this->getBackgroundColour( $period - $last, $period );
 205+ } else {
 206+ $enc = "<s>$enc</s>";
 207+ }
 208+
 209+ $stylestr = $this->formatStyle( $styles );
 210+ if ( $stylestr ) $attribs['style'] = $stylestr;
 211+
 212+ $users[$index] = $skin->link( $title, $enc, $attribs );
 213+ }
 214+
 215+ $wgOut->addHTML( "<p class='mw-translate-spsl-translators'>" . wfMsgExt(
 216+ 'supportedlanguages-translators',
 217+ 'parsemag',
 218+ $wgLang->listToText( $users ),
 219+ count( $users )
 220+ ) . "</p>\n" );
 221+ }
 222+
 223+ protected function getUserStats() {
 224+ $cache = wfGetCache( CACHE_ANYTHING );
 225+ $cachekey = wfMemcKey( 'translate-supportedlanguages-userstats' );
 226+ $data = $cache->get( $cachekey );
 227+ if ( !$this->purge && is_array( $data ) ) {
 228+ return $data;
 229+ }
 230+
 231+ $dbr = wfGetDB( DB_SLAVE );
 232+ $editcounts = $lastedits = array();
 233+ $tables = array( 'user', 'revision' );
 234+ $fields = array( 'user_name', 'user_editcount', 'MAX(rev_timestamp) as lastedit' );
 235+ $conds = array( 'user_id = rev_user' );
 236+ $options = array( 'GROUP BY' => 'user_name' );
 237+
 238+ $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options );
 239+ foreach ( $res as $row ) {
 240+ $editcounts[$row->user_name] = $row->user_editcount;
 241+ $lastedits[$row->user_name] = wfTimestamp( TS_UNIX, $row->lastedit );
 242+ }
 243+
 244+ $data = array( $editcounts, $lastedits );
 245+ $cache->set( $cachekey, $data, 3600 );
 246+ return $data;
 247+ }
 248+
 249+ protected function formatStyle( $styles ) {
 250+ $stylestr = '';
 251+ foreach ( $styles as $key => $value ) {
 252+ $stylestr .= "$key:$value;";
 253+ }
 254+ return $stylestr;
 255+ }
 256+
 257+ /// FIXME: copied from Special:LanguageStats
 258+ protected function getActivityColour( $subset, $total ) {
 259+ $v = @round( 255 * $subset / $total );
 260+
 261+ if ( $v < 128 ) {
 262+ // Red to Yellow
 263+ $red = 'FF';
 264+ $green = sprintf( '%02X', 2 * $v );
 265+ } else {
 266+ // Yellow to Green
 267+ $red = sprintf( '%02X', 2 * ( 255 - $v ) );
 268+ $green = 'FF';
 269+ }
 270+ $blue = '00';
 271+
 272+ return $red . $green . $blue;
 273+ }
180274 }

Follow-up revisions

RevisionCommit summaryAuthorDate
r89725Fu r89724: forgot i18n filenikerabbit10:27, 8 June 2011

Status & tagging log