Jalexander has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/350443 )
Change subject: Add voter scripts for board/fdc election 2017 ...................................................................... Add voter scripts for board/fdc election 2017 Bug: T163854 Change-Id: I69692de75377f72c923c066d4102fef9dd743e03 --- A cli/wm-scripts/bv2017/bv2017_tables.sql A cli/wm-scripts/bv2017/doSpam.php A cli/wm-scripts/bv2017/populateEditCount.php A cli/wm-scripts/bv2017/voterList.php 4 files changed, 337 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SecurePoll refs/changes/43/350443/1 diff --git a/cli/wm-scripts/bv2017/bv2017_tables.sql b/cli/wm-scripts/bv2017/bv2017_tables.sql new file mode 100644 index 0000000..b3d279f --- /dev/null +++ b/cli/wm-scripts/bv2017/bv2017_tables.sql @@ -0,0 +1,5 @@ +CREATE TABLE bv2017_edits ( + bv_user int not null primary key, + bv_long_edits int not null, + bv_short_edits int not null +); diff --git a/cli/wm-scripts/bv2017/doSpam.php b/cli/wm-scripts/bv2017/doSpam.php new file mode 100644 index 0000000..36b6273 --- /dev/null +++ b/cli/wm-scripts/bv2017/doSpam.php @@ -0,0 +1,120 @@ +<?php + +require_once '/srv/mediawiki/multiversion/MWMultiVersion.php'; +require_once MWMultiVersion::getMediaWiki( 'maintenance/commandLine.inc', 'enwiki' ); + +$wgConf->loadFullData(); + +/** + * A list of usernames that don't want email about elections + * e.g. copied from https://meta.wikimedia.org/wiki/Wikimedia_nomail_list + * @var array + */ +$nomail = array(); +$raw = file_get_contents( 'https://meta.wikimedia.org/wiki/Wikimedia_Foundation_nomail_list?action=raw' ); +if ( preg_match( '/(?<=<pre>).*(?=<\/pre>)/ms', $raw, $matches ) ) { + $nomail = array_filter( array_map( 'trim', explode( "\n", $matches[0] ) ) ); +} + +/** + * Name of the list of allowed voters + * @var string + */ +$listName = 'board-vote-2015a'; + +/** + * ID number of the election + * @var int + */ +$electionId = 512; + +$specialWikis = MWWikiversions::readDbListFile( '/srv/mediawiki/dblists/special.dblist' ); + +function getDefaultLang( $db ) { + global $wgConf, $specialWikis; + static $langs = array(); + + if ( empty( $langs[$db] ) ) { + list( $site, $siteLang ) = $wgConf->siteFromDB( $db ); + $tags = array(); + if ( in_array( $db, $specialWikis ) ) { + $tags[] = 'special'; + } + $langs[$db] = RequestContext::sanitizeLangCode( + $wgConf->get( 'wgLanguageCode', $db, null, array( 'lang' => $siteLang ), $tags ) ); + } + + return $langs[$db]; +} + +function getLanguage( $userId, $wikiId ) { + $db = CentralAuthUser::getLocalDB( $wikiId ); + $lang = false; + try { + $lang = RequestContext::sanitizeLangCode( + $db->selectField( 'user_properties', 'up_value', + array( 'up_user' => $userId, 'up_property' => 'language' ) ) ); + } catch ( Exception $e ) { + // echo 'Caught exception: ' . $e->getMessage() . "\n"; + } + if ( !$lang ) { + $lang = getDefaultLang( $wikiId ); + } + return $lang; +} + + + +$voted = array(); +$vdb = wfGetDB( DB_SLAVE, array(), 'votewiki' ); +$voted = $vdb->selectFieldValues( 'securepoll_voters', 'voter_name', + array( 'voter_election' => $electionId ) ); + + +$db = CentralAuthUser::getCentralSlaveDB(); +$res = $db->select( + array( 'securepoll_lists', 'globaluser' ), + array( + 'gu_id', + 'gu_name', + 'gu_email', + 'gu_home_db', + ), + array( + 'gu_id=li_member', + 'li_name' => $listName, + 'gu_email_authenticated is not null', + 'gu_email is not null', + ) +); + +$users = array(); +foreach ( $res as $row ) { + if ( !$row->gu_email ) { + continue; + } + if ( in_array( $row->gu_email, $nomail ) ) { + // echo "Skipping {$row->gu_email}; in nomail list.\n"; + continue; + } + if ( in_array( $row->gu_name, $voted ) ) { + // echo "Skipping {$row->gu_name}; already voted.\n"; + continue; + } else { + $users[] = array( + 'id' => $row->gu_id, + 'mail' => $row->gu_email, + 'name' => $row->gu_name, + 'project' => $row->gu_home_db, + ); + } +} + +foreach ( $users as $user ) { + if ( empty( $user['project'] ) ) { + $caUser = new CentralAuthUser( $user['name'] ); + $user['project'] = $caUser->getHomeWiki(); + } + $user['lang'] = getLanguage( $user['id'], $user['project'] ); + echo "{$user['mail']}\t{$user['lang']}\t{$user['project']}\t{$user['name']}\n"; +} diff --git a/cli/wm-scripts/bv2017/populateEditCount.php b/cli/wm-scripts/bv2017/populateEditCount.php new file mode 100644 index 0000000..28341d9 --- /dev/null +++ b/cli/wm-scripts/bv2017/populateEditCount.php @@ -0,0 +1,57 @@ +<?php + +/** + * have made at least 300 edits before 01 April 2017 across Wikimedia wikis + * (edits on several wikis can be combined if your accounts are unified into a global account); and + * have made at least 20 edits between 01 October 2016 and 01 April 2017. + */ + +require( dirname(__FILE__) . '/../../cli.inc' ); + +$dbr = wfGetDB( DB_SLAVE ); +$dbw = wfGetDB( DB_MASTER ); + +$maxUser = $dbr->selectField( 'user', 'MAX(user_id)', false ); +$beforeTime = '20170401000000'; +$betweenTime = array( '20161001000000', '20170401000000' ); +$fname = 'populateEditCount'; + +$numUsers = 0; + +for ( $userId = 1; $userId <= $maxUser; $userId++ ) { + $exists = $dbr->selectField( 'user', '1', array( 'user_id' => $userId ) ); + if ( !$exists ) { + continue; + } + + $longEdits = $dbr->selectField( 'revision', 'COUNT(*)', + array( + 'rev_user' => $userId, + 'rev_timestamp < ' . $dbr->addQuotes( $beforeTime ) + ), $fname + ); + + $shortEdits = $dbr->selectField( 'revision', 'COUNT(*)', + array( + 'rev_user' => $userId, + 'rev_timestamp BETWEEN ' . $dbr->addQuotes( $betweenTime[0] ) . + ' AND ' . $dbr->addQuotes( $betweenTime[1] ) + ), + $fname + ); + + if ( $longEdits != 0 || $shortEdits != 0 ) { + $dbw->insert( 'bv2017_edits', + array( + 'bv_user' => $userId, + 'bv_long_edits' => $longEdits, + 'bv_short_edits' => $shortEdits + ), + $fname + ); + $numUsers++; + } +} + +echo wfWikiID() . ": $numUsers users added\n"; + diff --git a/cli/wm-scripts/bv2017/voterList.php b/cli/wm-scripts/bv2017/voterList.php new file mode 100644 index 0000000..8cf9aa7 --- /dev/null +++ b/cli/wm-scripts/bv2017/voterList.php @@ -0,0 +1,155 @@ +<?php + +require( dirname( __FILE__ ) . '/../../cli.inc' ); +$dbcr = CentralAuthUser::getCentralSlaveDB(); +$dbcw = CentralAuthUser::getCentralDB(); + +$fname = 'voterList.php'; +$listName = 'board-vote-2017'; + +$dbcw->delete( 'securepoll_lists', array( 'li_name' => $listName ), $fname ); + +$totalUsers = $dbcr->selectField( 'globaluser', 'MAX(gu_id)', false, $fname ); + +$userName = ''; +$numUsers = 0; +$numQualified = 0; +while ( true ) { + $res = $dbcr->select( 'globaluser', + array( 'gu_id', 'gu_name' ), + array( 'gu_name > ' . $dbcr->addQuotes( $userName ) ), + $fname, + array( 'LIMIT' => 1000, 'ORDER BY' => 'gu_name' ) ); + if ( !$res->numRows() ) { + break; + } + + $users = array(); + foreach ( $res as $row ) { + $users[$row->gu_id] = $row->gu_name; + $userName = $row->gu_name; + $numUsers++; + } + + $qualifieds = spGetQualifiedUsers( $users ); + $insertBatch = array(); + foreach ( $qualifieds as $id => $name ) { + $insertBatch[] = array( + 'li_name' => $listName, + 'li_member' => $id + ); + } + if ( $insertBatch ) { + $dbcw->insert( 'securepoll_lists', $insertBatch, $fname ); + $numQualified += count( $insertBatch ); + } + spReportProgress( $numUsers, $totalUsers ); +} +echo wfWikiID() . " qualified \t$numQualified\n"; + +/** + * @param $users array + * @return array + */ +function spGetQualifiedUsers( $users ) { + global $wgLocalDatabases; + $dbcr = CentralAuthUser::getCentralSlaveDB(); + + $res = $dbcr->select( 'localuser', + array( 'lu_name', 'lu_wiki' ), + array( 'lu_name' => $users ), + __METHOD__ ); + + $editCounts = array(); + $foreignUsers = array(); + foreach ( $res as $row ) { + $foreignUsers[$row->lu_wiki][] = $row->lu_name; + $editCounts[$row->lu_name] = array( 0, 0 ); + } + + foreach ( $foreignUsers as $wiki => $wikiUsers ) { + if ( !in_array( $wiki, $wgLocalDatabases ) ) { + continue; + } + $lb = wfGetLB( $wiki ); + $db = $lb->getConnection( DB_SLAVE, array(), $wiki ); + $foreignEditCounts = spGetEditCounts( $db, $wikiUsers ); + $lb->reuseConnection( $db ); + foreach ( $foreignEditCounts as $name => $count ) { + $editCounts[$name][0] += $count[0]; + $editCounts[$name][1] += $count[1]; + } + } + + $idsByUser = array_flip( $users ); + $qualifiedUsers = array(); + foreach ( $editCounts as $user => $count ) { + if ( spIsQualified( $count[0], $count[1] ) ) { + $id = $idsByUser[$user]; + $qualifiedUsers[$id] = $user; + } + } + + return $qualifiedUsers; +} + +/** + * @param $db DatabaseBase + * @param $userNames + * @return array + */ +function spGetEditCounts( $db, $userNames ) { + $res = $db->select( + array( 'user', 'bv2017_edits' ), + array( 'user_name', 'bv_long_edits', 'bv_short_edits' ), + array( 'bv_user=user_id', 'user_name' => $userNames ), + __METHOD__ + ); + $editCounts = array(); + foreach ( $res as $row ) { + $editCounts[$row->user_name] = array( $row->bv_short_edits, $row->bv_long_edits ); + } + foreach ( $userNames as $user ) { + if ( !isset( $editCounts[$user] ) ) { + $editCounts[$user] = array( 0, 0 ); + } + } + return $editCounts; +} + +/** + * Returns whether a user "is qualified" to vote based on edit count + * + * @param $short + * @param $long + * @return bool + */ +function spIsQualified( $short, $long ) { + return $short >= 20 && $long >= 300; +} + +/** + * Report progress + */ +function spReportProgress( $current, $total ) { + static $lastReportTime, $startTime; + + $now = time(); + if ( !$startTime ) { + $startTime = $now; + } + if ( $now - $lastReportTime < 10 ) { + return; + } + $lastReportTime = $now; + $lang = Language::factory( 'en' ); + $estTotalDuration = ( $now - $startTime ) * $total / $current; + $estRemaining = $estTotalDuration - ( $now - $startTime ); + + print $lang->commafy( $current ) . " of " . + $lang->commafy( $total ) . " ; " . + number_format( $current / $total * 100, 2 ) . '% ; estimated time remaining: ' . + $lang->formatDuration( $estRemaining ) . + "\n"; +} + -- To view, visit https://gerrit.wikimedia.org/r/350443 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I69692de75377f72c923c066d4102fef9dd743e03 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/SecurePoll Gerrit-Branch: wmf/1.29.0-wmf.21 Gerrit-Owner: Jalexander <jalexan...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits