Index: trunk/extensions/ExtensionDistributor/ExtensionDistributor_body.php |
— | — | @@ -0,0 +1,252 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class ExtensionDistributorPage extends SpecialPage { |
| 5 | + var $extensionList; // cached list of extensions |
| 6 | + |
| 7 | + function __construct() { |
| 8 | + parent::__construct( 'ExtensionDistributor' ); |
| 9 | + } |
| 10 | + |
| 11 | + function execute( $subpage ) { |
| 12 | + global $wgExtDistTarDir, $wgExtDistWorkingCopy, $wgOut, $wgRequest; |
| 13 | + |
| 14 | + wfLoadExtensionMessages( 'ExtensionDistributor' ); |
| 15 | + $this->setHeaders(); |
| 16 | + |
| 17 | + if ( !$wgExtDistTarDir || !$wgExtDistWorkingCopy ) { |
| 18 | + $wgOut->addWikiMsg( 'extdist-not-configured' ); |
| 19 | + return; |
| 20 | + } |
| 21 | + |
| 22 | + if ( $subpage ) { |
| 23 | + $parts = explode( '/', $subpage, 2 ); |
| 24 | + if ( count( $parts ) == 1 ) { |
| 25 | + $parts[] = false; |
| 26 | + } |
| 27 | + list( $extension, $version ) = $parts; |
| 28 | + } else { |
| 29 | + $extension = $wgRequest->getVal( 'extdist_extension' ); |
| 30 | + $version = $wgRequest->getVal( 'extdist_version' ); |
| 31 | + } |
| 32 | + |
| 33 | + if ( !$extension ) { |
| 34 | + $this->showExtensionSelector(); |
| 35 | + return; |
| 36 | + } |
| 37 | + |
| 38 | + $extensions = $this->getExtensionList(); |
| 39 | + if( !in_array( $extension, $extensions['trunk'] ) ) { |
| 40 | + $wgOut->addWikiMsg( 'extdist-no-such-extension', $extension ); |
| 41 | + $this->showExtensionSelector(); |
| 42 | + return; |
| 43 | + } |
| 44 | + |
| 45 | + if ( !$version ) { |
| 46 | + $this->showVersionSelector( $extension ); |
| 47 | + return; |
| 48 | + } |
| 49 | + |
| 50 | + if ( !isset( $extensions[$version] ) || !in_array( $extension, $extensions[$version] ) ) { |
| 51 | + $wgOut->addWikiMsg( 'extdist-no-such-version', $extension, $version ); |
| 52 | + return; |
| 53 | + } |
| 54 | + |
| 55 | + $this->doDownload( $extension, $version ); |
| 56 | + } |
| 57 | + |
| 58 | + function getExtensionList() { |
| 59 | + global $wgExtDistWorkingCopy, $wgExtDistBranches; |
| 60 | + |
| 61 | + if ( isset( $this->extensionList ) ) { |
| 62 | + return $this->extensionList; |
| 63 | + } |
| 64 | + |
| 65 | + $this->extensionList = array(); |
| 66 | + foreach ( $wgExtDistBranches as $branchPath => $branch ) { |
| 67 | + $wc = "$wgExtDistWorkingCopy/$branchPath/extensions"; |
| 68 | + $dir = opendir( $wc ); |
| 69 | + if ( !$dir ) { |
| 70 | + return false; |
| 71 | + } |
| 72 | + |
| 73 | + $this->extensionList[$branchPath] = array(); |
| 74 | + while ( false !== ($file = readdir( $dir )) ) { |
| 75 | + if ( substr( $file, 0, 1 ) == '.' ) { |
| 76 | + continue; |
| 77 | + } |
| 78 | + if ( !is_dir( "$wc/$file" ) ) { |
| 79 | + continue; |
| 80 | + } |
| 81 | + if ( file_exists( "$wc/$file/NO-DIST" ) ) { |
| 82 | + continue; |
| 83 | + } |
| 84 | + $this->extensionList[$branchPath][] = $file; |
| 85 | + } |
| 86 | + natcasesort( $this->extensionList[$branchPath] ); |
| 87 | + } |
| 88 | + return $this->extensionList; |
| 89 | + } |
| 90 | + |
| 91 | + function getBranchName( $path ) { |
| 92 | + global $wgExtDistBranches; |
| 93 | + if ( !isset( $wgExtDistBranches[$path] ) ) { |
| 94 | + return false; |
| 95 | + } |
| 96 | + if ( isset( $wgExtDistBranches[$path]['msgName'] ) ) { |
| 97 | + return wfMsg( $wgExtDistBranches[$path]['msgName'] ); |
| 98 | + } else { |
| 99 | + return $wgExtDistBranches[$path]['name']; |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + function showExtensionSelector() { |
| 104 | + global $wgOut; |
| 105 | + |
| 106 | + $extensions = $this->getExtensionList(); |
| 107 | + if ( $extensions === false ) { |
| 108 | + $wgOut->addWikiMsg( 'extdist-wc-missing' ); |
| 109 | + return; |
| 110 | + } |
| 111 | + if ( !$extensions['trunk'] ) { |
| 112 | + $wgOut->addWikiMsg( 'extdist-wc-empty' ); |
| 113 | + return; |
| 114 | + } |
| 115 | + |
| 116 | + $wgOut->addWikiMsg( 'extdist-choose-extension' ); |
| 117 | + $wgOut->addHTML( |
| 118 | + Xml::openElement( 'form', array( |
| 119 | + 'action' => $this->getTitle()->getLocalUrl(), |
| 120 | + 'method' => 'POST' ) ) . |
| 121 | + "<select name=\"extdist_extension\">\n" . |
| 122 | + "<option value=''></option\n" |
| 123 | + ); |
| 124 | + |
| 125 | + foreach ( $extensions['trunk'] as $extension ) { |
| 126 | + $wgOut->addHTML( Xml::element( 'option', array( 'value' => $extension ), $extension ) . "\n" ); |
| 127 | + } |
| 128 | + |
| 129 | + $wgOut->addHTML( "</select>" . |
| 130 | + Xml::element( 'input', array( 'type' => 'submit', 'name' => 'extdist_submit', |
| 131 | + 'value' => wfMsg( 'extdist-submit-extension' ) ) ) . |
| 132 | + "</form>\n" ); |
| 133 | + } |
| 134 | + |
| 135 | + function showVersionSelector( $extensionName ) { |
| 136 | + global $wgOut, $wgExtDistBranches; |
| 137 | + $extensions = $this->getExtensionList(); |
| 138 | + |
| 139 | + $versions = array(); |
| 140 | + foreach ( $wgExtDistBranches as $branchPath => $branch ) { |
| 141 | + if ( !in_array( $extensionName, $extensions[$branchPath] ) ) { |
| 142 | + continue; |
| 143 | + } |
| 144 | + |
| 145 | + if ( isset( $branch['msgName'] ) ) { |
| 146 | + $branchName = wfMsg( $branch['msgName'] ); |
| 147 | + } else { |
| 148 | + $branchName = $branch['name']; |
| 149 | + } |
| 150 | + $versions[$branchPath] = $branchName; |
| 151 | + } |
| 152 | + |
| 153 | + if ( !$versions ) { |
| 154 | + $wgOut->addWikiMsg( 'extdist-no-versions', $extensionName ); |
| 155 | + $this->showExtensionSelector(); |
| 156 | + return; |
| 157 | + } |
| 158 | + |
| 159 | + $wgOut->addWikiMsg( 'extdist-choose-version', $extensionName ); |
| 160 | + $wgOut->addHTML( |
| 161 | + Xml::openElement( 'form', array( |
| 162 | + 'action' => $this->getTitle()->getLocalUrl(), |
| 163 | + 'method' => 'POST' ) ) . |
| 164 | + Xml::element( 'input' , array( 'type' => 'hidden', |
| 165 | + 'name' => 'extdist_extension', 'value' => $extensionName ) ) . |
| 166 | + "<select name=\"extdist_version\">\n" ); |
| 167 | + foreach ( $versions as $branchPath => $branchName ) { |
| 168 | + $wgOut->addHTML( Xml::element( 'option', |
| 169 | + array( 'value' => $branchPath ), $branchName ) . "\n" ); |
| 170 | + } |
| 171 | + $wgOut->addHTML( "</select>" . |
| 172 | + Xml::element( 'input', array( 'type' => 'submit', 'name' => 'extdist_submit', |
| 173 | + 'value' => wfMsg( 'extdist-submit-version' ) ) ) . |
| 174 | + "</form>\n" |
| 175 | + ); |
| 176 | + } |
| 177 | + |
| 178 | + function doDownload( $extension, $version ) { |
| 179 | + global $wgExtDistWorkingCopy, $wgExtDistTarDir, $wgExtDistBranches, |
| 180 | + $wgOut, $wgExtDistTarUrl; |
| 181 | + |
| 182 | + // svn up |
| 183 | + $dir = "$wgExtDistWorkingCopy/$version/extensions/$extension"; |
| 184 | + $cmd = "svn up --non-interactive " . wfEscapeShellArg( $dir ) . " 2>&1"; |
| 185 | + $retval = -1; |
| 186 | + $result = wfShellExec( $cmd, $retval ); |
| 187 | + if ( $retval ) { |
| 188 | + $wgOut->addWikiMsg( 'extdist-svn-error', $retval ); |
| 189 | + $wgOut->addHTML( '<pre>' . htmlspecialchars( $result ) . '</pre>' ); |
| 190 | + return; |
| 191 | + } |
| 192 | + |
| 193 | + // Determine last changed revision |
| 194 | + $cmd = "svn info --non-interactive --xml " . wfEscapeShellArg( $dir ); |
| 195 | + $retval = -1; |
| 196 | + $result = wfShellExec( $cmd, $retval ); |
| 197 | + if ( $retval ) { |
| 198 | + $wgOut->addWikiMsg( 'extdist-svn-error', $retval ); |
| 199 | + $wgOut->addHTML( '<pre>' . htmlspecialchars( $result ) . '</pre>' ); |
| 200 | + return; |
| 201 | + } |
| 202 | + |
| 203 | + $sx = new SimpleXMLElement( $result ); |
| 204 | + $rev = $sx->entry->commit['revision']; |
| 205 | + if ( !$rev || strpos( $rev, '/' ) !== false || strpos( $rev, "\000" ) !== false ) { |
| 206 | + $wgOut->addWikiMsg( 'extdist-svn-parse-error' ); |
| 207 | + $wgOut->addHTML( '<pre>' . htmlspecialchars( $result ) . '</pre>' ); |
| 208 | + return; |
| 209 | + } |
| 210 | + |
| 211 | + // Determine tar name |
| 212 | + $cleanName = str_replace( '/', '_', $extension ); |
| 213 | + $versionName = $wgExtDistBranches[$version]['tarLabel']; |
| 214 | + $tarName = "$cleanName-$versionName-r$rev.tar.gz"; |
| 215 | + $tarFile = "$wgExtDistTarDir/$tarName"; |
| 216 | + |
| 217 | + // Create it if it doesn't exist |
| 218 | + if ( !file_exists( $tarFile ) ) { |
| 219 | + // Does the tar file need ExtensionFunctions.php? |
| 220 | + $retval = -1; |
| 221 | + $files = call_user_func_array( 'wfEscapeShellArg', glob( "$dir/*.php" ) ); |
| 222 | + wfShellExec( "grep -q ExtensionFunctions " . $files, $retval ); |
| 223 | + $needEF = !$retval; |
| 224 | + |
| 225 | + // Create the archive |
| 226 | + $cmd = 'tar -czf ' . wfEscapeShellArg( $tarFile ) . |
| 227 | + ' --exclude \'*/.svn*\'' . |
| 228 | + ' -C ' . wfEscapeShellArg( "$wgExtDistWorkingCopy/$version/extensions" ) . |
| 229 | + ' ' . wfEscapeShellArg( $extension ) . |
| 230 | + ( $needEF ? ' ExtensionFunctions.php' : '' ) . |
| 231 | + ' 2>&1'; |
| 232 | + $retval = -1; |
| 233 | + $result = wfShellExec( $cmd, $retval ); |
| 234 | + if ( $retval ) { |
| 235 | + $wgOut->addWikiMsg( 'extdist-tar-error', $retval ); |
| 236 | + $wgOut->addHTML( '<pre>' . htmlspecialchars( $result ) . '</pre>' ); |
| 237 | + return; |
| 238 | + } |
| 239 | + } |
| 240 | + |
| 241 | + $url = "$wgExtDistTarUrl/$tarName"; |
| 242 | + |
| 243 | + // Show a message |
| 244 | + $wgOut->addWikiMsg( 'extdist-created', $extension, "r$rev", |
| 245 | + $this->getBranchName( $version ), $url ); |
| 246 | + $wgOut->addHTML( '<p><br/><big>' . |
| 247 | + '<a href="' . $this->getTitle()->escapeLocalUrl() . '">' . |
| 248 | + htmlspecialchars( wfMsg( 'extdist-want-more' ) ) . '</a></big></p>' ); |
| 249 | + |
| 250 | + // Redirect to the file |
| 251 | + header( 'Refresh: 5;' . $url ); |
| 252 | + } |
| 253 | +} |
Property changes on: trunk/extensions/ExtensionDistributor/ExtensionDistributor_body.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 254 | + native |
Index: trunk/extensions/ExtensionDistributor/ExtensionDistributor.i18n.php |
— | — | @@ -0,0 +1,35 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +$messages = array( |
| 5 | + 'en' => array( |
| 6 | + 'extensiondistributor' => 'Download MediaWiki extension', |
| 7 | + 'extdist-not-configured' => 'Please configure $wgExtDistTarDir and $wgExtDistWorkingCopy', |
| 8 | + 'extdist-wc-missing' => 'The configured working copy directory does not exist!', |
| 9 | + 'extdist-no-such-extension' => 'No such extension "$1"', |
| 10 | + 'extdist-no-such-version' => 'The extension "$1" does not exist in the version "$2".', |
| 11 | + 'extdist-choose-extension' => 'Select which extension you want to download:', |
| 12 | + 'extdist-wc-empty' => 'The configured working copy directory has no distributable extensions!', |
| 13 | + 'extdist-submit-extension' => 'Continue', |
| 14 | + 'extdist-current-version' => 'Current version (trunk)', |
| 15 | + 'extdist-choose-version' => ' |
| 16 | +<big>You are downloading the <b>$1</b> extension.</big> |
| 17 | + |
| 18 | +Select your MediaWiki version. |
| 19 | + |
| 20 | +Most extensions work across multiple versions of MediaWiki, so if your MediaWiki version is not here, or if you have a need for the latest extension features, try using the current version.', |
| 21 | + 'extdist-no-versions' => 'The selected extension ($1) is not available in any version!', |
| 22 | + 'extdist-submit-version' => 'Continue', |
| 23 | + 'extdist-svn-error' => 'Subversion returned exit code $1:', |
| 24 | + 'extdist-svn-parse-error' => 'Unable to process the XML from "svn info"', |
| 25 | + 'extdist-tar-error' => 'Tar returned exit code $1:', |
| 26 | + 'extdist-created' => "A snapshot of version <b>$2</b> of the <b>$1</b> extension for MediaWiki <b>$3</b> has been created. Your download should start automatically in 5 seconds. |
| 27 | + |
| 28 | +The URL for this snapshot is: |
| 29 | +:$4 |
| 30 | +It may be used for immediate download to a server, but please do not bookmark it, since the contents will not be updated, and it may be deleted at a later date. |
| 31 | + |
| 32 | +The tar archive should be extracted into your extensions directory, then follow the extension's documentation to enable it in MediaWiki. |
| 33 | +", |
| 34 | + 'extdist-want-more' => 'Get another extension', |
| 35 | + ), |
| 36 | +); |
Property changes on: trunk/extensions/ExtensionDistributor/ExtensionDistributor.i18n.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 37 | + native |
Index: trunk/extensions/ExtensionDistributor/ExtensionDistributor.php |
— | — | @@ -0,0 +1,48 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | + * This is an extension for distributing snapshot archives of extensions, |
| 6 | + * to be run on mediawiki.org |
| 7 | + */ |
| 8 | + |
| 9 | + |
| 10 | +/******************** |
| 11 | + * Configuration |
| 12 | + */ |
| 13 | + |
| 14 | +/** Directory to put tar files in */ |
| 15 | +$wgExtDistTarDir = false; |
| 16 | + |
| 17 | +/** URL corresponding to $wgExtDistTarDir */ |
| 18 | +$wgExtDistTarUrl = false; |
| 19 | + |
| 20 | +/** Subversion /mediawiki working copy */ |
| 21 | +$wgExtDistWorkingCopy = false; |
| 22 | + |
| 23 | +/** Supported branches, the first one is the default */ |
| 24 | +$wgExtDistBranches = array( |
| 25 | + 'trunk' => array( |
| 26 | + 'tarLabel' => 'trunk', |
| 27 | + 'msgName' => 'extdist-current-version', |
| 28 | + ), |
| 29 | + 'branches/REL1_12' => array( |
| 30 | + 'tarLabel' => 'MW1.12', |
| 31 | + 'name' => '1.12.x', |
| 32 | + ), |
| 33 | + 'branches/REL1_11' => array( |
| 34 | + 'tarLabel' => 'MW1.11', |
| 35 | + 'name' => '1.11.x', |
| 36 | + ), |
| 37 | + 'branches/REL1_10' => array( |
| 38 | + 'tarLabel' => 'MW1.12', |
| 39 | + 'name' => '1.10.x', |
| 40 | + ), |
| 41 | +); |
| 42 | + |
| 43 | +/******************** |
| 44 | + * Registration |
| 45 | + */ |
| 46 | +$wgSpecialPages['ExtensionDistributor'] = 'ExtensionDistributorPage'; |
| 47 | +$wgAutoloadClasses['ExtensionDistributorPage'] = dirname(__FILE__).'/ExtensionDistributor_body.php'; |
| 48 | +$wgExtensionMessagesFiles['ExtensionDistributor'] = dirname(__FILE__).'/ExtensionDistributor.i18n.php'; |
| 49 | + |
Property changes on: trunk/extensions/ExtensionDistributor/ExtensionDistributor.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 50 | + native |
Index: trunk/extensions/ExtensionDistributor/svn-setup.sh |
— | — | @@ -0,0 +1,16 @@ |
| 2 | +#!/bin/bash |
| 3 | +set -e |
| 4 | + |
| 5 | +svn co -N http://svn.wikimedia.org/svnroot/mediawiki mw-snapshot |
| 6 | +cd mw-snapshot |
| 7 | +svn co -N http://svn.wikimedia.org/svnroot/mediawiki/trunk |
| 8 | +svn co -N http://svn.wikimedia.org/svnroot/mediawiki/branches |
| 9 | +cd branches |
| 10 | +svn co -N http://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_10 |
| 11 | +svn co -N http://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_11 |
| 12 | +svn co -N http://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_12 |
| 13 | +svn co http://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_10/extensions REL1_10/extensions |
| 14 | +svn co http://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_11/extensions REL1_11/extensions |
| 15 | +svn co http://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_12/extensions REL1_12/extensions |
| 16 | +cd ../trunk |
| 17 | +svn co http://svn.wikimedia.org/svnroot/mediawiki/trunk/extensions |
Property changes on: trunk/extensions/ExtensionDistributor/svn-setup.sh |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 18 | + native |
Added: svn:executable |
2 | 19 | + * |