http://www.mediawiki.org/wiki/Special:Code/MediaWiki/89973

Revision: 89973
Author:   dale
Date:     2011-06-13 16:05:05 +0000 (Mon, 13 Jun 2011)
Log Message:
-----------
fixes bug 29178 re-run failed transcodes after some manual intervention
* Adds a "reset transcode api entry point"
* Adds transcode-reset permission 
* Adds action button to js, to rest a given transcode job
* Adds some safe guards to WebVideoTranscodeJob for out of order removal of 
transcode tasks and associated edge cases
* Adds ApiTranscodeStatus for getting transcode state from API ( could be used 
for a javascript based dynamic transcode table, or for api based transcode 
table management )  
* Refactored shared components to single location> 
WebVideoTranscode::removeTranscodeJobs() and 
WebVideoTranscode::invalidatePagesWithAsset() 

Modified Paths:
--------------
    trunk/extensions/TimedMediaHandler/ApiQueryVideoInfo.php
    
trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js
    trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php
    trunk/extensions/TimedMediaHandler/TimedMediaHandler.i18n.php
    trunk/extensions/TimedMediaHandler/TimedMediaHandler.php
    trunk/extensions/TimedMediaHandler/TranscodeStatusTable.php
    trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php
    
trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php
    trunk/extensions/TimedMediaHandler/resources/ext.tmh.transcodetable.js

Added Paths:
-----------
    trunk/extensions/TimedMediaHandler/ApiTranscodeReset.php
    trunk/extensions/TimedMediaHandler/ApiTranscodeStatus.php

Modified: trunk/extensions/TimedMediaHandler/ApiQueryVideoInfo.php
===================================================================
--- trunk/extensions/TimedMediaHandler/ApiQueryVideoInfo.php    2011-06-13 
15:32:23 UTC (rev 89972)
+++ trunk/extensions/TimedMediaHandler/ApiQueryVideoInfo.php    2011-06-13 
16:05:05 UTC (rev 89973)
@@ -6,6 +6,12 @@
  * see: 
http://www.mediawiki.org/wiki/User:Catrope/Extension_review/TimedMediaHandler#ApiQueryVideoInfo.php
  * 
  */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+       // Eclipse helper - will be ignored in production
