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 MediaWiki\FileRepo\File\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 ) { |
| 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 |