r53859 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r53858‎ | r53859 | r53860 >
Date:06:12, 28 July 2009
Author:tstarling
Status:deferred
Tags:
Comment:
Committing Wikimedia-specific scripts for the 2009 Board election.
Modified paths:
  • /trunk/extensions/SecurePoll/cli/wm-scripts (added) (history)
  • /trunk/extensions/SecurePoll/cli/wm-scripts/README (added) (history)
  • /trunk/extensions/SecurePoll/cli/wm-scripts/bv2009_tables.sql (added) (history)
  • /trunk/extensions/SecurePoll/cli/wm-scripts/dumpMetaTranslations.php (added) (history)
  • /trunk/extensions/SecurePoll/cli/wm-scripts/populateBv2009EditCount.php (added) (history)
  • /trunk/extensions/SecurePoll/cli/wm-scripts/voterList-bv2009.php (added) (history)

Diff [purge]

Index: trunk/extensions/SecurePoll/cli/wm-scripts/populateBv2009EditCount.php
@@ -0,0 +1,53 @@
 2+<?php
 3+
 4+/**
 5+ * have made at least 600 edits before 01 June 2009 across Wikimedia wikis (edits on several wikis can be combined if your accounts are unified into a global account); and
 6+ * have made at least 50 edits between 01 January and 01 July 2009.
 7+ */
 8+
 9+require( dirname(__FILE__) . '/../cli.inc' );
 10+$dbr = wfGetDB( DB_SLAVE );
 11+$dbw = wfGetDB( DB_MASTER );
 12+
 13+
 14+$maxUser = $dbr->selectField( 'user', 'MAX(user_id)', false );
 15+$beforeTime = '20090601000000';
 16+$betweenTime = array( '20090101000000', '20090701000000' );
 17+$fname = 'populatebv2009EditCount';
 18+
 19+for ( $userId = 1; $userId <= $maxUser; $userId++ ) {
 20+ $exists = $dbr->selectField( 'user', '1', array( 'user_id' => $userId ) );
 21+ if ( !$exists ) {
 22+ continue;
 23+ }
 24+
 25+ $longEdits = $dbr->selectField( 'revision', 'COUNT(*)',
 26+ array(
 27+ 'rev_user' => $userId,
 28+ 'rev_timestamp < ' . $dbr->addQuotes( $beforeTime )
 29+ ), $fname );
 30+
 31+ $shortEdits = $dbr->selectField( 'revision', 'COUNT(*)',
 32+ array(
 33+ 'rev_user' => $userId,
 34+ 'rev_timestamp BETWEEN ' . $dbr->addQuotes( $betweenTime[0] ) .
 35+ ' AND ' . $dbr->addQuotes( $betweenTime[1] )
 36+ ),
 37+ $fname
 38+ );
 39+
 40+ if ( $longEdits !== 0 || $shortEdits !== 0 ) {
 41+ $dbw->insert( 'bv2009_edits',
 42+ array(
 43+ 'bv_user' => $userId,
 44+ 'bv_long_edits' => $longEdits,
 45+ 'bv_short_edits' => $shortEdits
 46+ ),
 47+ $fname
 48+ );
 49+ $numUsers++;
 50+ }
 51+}
 52+
 53+echo wfWikiID() . ": $numUsers users added\n";
 54+