+       require_once( "ApiBase.php" );
+}
+
 class ApiQueryVideoInfo extends ApiQueryImageInfo {
 
        public function __construct( $query, $moduleName, $prefix = 'vi' ) {

Added: trunk/extensions/TimedMediaHandler/ApiTranscodeReset.php
===================================================================
--- trunk/extensions/TimedMediaHandler/ApiTranscodeReset.php                    
        (rev 0)
+++ trunk/extensions/TimedMediaHandler/ApiTranscodeReset.php    2011-06-13 
16:05:05 UTC (rev 89973)
@@ -0,0 +1,104 @@
+<?php
+if ( !defined( 'MEDIAWIKI' ) ) {
+       // Eclipse helper - will be ignored in production
+       require_once( 'ApiBase.php' );
+}
+
+/**
+ * Allows users with the 'transcode-reset' right to reset / re-run a transcode 
job.
+ * 
+ * You can specify must specify a media asset title. You optionally can 
specify 
+ * a transcode key, to only reset a single transcode job for a particular 
media asset.
+ * @ingroup API
+ */
+class ApiTranscodeReset extends ApiBase {
+
+       public function execute() {
+               global $wgUser, $wgEnabledTranscodeSet, $wgEnableTranscode;     
        
+               // Check if transcoding is enabled on this wiki at all: 
+               if( !$wgEnableTranscode ){
+                       $this->dieUsage( 'Transcode is disabled on this wiki', 
'disabledtranscode' );
+               }
+               
+               // Confirm the user has the transcode-reset right
+               if( !$wgUser->isAllowed( 'transcode-reset' ) ){
+                       $this->dieUsage( 'You don\'t have permission to reset 
transcodes', 'missingpermission' );
+               }
+               $params = $this->extractRequestParams();
+               
+               // Make sure we have a valid Title
+               $titleObj = Title::newFromText( $params['title'] );
+               if ( !$titleObj || $titleObj->isExternal() ) {
+                       $this->dieUsageMsg( array( 'invalidtitle', 
$params['title'] ) );
+               }
+               // Make sure the title can be transcoded
+               if( !TimedMediaHandlerHooks::isTranscodableTitle( $titleObj ) ){
+                       $this->dieUsage( array( 'invalidtranscodetitle', 
$params['title'] ) );
+               }
+               $file = wfFindFile( $titleObj );
+               WebVideoTranscode::removeTranscodeJobs( $file, isset( 
$params['transcodekey'] )? $params['transcodekey']: false );
+               
+               $this->getResult()->addValue(null, 'success', 'removed 
transcode');
+       }
+
+       public function mustBePosted() {
+               return true;
+       }
+
+       public function isWriteMode() {
+               return true;
+       }
+
+       protected function getDescription() {
+               return 'Users with the \'transcode-reset\' right can reset and 
re-run a transcode job';
+       }
+
+       public function getPossibleErrors() {
+               return array_merge( parent::getPossibleErrors(), array(
+                       array( 'code' => 'missingpermission', 'info' => 'You 
don\'t have permission to reset transcodes'),
+                       array( 'code' => 'disabledtranscode', 'info' => 
'Transcode is disabled on this wiki' ),
+                       array( 'invalidtitle', 'title' ),
+               ) );
+       }
+
+       protected function getAllowedParams() {
+               return array(
+                       'title' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => true
+                       ),
+                       'transcodekey' => null,
+                       'token' => null,
+               );
+       }
+
+       protected function getParamDescription() {
+               return array(
+                       'title' => 'The media file title',
+                       'transcodekey' => 'The transcode key you wish to reset',
+                       'token' => 'You can get one of these through prop=info',
+               );
+       }
+
+       public function needsToken() {
+               return true;
+       }
+
+       public function getTokenSalt() {
+               return '';
+       }
+
+       protected function getExamples() {
+               return array(
+                       'Reset all transcodes for Clip.webm :',
+                       '    
api.php?action=transcodereset&title=File:Clip.webm&token=%2B\\',
+                       'Reset the \'360_560kbs.webm\' transcode key for 
clip.webm. Get a list of transcode keys via a \'transcodestatus\' query',
+                       '    
api.php?action=transcodereset&title=File:Clip.webm&transcodekey=360_560kbs.webm&token=%2B\\',
+               );
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id: ApiTranscodeReset.php 89751 $';
+       }
+       
+}
\ No newline at end of file

Added: trunk/extensions/TimedMediaHandler/ApiTranscodeStatus.php
===================================================================
--- trunk/extensions/TimedMediaHandler/ApiTranscodeStatus.php                   
        (rev 0)
+++ trunk/extensions/TimedMediaHandler/ApiTranscodeStatus.php   2011-06-13 
16:05:05 UTC (rev 89973)
@@ -0,0 +1,62 @@
+<?php 
+/**
+ * Allows for api queries to get detailed information about the transcode 
state of a particular
+ * media asset. ( basically directly returns the transcode status table )  
+ * 
+ * This information can be used to generate status tables similar to the one 
seen 
+ * on the image page.
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+       // Eclipse helper - will be ignored in production
+       require_once( "ApiBase.php" );
+}
+
+class ApiTranscodeStatus extends ApiQueryBase {
+       public function execute() {
+               $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
+               // Make sure we have files in the title set: 
+               if ( !empty( $pageIds[NS_FILE] ) ) {
+                       $titles = array_keys( $pageIds[NS_FILE] );
+                       asort( $titles ); // Ensure the order is always the same
+                       
+                       $result = $this->getResult();
+                       $images = RepoGroup::singleton()->findFiles( $titles );
+                       foreach ( $images as $img ) {
+                               // if its a "transcode" add the transcode 
status table output
+                               if( 
TimedMediaHandlerHooks::isTranscodableTitle( $img->getTitle() ) ){
+                                       $transcodeStatus = 
WebVideoTranscode::getTranscodeState( $img->getTitle()->getDBKey() );
+                                       // remove useless properties 
+                                       foreach($transcodeStatus as $key=>&$val 
){
+                                               unset( $val['id'] );
+                                               unset( $val['image_name']);
+                                               unset( $val['key'] );
+                                       }
+                                       $result->addValue( array( 'query', 
'pages', $img->getTitle()->getArticleID() ), 'transcodestatus', 
$transcodeStatus );
+                               }
+                       }
+               }
+       }
+       public function getCacheMode( $params ) {
+               return 'public';
+       }
+       public function getAllowedParams() {
+               return array();
+       }
+
+       public function getDescription() {
+               return array(
+                       'Get transcode status for a given file page'
+               );
+       }
+       
+       protected function getExamples() {
+               return array (
+                       
'api.php?action=query&prop=transcodestatus&titles=File:Clip.webm',
+               );
+       }
+       
+       public function getVersion() {
+               return __CLASS__ . ': $Id: ApiQueryFlagged.php 85713 2011-04-09 
04:30:07Z aaron $';
+       }
+}
\ No newline at end of file

Modified: 
trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js
===================================================================
--- 
trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js
   2011-06-13 15:32:23 UTC (rev 89972)
+++ 
trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js
   2011-06-13 16:05:05 UTC (rev 89973)
@@ -202,7 +202,6 @@
 
                        var playerInterface = new mw.EmbedPlayer( playerElement 
);
                        var swapPlayer = swapEmbedPlayerElement( playerElement, 
playerInterface );                      
-
                        // Trigger the EmbedPlayerNewPlayer for embedPlayer 
interface
                        mw.log("EmbedPlayer::EmbedPlayerNewPlayer:trigger " + 
playerInterface.id );
                        $( mw ).trigger ( 'EmbedPlayerNewPlayer', $( '#' + 
playerInterface.id ).get(0) );

Modified: trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php
===================================================================
--- trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php      
2011-06-13 15:32:23 UTC (rev 89972)
+++ trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php      
2011-06-13 16:05:05 UTC (rev 89973)
@@ -22,12 +22,6 @@
                $wgMediaHandlers['application/ogg'] = 'OggHandler';
                $wgMediaHandlers['video/webm'] = 'WebMHandler';
 
-               // Setup a hook for iframe embed handling:
-               $wgHooks['ArticleFromTitle'][] = 
'TimedMediaIframeOutput::iframeHook';
-
-               // Add parser hook
-               $wgParserOutputHooks['TimedMediaHandler'] = array( 
'TimedMediaHandler', 'outputHook' );
-
                // Add transcode job class:
                $wgJobClasses+= array(
                        'webVideoTranscode' => 'WebVideoTranscodeJob'
@@ -53,10 +47,25 @@
                        ) ),
                        'ext.tmh.transcodetable' => 
array_merge($baseExtensionResource, array(
                                'scripts' => 
'resources/ext.tmh.transcodetable.js',
-                               'styles' => 'resources/transcodeTable.css'
+                               'styles' => 'resources/transcodeTable.css',
+                               'messages'=> array(
+                                       'mwe-ok',
+                                       'mwe-cancel',
+                                       'timedmedia-reset-error',
+                                       'timedmedia-reset',
+                                       'timedmedia-reset-confirm'
+                               )
                        ) )
                );
+               // Setup a hook for iframe embed handling:
+               $wgHooks['ArticleFromTitle'][] = 
'TimedMediaIframeOutput::iframeHook';
+               
+               // When an upload completes ( check clear any existing 
transcodes )
+               $wgHooks['UploadComplete'][] = 
'TimedMediaHandlerHooks::checkUploadComplete';
 
+               // Add parser hook
+               $wgParserOutputHooks['TimedMediaHandler'] = array( 
'TimedMediaHandler', 'outputHook' );
+               
                // We should probably move this script output to a parser 
function but not working correctly in
                // dynamic contexts ( for example in special upload, when there 
is an "existing file" warning. )
                $wgHooks['BeforePageDisplay'][] = 
'TimedMediaHandlerHooks::pageOutputHook';
@@ -71,18 +80,12 @@
                // Also add the .log file ( used in two pass encoding )
                // ( probably should move in-progress encodes out of web 
accessible directory )
                $wgExcludeFromThumbnailPurge[] = 'log';
-
-               // Api hooks for derivatives and query video derivatives
-               $wgAPIPropModules += array(
-                       'videoinfo' => 'ApiQueryVideoInfo'
-               );
-
+               
                $wgHooks['LoadExtensionSchemaUpdates'][] = 
'TimedMediaHandlerHooks::loadExtensionSchemaUpdates';
                
                // Add unit tests
                $wgHooks['UnitTestsList'][] = 
'TimedMediaHandlerHooks::registerUnitTests';
                
-
                /**
                 * Add support for the "TimedText" NameSpace
                 */
@@ -107,43 +110,67 @@
                }
                return true;                    
        }
-       public static function checkForTranscodeStatus( $article, &$html ){
+       
+       /**
+        * Wraps the isTranscodableFile function
+        * @param $title Title
+        */
+       public static function isTranscodableTitle( $title ){
+               if( $title->getNamespace() != NS_FILE ){
+                       return false;
+               }
+               $file = wfFindFile( $title );
+               return self::isTranscodableFile( $file );
+       }
+       
+       /**
+        * Utility function to check if a given file can be "transcoded"
+        * @param $file File object
+        */
+       public static function isTranscodableFile( & $file ){
                global $wgEnableTranscode;
+               
                // don't show the transcode table if transcode is disabled 
                if( $wgEnableTranscode === false ){
-                       return true;
+                       return false;
                }
-               // load the file: 
-               $file = wfFindFile( $article->getTitle() );
-               // cant find file
+               // Can't find file 
                if( !$file ){
-                       return true;
+                       return false;
                }
-               // We don't show transcode status for remote files: 
+               // We can only transcode local files
                if( !$file->isLocal() ){
-                       return true;
+                       return false;
                }
-               // get mediaType
                $mediaType = $file->getHandler()->getMetadataType( $image = '' 
); 
-               // if ogg or webm format and not audio show transcode page: 
+               // If ogg or webm format and not audio we can "transcode" this 
file
                if( ( $mediaType == 'webm' || $mediaType == 'ogg' ) && ! 
$file->getHandler()->isAudio( $file ) ){
+                       return true;
+               }
+               return false;
+       }
+       
+       public static function checkForTranscodeStatus( $article, &$html ){
+               // load the file: 
+               $file = wfFindFile( $article->getTitle() );
+               if( self::isTranscodableFile( $file ) ){
                        $html = TranscodeStatusTable::getHTML( $file );
                }
                return true;
        }
+       public static function checkUploadComplete( &$image ){
+               if( self::isTranscodableTitle( $image->getTitle() ) ){
+                       // clear transcode data:
+               }
+               return true;
+       }
        public static function checkArticleDeleteComplete( &$article, &$user, 
$reason, $id  ){
                // Check if the article is a file and remove transcode jobs:
                if( $article->getTitle()->getNamespace() == NS_FILE ) {
-                       
                        $file = wfFindFile( $article->getTitle() );
-                       if ( $file ) {
-                               $mediaType = 
$file->getHandler()->getMetadataType( $image = '' );
-
-                               if( $mediaType == 'webm' || $mediaType == 'ogg' 
){
-                                       WebVideoTranscode::removeTranscodeJobs( 
$file );
-                               }
+                       if( self::isTranscodableFile( $file ) ){
+                               WebVideoTranscode::removeTranscodeJobs( $file );
                        }
-                       
                } 
                return true;
        }
@@ -161,7 +188,7 @@
        
        /**
         * Hook to add list of PHPUnit test cases.
-        * @param array $files
+        * @param $files Array of files
         */
        public static function registerUnitTests( array &$files ) {
                $testDir = dirname( __FILE__ ) . '/tests/phpunit/';

Modified: trunk/extensions/TimedMediaHandler/TimedMediaHandler.i18n.php
===================================================================
--- trunk/extensions/TimedMediaHandler/TimedMediaHandler.i18n.php       
2011-06-13 15:32:23 UTC (rev 89972)
+++ trunk/extensions/TimedMediaHandler/TimedMediaHandler.i18n.php       
2011-06-13 16:05:05 UTC (rev 89973)
@@ -37,10 +37,10 @@
        
        'timedmedia-status-header'              => 'Transcode status',
        'timedmedia-update-status'              => 'Update transcode status',
-       'timedmedia-status'                             => 'status',
-       'timedmedia-status-unknown'             => 'unknown status',
+       'timedmedia-status'                             => 'Status',
+       'timedmedia-status-unknown'             => 'Unknown status',
        'timedmedia-transcodeinfo'              => 'Transcode derivative 
description',
-       'timedmedia-actions'                    => 'actions',
+       'timedmedia-actions'                    => 'Actions',
        'timedmedia-direct-link'                => 'Download derivative',
        'timedmedia-not-ready'                  => 'Not ready',
        'timedmedia-completed-on'               => 'Completed transcode $1',
@@ -53,9 +53,15 @@
        'timedmedia-hours'                              => '{{PLURAL:$1|hour|$1 
hours}}',
        'timedmedia-minutes'                    => '{{PLURAL:$1|minute|$1 
minutes}}',
        'timedmedia-seconds'                    => '{{PLURAL:$1|second|$1 
