ec5a16b36eb5908a23fc43fe37f3e0c1ba30f00a
[lhc/web/wiklou.git] / maintenance / importImages.php
1 <?php
2
3 /**
4 * Maintenance script to import one or more images from the local file system into
5 * the wiki without using the web-based interface
6 *
7 * @file
8 * @ingroup Maintenance
9 * @author Rob Church <robchur@gmail.com>
10 */
11
12 $optionsWithArgs = array( 'extensions', 'comment', 'comment-file', 'comment-ext', 'user', 'license', 'sleep', 'limit', 'from' );
13 require_once( dirname(__FILE__) . '/commandLine.inc' );
14 require_once( 'importImages.inc' );
15 $processed = $added = $ignored = $skipped = $overwritten = $failed = 0;
16
17 echo( "Import Images\n\n" );
18
19 # Need a path
20 if( count( $args ) > 0 ) {
21
22 $dir = $args[0];
23
24 # Check Protection
25 if (isset($options['protect']) && isset($options['unprotect']))
26 die("Cannot specify both protect and unprotect. Only 1 is allowed.\n");
27
28 if (isset($options['protect']) && $options['protect'] == 1)
29 die("You must specify a protection option.\n");
30
31 # Prepare the list of allowed extensions
32 global $wgFileExtensions;
33 $extensions = isset( $options['extensions'] )
34 ? explode( ',', strtolower( $options['extensions'] ) )
35 : $wgFileExtensions;
36
37 # Search the path provided for candidates for import
38 $files = findFiles( $dir, $extensions );
39
40 # Initialise the user for this operation
41 $user = isset( $options['user'] )
42 ? User::newFromName( $options['user'] )
43 : User::newFromName( 'Maintenance script' );
44 if( !$user instanceof User )
45 $user = User::newFromName( 'Maintenance script' );
46 $wgUser = $user;
47
48 # Get --from
49 $from = @$options['from'];
50
51 # Get sleep time.
52 $sleep = @$options['sleep'];
53 if ( $sleep ) $sleep = (int)$sleep;
54
55 # Get limit number
56 $limit = @$options['limit'];
57 if ( $limit ) $limit = (int)$limit;
58
59 # Get the upload comment
60 $comment = 'Importing image file';
61
62 if ( isset( $options['comment-file'] ) ) {
63 $comment = file_get_contents( $options['comment-file'] );
64 if ( $comment === false || $comment === NULL ) {
65 die( "failed to read comment file: {$options['comment-file']}\n" );
66 }
67 }
68 else if ( isset( $options['comment'] ) ) {
69 $comment = $options['comment'];
70 }
71
72 $commentExt = isset( $options['comment-ext'] ) ? $options['comment-ext'] : false;
73
74 # Get the license specifier
75 $license = isset( $options['license'] ) ? $options['license'] : '';
76
77 # Batch "upload" operation
78 if( ( $count = count( $files ) ) > 0 ) {
79
80 foreach( $files as $file ) {
81 $base = wfBaseName( $file );
82
83 # Validate a title
84 $title = Title::makeTitleSafe( NS_FILE, $base );
85 if( !is_object( $title ) ) {
86 echo( "{$base} could not be imported; a valid title cannot be produced\n" );
87 continue;
88 }
89
90 if ( $from ) {
91 if ( $from == $title->getDBkey() ) {
92 $from = NULL;
93 } else {
94 $ignored++;
95 continue;
96 }
97 }
98
99 # Check existence
100 $image = wfLocalFile( $title );
101 if( $image->exists() ) {
102 if( isset( $options['overwrite'] ) ) {
103 echo( "{$base} exists, overwriting..." );
104 $svar = 'overwritten';
105 } else {
106 echo( "{$base} exists, skipping\n" );
107 $skipped++;
108 continue;
109 }
110 } else {
111 echo( "Importing {$base}..." );
112 $svar = 'added';
113 }
114
115 # Find comment text
116 $commentText = false;
117
118 if ( $commentExt ) {
119 $f = findAuxFile( $file, $commentExt );
120 if ( !$f ) {
121 echo( " No comment file with extension {$commentExt} found for {$file}, using default comment. " );
122 } else {
123 $commentText = file_get_contents( $f );
124 if ( !$f ) {
125 echo( " Failed to load comment file {$f}, using default comment. " );
126 }
127 }
128
129 if ( $commentText && $comment ) {
130 $commentText = trim( $commentText ) . "\n\n" . trim( $comment );
131 }
132 }
133
134 if ( !$commentText ) {
135 $commentText = $comment;
136 }
137
138 # Import the file
139 if ( isset( $options['dry'] ) ) {
140 echo( " publishing {$file}... " );
141 } else {
142 $archive = $image->publish( $file );
143 if( WikiError::isError( $archive ) || !$archive->isGood() ) {
144 echo( "failed.\n" );
145 $failed++;
146 continue;
147 }
148 }
149
150 $doProtect = false;
151 $restrictions = array();
152
153 global $wgRestrictionLevels;
154
155 $protectLevel = isset($options['protect']) ? $options['protect'] : null;
156
157 if ( $protectLevel && in_array( $protectLevel, $wgRestrictionLevels ) ) {
158 $restrictions['move'] = $protectLevel;
159 $restrictions['edit'] = $protectLevel;
160 $doProtect = true;
161 }
162 if (isset($options['unprotect'])) {
163 $restrictions['move'] = '';
164 $restrictions['edit'] = '';
165 $doProtect = true;
166 }
167
168
169 if ( isset( $options['dry'] ) ) {
170 echo( "done.\n" );
171 } else if ( $image->recordUpload( $archive->value, $commentText, $license ) ) {
172 # We're done!
173 echo( "done.\n" );
174 if ($doProtect) {
175 # Protect the file
176 $article = new Article( $title );
177 echo "\nWaiting for slaves...\n";
178 // Wait for slaves.
179 sleep(2.0);
180 wfWaitForSlaves( 1.0 );
181
182 echo( "\nSetting image restrictions ... " );
183 if ( $article->updateRestrictions($restrictions) )
184 echo( "done.\n" );
185 else
186 echo( "failed.\n" );
187 }
188
189 } else {
190 echo( "failed.\n" );
191 $svar = 'failed';
192 }
193
194 $$svar++;
195 $processed++;
196
197 if ( $limit && $processed >= $limit )
198 break;
199
200 if ( $sleep )
201 sleep( $sleep );
202 }
203
204 # Print out some statistics
205 echo( "\n" );
206 foreach( array( 'count' => 'Found', 'limit' => 'Limit', 'ignored' => 'Ignored',
207 'added' => 'Added', 'skipped' => 'Skipped', 'overwritten' => 'Overwritten',
208 'failed' => 'Failed' ) as $var => $desc ) {
209 if( $$var > 0 )
210 echo( "{$desc}: {$$var}\n" );
211 }
212
213 } else {
214 echo( "No suitable files could be found for import.\n" );
215 }
216
217 } else {
218 showUsage();
219 }
220
221 exit(0);
222
223 function showUsage( $reason = false ) {
224 if( $reason ) {
225 echo( $reason . "\n" );
226 }
227
228 echo <<<END
229 Imports images and other media files into the wiki
230 USAGE: php importImages.php [options] <dir>
231
232 <dir> : Path to the directory containing images to be imported
233
234 Options:
235 --extensions=<exts> Comma-separated list of allowable extensions, defaults to \$wgFileExtensions
236 --overwrite Overwrite existing images with the same name (default is to skip them)
237 --limit=<num> Limit the number of images to process. Ignored or skipped images are not counted.
238 --from=<name> Ignore all files until the one with the given name. Useful for resuming
239 aborted imports. <name> should be the file's canonical database form.
240 --sleep=<sec> Sleep between files. Useful mostly for debugging.
241 --user=<username> Set username of uploader, default 'Maintenance script'
242 --comment=<text> Set upload summary comment, default 'Importing image file'.
243 --comment-file=<file> Set upload summary comment the the content of <file>.
244 --comment-ext=<ext> Causes the comment for each file to be loaded from a file with the same name
245 but the extension <ext>. If a global comment is also given, it is appended.
246 --license=<code> Use an optional license template
247 --dry Dry run, don't import anything
248 --protect=<protect> Specify the protect value (autoconfirmed,sysop)
249 --unprotect Unprotects all uploaded images
250
251 END;
252 exit(1);
253 }