Property changes on: trunk/extensions/SecurePoll/cli/wm-scripts/populateBv2009EditCount.php
___________________________________________________________________
Name: svn:eol-style
155 + native
Index: trunk/extensions/SecurePoll/cli/wm-scripts/voterList-bv2009.php
@@ -0,0 +1,134 @@
 2+<?php
 3+
 4+require( dirname( __FILE__ ) . '/../cli.inc' );
 5+$dbr = wfGetDB( DB_SLAVE );
 6+$dbw = wfGetDB( DB_MASTER );
 7+$fname = 'voterList-bv2009.php';
 8+
 9+if ( !$wgCentralAuthDatabase ) {
 10+ echo wfWikiID() . ": CentralAuth not active, skipping\n";
 11+ exit( 0 );
 12+}
 13+
 14+$dbw->delete( 'securepoll_lists', array( 'li_name' => 'board-vote-2009' ), $fname );
 15+
 16+$userId = 0;
 17+$numQualified = 0;
 18+while ( true ) {
 19+ $res = $dbr->select( 'user', array( 'user_id', 'user_name' ),
 20+ array( 'user_id > ' . $dbr->addQuotes( $userId ) ),
 21+ __METHOD__,
 22+ array( 'LIMIT' => 1000, 'ORDER BY' => 'user_id' ) );
 23+ if ( !$res->numRows() ) {
 24+ break;
 25+ }
 26+
 27+ $users = array();
 28+ foreach ( $res as $row ) {
 29+ $users[$row->user_id] = $row->user_name;
 30+ $userId = $row->user_id;
 31+ }
 32+ $qualifieds = spGetQualifiedUsers( $users );
 33+ $insertBatch = array();
 34+ foreach ( $qualifieds as $id => $name ) {
 35+ $insertBatch[] = array(
 36+ 'li_name' => 'board-vote-2009',
 37+ 'li_member' => $id
 38+ );
 39+ }
 40+ if ( $insertBatch ) {
 41+ $dbw->insert( 'securepoll_lists', $insertBatch, $fname );
 42+ $numQualified += count( $insertBatch );
 43+ }
 44+}
 45+echo wfWikiID() . " qualified \t$numQualified\n";
 46+
 47+function spGetQualifiedUsers( $users ) {
 48+ global $wgCentralAuthDatabase, $wgLocalDatabases;
 49+ $dbc = wfGetDB( DB_SLAVE, array(), $wgCentralAuthDatabase );
 50+ $editCounts = array();
 51+
 52+ # Check local attachment
 53+ $res = $dbc->select( 'localuser', array( 'lu_name' ),
 54+ array(
 55+ 'lu_wiki' => wfWikiID(),
 56+ 'lu_name' => array_values( $users )
 57+ ), __METHOD__ );
 58+
 59+ $attached = array();
 60+ foreach ( $res as $row ) {
 61+ $attached[] = $row->lu_name;
 62+ $editCounts[$row->lu_name] = array( 0, 0 );
 63+ }
 64+ $nonLocalUsers = array();
 65+
 66+ $localEditCounts = spGetEditCounts( wfGetDB( DB_SLAVE ), $users );
 67+ foreach ( $localEditCounts as $user => $counts ) {
 68+ if ( $counts[0] == 0 ) {
 69+ // No recent local edits, remove from consideration
 70+ // This is just for efficiency, the user can vote somewhere else
 71+ $nonLocalUsers[] = $user;
 72+ }
 73+ $editCounts[$user] = $counts;
 74+ }
 75+ $attached = array_diff( $attached, $nonLocalUsers );
 76+
 77+ # Check all global accounts
 78+ if ( $attached ) {
 79+ $res = $dbc->select( 'localuser',
 80+ array( 'lu_name', 'lu_wiki' ),
 81+ array( 'lu_name' => $attached ),
 82+ __METHOD__ );
 83+ $foreignUsers = array();
 84+ foreach ( $res as $row ) {
 85+ $foreignUsers[$row->lu_wiki][] = $row->lu_name;
 86+ }
 87+
 88+ foreach ( $foreignUsers as $wiki => $wikiUsers ) {
 89+ if ( !in_array( $wiki, $wgLocalDatabases ) ) {
 90+ continue;
 91+ }
 92+ $lb = wfGetLB( $wiki );
 93+ $db = $lb->getConnection( DB_SLAVE, array(), $wiki );
 94+ $foreignEditCounts = spGetEditCounts( $db, $wikiUsers );
 95+ $lb->reuseConnection( $db );
 96+ foreach ( $foreignEditCounts as $name => $count ) {
 97+ $editCounts[$name][0] += $count[0];
 98+ $editCounts[$name][1] += $count[1];
 99+ }
 100+ }
 101+ }
 102+
 103+ $idsByUser = array_flip( $users );
 104+ $qualifiedUsers = array();
 105+ foreach ( $editCounts as $user => $count ) {
 106+ if ( spIsQualified( $count[0], $count[1] ) ) {
 107+ $id = $idsByUser[$user];
 108+ $qualifiedUsers[$id] = $user;
 109+ }
 110+ }
 111+
 112+ return $qualifiedUsers;
 113+}
 114+
 115+function spGetEditCounts( $db, $userNames ) {
 116+ $res = $db->select(
 117+ array( 'user', 'bv2009_edits' ),
 118+ array( 'user_name', 'bv_long_edits', 'bv_short_edits' ),
 119+ array( 'bv_user=user_id', 'user_name' => $userNames ),
 120+ __METHOD__ );
 121+ $editCounts = array();
 122+ foreach ( $res as $row ) {
 123+ $editCounts[$row->user_name] = array( $row->bv_short_edits, $row->bv_long_edits );
 124+ }
 125+ foreach ( $userNames as $user ) {
 126+ if ( !isset( $editCounts[$user] ) ) {
 127+ $editCounts[$user] = array( 0, 0 );
 128+ }
 129+ }
 130+ return $editCounts;
 131+}
 132+
 133+function spIsQualified( $short, $long ) {
 134+ return $short >= 50 && $long >= 600;
 135+}