seconds}}',
-       'timedmedia-and'                                => 'and $1',
-       'timedmedia-days-hours-min-sec-time' => '$1, $2, $3 $4',
+       'timedmedia-time-4-measurements' => '$1, $2, $3 and $4',
+       'timedmedia-time-3-measurements' => '$1, $2 and $3',
+       'timedmedia-time-2-measurements' => '$1 and $2',
+       'timedmedia-time-1-measurements' => '$1',
        'timedmedia-show-error'                 => 'Show error',
+       'timedmedia-reset'                              => 'Reset transcode',
+       'timedmedia-reset-confirm'              => 'Resetting this transcode, 
will remove any existing file ( if present ), and it will re-add the transcode 
to the job queue. It will take some time to re-transcode. <br /><br />' . 
+'Are you sure you want to proceed?',
+       'timedmedia-reset-error'                => 'Error in reseting transcode 
job',
        
        // Original uploaded asset
        'timedmedia-ogg' => 'Ogg',

Modified: trunk/extensions/TimedMediaHandler/TimedMediaHandler.php
===================================================================
--- trunk/extensions/TimedMediaHandler/TimedMediaHandler.php    2011-06-13 
15:32:23 UTC (rev 89972)
+++ trunk/extensions/TimedMediaHandler/TimedMediaHandler.php    2011-06-13 
16:05:05 UTC (rev 89973)
@@ -29,10 +29,10 @@
 /*** end MwEmbed module configuration: ******************************/
 
 // Add the rest transcode right:
-$wgAvailableRights[] = 'resetTranscode'; 
+$wgAvailableRights[] = 'transcode-reset'; 
 
 // Which users can restart failed or expired transcode jobs
-$wgGroupPermissions['sysop']['resetTranscode'] = true;
+$wgGroupPermissions['sysop']['transcode-reset'] = true;
 
 // The minimum size for an embed video player:
 $wgMinimumVideoPlayerSize = 200;
@@ -48,7 +48,7 @@
 $wgEnableIframeEmbed = true;
 
 // If transcoding is enabled for this wiki ( if disabled, no transcode jobs 
are added and no 
-// transcode status is displayed. Note if remote embeding an asset we will 
still check if 
+// transcode status is displayed. Note if remote embedding an asset we will 
still check if 
 // the remote repo has transcoding enabled and associated flavors for that 
media embed. 
 $wgEnableTranscode = true;
 
@@ -82,9 +82,6 @@
        // A high end web streamable ogg video 
        WebVideoTranscode::ENC_OGV_9MBS,
        
-       // High quality 720P ogg video: 
-       WebVideoTranscode::ENC_OGV_HQ_VBR,
-       
        // A web streamable WebM video  
        WebVideoTranscode::ENC_WEBM_9MBS,
        
@@ -130,8 +127,18 @@
 
 // Transcode support
 $wgAutoloadClasses['WebVideoTranscodeJob'] = 
"$timedMediaDir/WebVideoTranscode/WebVideoTranscodeJob.php";
+
+// Api modules:
 $wgAutoloadClasses['ApiQueryVideoInfo'] = 
"$timedMediaDir/ApiQueryVideoInfo.php";
+$wgAPIPropModules ['videoinfo'] = 'ApiQueryVideoInfo';
 
+$wgAutoloadClasses['ApiTranscodeStatus'] = 
"$timedMediaDir/ApiTranscodeStatus.php";
+$wgAPIPropModules ['transcodestatus'] = 'ApiTranscodeStatus';
+
+$wgAutoloadClasses['ApiTranscodeReset'] = 
"$timedMediaDir/ApiTranscodeReset.php";
+$wgAPIModules['transcodereset'] = 'ApiTranscodeReset';
+
+
 // Localization 
 $wgExtensionMessagesFiles['TimedMediaHandler'] = 
"$timedMediaDir/TimedMediaHandler.i18n.php";
 $wgExtensionMessagesFiles['TimedMediaHandlerMagic'] = 
"$timedMediaDir/TimedMediaHandler.i18n.magic.php";
@@ -145,7 +152,7 @@
 $wgExtensionCredits['media'][] = array(
        'path'           => __FILE__,
        'name'           => 'TimedMediaHandler',
-       'author'         => array( 'Michael Dale', 'Tim Starling' ),
+       'author'         => array( 'Michael Dale', 'Tim Starling', 'James 
Heinrich' ),
        'url'            => 
'http://www.mediawiki.org/wiki/Extension:TimedMediaHandler',
        'descriptionmsg' => 'timedmedia-desc',
        'version'                => '0.2',

Modified: trunk/extensions/TimedMediaHandler/TranscodeStatusTable.php
===================================================================
--- trunk/extensions/TimedMediaHandler/TranscodeStatusTable.php 2011-06-13 
15:32:23 UTC (rev 89972)
+++ trunk/extensions/TimedMediaHandler/TranscodeStatusTable.php 2011-06-13 
16:05:05 UTC (rev 89973)
@@ -24,7 +24,7 @@
                        . '<th>' . wfMsgHtml( 'timedmedia-transcodeinfo' ) . 
'</th>'
                        . '<th>'.wfMsgHtml( 'timedmedia-direct-link' ) .'</th>';
                        
-               if( array_search( 'resetTranscode', $wgUser->getRights() )!== 
false ){
+               if( $wgUser->isAllowed( 'transcode-reset' ) ){
                        $o.= '<th>' . wfMsgHtml( 'timedmedia-actions' ) . 
'</th>';
                }
                        
@@ -57,9 +57,9 @@
                        $o.='</td>';
                        
                        // Check if we should include actions: 
-                       if( array_search( 'resetTranscode', 
$wgUser->getRights() )!== false ){
+                       if( $wgUser->isAllowed( 'transcode-reset' ) ){
                                // include reset transcode action buttons
-                               
+                               $o.='<td class="transcodereset"><a href="#" 
data-transcodekey="' . htmlspecialchars( $transcodeKey ). '">' . 
wfMsg('timedmedia-reset') . '</a></td>';
                        }
                        $o.='</tr>';
                }
@@ -90,13 +90,14 @@
                        }
                        return wfMsgHtml('timedmedia-error-on', 
$state['time_error'] ) . $showErrorLink;
                }               
+               $db = wfGetDB( DB_SLAVE );
                // Check for started encoding
                if( !is_null( $state['time_startwork'] ) ){
-                       $timePassed = wfTimestamp() - wfTimestamp( TS_UNIX, 
strtotime( $state['time_startwork'] ) );
+                       $timePassed = wfTimestampNow() - $db->timestamp( 
$state['time_startwork'] );
 
                        // Get the rough estimate of time done: ( this is not 
very costly considering everything else
                        // that happens in an action=purge video page request ) 
-                       $filePath = WebVideoTranscode::getTargetEncodePath( 
$file, $state['key'] );
+                       /*$filePath = WebVideoTranscode::getTargetEncodePath( 
$file, $state['key'] );
                        if( is_file( $filePath ) ){
                                $targetSize = 
WebVideoTranscode::getProjectedFileSize( $file, $state['key'] );
                                if( $targetSize === false ){
@@ -104,12 +105,14 @@
                                } else {
                                        $doneMsg = 
wfMsgHtml('timedmedia-percent-done', round( filesize( $filePath ) / 
$targetSize, 2 ) );
                                }
-                       }                                       
+                       }       */
+                       // predicting percent done is not working well right 
now ( disabled for now )
+                       $doneMsg = '';
                        return wfMsgHtml('timedmedia-started-transcode', 
self::getTimePassedMsg( $timePassed ), $doneMsg );
                }
                // Check for job added ( but not started encoding )
                if( !is_null( $state['time_addjob'] ) ){
-                       $timePassed =  wfTimestamp() - wfTimestamp( TS_UNIX, 
strtotime( $state['time_addjob'] ) );
+                       $timePassed =  wfTimestampNow() - $db->timestamp( 
$state['time_addjob'] ) ;
                        return wfMsgHtml('timedmedia-in-job-queue', 
self::getTimePassedMsg( $timePassed ) );
                }
                // Return unknown status error:
@@ -120,21 +123,18 @@
                $t['hours'] = floor($timePassed/60/60)%24;
                $t['minutes'] = floor($timePassed/60)%60;
                $t['seconds'] = $timePassed%60;                 
+               
                foreach( $t as $k => $v ){
                        if($v == 0 ){
-                               $t[$k] = '';
+                               unset( $t[$k] );
                        }else{
                                $t[$k] = wfMsg( 'timedmedia-' . $k, $v);
                        }
                }
-               // Add the tailing and $1 text:
-               if( $t['seconds'] !== '' ){
-                       $t['seconds'] = wfMsg('timedmedia-and', $t['seconds'] );
-               } else if( $t['minutes'] !== '' ){
-                       $t['minutes'] = wfMsg('timedmedia-and', $t['minutes'] );
-               } else if( $t['hours'] !== '' ){
-                       $t['hours'] = wfMsg('timedmedia-and', $t['hours'] );
+               if( count( $t ) == 0 ){
+                       $t = array( wfMsg( 'timedmedia-seconds', 0) ) ;
                }
-               return wfMsgHtml('timedmedia-days-hours-min-sec-time', 
$t['days'], $t['hours'], $t['minutes'], $t['seconds'] );
+               // Call to the correct set of significant measurements:
+               return wfMsgHtml( 'timedmedia-time-' . count($t) . 
'-measurements', $t);
        }
 }
