Permalink
Browse files

Initial web view - bad error handling :)

  • Loading branch information...
brion committed Mar 26, 2012
1 parent 398725a commit b959274db16ab0502c2b6ce5d8e12cbd2e46d9e7
View
@@ -35,7 +35,7 @@ static function discoverExtensions() {
$out = array();
$repos = self::discoverRepos();
foreach( $repos as $repo ) {
- if ( $repo['parent']['name'] == 'mediawiki/extensions' ) {
+ if ( isset($repo['parent']) && $repo['parent']['name'] == 'mediawiki/extensions' ) {
$ext = new ExtFetchExtension( $repo );
$out[$ext->name] = $ext;
}
@@ -63,14 +63,14 @@ function __construct( $repo ) {
* @param bool auth
*/
function cloneRepo( $asDeveloper=false ) {
- global $wgExtFetchGerrit, $wgExtFetchGitDeveloper, $wgExtFetchGitAnon, $IP;
+ global $wgExtFetchGerrit, $wgExtFetchGitDeveloper, $wgExtFetchGitAnon;
if ( $asDeveloper ) {
$baseUrl = $wgExtFetchGitDeveloper;
} else {
$baseUrl = $wgExtFetchGitAnon;
}
$url = str_replace( '$1', $wgExtFetchGerrit, $baseUrl ) . '/' . $this->repo;
- $dest = "$IP/extensions/$this->name";
+ $dest = $this->getDirectory();
$cmd = wfEscapeShellArg(
'git',
'clone',
@@ -80,4 +80,18 @@ function cloneRepo( $asDeveloper=false ) {
echo "$cmd\n";
wfShellExec( $cmd );
}
+
+ function getLink() {
+ return 'https://www.mediawiki.org/wiki/Extension:' . ucfirst( $this->name );
+ }
+
+ function getDirectory() {
+ global $IP;
+ return "$IP/extensions/$this->name";
+ }
+
+ function isPresent() {
+ return is_dir( $this->getDirectory() );
+ }
}
+
View
@@ -0,0 +1,18 @@
+<?php
+
+$messages = array();
+
+$messages['en'] = array(
+ 'extensionfetcher' => 'Extension Fetcher',
+ 'action-extension-install' => 'install extensions',
+ 'extfetch-present' => 'Present',
+ 'extfetch-fetch' => 'Fetch',
+);
+
+$messages['qqq'] = array(
+ 'extensionfetcher' => 'page title for Special:ExtensionFetcher',
+ 'action-extension-install' => 'subphrase used in permission error messages; describes the action of installing extensions in "you do not have permission to X"',
+ 'extfetch-present' => 'label in place of fetch button to indicate that extension is already present',
+ 'extfetch-fetch' => 'label for button to fetch an extension and start installing it',
+);
+
View
@@ -11,5 +11,30 @@
$wgExtFetchGitDeveloper = "ssh://$1:29418";
$wgExtFetchGitAnon = "https://$1/r/p";
-$wgAutoloadClasses['ExtensionFetcher'] = dirname( __FILE__ ) . '/ExtensionFetcher.body.php';
-$wgAutoloadClasses['ExtFetchExtension'] = dirname( __FILE__ ) . '/ExtensionFetcher.body.php';
+$dir = dirname( __FILE__ );
+$wgAutoloadClasses['ExtensionFetcher'] = $dir . '/ExtensionFetcher.body.php';
+$wgAutoloadClasses['ExtFetchExtension'] = $dir . '/ExtensionFetcher.body.php';
+$wgAutoloadClasses['SpecialExtensionFetcher'] = $dir . '/specials/SpecialExtensionFetcher.php';
+$wgAutoloadClasses['ApiExtFetch'] = $dir . '/api/ApiExtFetch.php';
+
+$wgExtensionMessagesFiles['ExtensionFetcher'] = $dir . '/ExtensionFetcher.i18n.php';
+
+$wgSpecialPages['ExtensionFetcher'] = 'SpecialExtensionFetcher';
+
+$wgAPIModules['extfetch'] = 'ApiExtFetch';
+
+$wgResourceModules['ext.extfetch'] = array(
+ 'localBasePath' => dirname( __FILE__ ) . '/modules',
+ 'remoteExtPath' => 'ExtensionFetcher/modules',
+ 'scripts' => 'ext.extfetch.js',
+ 'dependencies' => array(
+ 'mediawiki.util',
+ 'mediawiki.user',
+ 'user.tokens'
+ )
+);
+
+$wgAvailablePermissions[] = 'extension-install';
+$wgGroupPermissions['sysop']['extension-install'] = true; // ???? safe default? :)
+
+
View
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * ExtensionFetcher for MediaWiki
+ * Copyright (c) 2012 Brion Vibber & Wikimedia Foundation, Inc.
+ * licensed under GNU GPL v2 or later
+ */
+
+class ApiExtFetch extends ApiBase {
+
+ public function execute() {
+ global $wgUser;
+ // Before doing anything at all, let's check permissions
+ if ( !$wgUser->isAllowed( 'extension-install' ) ) {
+ $this->dieUsage( 'You don\'t have permission to install extensions', 'permissiondenied' );
+ }
+
+ $params = $this->extractRequestParams();
+ $extension = $params['extension'];
+ $exts = ExtensionFetcher::discoverExtensions();
+ if ( !array_key_exists( $extension, $exts ) ) {
+ $this->dieUsage( "Invalid extension ``{$extension}''", 'invalidextension' );
+ }
+
+ $ext = $exts[$extension];
+ $ext->cloneRepo();
+
+ $r[$ext] = 'installed';
+
+ $this->getResult()->addValue( null, $this->getModuleName(), $r );
+ }
+
+ public function mustBePosted() {
+ return true;
+ }
+
+ public function isWriteMode() {
+ return true;
+ }
+
+ public function needsToken() {
+ return true;
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'extension' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'token' => null,
+ );
+ }
+
+ public function getParamDescription() {
+ return array(
+ 'extension' => 'Name of extension',
+ 'token' => 'Edit token. You can get one of these through prop=info.' ,
+ );
+ }
+
+ public function getDescription() {
+ return array(
+ 'Attempt to fetch and install an extension from the master gerrit repositories'
+ );
+ }
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'permissiondenied', 'info' => 'You don\'t have permission to update code' ),
+ array( 'code' => 'invalidextension', 'info' => "Invalid extension ``extension''" ),
+ ) );
+ }
+
+ public function getVersion() {
+ return '1';
+ }
+}
View
@@ -0,0 +1,28 @@
+$(function() {
+ $('button.mw-extfetch-fetch').click(function() {
+ var $button = $(this);
+ $button.attr('disabled', 'disabled');
+
+ $.ajax({
+ url: mw.util.wikiScript('api'),
+ data: {
+ format: 'json',
+ action: 'extfetch',
+ extension: $button.data('extension'),
+ token: mw.user.tokens.get('editToken')
+ },
+ type: 'POST',
+ }).done(function(data) {
+ if (typeof data.error == "object") {
+ console.log('error!', data);
+ $button.removeAttr('disabled');
+ } else {
+ console.log('success!', data);
+ $button.replaceWith('Present'); // @fixme localize
+ }
+ }).fail(function(data) {
+ console.log('fail!');
+ });
+ });
+});
+
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * ExtensionFetcher for MediaWiki
+ * Copyright (c) 2012 Brion Vibber & Wikimedia Foundation, Inc.
+ * licensed under GNU GPL v2 or later
+ */
+
+class SpecialExtensionFetcher extends SpecialPage {
+ public function __construct() {
+ parent::__construct( 'ExtensionFetcher', 'extension-install' );
+ }
+
+ public function execute( $subpage ) {
+ global $wgRequest, $wgUser;
+
+ $this->setHeaders();
+
+ if ( !$this->userCanExecute( $wgUser ) ) {
+ $this->displayRestrictionError();
+ return;
+ }
+
+ $extensions = ExtensionFetcher::discoverExtensions();
+ $out = $this->getOutput();
+ $out->addModules( 'ext.extfetch' );
+
+ $out->addHTML( Html::openElement( 'table' ) );
+
+ foreach( $extensions as $ext ) {
+ $this->addExtensionRow( $ext );
+ }
+
+ $out->addHTML( Html::closeElement( 'table' ) );
+ }
+
+ protected function addExtensionRow( ExtFetchExtension $ext ) {
+ $out = $this->getOutput();
+ $classes = array();
+ if ( $ext->isPresent() ) {
+ $classes[] = 'present';
+ $button = wfMessage( 'extfetch-present' )->escaped();
+ } else {
+ $classes[] = 'available';
+ $button = Html::element( 'button', array( 'class' => 'mw-extfetch-fetch', 'data-extension' => $ext->name ), wfMsg( 'extfetch-fetch' ) );
+ }
+ $out->addHTML( Html::openElement( 'tr', array( 'class' => implode( ' ', $classes ) ) ) );
+
+ $out->addHTML( Html::openElement( 'td' ) );
+ $out->addHTML( $button );
+ $out->addHTML( Html::closeElement( 'td' ) );
+
+ $out->addHTML( Html::openElement( 'td' ) );
+ $out->addHTML( Html::element( 'a', array( 'href' => $ext->getLink() ), $ext->name ) );
+ $out->addHTML( Html::closeElement( 'td' ) );
+
+ $out->addHTML( Html::element( 'td', array(), $ext->description ) );
+
+ $out->addHTML( Html::closeElement( 'tr' ) );
+ }
+}
+

0 comments on commit b959274

Please sign in to comment.