Property changes on: trunk/extensions/SecurePoll/cli/wm-scripts/voterList-bv2009.php
___________________________________________________________________
Name: svn:eol-style
1136 + native
Index: trunk/extensions/SecurePoll/cli/wm-scripts/dumpMetaTranslations.php
@@ -0,0 +1,193 @@
 2+<?php
 3+
 4+require( dirname( __FILE__ ) . '/../cli.inc' );
 5+
 6+$spConf = array(
 7+ 'numCandidates' => 18,
 8+ 'baseId' => 17,
 9+ 'basePage' => 'Board elections/2009/Vote interface',
 10+ 'langs' => array(
 11+ 'ar',
 12+ 'ca',
 13+ 'cs',
 14+ 'de',
 15+ 'el',
 16+ 'en',
 17+ 'eo',
 18+ 'es',
 19+ 'fi',
 20+ 'fr',
 21+ 'hr',
 22+ 'hu',
 23+ 'id',
 24+ 'it',
 25+ 'ja',
 26+ 'jv',
 27+ 'ms',
 28+ 'nb',
 29+ 'nl',
 30+ 'pl',
 31+ 'pt',
 32+ 'pt-br',
 33+ 'ru',
 34+ 'sk',
 35+ 'sv',
 36+ 'tr',
 37+ 'vi',
 38+ 'zh-hans',
 39+ 'zh-hant',
 40+ )
 41+);
 42+
 43+$header = <<<EOT
 44+<SecurePoll>
 45+<election>
 46+<configuration>
 47+<title>Wikimedia Board of Trustees Election, 2009</title>
 48+<ballot>preferential</ballot>
 49+<tally>schulze</tally>
 50+<primaryLang>en</primaryLang>
 51+<startDate>2009-07-28T08:00:00Z</startDate>
 52+<endDate>2009-08-10T23:59:59Z</endDate>
 53+<auth>remote-mw</auth>
 54+<id>{$spConf['baseId']}</id>
 55+<property name="admins">Pathoschild|Daniel|Yann|Dvortygirl|IAlex|Mardetanha|Werdna|Philippe Beaudette</property>
 56+<property name="not-blocked">1</property>
 57+<property name="not-bot">1</property>
 58+<property name="need-list">board-vote-2009</property>
 59+<property name="encrypt-type">gpg</property>
 60+<property name="remote-mw-script-path">https://secure.wikimedia.org/\$site/\$lang/w</property>
 61+<property name="shuffle-options">1</property>
 62+<property name="gpg-encrypt-key"><!-- insert key here --></property>
 63+<property name="gpg-sign-key"><!-- insert key here --></property>
 64+
 65+
 66+EOT;
 67+
 68+$allMessages = array();
 69+foreach ( $spConf['langs'] as $lang ) {
 70+ $messages = spGetMetaTranslations( $lang );
 71+ if ( $messages ) {
 72+ $allMessages[$lang] = $messages;
 73+ } else {
 74+ fwrite( STDERR, "Messages not found for $lang\n" );
 75+ }
 76+}
 77+
 78+$s = $header .
 79+ spFormatEntityMessages( $allMessages, 'election' ) .
 80+ "<question>\n" .
 81+ "<id>" . ($spConf['baseId'] + 1) . "</id>\n" .
 82+ "<message name=\"text\" lang=\"en\"></message>\n";
 83+
 84+for ( $i = 1; $i <= $spConf['numCandidates']; $i++ ) {
 85+ $s .=
 86+ "<option>\n" .
 87+ "<id>" . ( $i + $spConf['baseId'] + 1 ) . "</id>\n" .
 88+ spFormatEntityMessages( $allMessages, "option_$i" ) .
 89+ "</option>\n";
 90+}
 91+$s .= "</question>
 92+</configuration>
 93+</election>
 94+</SecurePoll>
 95+";
 96+
 97+echo $s;
 98+exit( 0 );
 99+//------------------------------------------------------------------
 100+
 101+function spGetMetaTranslations( $lang ) {
 102+ global $spConf, $wgParser;
 103+ $messages = array();
 104+ $titleText = "{$spConf['basePage']}/$lang";
 105+ $title = Title::newFromText( $titleText );
 106+ $numMessages = 0;
 107+ if ( !$title ) {
 108+ fwrite( STDERR, "Title invalid for lang $lang\n" );
 109+ return false;
 110+ }
 111+ $revision = Revision::newFromTitle( $title );
 112+ if ( !$revision ) {
 113+ fwrite( STDERR, "Revision not found for page [[$titleText]]\n" );
 114+ return false;
 115+ }
 116+ $text = $revision->getText();
 117+ if ( $text === false ) {
 118+ fwrite( STDERR, "Text not found for page [[$titleText]]\n" );
 119+ return false;
 120+ }
 121+
 122+ for ( $sectionIndex = 1; $sectionIndex <= 10; $sectionIndex++ ) {
 123+ $section = $wgParser->getSection( $text, $sectionIndex, false );
 124+ if ( $section === false ) {
 125+ break;
 126+ }
 127+
 128+ if ( !preg_match( '/^== *(.*?) *==\s*$/m', $section, $m ) ) {
 129+ fwrite( STDERR, "Section header mismatch for section $sectionIndex of [[$titleText]]\n" );
 130+ continue;
 131+ }
 132+ $sectionName = strtolower( $m[1] );
 133+ $remainder = trim( substr( $section, strlen( $m[0] ) ) );
 134+ if ( strpos( $remainder, '<nowiki>' ) !== false ) {
 135+ fwrite( STDERR, "Message $sectionName for $lang contains <nowiki>\n" );
 136+ continue;
 137+ }
 138+
 139+ $electionMsgMap = array(
 140+ 'title' => 'title',
 141+ 'introduction' => 'intro',
 142+ 'jump text' => 'jump-text'
 143+ );
 144+ if ( isset( $electionMsgMap[$sectionName] ) ) {
 145+ $messages['election'][$electionMsgMap[$sectionName]] = $remainder;
 146+ $numMessages++;
 147+ continue;
 148+ }
 149+
 150+ if ( $sectionName == 'candidate text' ) {
 151+ $i = 1;
 152+ $lines = explode( "\n", $remainder );
 153+ foreach ( $lines as $line ) {
 154+ if ( preg_match( '/^# *(.*)/', $line, $m ) ) {
 155+ $messages["option_$i"]['text'] = $m[1];
 156+ $numMessages++;
 157+ $i++;
 158+ }
 159+ }
 160+ $i--;
 161+ if ( $i !== $spConf['numCandidates'] ) {
 162+ fwrite( STDERR, "Not enough candidates for $lang: $i/{$spConf['numCandidates']}\n" );
 163+ return false;
 164+ }
 165+ continue;
 166+ }
 167+
 168+ fwrite( STDERR, "Unrecognised section \"$sectionName\" in $lang\n" );
 169+ }
 170+
 171+ fwrite( STDERR, "[[$titleText]]: found " . $numMessages . " messages\n" );
 172+ return $messages;
 173+}
 174+
 175+function spFormatEntityMessages( $messages, $entity ) {
 176+ $s = '';
 177+ $targetEntity = $entity;
 178+ foreach ( $messages as $lang => $langMsgs ) {
 179+ foreach ( $langMsgs as $entity => $entityMsgs ) {
 180+ if ( $entity === $targetEntity ) {
 181+ foreach ( $entityMsgs as $key => $value ) {
 182+ $s .= Xml::element(
 183+ 'message',
 184+ array( 'name' => $key, 'lang' => $lang ),
 185+ $value
 186+ ) .
 187+ "\n";
 188+ }
 189+ }
 190+ }
 191+ }
 192+ return $s;
 193+}
 194+
Property changes on: trunk/extensions/SecurePoll/cli/wm-scripts/dumpMetaTranslations.php
___________________________________________________________________
Name: svn:eol-style
1195 + native
Index: trunk/extensions/SecurePoll/cli/wm-scripts/bv2009_tables.sql
@@ -0,0 +1,5 @@
 2+CREATE TABLE bv2009_edits (
 3+ bv_user int not null primary key,
 4+ bv_long_edits int not null,
 5+ bv_short_edits int not null
 6+);
Property changes on: trunk/extensions/SecurePoll/cli/wm-scripts/bv2009_tables.sql
___________________________________________________________________
Name: svn:eol-style
17 + native
Index: trunk/extensions/SecurePoll/cli/wm-scripts/README
@@ -0,0 +1 @@
 2+These are Wikimedia-specific scripts for voter lists, configuration and translation transfer.
Property changes on: trunk/extensions/SecurePoll/cli/wm-scripts/README
___________________________________________________________________
Name: svn:eol-style
13 + native

Status & tagging log