\ No newline at end of file

Modified: 
trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php
===================================================================
--- trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php  
2011-06-13 15:32:23 UTC (rev 89972)
+++ trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php  
2011-06-13 16:05:05 UTC (rev 89973)
@@ -144,8 +144,8 @@
        /**
         * Get the target encode path for a video encode
         * 
-        * @param File $file
-        * @param String $transcodeKey
+        * @param $file File
+        * @param $transcodeKey String 
         * 
         * @returns the local target encode path
         */
@@ -154,7 +154,7 @@
                // in-progress encodes, its nice having it publicly accessible 
for debugging though
                $filePath = self::getDerivativeFilePath( $file, $transcodeKey );
                $ext = strtolower( pathinfo( "$filePath", PATHINFO_EXTENSION ) 
);
-               return "{$filePath}.queue.{$ext}";
+               return "{$filePath}.tmp.{$ext}";
        }
        
        /**
@@ -201,7 +201,7 @@
        /**
         * Grabs sources from the remote repo via ApiQueryVideoInfo.php entry 
point. 
         * 
-        * Because this works on both TimedMediaHandler commons and no 
TimedMediaHandler commons
+        * Because this works with commons regardless of whether 
TimedMediaHandler is installed or not
         */
        static public function getRemoteSources(&$file , $options = array() ){
                global $wgMemc;
@@ -398,28 +398,75 @@
         * Remove any transcode jobs associated with a given $fileName
         * 
         * also remove the transcode files: 
+        * @param $file File Object
+        * @param $transcodeKey String Optional transcode key to remove only 
this key
         */
-       public static function removeTranscodeJobs( &$file ){
-               $fileName = $file->getTitle()->getDbKey();
+       public static function removeTranscodeJobs( &$file, $transcodeKey = 
false ){
+               $titleObj = $file->getTitle();
+               print " \n\n " . $titleObj->getDBKey() . "\n\n";
+               // if transcode key is non-false, non-null:
+               if( $transcodeKey ){
+                       // only remove the requested $transcodeKey
+                       $removeKeys = array( $transcodeKey );
+               } else {
+                       // Remove any existing files ( regardless of their 
state )
+                       $res = wfGetDB( DB_SLAVE )->select( 'transcode', 
+                               array( 'transcode_key' ),
+                               array( 'transcode_image_name' => 
$titleObj->getDBKey() )
+                       );
+                       $removeKeys = array();
+                       foreach( $res as $transcodeRow ){
+                               $removeKeys[] = $transcodeRow->transcode_key;
+                       } 
+               }
                
-               $res = wfGetDB( DB_SLAVE )->select( 'transcode', 
-                       array( 'transcode_key' ),
-                       array( 'transcode_image_name' => $fileName )
-               );
-               // remove the file
-               foreach( $res as $transcodeRow ){
-                       $filePath = self::getDerivativeFilePath($file, 
$transcodeRow->transcode_key );
-                       if( ! @unlink( $filePath ) ){
-                               wfDebug( "Could not delete file $filePath\n" );
+               // Remove files by key:
+               foreach( $removeKeys as $tKey){
+                       $filePath = self::getDerivativeFilePath($file,  $tKey);
+                       if( is_file( $filePath ) ){
+                               if( ! @unlink( $filePath ) ){
+                                       wfDebug( "Could not delete file 
$filePath\n" );
+                               }
                        }
-               } 
+               }
+                               
+               // Build the sql query:
+               $dbw = wfGetDB( DB_MASTER );
+               $deleteWhere = array( 'transcode_image_name ='. 
$dbw->addQuotes( $titleObj->getDBkey() ) );
+               // Check if we are removing a specific transcode key
+               if( $transcodeKey !== false ){
+                       $deleteWhere[] = 'transcode_key =' . $dbw->addQuotes( 
$transcodeKey );
+               }
                // Remove the db entries
-               wfGetDB( DB_MASTER )->delete( 'transcode', 
-                       array( 'transcode_image_name' => $fileName ),
-                       __METHOD__ 
+               $dbw->delete( 'transcode', $deleteWhere, __METHOD__ );
+               
+               // Purge the cache for pages that include this video: 
+               self::invalidatePagesWithAsset( $titleObj );
+
+               // Remove from local WebVideoTranscode cache:
+               self::clearTranscodeCache(  $titleObj->getDBKey()  );
+       }
+       
+       public static function invalidatePagesWithAsset( &$titleObj ){
+               wfDebug("WebVideoTranscode:: Invalidate pages that include: " . 
$titleObj->getDBKey() );
+               // Purge the main image page: 
+               $titleObj->invalidateCache();
+               
+               // TODO if the video is used in over 500 pages add to 'job 
queue'
+               // TODO interwiki invalidation ?
+               $limit = 500;           
+               $dbr = wfGetDB( DB_SLAVE );
+               $res = $dbr->select(
+                       array( 'imagelinks', 'page' ),
+                       array( 'page_namespace', 'page_title' ),
+                       array( 'il_to' => $titleObj->getDBkey(), 'il_from = 
page_id' ),
+                       __METHOD__,
+                       array( 'LIMIT' => $limit + 1 )
                );
-               // Remove from local cache:
-               self::clearTranscodeCache( $fileName );
+               foreach ( $res as $page ) {
+                       $title = Title::makeTitle( $page->page_namespace, 
$page->page_title );
+                       $title->invalidateCache();
+               }
        }
        
        /**
@@ -429,7 +476,7 @@
        public static function addSourceIfReady( &$file, &$sources, 
$transcodeKey, $dataPrefix = '' ){
                global $wgLang;
                $fileName = $file->getTitle()->getDbKey();
-               // Check if the transcode is ready:                     
+               // Check if the transcode is ready:
                if( self::isTranscodeReady( $fileName, $transcodeKey ) ){
                        $sources[] = self::getDerivativeSourceAttributes( 
$file, $transcodeKey, $dataPrefix );
                } else {
@@ -510,8 +557,8 @@
        }
        /**
         * Update the job queue if the file is not already in the job queue:
-        * @param object File object 
-        * @param 
+        * @param $file File object 
+        * @param $transcodeKey String transcode key
         */     
        public static function updateJobQueue( &$file, $transcodeKey ){
                wfProfileIn( __METHOD__ );
@@ -520,9 +567,8 @@
                                
                // Check if we need to update the transcode state:
                $transcodeState = self::getTranscodeState( $fileName );
-               
                // Check if the job has been added: 
-               if( isset( $transcodeState[ $transcodeKey ] ) &&  is_null( 
$transcodeState[ $transcodeKey ]['time_addjob'] ) ) {
+               if( !isset( $transcodeState[ $transcodeKey ] ) || is_null( 
$transcodeState[ $transcodeKey ]['time_addjob'] ) ) {
                        // Add to job queue and update the db
                        $job = new WebVideoTranscodeJob( $file->getTitle(), 
array(
                                'transcodeMode' => 'derivative',

Modified: 
trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php
===================================================================
--- 
trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php   
    2011-06-13 15:32:23 UTC (rev 89972)
+++ 
trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php   
    2011-06-13 16:05:05 UTC (rev 89973)
@@ -40,21 +40,34 @@
                
                // Build the destination target
                $destinationFile = WebVideoTranscode::getTargetEncodePath( 
$file, $transcodeKey );
-               
                if( ! isset(  WebVideoTranscode::$derivativeSettings[ 
$transcodeKey ] )){
-                       $this->output("Transcode key $transcodeKey not found, 
skipping");
+                       $this->output( "Transcode key $transcodeKey not found, 
skipping" );
                        return false;
                }
                $options = WebVideoTranscode::$derivativeSettings[ 
$transcodeKey ];
                                
                $this->output( "Encoding to codec: " . $options['videoCodec'] );
                
-               $db =wfGetDB( DB_MASTER );
+               $dbw = wfGetDB( DB_MASTER );
+               $db = wfGetDB( DB_SLAVE );
                
-               // Update the transcode table letting it know we have "started 
work":  
-               $db->update( 
+               // Check if we have "already started" the transcode ( possible 
error ) 
+               $dbStartTime = $db->selectField( 'transcode', 
'transcode_time_startwork',
+                       array(  'transcode_image_name = ' . $db->addQuotes( 
$this->title->getDBKey() ),
+                                       'transcode_key =' . $db->addQuotes( 
$transcodeKey ) )
+               );
+               if( ! is_null( $dbStartTime ) ){
+                       $this->output( 'Error, running transcode job, for job 
that has already started' );
+                       // back out of this job. ( if there was a transcode 
error it should be restarted with api transcode-reset ) 
+                       // not some strange out-of-order error. 
+                       return false;
+               }
+               
+               // Update the transcode table letting it know we have "started 
work":           
+               $jobStartTimeCache = $db->timestamp();
+               $dbw->update( 
                        'transcode',
-                       array( 'transcode_time_startwork' => $db->timestamp() ),
+                       array( 'transcode_time_startwork' => $jobStartTimeCache 
),
                        array( 
                                'transcode_image_name' => 
$this->title->getDBkey(),
                                'transcode_key' => $transcodeKey
@@ -62,8 +75,8 @@
                        __METHOD__,
                        array( 'LIMIT' => 1 )
                );
-                               
                
+               
                // Check the codec see which encode method to call;
                if( $options['videoCodec'] == 'theora' ){
                        $status = $this->ffmpeg2TheoraEncode( $file, 
$destinationFile, $options );
@@ -92,6 +105,25 @@
                        $status =  'Error unknown target encode codec:' . 
$options['codec'];
                }
                
+               // Do a quick check to confirm the job was not restarted or 
removed while we were transcoding
+               // Confirm the in memory $jobStartTimeCache matches db start 
time
+               $dbStartTime = $db->selectField( 'transcode', 
'transcode_time_startwork',
+                       array(  'transcode_image_name = ' . $db->addQuotes( 
$this->title->getDBKey() ),
+                                       'transcode_key =' . $db->addQuotes( 
$transcodeKey )
+                       )
+               );
+               
+               // Check for ( hopefully rare ) issue of or job restarted while 
transcode in progress
+               if( $jobStartTimeCache != $dbStartTime ){
+                       wfDebug('Possible Error, transcode task restarted, 
removed, or completed while transcode was in progress');
+                       // if an error; just error out, we can't remove temp 
files or update states, because the new job may be doing stuff.
+                       if( $status !== true ){
+                               return false;   
+                       }
+                       // else just continue with db updates, and when the new 
job comes around it won't start because it will see 
+                       // that the job has already been started.
+               }
+                       
                // If status is oky move the file to its final destination. ( 
timedMediaHandler will look for it there ) 
                if( $status === true ){
                        $finalDerivativeFilePath = 
WebVideoTranscode::getDerivativeFilePath( $file, $transcodeKey);
@@ -100,7 +132,7 @@
                        wfRestoreWarnings();
                        $bitrate = round( intval( filesize( 
$finalDerivativeFilePath ) /  $file->getLength() ) * 8 );
                        // Update the transcode table with success time: 
-                       $db->update( 
+                       $dbw->update( 
                                'transcode',
                                array( 
                                        'transcode_time_success' => 
$db->timestamp(),
@@ -113,10 +145,10 @@
                                __METHOD__,
                                array( 'LIMIT' => 1 )
                        );                      
-                       $this->invalidateCache();
+                       WebVideoTranscode::invalidatePagesWithAsset( 
$this->title );
                } else {
                        // Update the transcode table with failure time and 
error 
-                       $db->update( 
+                       $dbw->update( 
                                'transcode',
                                array( 
                                        'transcode_time_error' => 
$db->timestamp(),
@@ -128,36 +160,15 @@
                                ),
                                __METHOD__,
                                array( 'LIMIT' => 1 )
-                       );                      
+                       );
+                       // no need to invalidate cache. Because all pages 
remain valid ( no $transcodeKey derivative ) 
                }
+               // Clear the webVideoTranscode cache ( so we don't keep out 
dated table cache around ) 
+               webVideoTranscode::clearTranscodeCache( 
$this->title->getDBkey() );
+               
                // pass along result status: 
                return $status;
        }
-       /**
-        * Invalidate the cache of all pages where the video is displayed  
-        */
-       function invalidateCache(){
-               // The static cache of webVideoTranscode should be cleared
-               webVideoTranscode::clearTranscodeCache();
-               
-               // The file page cache should be invalidated: 
-               $this->title->invalidateCache();
-               
-               // TODO if the video is used in over 500 pages add to 'job 
queue'
-               $limit = 500;           
-               $dbr = wfGetDB( DB_SLAVE );
-               $res = $dbr->select(
-                       array( 'imagelinks', 'page' ),
-                       array( 'page_namespace', 'page_title' ),
-                       array( 'il_to' => $this->title->getDBkey(), 'il_from = 
page_id' ),
-                       __METHOD__,
-                       array( 'LIMIT' => $limit + 1 )
-               );
-               foreach ( $res as $page ) {
-                       $title = Title::makeTitle( $page->page_namespace, 
$page->page_title );
-                       $title->invalidateCache();
-               }               
-       }
        function removeFffmpgeLogFiles( $dir ){
                if (is_dir($dir)) {
                        if ($dh = opendir($dir)) {

Modified: trunk/extensions/TimedMediaHandler/resources/ext.tmh.transcodetable.js
===================================================================
--- trunk/extensions/TimedMediaHandler/resources/ext.tmh.transcodetable.js      
2011-06-13 15:32:23 UTC (rev 89972)
+++ trunk/extensions/TimedMediaHandler/resources/ext.tmh.transcodetable.js      
2011-06-13 16:05:05 UTC (rev 89973)
@@ -19,4 +19,49 @@
                .css('overflow', 'hidden');
                return false;
        })
+       // Reset transcode action: 
+       $j('.transcodereset a').click( function(){
+               var tKey = $(this).attr('data-transcodekey');
+               var buttons = {};
+               buttons[ gM('mwe-ok') ] = function(){
+                       var _thisDialog = this;
+                       $(this).loadingSpinner();
+                       var apiUrl =  mw.config.get('wgServer') + 
mw.config.get( 'wgScriptPath' ) + '/api.php';
+                       // Do an api post action: 
+                       $.post( apiUrl, {
+                               'action' : 'transcodereset',
+                               'transcodekey' : tKey,
+                               'title' : mw.config.get('wgPageName'),
+                               'token' : mw.user.tokens.get('editToken'),
+                               'format' : 'json'
+                       }, function( data ){
+                               if( data && data['success'] ){
+                                       // refresh the page
+                                       window.location.reload();
+                               } else {
+                                       if( data.error && data.error.info ){
+                                               $( _thisDialog ).text( 
data.error.info );
+                                       } else {
+                                               $( _thisDialog ).text( gM( 
'timedmedia-reset-error' ) );
+                                       }
+                                       var okBtn = {};
+                                       okBtn[ gM('mwe-ok') ] = function() { 
$(this).dialog("close"); } 
+                                       $( _thisDialog ).dialog( "option", 
"buttons", okBtn );
+                               }
+                       })
+               };
+               buttons[ gM('mwe-cancel') ] =function(){
+                       $(this).dialog('close');
+               }
+               // pop up dialog 
+               mw.addDialog({
+                       'width' : '400',
+                       'height' : '200',
+                       'title' : gM('timedmedia-reset'),                       
+                       'content' : gM('timedmedia-reset-confirm'),
+                       'buttons': buttons
+               })
+               .css('overflow', 'hidden');
+               return false;
+       })
 })


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to