| Current File : /home/jvzmxxx/wiki1/extensions/TimedMediaHandler/SpecialTimedMediaHandler.php |
<?php
/**
* Special:TimedMediaHandler
*
* Show some information about unprocessed jobs
*
* @file
* @ingroup SpecialPage
*/
class SpecialTimedMediaHandler extends SpecialPage {
// @codingStandardsIgnoreStart
private $transcodeStates = array(
'active' => 'transcode_time_startwork IS NOT NULL AND transcode_time_success IS NULL AND transcode_time_error IS NULL',
'failed' => 'transcode_time_startwork IS NOT NULL AND transcode_time_error IS NOT NULL',
'queued' => 'transcode_time_addjob IS NOT NULL AND transcode_time_startwork IS NULL',
'missing' => 'transcode_time_addjob IS NULL',
);
// @codingStandardsIgnoreEnd
private $formats = [
'ogg' => 'img_major_mime="application" AND img_minor_mime = "ogg"',
'webm' => 'img_major_mime="video" AND img_minor_mime = "webm"',
];
private $audioFormats = [
'ogg' => 'img_major_mime="application" AND img_minor_mime = "ogg"',
'webm' => 'img_major_mime="audio" AND img_minor_mime = "webm"',
'flac' => 'img_major_mime="audio" AND img_minor_mime="x-flac"',
'wav' => 'img_major_mime="audio" AND img_minor_mime="wav"',
];
public function __construct( $request = null, $par = null ) {
parent::__construct( 'TimedMediaHandler', 'transcode-status' );
}
public function execute( $par ) {
$this->setHeaders();
$out = $this->getOutput();
$out->addModuleStyles( 'mediawiki.special' );
$stats = $this->getStats();
foreach ( [ 'audios', 'videos' ] as $type ) {
// for grep timedmedia-audios, timedmedia-videos
$out->addHTML(
"<h2>"
. $this->msg( 'timedmedia-' . $type )->numParams( $stats[$type]['total'] )->escaped()
. "</h2>"
);
// Give grep a chance to find the usages: timedmedia-ogg-videos, timedmedia-webm-videos,
// timedmedia-ogg-audios, timedmedia-flac-audios, timedmedia-wav-audios
$formats = $type == 'audios' ? $this->audioFormats : $this->formats;
foreach ( $formats as $format => $condition ) {
if ( $stats[ $type ][ $format ] ) {
$out->addHTML(
$this->msg( "timedmedia-$format-$type" )->numParams( $stats[ $type ][ $format ] )->escaped()
. Html::element( 'br' )
);
}
}
}
$states = $this->getStates();
$this->renderState( $out, 'transcodes', $states, false );
foreach ( $this->transcodeStates as $state => $condition ) {
$this->renderState( $out, $state, $states, $state !== 'missing' );
}
}
/**
* @param OutputPage $out
* @param $state
* @param $states
* @param bool $showTable
*/
private function renderState( $out, $state, $states, $showTable = true ) {
global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet;
$allTranscodes = array_merge( $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet );
if ( $states[ $state ][ 'total' ] ) {
// Give grep a chance to find the usages:
// timedmedia-derivative-state-transcodes, timedmedia-derivative-state-active,
// timedmedia-derivative-state-queued, timedmedia-derivative-state-failed,
// timedmedia-derivative-state-missing
$out->addHTML(
"<h2>"
. $this->msg(
'timedmedia-derivative-state-' . $state
)->numParams( $states[ $state ]['total'] )->escaped()
. "</h2>"
);
foreach ( $allTranscodes as $key ) {
if ( isset( $states[ $state ] )
&& isset( $states[ $state ][ $key ] )
&& $states[ $state ][ $key ] ) {
$out->addHTML(
htmlspecialchars( $this->getLanguage()->formatNum( $states[ $state ][ $key ] ) )
. ' '
. $this->msg( 'timedmedia-derivative-desc-' . $key )->escaped()
. "<br>" );
}
}
if ( $showTable ) {
$out->addHTML( $this->getTranscodesTable( $state ) );
}
}
}
private function getTranscodes( $state, $limit = 50 ) {
global $wgMemc;
$memcKey = wfMemcKey( 'TimedMediaHandler', 'files', $state );
$files = $wgMemc->get( $memcKey );
if ( !$files ) {
$dbr = wfGetDB( DB_SLAVE );
$files = [];
$res = $dbr->select(
'transcode',
'*',
$this->transcodeStates[ $state ],
__METHOD__,
[ 'LIMIT' => $limit, 'ORDER BY' => 'transcode_time_error DESC' ]
);
foreach ( $res as $row ) {
$transcode = [];
foreach ( $row as $k => $v ) {
$transcode[ str_replace( 'transcode_', '', $k ) ] = $v;
}
$files[] = $transcode;
}
$wgMemc->add( $memcKey, $files, 60 );
}
return $files;
}
private function getTranscodesTable( $state, $limit = 50 ) {
$table = '<table class="wikitable">' . "\n"
. '<tr>'
. '<th>' . $this->msg( 'timedmedia-transcodeinfo' )->escaped() . '</th>'
. '<th>' . $this->msg( 'timedmedia-file' )->escaped() . '</th>'
. '</tr>'
. "\n";
foreach ( $this->getTranscodes( $state, $limit ) as $transcode ) {
$title = Title::newFromText( $transcode[ 'image_name' ], NS_FILE );
$table .= '<tr>'
. '<td>' . $this->msg(
'timedmedia-derivative-desc-' . $transcode[ 'key' ]
)->escaped() . '</td>'
. '<td>' . Linker::link( $title, $transcode[ 'image_name' ] ) . '</td>'
. '</tr>'
. "\n";
}
$table .= '</table>';
return $table;
}
private function getStats() {
global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet, $wgMemc;
$allTranscodes = array_merge( $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet );
$memcKey= wfMemcKey( 'TimedMediaHandler', 'stats', '1' /* version */ );
$stats = $wgMemc->get( $memcKey );
if ( !$stats ) {
$dbr = wfGetDB( DB_SLAVE );
$stats = [];
$stats[ 'videos' ] = [ 'total' => 0 ];
foreach ( $this->formats as $format => $condition ) {
$stats[ 'videos' ][ $format ] = (int)$dbr->selectField(
'image',
'COUNT(*)',
'img_media_type = "VIDEO" AND (' . $condition . ')',
__METHOD__
);
$stats[ 'videos' ][ 'total' ] += $stats[ 'videos' ][ $format ];
}
$stats[ 'audios' ] = [ 'total' => 0 ];
foreach ( $this->audioFormats as $format => $condition ) {
$stats[ 'audios' ][ $format ] = (int)$dbr->selectField(
'image',
'COUNT(*)',
'img_media_type = "AUDIO" AND (' . $condition . ')',
__METHOD__
);
$stats[ 'audios' ][ 'total' ] += $stats[ 'audios' ][ $format ];
}
}
return $stats;
}
private function getStates() {
global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet, $wgMemc;
$allTranscodes = array_merge( $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet );
$memcKey = wfMemcKey( 'TimedMediaHandler', 'states' );
$states = $wgMemc->get( $memcKey );
if ( !$states ) {
$dbr = wfGetDB( DB_SLAVE );
$states = [];
$states[ 'transcodes' ] = [ 'total' => 0 ];
foreach ( $this->transcodeStates as $state => $condition ) {
$states[ $state ] = [ 'total' => 0 ];
foreach ( $allTranscodes as $type ) {
// Important to pre-initialize, as can give
// warnings if you don't have a lot of things in transcode table.
$states[ $state ][ $type ] = 0;
}
}
foreach ( $this->transcodeStates as $state => $condition ) {
$cond = [ 'transcode_key' => $allTranscodes ];
$cond[] = $condition;
$res = $dbr->select( 'transcode',
[ 'COUNT(*) as count', 'transcode_key' ],
$cond,
__METHOD__,
[ 'GROUP BY' => 'transcode_key' ]
);
foreach ( $res as $row ) {
$key = $row->transcode_key;
$states[ $state ][ $key ] = $row->count;
$states[ $state ][ 'total' ] += $states[ $state ][ $key ];
}
}
$res = $dbr->select( 'transcode',
[ 'COUNT(*) as count', 'transcode_key' ],
[ 'transcode_key' => $allTranscodes ],
__METHOD__,
[ 'GROUP BY' => 'transcode_key' ]
);
foreach ( $res as $row ) {
$key = $row->transcode_key;
$states[ 'transcodes' ][ $key ] = $row->count;
$states[ 'transcodes' ][ $key ] -= $states[ 'queued' ][ $key ];
$states[ 'transcodes' ][ $key ] -= $states[ 'missing' ][ $key ];
$states[ 'transcodes' ][ $key ] -= $states[ 'active' ][ $key ];
$states[ 'transcodes' ][ $key ] -= $states[ 'failed' ][ $key ];
$states[ 'transcodes' ][ 'total' ] += $states[ 'transcodes' ][ $key ];
}
$wgMemc->add( $memcKey, $states, 60 );
}
return $states;
}
protected function getGroupName() {
return 'media';
}
}