Robert Vogel has uploaded a new change for review. https://gerrit.wikimedia.org/r/164908
Change subject: First version of automated deployment tool ...................................................................... First version of automated deployment tool The Gadgetize.php maintenance script makes it easier to deploy a set of source code files to a MediaWiki installation. Change-Id: I3a06c4305253ffab0e076b8360b15600618d09df --- A assets/MediaWiki_Gadget-teahouse.wiki M gadgetize.json M maintenance/Gadgetize.php 3 files changed, 215 insertions(+), 18 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Teahouse refs/changes/08/164908/1 diff --git a/assets/MediaWiki_Gadget-teahouse.wiki b/assets/MediaWiki_Gadget-teahouse.wiki new file mode 100644 index 0000000..7391e1e --- /dev/null +++ b/assets/MediaWiki_Gadget-teahouse.wiki @@ -0,0 +1 @@ +Wikipedia Teahouse - Wikimedia Deutschland e.V., Hallo Welt! - Medienwerkstatt GmbH, [[mw:User:Osnard|Robert Vogel]] \ No newline at end of file diff --git a/gadgetize.json b/gadgetize.json index 6405a8b..5482a1c 100644 --- a/gadgetize.json +++ b/gadgetize.json @@ -1,20 +1,19 @@ { - _includeI18N: true, //Maybe better make two properties: One for config and one for assets? - - "MediaWiki:teahouse.js": [ - "resources/teahouse.apiStore.js", - "resources/teahouse.dialog.js", - "resources/teahouse.button.js", - "resources/teahouse.init.js" - ], - - "MediaWiki:teahouse.css": [ - "resources/teahouse.dialog.css", - "resources/teahouse.button.css" - ], - - "Template:Pending_Question": "assets/Template_Pending_Questions.wiki", - "Template:Answered_Question": "assets/Template_Answered_Questions.wiki", - "Module:Teahouse_Questions": "assets/Module_Teahouse_Questions.lua", - "Help:Teahouse": "assets/Help_Teahouse.wiki" + "MediaWiki:Gadget-teahouse": ["assets/MediaWiki_Gadget-teahouse.wiki"], + + "MediaWiki:Gadget-teahouse/main.js": [ + "resources/mediawiki.teahouse.js", + "resources/mediawiki.teahouse.QuestionDialog.js", + "resources/mediawiki.teahouse.gadget.js" + ], + + "MediaWiki:Gadget-teahouse/teahouse.css": [ + "resources/mediawiki.teahouse.dialog.css", + "resources/mediawiki.teahouse.button.css" + ], + + "Template:Pending_Question": [ "assets/Template_Pending_Questions.wiki" ], + "Template:Answered_Question": [ "assets/Template_Answered_Questions.wiki" ], + "Module:Teahouse_Questions": [ "assets/Module_Teahouse_Questions.lua" ], + "Help:Teahouse": [ "assets/Help_Teahouse.wiki" ] } \ No newline at end of file diff --git a/maintenance/Gadgetize.php b/maintenance/Gadgetize.php index e69de29..565fbf8 100644 --- a/maintenance/Gadgetize.php +++ b/maintenance/Gadgetize.php @@ -0,0 +1,197 @@ +<?php + +require_once( dirname(dirname(dirname(__DIR__))) . '/maintenance/Maintenance.php' ); + +class Gadgetize extends Maintenance { + + public function __construct() { + parent::__construct(); + + $this->addOption('targetapi', 'Absolute path the target wiki\'s "api.php"', true, true); + $this->addOption('u', 'A valid username on the target wiki with sufficient write permissions', true, true); + $this->addOption('p', 'The users password for API login. If not provided as argument you will be promted for it', false, true); + $this->addOption('config', 'Path to the JSON file with the configuration', false, true); + + } + + private $apiUrl = ''; + private $username = ''; + private $password = ''; + private $config = ''; + private $configArray = null; + private $cookieJar = null; + private $token = null; + private $edittoken = null; + + public function execute() { + $this->apiUrl = $this->getOption( 'targetapi' ); + $this->username = $this->getOption( 'u' ); + if( empty($this->username) ) { + $this->error( '"username" can not be empty'); + return; + } + $this->password = $this->getOption( 'p' ); + if( $this->password === null ) { + $this->password = $this->readconsole('Password for user "'.$this->username.'": '); + } + if( empty($this->password) ) { + $this->error( '"password" can not be empty'); + return; + } + + $this->config = $this->getOption( 'config', getcwd().'/gadgetize.json' ); + $this->configArray = FormatJson::decode( + file_get_contents( $this->config ), + true + ); + + if( $this->configArray === null ) { + $this->error( 'Config file could not be read'); + return; + } + + if( !$this->doAPILogin() ) { + $this->error( 'Authentication failed' ); + return; + } + $this->output( 'Authentication successfull' ); + + $this->getAPIEditToken(); + $this->processConfig(); + } + + public function doAPILogin() { + $options = array( + 'method' => 'POST', + 'postData' => array( + 'action' => 'login', + 'format' => 'json', + 'lgname' => $this->username, + 'lgpassword' => $this->password + ) + ); + + //Second pass + if ( $this->token !== null ) { + $options['postData']['lgtoken'] = $this->token; + } + + $req = MWHttpRequest::factory( $this->apiUrl, $options ); + + if ( $this->cookieJar !== null ) { + $req->setCookieJar( $this->cookieJar ); + } + + $status = $req->execute(); + + if ( $status->isOK() ) { + $response = FormatJson::decode( $req->getContent() ); + + if ( isset( $response->login ) && isset( $response->login->result ) ) { + + if ( strtolower( $response->login->result ) === 'needtoken' ) { + $this->token = $response->login->token; + $this->cookieJar = $req->getCookieJar(); + return $this->doAPILogin(); + } + elseif ( strtolower ( $response->login->result ) === 'success' ) { + $this->cookieJar = $req->getCookieJar(); + return true; + } + } + + return false; + } + return false; + } + + public function processConfig() { + foreach( $this->configArray as $title => $files ) { + if( !is_array( $files ) ) { + continue; + } + $this->output( "\n".'Generating "'.$title.'" from ...'); + $content = ''; + foreach( $files as $file ){ + $filePath = dirname($this->config).'/'.$file; + + if( !file_exists($filePath) ) { + $this->error( '... "'.$file.'" does not exist!'); + continue; + } + + $this->output( '... "'.$file.'"'); + + $content .= "\n"; + $content .= file_get_contents($filePath); + $content .= "\n\n"; + } + if( empty( $content ) ) { + continue; + } + + $options = array( + 'method' => 'POST', + 'postData' => array( + 'action' => 'edit', + 'title' => $title, + 'format' => 'json', + 'summary' => 'Automated deployment using "'.__CLASS__.'"', + 'text' => $content, + 'token' => $this->edittoken, + ) + ); + + $req = MWHttpRequest::factory( $this->apiUrl, $options ); + $req->setCookieJar( $this->cookieJar ); + + $status = $req->execute(); + $response = FormatJson::decode( $req->getContent() ); + + if ( $status->isOK() && isset( $response->edit ) && strtolower( $response->edit->result ) === 'success' ) { + $this->output( 'Upload successful!' ); + } + else { + $this->error( 'Upload failed!' ); + } + } + } + + public function getAPIEditToken() { + $query = array( + 'action' => 'query', + 'format' => 'json', + 'meta' => 'tokens', + 'type' => 'csrf', + ); + + $req = MWHttpRequest::factory( + wfAppendQuery($this->apiUrl, $query) + ); + $req->setCookieJar( $this->cookieJar ); + + $status = $req->execute(); + + if ( $status->isOK() ) { + $response = FormatJson::decode( $req->getContent() ); + if( isset( $response->query ) && isset( $response->query->tokens ) && isset( $response->query->tokens->csrftoken ) ) { + $this->edittoken = $response->query->tokens->csrftoken; + return true; + } + } + + return false; + } + + protected function output($out, $channel = null) { + parent::output($out."\n", $channel); + } + +} + +$maintClass = 'Gadgetize'; +if (defined('RUN_MAINTENANCE_IF_MAIN')) { + require_once( RUN_MAINTENANCE_IF_MAIN ); +} else { + require_once( DO_MAINTENANCE ); # Make this work on versions before 1.17 +} \ No newline at end of file -- To view, visit https://gerrit.wikimedia.org/r/164908 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3a06c4305253ffab0e076b8360b15600618d09df Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Teahouse Gerrit-Branch: master Gerrit-Owner: Robert Vogel <vo...@hallowelt.biz> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits