'transcode_time_startwork IS NOT NULL AND transcode_time_success IS NULL AND transcode_time_error IS NULL', 'failed' => 'transcode_error != "" AND transcode_time_success IS NULL', 'queued' => 'transcode_time_startwork IS NULL AND transcode_time_success IS NULL AND transcode_time_error IS NULL', ); private $formats = array( 'ogg' => 'img_major_mime="application" AND img_minor_mime = "ogg"', 'webm' => 'img_major_mime="video" AND img_minor_mime = "webm"', ); private $audioFormats = array( '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( array( 'audios', 'videos' ) as $type ) { // for grep timedmedia-audios, timedmedia-videos $out->addHTML( "

" . $this->msg( 'timedmedia-' . $type )->numParams( $stats[$type]['total'] )->escaped() . "

" ); // 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 ); } } /** * @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 $out->addHTML( "

" . $this->msg( 'timedmedia-derivative-state-' . $state )->numParams( $states[ $state ]['total'] )->escaped() . "

" ); 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() . "
" ); } } 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 = array(); $res = $dbr->select( 'transcode', '*', $this->transcodeStates[ $state ], __METHOD__, array( 'LIMIT' => $limit, 'ORDER BY' => 'transcode_time_error DESC' ) ); foreach( $res as $row ) { $transcode = array(); 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 = '' . "\n" . '' . '' . '' . '' . "\n"; foreach( $this->getTranscodes( $state, $limit ) as $transcode ) { $title = Title::newFromText( $transcode[ 'image_name' ], NS_FILE ); $table .= '' . '' . '' . '' . "\n"; } $table .= '
' . $this->msg( 'timedmedia-transcodeinfo' )->escaped() . '' . $this->msg( 'timedmedia-file' )->escaped() . '
' . $this->msg('timedmedia-derivative-desc-' . $transcode[ 'key' ] )->escaped() . '' . Linker::link( $title, $transcode[ 'image_name' ] ) . '
'; 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 = array(); $stats[ 'videos' ] = array( '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' ] = array( '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 = array(); $states[ 'transcodes' ] = array( 'total' => 0 ); foreach ( $this->transcodeStates as $state => $condition ) { $states[ $state ] = array( '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 = array( 'transcode_key' => $allTranscodes ); $cond[] = $condition; $res = $dbr->select( 'transcode', array('COUNT(*) as count', 'transcode_key'), $cond, __METHOD__, array( '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', array( 'COUNT(*) as count', 'transcode_key' ), array( 'transcode_key' => $allTranscodes ), __METHOD__, array( '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' ][ 'total' ] += $states[ 'transcodes' ][ $key ]; } $wgMemc->add( $memcKey, $states, 60 ); } return $states; } protected function getGroupName() { return 'media'; } }