Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | n/a |
0 / 0 |
n/a |
0 / 0 |
CRAP | n/a |
0 / 0 |
|||
PopulateImageTables | n/a |
0 / 0 |
n/a |
0 / 0 |
17 | n/a |
0 / 0 |
|||
__construct | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
execute | n/a |
0 / 0 |
n/a |
0 / 0 |
13 | |||||
getImages | n/a |
0 / 0 |
n/a |
0 / 0 |
3 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\MediaModeration\Maintenance\Dev; |
4 | |
5 | use Error; |
6 | use LocalFile; |
7 | use MediaWiki\Maintenance\Maintenance; |
8 | use MediaWiki\Title\Title; |
9 | use MediaWiki\User\User; |
10 | use UploadFromUrl; |
11 | |
12 | // This is a local development only script, no need to count it in code coverage metrics. |
13 | // @codeCoverageIgnoreStart |
14 | $IP = getenv( 'MW_INSTALL_PATH' ); |
15 | if ( $IP === false ) { |
16 | $IP = __DIR__ . '/../../..'; |
17 | } |
18 | require_once "$IP/maintenance/Maintenance.php"; |
19 | |
20 | /** |
21 | * Maintenance script for importing some real world images from Commons to a local wiki. A subset |
22 | * of the total will have new versions uploaded and another subset of the total will be deleted, so |
23 | * as to populate various tables that MediaModeration scans. |
24 | */ |
25 | class PopulateImageTables extends Maintenance { |
26 | |
27 | public function __construct() { |
28 | parent::__construct(); |
29 | $this->addDescription( 'Populate rows in image tables with fake data. |
30 | This cannot be easily undone. Do not run this script in production!' ); |
31 | $this->addOption( 'count', 'How many rows to create' ); |
32 | } |
33 | |
34 | public function execute() { |
35 | if ( !$this->getConfig()->get( 'MediaModerationDeveloperMode' ) || |
36 | !$this->getConfig()->get( 'AllowCopyUploads' ) ) { |
37 | $this->error( 'AllowCopyUploads and MediaModerationDeveloperMode must be set to true.' ); |
38 | return; |
39 | } |
40 | if ( $this->getConfig()->get( 'MaxImageArea' ) ) { |
41 | $this->output( 'For this script, the recommended value for $wgMaxImageArea is `false`.' ); |
42 | } |
43 | if ( $this->getConfig()->get( 'CheckFileExtensions' ) ) { |
44 | $this->output( 'For this script, the recommended value for $wgCheckFileExtensions is `false`.' ); |
45 | } |
46 | $count = $this->getOption( 'count', 100 ); |
47 | $user = User::newSystemUser( 'MediaModeration' ); |
48 | |
49 | // TODO: Allow for continuation if the user wants e.g. 1000 images imported. |
50 | |
51 | $uploadedImages = []; |
52 | $fileRepo = $this->getServiceContainer()->getRepoGroup()->getLocalRepo(); |
53 | |
54 | foreach ( $this->getImages( $count ) as $image ) { |
55 | $this->output( "Importing image {$image['title']}\n" ); |
56 | $maintenanceUpload = new UploadFromUrl(); |
57 | if ( !isset( $image['pageimage'] ) ) { |
58 | // TODO This occurs often. Should find some way to require that the metadata is present. |
59 | $this->output( "... skipping, does not have image metadata\n" ); |
60 | continue; |
61 | } |
62 | $maintenanceUpload->initialize( $image['pageimage'], $image['original']['source'] ); |
63 | if ( !$maintenanceUpload->getTitle() ) { |
64 | $this->fatalError( 'illegal-filename' ); |
65 | } |
66 | $maintenanceUpload->fetchFile(); |
67 | try { |
68 | $uploadResult = $maintenanceUpload->performUpload( |
69 | 'MediaModeration PopulateImageTables.php', |
70 | 'MediaModeration', |
71 | false, |
72 | $user |
73 | ); |
74 | if ( $uploadResult->isGood() ) { |
75 | $uploadedImages[] = $fileRepo->newFile( |
76 | Title::newFromText( $image['title'], NS_FILE ) |
77 | ); |
78 | } else { |
79 | $this->error( "... unable to perform upload.\n" ); |
80 | } |
81 | } catch ( Error $error ) { |
82 | $this->error( "... unable to import\n" ); |
83 | } |
84 | } |
85 | // Upload new versions of 20% of images. |
86 | $newImageVersions = array_intersect_key( $uploadedImages, array_rand( $uploadedImages, $count / 5 ) ); |
87 | // Get new images to use |
88 | $newImages = $this->getImages( $count / 5 ); |
89 | /** |
90 | * @var int $key |
91 | * @var LocalFile $newImageVersion |
92 | */ |
93 | foreach ( $newImageVersions as $key => $newImageVersion ) { |
94 | // Upload new version of image. |
95 | $maintenanceUpload = new UploadFromUrl(); |
96 | $titleText = $newImageVersion->getTitle()->getText(); |
97 | $maintenanceUpload->initialize( $titleText, $newImages[$key]['original']['source'] ); |
98 | if ( !$maintenanceUpload->getTitle() ) { |
99 | $this->fatalError( 'illegal-filename' ); |
100 | } |
101 | $maintenanceUpload->fetchFile(); |
102 | $this->output( "Uploading new version of $titleText\n" ); |
103 | $maintenanceUpload->performUpload( |
104 | 'MediaModeration PopulateImages.php update', |
105 | 'MediaModeration', |
106 | false, |
107 | $user |
108 | ); |
109 | } |
110 | $deleteImages = array_intersect_key( $uploadedImages, array_rand( $uploadedImages, $count / 5 ) ); |
111 | /** @var LocalFile $image */ |
112 | foreach ( $deleteImages as $image ) { |
113 | $this->output( 'Deleting ' . $image->getTitle()->getText() . PHP_EOL ); |
114 | $image->deleteFile( 'MediaModeration testing', $user ); |
115 | } |
116 | } |
117 | |
118 | private function getImages( int $count ): array { |
119 | $url = wfAppendQuery( 'https://commons.wikimedia.org/w/api.php', [ |
120 | 'action' => 'query', |
121 | 'prop' => 'pageimages', |
122 | 'generator' => 'search', |
123 | 'piprop' => 'thumbnail|name|original', |
124 | 'format' => 'json', |
125 | // Exclude items with .pdf |
126 | // TODO there's probably a nicer way to get just the file types we want. |
127 | 'gsrsearch' => '!".pdf"', |
128 | 'gsrnamespace' => NS_FILE, |
129 | 'gsrsort' => 'random', |
130 | 'gsrlimit' => $count, |
131 | 'formatversion' => 2 |
132 | ] ); |
133 | $request = $this->getServiceContainer()->getHttpRequestFactory()->create( $url, [], __METHOD__ ); |
134 | $result = $request->execute(); |
135 | if ( !$result->isOK() ) { |
136 | return []; |
137 | } |
138 | $data = json_decode( $request->getContent(), true ); |
139 | if ( !isset( $data['query']['pages'] ) ) { |
140 | $this->error( 'Unable to get images' ); |
141 | return []; |
142 | } |
143 | return $data['query']['pages']; |
144 | } |
145 | } |
146 | |
147 | $maintClass = PopulateImageTables::class; |
148 | require_once RUN_MAINTENANCE_IF_MAIN; |
149 | // @codeCoverageIgnoreEnd |