2012-11-27 00:09:01 +00:00
|
|
|
<?php
|
|
|
|
|
/**
|
|
|
|
|
* Refresh file headers from metadata.
|
|
|
|
|
*
|
|
|
|
|
* Usage: php refreshFileHeaders.php
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
|
|
|
*
|
|
|
|
|
* @file
|
|
|
|
|
* @ingroup Maintenance
|
|
|
|
|
*/
|
|
|
|
|
|
2023-08-01 21:04:32 +00:00
|
|
|
use MediaWiki\FileRepo\File\FileSelectQueryBuilder;
|
|
|
|
|
use Wikimedia\Rdbms\SelectQueryBuilder;
|
2020-02-04 15:44:08 +00:00
|
|
|
|
2024-08-27 12:00:25 +00:00
|
|
|
// @codeCoverageIgnoreStart
|
2013-05-17 00:16:59 +00:00
|
|
|
require_once __DIR__ . '/Maintenance.php';
|
2024-08-27 12:00:25 +00:00
|
|
|
// @codeCoverageIgnoreEnd
|
2012-11-27 00:09:01 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Maintenance script to refresh file headers from metadata
|
|
|
|
|
*
|
|
|
|
|
* @ingroup Maintenance
|
|
|
|
|
*/
|
|
|
|
|
class RefreshFileHeaders extends Maintenance {
|
2019-10-09 18:41:33 +00:00
|
|
|
public function __construct() {
|
2012-11-27 00:09:01 +00:00
|
|
|
parent::__construct();
|
2016-01-30 02:48:47 +00:00
|
|
|
$this->addDescription( 'Script to update file HTTP headers' );
|
2012-11-27 00:09:01 +00:00
|
|
|
$this->addOption( 'verbose', 'Output information about each file.', false, false, 'v' );
|
|
|
|
|
$this->addOption( 'start', 'Name of file to start with', false, true );
|
|
|
|
|
$this->addOption( 'end', 'Name of file to end with', false, true );
|
2017-09-21 13:17:10 +00:00
|
|
|
$this->addOption( 'media_type', 'Media type to filter for', false, true );
|
|
|
|
|
$this->addOption( 'major_mime', 'Major mime type to filter for', false, true );
|
|
|
|
|
$this->addOption( 'minor_mime', 'Minor mime type to filter for', false, true );
|
2017-11-27 15:01:37 +00:00
|
|
|
$this->addOption(
|
|
|
|
|
'refreshContentType',
|
|
|
|
|
'Set true to refresh file content type from mime data in db',
|
|
|
|
|
false,
|
|
|
|
|
false
|
|
|
|
|
);
|
2012-11-27 00:09:01 +00:00
|
|
|
$this->setBatchSize( 200 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function execute() {
|
2023-08-31 09:21:12 +00:00
|
|
|
$repo = $this->getServiceContainer()->getRepoGroup()->getLocalRepo();
|
2012-11-27 00:09:01 +00:00
|
|
|
$start = str_replace( ' ', '_', $this->getOption( 'start', '' ) ); // page on img_name
|
|
|
|
|
$end = str_replace( ' ', '_', $this->getOption( 'end', '' ) ); // page on img_name
|
2021-09-03 22:52:31 +00:00
|
|
|
// filter by img_media_type
|
2017-09-21 13:17:10 +00:00
|
|
|
$media_type = str_replace( ' ', '_', $this->getOption( 'media_type', '' ) );
|
2021-09-03 22:52:31 +00:00
|
|
|
// filter by img_major_mime
|
2017-09-21 13:17:10 +00:00
|
|
|
$major_mime = str_replace( ' ', '_', $this->getOption( 'major_mime', '' ) );
|
2021-09-03 22:52:31 +00:00
|
|
|
// filter by img_minor_mime
|
2017-09-21 13:17:10 +00:00
|
|
|
$minor_mime = str_replace( ' ', '_', $this->getOption( 'minor_mime', '' ) );
|
2012-11-27 00:09:01 +00:00
|
|
|
|
|
|
|
|
$count = 0;
|
2024-01-17 18:53:40 +00:00
|
|
|
$dbr = $this->getReplicaDB();
|
2017-05-23 08:41:33 +00:00
|
|
|
|
2012-11-27 00:09:01 +00:00
|
|
|
do {
|
2023-08-01 21:04:32 +00:00
|
|
|
$queryBuilder = FileSelectQueryBuilder::newForFile( $dbr );
|
2017-05-23 08:41:33 +00:00
|
|
|
|
2024-01-17 17:48:40 +00:00
|
|
|
$queryBuilder->where( $dbr->expr( 'img_name', '>', $start ) );
|
2012-11-27 00:09:01 +00:00
|
|
|
if ( strlen( $end ) ) {
|
2024-01-17 17:48:40 +00:00
|
|
|
$queryBuilder->andWhere( $dbr->expr( 'img_name', '<=', $end ) );
|
2012-11-27 00:09:01 +00:00
|
|
|
}
|
2017-05-23 08:41:33 +00:00
|
|
|
|
2017-09-21 13:17:10 +00:00
|
|
|
if ( strlen( $media_type ) ) {
|
2023-08-01 21:04:32 +00:00
|
|
|
$queryBuilder->andWhere( [ 'img_media_type' => $media_type ] );
|
2017-09-21 13:17:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( strlen( $major_mime ) ) {
|
2023-08-01 21:04:32 +00:00
|
|
|
$queryBuilder->andWhere( [ 'img_major_mime' => $major_mime ] );
|
2017-09-21 13:17:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( strlen( $minor_mime ) ) {
|
2023-08-01 21:04:32 +00:00
|
|
|
$queryBuilder->andWhere( [ 'img_minor_mime' => $minor_mime ] );
|
2017-09-21 13:17:10 +00:00
|
|
|
}
|
|
|
|
|
|
2023-08-01 21:04:32 +00:00
|
|
|
$res = $queryBuilder
|
|
|
|
|
->orderBy( 'img_name', SelectQueryBuilder::SORT_ASC )
|
|
|
|
|
->limit( $this->getBatchSize() )
|
|
|
|
|
->caller( __METHOD__ )->fetchResultSet();
|
2017-05-15 21:16:35 +00:00
|
|
|
|
|
|
|
|
if ( $res->numRows() > 0 ) {
|
|
|
|
|
$row1 = $res->current();
|
|
|
|
|
$this->output( "Processing next {$res->numRows()} row(s) starting with {$row1->img_name}.\n" );
|
|
|
|
|
$res->rewind();
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-23 08:41:33 +00:00
|
|
|
$backendOperations = [];
|
|
|
|
|
|
2012-11-27 00:09:01 +00:00
|
|
|
foreach ( $res as $row ) {
|
|
|
|
|
$file = $repo->newFileFromRow( $row );
|
2017-04-26 12:01:49 +00:00
|
|
|
$headers = $file->getContentHeaders();
|
2017-11-27 15:01:37 +00:00
|
|
|
if ( $this->getOption( 'refreshContentType', false ) ) {
|
|
|
|
|
$headers['Content-Type'] = $row->img_major_mime . '/' . $row->img_minor_mime;
|
|
|
|
|
}
|
2017-05-23 08:41:33 +00:00
|
|
|
|
2012-11-27 00:09:01 +00:00
|
|
|
if ( count( $headers ) ) {
|
2017-05-23 08:41:33 +00:00
|
|
|
$backendOperations[] = [
|
|
|
|
|
'op' => 'describe', 'src' => $file->getPath(), 'headers' => $headers
|
|
|
|
|
];
|
2012-11-27 00:09:01 +00:00
|
|
|
}
|
2017-05-23 08:41:33 +00:00
|
|
|
|
2012-11-27 00:09:01 +00:00
|
|
|
// Do all of the older file versions...
|
|
|
|
|
foreach ( $file->getHistory() as $oldFile ) {
|
2017-04-26 12:01:49 +00:00
|
|
|
$headers = $oldFile->getContentHeaders();
|
2012-11-27 00:09:01 +00:00
|
|
|
if ( count( $headers ) ) {
|
2017-05-23 08:41:33 +00:00
|
|
|
$backendOperations[] = [
|
|
|
|
|
'op' => 'describe', 'src' => $oldFile->getPath(), 'headers' => $headers
|
|
|
|
|
];
|
2012-11-27 00:09:01 +00:00
|
|
|
}
|
|
|
|
|
}
|
2017-05-23 08:41:33 +00:00
|
|
|
|
2012-11-27 00:09:01 +00:00
|
|
|
if ( $this->hasOption( 'verbose' ) ) {
|
2017-05-23 08:41:33 +00:00
|
|
|
$this->output( "Queued headers update for file '{$row->img_name}'.\n" );
|
2012-11-27 00:09:01 +00:00
|
|
|
}
|
2017-05-23 08:41:33 +00:00
|
|
|
|
2012-11-27 00:09:01 +00:00
|
|
|
$start = $row->img_name; // advance
|
|
|
|
|
}
|
2017-05-23 08:41:33 +00:00
|
|
|
|
|
|
|
|
$backendOperationsCount = count( $backendOperations );
|
|
|
|
|
$count += $backendOperationsCount;
|
|
|
|
|
|
|
|
|
|
$this->output( "Updating headers for {$backendOperationsCount} file(s).\n" );
|
|
|
|
|
$this->updateFileHeaders( $repo, $backendOperations );
|
2017-11-05 08:09:51 +00:00
|
|
|
} while ( $res->numRows() === $this->getBatchSize() );
|
2012-11-27 00:09:01 +00:00
|
|
|
|
|
|
|
|
$this->output( "Done. Updated headers for $count file(s).\n" );
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-18 20:26:00 +00:00
|
|
|
/**
|
|
|
|
|
* @param LocalRepo $repo
|
|
|
|
|
* @param array $backendOperations
|
|
|
|
|
*/
|
2017-05-23 08:41:33 +00:00
|
|
|
protected function updateFileHeaders( $repo, $backendOperations ) {
|
|
|
|
|
$status = $repo->getBackend()->doQuickOperations( $backendOperations );
|
|
|
|
|
|
2012-11-27 00:09:01 +00:00
|
|
|
if ( !$status->isGood() ) {
|
Maintenance: Print errors from StatusValue objects in a consistent way
Allow Maintenance::error() and Maintenance::fatalError() to take
StatusValue objects. They now print each error message from the
status on a separate line, in English, ignoring on-wiki message
overrides, as wikitext but after parser function expansion.
Thoughts on the previously commonly used methods:
- $status->getMessage( false, false, 'en' )->text()
Almost the same as the new output, but it allows on-wiki message
overrides, and if there is more than one error, it prefixes each
line with a '*' (like a wikitext list).
- $status->getMessage( false, false, 'en' )->plain()
- $status->getWikiText( false, false, 'en' )
As above, but these forms do not expand parser functions
such as {{GENDER:}}.
- print_r( $status->getErrorsArray(), true )
- print_r( $status->getErrors(), true )
These forms output the message keys instead of the message text,
which is not very human-readable.
The error messages are now always printed using error() rather
than output(), which means they go to STDERR rather than STDOUT
and they're printed even with the --quiet flag.
Change-Id: I5b8e7c7ed2a896a1029f58857a478d3f1b4b0589
2024-06-06 23:50:00 +00:00
|
|
|
$this->error( $status );
|
2012-11-27 00:09:01 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-27 12:00:25 +00:00
|
|
|
// @codeCoverageIgnoreStart
|
2018-01-13 00:02:09 +00:00
|
|
|
$maintClass = RefreshFileHeaders::class;
|
2013-05-07 23:00:15 +00:00
|
|
|
require_once RUN_MAINTENANCE_IF_MAIN;
|
2024-08-27 12:00:25 +00:00
|
|
|
// @codeCoverageIgnoreEnd
|