Index: trunk/extensions/WikiAtHome/WikiAtHome.sql |
— | — | @@ -1,9 +1,7 @@ |
2 | | - |
3 | 2 | -- |
4 | 3 | -- Table structure for table `wah_jobqueue` |
5 | 4 | -- |
6 | 5 | |
7 | | -DROP TABLE IF EXISTS `wah_jobqueue`; |
8 | 6 | CREATE TABLE IF NOT EXISTS `wah_jobqueue` ( |
9 | 7 | `job_id` int(12) unsigned NOT NULL auto_increment, |
10 | 8 | `job_set_id` int(12) unsigned NOT NULL, |
— | — | @@ -14,8 +12,9 @@ |
15 | 13 | `job_assign_count` int(4) unsigned NOT NULL default '0', |
16 | 14 | `job_json` blob NOT NULL, |
17 | 15 | PRIMARY KEY (`job_id`), |
18 | | - KEY `job_set_id` (`job_set_id`) |
19 | | -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ; |
| 16 | + KEY `job_set_id` (`job_set_id`), |
| 17 | + KEY `job_last_assigned_user_id` (`job_last_assigned_user_id`) |
| 18 | +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; |
20 | 19 | |
21 | 20 | -- -------------------------------------------------------- |
22 | 21 | |
— | — | @@ -23,18 +22,17 @@ |
24 | 23 | -- Table structure for table `wah_jobset` |
25 | 24 | -- |
26 | 25 | |
27 | | -DROP TABLE IF EXISTS `wah_jobset`; |
28 | 26 | CREATE TABLE IF NOT EXISTS `wah_jobset` ( |
29 | 27 | `set_id` int(10) unsigned NOT NULL auto_increment, |
30 | 28 | `set_namespace` int(11) default NULL, |
31 | 29 | `set_title` varchar(255) default NULL, |
32 | 30 | `set_jobs_count` int(11) unsigned NOT NULL, |
33 | 31 | `set_encodekey` varchar(40) default NULL, |
34 | | - `job_creation_time` int(14) NOT NULL, |
| 32 | + `set_creation_time` int(14) NOT NULL, |
35 | 33 | `set_done_time` int(14) default NULL, |
36 | 34 | `set_client_count` int(5) NOT NULL default '0', |
37 | 35 | PRIMARY KEY (`set_id`), |
38 | 36 | KEY `set_namespace` (`set_namespace`,`set_title`), |
39 | 37 | KEY `set_done_time` (`set_done_time`), |
40 | 38 | KEY `set_client_count` (`set_client_count`) |
41 | | -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; |
| 39 | +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; |
Index: trunk/extensions/WikiAtHome/ApiWikiAtHome.php |
— | — | @@ -52,26 +52,93 @@ |
53 | 53 | $job4Client['job_key'] = $job->job_id . '_'. sha1( $job->job_json ); |
54 | 54 | $job4Client['job_title']= $job->title; |
55 | 55 | $job4Client['job_ns'] = $job->ns; |
56 | | - |
| 56 | + $job4Client['job_set_id'] = $job->job_set_id; |
| 57 | + |
57 | 58 | $tTitle = Title::newFromText($job->title, $job->ns); |
58 | | - |
| 59 | + |
59 | 60 | $job4Client['job_fullTitle'] = $tTitle->getFullText(); |
60 | | - |
| 61 | + |
61 | 62 | //@@todo avoid an api round trip return url here: |
62 | 63 | //$job4Client['job_url'] = $file->getFullURL(); |
63 | | - |
| 64 | + |
64 | 65 | $this->getResult()->addValue( null, $this->getModuleName(), |
65 | 66 | array( |
66 | 67 | 'job' => $job4Client |
67 | 68 | ) |
68 | 69 | ); |
69 | 70 | } |
| 71 | + }else if ( $this->mParams['jobkey'] ){ |
| 72 | + print "have jobKey: " . $this->mParams['jobkey'] ; |
| 73 | + //process the upload |
| 74 | + //check if its a valid job key (job_number _ sh1(job_json) ) |
| 75 | + list($job_id, $json_sha1) = explode( '_', $this->mParams['jobkey'] ); |
| 76 | + $job = WahJobManager::getJobById( $job_id ); |
| 77 | + if( !$job || sha1($job->job_json) != $json_sha1){ |
| 78 | + //die on bad job key |
| 79 | + return $this->dieUsage('Your job key is not valid', 'badjobkey' ); |
| 80 | + } |
| 81 | + $jobSet = WahJobManager::getJobSetById( $job->job_set_id ); |
| 82 | + //check if its a valid video ogg file (ffmpeg2theora --info) |
| 83 | + $uploadedJobFile = $this->getFileTempname('file'); |
| 84 | + $mediaMeta = wahGetMediaJsonMeta( $uploadedJobFile ); |
| 85 | + |
| 86 | + if( !$mediaMeta ){ |
| 87 | + //failed basic ffmpeg2theora video validation |
| 88 | + return $this->dieUsage('Not a valid Video File', 'badfile' ); |
| 89 | + } |
| 90 | + //check for theora and vorbis streams in the metadata output of the file: |
| 91 | + if( class_exists( OggHandler ) ){ |
| 92 | + $isOgg = false; |
| 93 | + |
| 94 | + if( OggHandler::audioTypes ){ |
| 95 | + $audioTypes = OggHandler::audioTypes; |
| 96 | + } |
| 97 | + foreach ( $mediaMeta['video'] as $videoStream ) { |
| 98 | + if(in_array( ucfirst( $videoStream->codec ), OggHandler::videoTypes)) |
| 99 | + $isOgg =true; |
| 100 | + } |
| 101 | + foreach ( $mediaMeta['audio'] as $audioStream ) { |
| 102 | + if(in_array( ucfirst( $audioStream->codec ), OggHandler::audioTypes)) |
| 103 | + $isOgg = true; |
| 104 | + } |
| 105 | + if(!$isOgg){ |
| 106 | + return $this->dieUsage('Not a valid Ogg file', 'badfile' ); |
| 107 | + } |
| 108 | + } |
| 109 | + //all good so far put it into the derivative temp folder by with each piece as it job_id name |
| 110 | + //@@todo need to rework this a bit for flattening "sequences" |
| 111 | + $fTitle = Title::newFromText( $jobSet->set_title, $jobSet->set_namespace ); |
| 112 | + $file = RepoGroup::singleton()->getLocalRepo()->newFile( $fTitle ); |
| 113 | + $thumbPath = $file->getThumbPath( $jobSet->set_encodekey ); |
| 114 | + |
| 115 | + $destTarget = $job_id . '.ogg'; |
| 116 | + |
| 117 | + //copy the current chunk to that path: |
| 118 | + $status = RepoGroup::singleton()->getLocalRepo()->store( |
| 119 | + $uploadedJobFile, |
| 120 | + 'thumb', |
| 121 | + $destTarget |
| 122 | + ); |
| 123 | + if( !$status->isGood() ){ |
| 124 | + return $this->dieUsage( 'Could not Copy File'); |
| 125 | + } |
| 126 | + return $this->dieUsage('copied file to: ' . $destTarget); |
| 127 | + |
| 128 | + //update the table with job done time & job user |
| 129 | + |
| 130 | + |
| 131 | + //check if its the "last" job shell out a join command |
| 132 | + |
| 133 | + //double check all the files exist. |
| 134 | + |
| 135 | + //return success |
| 136 | + |
70 | 137 | } |
71 | 138 | } |
72 | 139 | public function getAllowedParams() { |
73 | 140 | return array( |
74 | 141 | 'file' => null, |
75 | | - 'job_key' => null, |
| 142 | + 'jobkey' => null, |
76 | 143 | 'getnewjob' => null, |
77 | 144 | 'jobset' => null, |
78 | 145 | 'token' => null |
— | — | @@ -81,7 +148,7 @@ |
82 | 149 | public function getParamDescription() { |
83 | 150 | return array( |
84 | 151 | 'file' => 'the file or data being uploaded for a given job', |
85 | | - 'job_key' => 'used to submit the resulting file of a given job key', |
| 152 | + 'jobkey' => 'used to submit the resulting file of a given job key', |
86 | 153 | 'getnewjob' => 'set to ture to get a new job', |
87 | 154 | 'jobset' => 'jobset used with getnewjob to set jobset prefrence', |
88 | 155 | 'token' => 'the edittoken (needed to submit job chunks)' |
Index: trunk/extensions/WikiAtHome/NonFreeVideoHandler.php |
— | — | @@ -94,15 +94,10 @@ |
95 | 95 | //if we have fffmpeg2theora |
96 | 96 | if( $wgffmpeg2theora && is_file( $wgffmpeg2theora ) ){ |
97 | 97 | |
98 | | - $cmd = wfEscapeShellArg( $wgffmpeg2theora ) . ' ' . wfEscapeShellArg ( $path ). ' --info'; |
99 | | - wfProfileIn( 'ffmpeg2theora' ); |
100 | | - wfDebug( __METHOD__.": $cmd\n" ); |
101 | | - $json_meta_str = wfShellExec( $cmd ); |
102 | | - wfProfileOut( 'ffmpeg2theora' ); |
| 98 | + $mediaMeta = wahGetMediaJsonMeta( $path ); |
103 | 99 | |
104 | | - $json_file_meta = json_decode( $json_meta_str ); |
105 | | - if( $json_file_meta ){ |
106 | | - foreach($json_file_meta as $k=>$v){ |
| 100 | + if( $mediaMeta ){ |
| 101 | + foreach($mediaMeta as $k=>$v){ |
107 | 102 | if( !isset( $metadata[ $k ])) |
108 | 103 | $metadata[ $k ] = $v; |
109 | 104 | } |
— | — | @@ -138,8 +133,11 @@ |
139 | 134 | $height = $srcWidth == 0 ? $srcHeight : $width * $srcHeight / $srcWidth; |
140 | 135 | //set the width based on the requested width: |
141 | 136 | |
| 137 | + /*print_r($file); |
| 138 | + print_r($params); |
| 139 | + print " dpath: $dstPath, durl: $dstUrl <br>"; |
| 140 | + die();*/ |
142 | 141 | |
143 | | - |
144 | 142 | //do some arbitrary derivative selection logic: |
145 | 143 | $encodeKey = $this->getTargetDerivative($width, $srcWidth); |
146 | 144 | //see if we have that encoding profile already: |
Index: trunk/extensions/WikiAtHome/WikiAtHome.php |
— | — | @@ -56,6 +56,26 @@ |
57 | 57 | const ENC_HQ_STREAM = 'high_quality'; |
58 | 58 | } |
59 | 59 | |
| 60 | +//GLOBAL FUNCTIONS: |
| 61 | + |
| 62 | +/* |
| 63 | + * gets the json metadata from a given file (also validates it as a valid file) |
| 64 | + */ |
| 65 | +function wahGetMediaJsonMeta( $path ){ |
| 66 | + $cmd = wfEscapeShellArg( $wgffmpeg2theora ) . ' ' . wfEscapeShellArg ( $path ). ' --info'; |
| 67 | + wfProfileIn( 'ffmpeg2theora shellExec' ); |
| 68 | + wfDebug( __METHOD__.": $cmd\n" ); |
| 69 | + $json_meta_str = wfShellExec( $cmd ); |
| 70 | + wfProfileOut( 'ffmpeg2theora shellExec' ); |
| 71 | + $objMeta = json_decode( $json_meta_str ); |
| 72 | + |
| 73 | + //if we return the same string then json_decode has failed in php < 5.2.6 |
| 74 | + //workaround for bug http://bugs.php.net/bug.php?id=45989 |
| 75 | + if( $objMeta == $json_meta_str ) |
| 76 | + return false; |
| 77 | + return $objMeta; |
| 78 | +} |
| 79 | + |
60 | 80 | /******************* CONFIGURATION STARTS HERE **********************/ |
61 | 81 | |
62 | 82 | //ffmpeg2theora path: enables us to get basic source file information |
Index: trunk/extensions/WikiAtHome/WahJobManager.php |
— | — | @@ -16,7 +16,7 @@ |
17 | 17 | $fname = 'WahJobManager::getDonePerc'; |
18 | 18 | //grab the jobset |
19 | 19 | $dbr = &wfGetDb( DB_READ ); |
20 | | - $res = $dbr->select('wah_jobset', |
| 20 | + $setRow = $dbr->selectRow('wah_jobset', |
21 | 21 | '*', |
22 | 22 | array( |
23 | 23 | 'set_namespace' => $this->sNamespace, |
— | — | @@ -25,30 +25,38 @@ |
26 | 26 | ), |
27 | 27 | __METHOD__ |
28 | 28 | ); |
29 | | - if( $dbr->numRows( $res ) == 0 ){ |
| 29 | + if( !$setRow ){ |
30 | 30 | //we should setup the job: |
31 | 31 | $this->doJobSetup(); |
32 | 32 | //return 0 percent done |
33 | 33 | return 0; |
34 | 34 | }else{ |
35 | | - $setRow = $dbr->fetchObject( $res ); |
| 35 | + //quick check if we are done at the set level: |
| 36 | + if( $setRow->set_done_time ) |
| 37 | + return 1; |
| 38 | + |
| 39 | + //else check how done are we: |
36 | 40 | $this->sId = $setRow->set_id; |
37 | 41 | $this->sJobsCount = $setRow->set_jobs_count; |
38 | | - //get an estimate of how many of the current job are NULL (not completed) |
| 42 | + //get an estimate of how many jobs are done (not null) |
| 43 | + //@@note: estimateRowCount ~might be more appropriate |
| 44 | + // but it was behaving inconsistently for me~ |
39 | 45 | $doneRes = $dbr->select('wah_jobqueue', |
40 | 46 | 'job_id', |
41 | 47 | array( |
42 | 48 | 'job_set_id' => $this->sId, |
43 | 49 | 'job_done_time IS NOT NULL' |
44 | 50 | ), |
45 | | - $fname |
| 51 | + __METHOD__ |
46 | 52 | ); |
47 | 53 | $doneCount = $dbr->numRows( $doneRes ); |
48 | | - if( $doneCount == $this->sJobsCount ) |
| 54 | + if( $doneCount == $this->sJobsCount ){ |
| 55 | + //update the job_set (should already hae been done) |
49 | 56 | return 1; |
| 57 | + } |
50 | 58 | //return 1 when doneCount == sJobCount |
51 | 59 | //(we also set this at a higher level and avoid hitting the wah_jobqueue table alltogehter) |
52 | | - return round( $doneCount / $this->sJobsCount , 3); |
| 60 | + return round( $doneCount / $this->sJobsCount , 2); |
53 | 61 | } |
54 | 62 | } |
55 | 63 | /* |
— | — | @@ -65,79 +73,64 @@ |
66 | 74 | //its always best to assigning from jobset (since the user already has the data) |
67 | 75 | if( $jobset_id ){ |
68 | 76 | //try to get one from the current jobset |
69 | | - $res = $dbr->select( 'wah_jobqueue', |
| 77 | + $job = $dbr->selectRow( 'wah_jobqueue', |
70 | 78 | '*', |
71 | 79 | array( |
72 | 80 | 'job_set_id' => intval( $jobset_id ), |
73 | 81 | 'job_done_time IS NULL', |
74 | 82 | 'job_last_assigned_time < '. $dbr->addQuotes( time() - $wgJobTimeOut ) |
75 | 83 | ), |
76 | | - __METHOD__, |
77 | | - array( |
78 | | - 'LIMIT'=>1 |
79 | | - ) |
| 84 | + __METHOD__ |
80 | 85 | ); |
81 | | - if( $dbr->numRows( $res ) != 0){ |
82 | | - $job = $dbr->fetchObject( $res ); |
| 86 | + if( $job ){ |
83 | 87 | return WahJobManager::assignJob( $job ); |
84 | 88 | } |
85 | 89 | } |
86 | | - |
| 90 | + |
87 | 91 | //check if we already have a job given but never completed: |
88 | | - $res = $dbr->select( 'wah_jobqueue', |
| 92 | + $job = $dbr->selectRow( 'wah_jobqueue', |
89 | 93 | '*', |
90 | 94 | array( |
91 | 95 | 'job_last_assigned_user_id' => $wgUser->getId() |
92 | 96 | ), |
93 | | - __METHOD__, |
94 | | - array( |
95 | | - 'LIMIT'=>1 |
96 | | - ) |
| 97 | + __METHOD__ |
97 | 98 | ); |
98 | | - //re-assing the same job (don't update |
99 | | - if( $dbr->numRows( $res ) != 0){ |
100 | | - $job = $dbr->fetchObject( $res ); |
101 | | - return WahJobManager::assignJob( $job , false, false); |
| 99 | + |
| 100 | + //re-assign the same job (don't update anything so it can timeout if they keep getting the same job) |
| 101 | + if( $job ){ |
| 102 | + return WahJobManager::assignJob( $job , false, false); |
102 | 103 | } |
103 | | - |
| 104 | + |
104 | 105 | //just do a normal select from jobset |
105 | | - $setRes = $dbr->select( 'wah_jobset', |
| 106 | + $jobSet = $dbr->selectRow( 'wah_jobset', |
106 | 107 | '*', |
107 | 108 | array( |
108 | 109 | 'set_done_time IS NULL', |
109 | 110 | 'set_client_count < '. $dbr->addQuotes( $wgNumberOfClientsPerJobSet ) |
110 | 111 | ), |
111 | | - __METHOD__, |
112 | | - array( |
113 | | - 'LIMIT' => 1 |
114 | | - ) |
| 112 | + __METHOD__ |
115 | 113 | ); |
116 | | - if( $dbr->numRows( $setRes ) == 0){ |
117 | | - //no jobs: |
| 114 | + if( $jobSet ){ |
| 115 | + //no jobs: |
118 | 116 | return false; |
119 | 117 | }else{ |
120 | 118 | //get a job from the jobset and increment the set_client_count |
121 | 119 | //(if the user has an unfinished job) re assign it (in cases where job is lost in trasport) |
122 | | - $jobSet = $dbr->fetchObject( $setRes ); |
123 | 120 | //get a job from the selected jobset: |
124 | | - $jobRes = $dbr->select('wah_jobqueue', '*', |
| 121 | + $job = $dbr->selectRow('wah_jobqueue', '*', |
125 | 122 | array( |
126 | 123 | 'job_set_id' => $jobSet->set_id, |
127 | 124 | 'job_done_time IS NULL', |
128 | | - 'job_last_assigned_time IS NULL OR job_last_assigned_time < ' . |
129 | | - $dbr->addQuotes( time() - $wgJobTimeOut ) |
| 125 | + 'job_last_assigned_time IS NULL OR job_last_assigned_time < ' . |
| 126 | + $dbr->addQuotes( time() - $wgJobTimeOut ) |
130 | 127 | ), |
131 | | - __METHOD__, |
132 | | - array( |
133 | | - 'LIMIT' => 1 |
134 | | - ) |
| 128 | + __METHOD__ |
135 | 129 | ); |
136 | | - if( $dbr->numRows( $jobRes ) == 0){ |
| 130 | + if( !$job ){ |
137 | 131 | //no jobs in this jobset (return nojob) |
138 | 132 | //@@todo we could "retry" since we will get here when a set has everything assigned in less than $wgJobTimeOut |
139 | 133 | return false; |
140 | 134 | }else{ |
141 | | - $job = $dbr->fetchObject( $jobRes ); |
142 | 135 | return WahJobManager::assignJob( $job , $jobSet); |
143 | 136 | } |
144 | 137 | } |
— | — | @@ -154,12 +147,12 @@ |
155 | 148 | $dbr = wfGetDb( DB_READ ); |
156 | 149 | $dbw = wfGetDb( DB_WRITE ); |
157 | 150 | if( $jobSet == false ){ |
158 | | - $jobSet = self::getJobSetBySetId( $job->job_set_id ); |
| 151 | + $jobSet = self::getJobSetById( $job->job_set_id ); |
159 | 152 | } |
160 | 153 | //set the title and namespace: |
161 | 154 | $job->title = $jobSet->set_title; |
162 | 155 | $job->ns = $jobSet->set_namespace; |
163 | | - |
| 156 | + |
164 | 157 | //check if we should update the tables for the assigned Job |
165 | 158 | if( $doUpdate ){ |
166 | 159 | //for jobqueue update: job_last_assigned_time, job_last_assigned_user_id, job_assign_count |
— | — | @@ -196,19 +189,23 @@ |
197 | 190 | } |
198 | 191 | return $job; |
199 | 192 | } |
200 | | - static function getJobSetBySetId( $set_id ){ |
| 193 | + static function getJobSetById( $set_id ){ |
201 | 194 | $dbr = wfGetDb( DB_READ ); |
202 | | - $setRes = $dbr->select('wah_jobset', '*', |
| 195 | + return $dbr->selectRow('wah_jobset', '*', |
203 | 196 | array( |
204 | 197 | 'set_id' => $set_id |
205 | 198 | ), |
206 | | - __METHOD__, |
| 199 | + __METHOD__ |
| 200 | + ); |
| 201 | + } |
| 202 | + static function getJobById( $job_id ){ |
| 203 | + $dbr = wfGetDb( DB_READ ); |
| 204 | + return $dbr->selectRow('wah_jobset', '*', |
207 | 205 | array( |
208 | | - 'LIMIT' => 1 |
209 | | - ) |
| 206 | + 'job_id' => $set_id |
| 207 | + ), |
| 208 | + __METHOD__ |
210 | 209 | ); |
211 | | - $jobSet = $dbr->fetchObject( $setRes ); |
212 | | - return $jobSet; |
213 | 210 | } |
214 | 211 | /* |
215 | 212 | * setups up a new job |
— | — | @@ -243,7 +240,7 @@ |
244 | 241 | $encSettingsAry['endtime'] = $encSettingsAry['starttime'] + $wgChunkDuration; |
245 | 242 | |
246 | 243 | $jobJsonAry = array( |
247 | | - 'jobType' => 'transcode', |
| 244 | + 'jobType' => 'transcode', |
248 | 245 | 'chunkNumber' => $i, |
249 | 246 | 'encodeSettings'=> $encSettingsAry |
250 | 247 | ); |
— | — | @@ -251,7 +248,7 @@ |
252 | 249 | //add starttime and endtime |
253 | 250 | $jobInsertArray[] = |
254 | 251 | array( |
255 | | - 'job_set_id' => $this->sId, |
| 252 | + 'job_set_id' => $this->sId, |
256 | 253 | 'job_json' => ApiFormatJson::getJsonEncode( $jobJsonAry ) |
257 | 254 | ); |
258 | 255 | } |
Index: trunk/extensions/WikiAtHome/WikiAtHome.js |
— | — | @@ -2,19 +2,30 @@ |
3 | 3 | |
4 | 4 | //load msgs: |
5 | 5 | loadGM({ |
6 | | - 'wah-menu-jobs' : "Jobs", |
7 | | - 'wah-menu-stats': "Stats", |
8 | | - 'wah-menu-pref' : "Prefrences", |
9 | | - 'wah-loading' : 'loading wiki@home interface <blink>...</blink>', |
| 6 | + "wah-menu-jobs" : "Jobs", |
| 7 | + "wah-menu-stats": "Stats", |
| 8 | + "wah-menu-pref" : "Prefrences", |
| 9 | + "wah-loading" : "loading Wiki@Home interface <blink>...</blink>", |
10 | 10 | |
11 | | - 'wah-lookingforjob' : "Looking For a Job <blink>...</blink>", |
12 | | - 'wah-nojobfound' : "No Job Found, Will retry in $1 seconds", |
13 | | - 'wah-notoken-login' : "Could not get a token. Are you logged in?", |
| 11 | + "wah-lookingforjob" : "Looking For a Job <blink>...</blink>", |
14 | 12 | |
15 | | - 'wah-doing-job' : "Job: <i>$1</i> on: <i>$2</i>", |
16 | | - 'wah-downloading' : "Downloading File <i>$1%</i> done", |
17 | | - 'wah-needs-firefogg': "To particate in wiki@home you need to install firefogg." |
| 13 | + "wah-start-on-visit": "Start up Wiki@Home anytime I visit this site", |
| 14 | + "wah-jobs-while-away": "Only run jobs when I have been away from my browser for 20 minnutes", |
18 | 15 | |
| 16 | + "wah-nojobfound" : "No Job Found, Will retry in $1 seconds", |
| 17 | + |
| 18 | + "wah-notoken-login" : "Could not get a token. Are you logged in?", |
| 19 | + "wah-apioff" : "The api appears to be off. Please Contact your Wiki Admin", |
| 20 | + |
| 21 | + "wah-doing-job" : "Job: <i>$1</i> on: <i>$2</i>", |
| 22 | + "wah-downloading" : "Downloading File <i>$1%</i> done", |
| 23 | + "wah-encoding" : "Encoding File <i>$1%</i> done", |
| 24 | + "wah-uploading" : "Uploading File <i>$i</i> done", |
| 25 | + "wah-uploadfail" : "Uploading Failed", |
| 26 | + "wah-doneuploading" : "Done Uploading. Thanks for your Contribution.", |
| 27 | + |
| 28 | + "wah-needs-firefogg": "To particate in wiki@home you need to install firefogg." |
| 29 | + |
19 | 30 | }); |
20 | 31 | |
21 | 32 | |
— | — | @@ -54,6 +65,11 @@ |
55 | 66 | for(var i in wahConfig){ |
56 | 67 | _this[i] = wahConfig[i]; |
57 | 68 | } |
| 69 | + //make sure api is "on" |
| 70 | + if( !wgEnableAPI ){ |
| 71 | + $j( _this.wah_container ).html( gM('wah-apioff') ); |
| 72 | + return false; |
| 73 | + } |
58 | 74 | |
59 | 75 | //fist see if we are even logged in: |
60 | 76 | if( !wgUserName ){ |
— | — | @@ -100,14 +116,30 @@ |
101 | 117 | select: function(event, ui) { |
102 | 118 | //_this.selectTab( $j(ui.tab).attr('id').replace('rsd_tab_', '') ); |
103 | 119 | } |
104 | | - }).find(".ui-tabs-nav").sortable({axis:'x'}); |
105 | | - |
| 120 | + }).find(".ui-tabs-nav").sortable({axis:'x'}); |
| 121 | + |
| 122 | + //set pref initial layout |
| 123 | + $j('#tab-pref').html( |
| 124 | + '<h2>' + gM('wah-menu-pref') + '</h2>' + |
| 125 | + '<i>These prefrences are not yet active</i>' + |
| 126 | + '<ul>' + |
| 127 | + '<li><input type="checkbox">' + gM('wah-start-on-visit') + '</li>' + |
| 128 | + '<li><input type="checkbox">' + gM('wah-jobs-while-away') + '</li>' + |
| 129 | + '</ul>' |
| 130 | + ); |
| 131 | + |
| 132 | + //set the initail stats layout |
| 133 | + $j('#tab-stats').html( |
| 134 | + '<h2>Some Cool Visual Stats Go here!</h2>' |
| 135 | + ) |
| 136 | + |
106 | 137 | //set tabs to initial layout |
107 | 138 | $j('#tab-jobs').html( |
108 | 139 | '<h2 class="wah-gen-status"></h2>' + |
109 | | - '<div class="progress-bar" style="width:400px;heigh:20px;"></div>' + |
110 | | - '<div class="prograss-status" style="width:400px;heigh:20px;"></div>' |
| 140 | + '<div class="progress-bar" style="width:400px;height:20px;"></div>' + |
| 141 | + '<div class="prograss-status" ></div>' |
111 | 142 | ); |
| 143 | + |
112 | 144 | //make sure we have firefogg |
113 | 145 | //check if we have firefogg installed (needed for transcoding jobs) |
114 | 146 | this.myFogg = new mvFirefogg({ |
— | — | @@ -115,7 +147,9 @@ |
116 | 148 | }); |
117 | 149 | |
118 | 150 | if(!this.myFogg.firefoggCheck() ){ |
119 | | - $j('#tab-jobs .progress-bar').hide().after( gM('wah-needs-firefogg') ); |
| 151 | + $j('#tab-jobs .progress-bar').hide().after( |
| 152 | + gM('wah-needs-firefogg') |
| 153 | + ); |
120 | 154 | |
121 | 155 | //if we don't have 3.5 firefox update link: |
122 | 156 | if(!($j.browser.mozilla && $j.browser.version >= '1.9.1')) { |
— | — | @@ -130,19 +164,24 @@ |
131 | 165 | } |
132 | 166 | return false; |
133 | 167 | } |
| 168 | + //set up local fogg pointer: |
| 169 | + this.fogg = this.myFogg.fogg; |
134 | 170 | return true; |
135 | 171 | }, |
136 | | - lookForJob: function(){ |
| 172 | + lookForJob: function( job_set_id ){ |
137 | 173 | var _this = this; |
138 | 174 | //set the big status |
139 | 175 | $j('#tab-jobs .wah-gen-status').html( gM('wah-lookingforjob') ); |
140 | | - |
| 176 | + var reqObj = { |
| 177 | + 'action' : 'wikiathome', |
| 178 | + 'getnewjob' : true, |
| 179 | + 'token' : _this.eToken |
| 180 | + }; |
| 181 | + if( job_set_id ){ |
| 182 | + reqObj['jobset'] = job_set_id; |
| 183 | + } |
141 | 184 | do_api_req({ |
142 | | - 'data':{ |
143 | | - 'action' : 'wikiathome', |
144 | | - 'getnewjob' : true, |
145 | | - 'token' : _this.eToken |
146 | | - } |
| 185 | + 'data' : reqObj |
147 | 186 | },function(data){ |
148 | 187 | //if we have a job update status to proccessing |
149 | 188 | if( data.wikiathome.nojobs ){ |
— | — | @@ -153,6 +192,7 @@ |
154 | 193 | } |
155 | 194 | }); |
156 | 195 | }, |
| 196 | + |
157 | 197 | delayLookForJob:function(){ |
158 | 198 | var _this = this; |
159 | 199 | var i=0; |
— | — | @@ -160,12 +200,14 @@ |
161 | 201 | i++; |
162 | 202 | if(i == _this.jobsearch_delay){ |
163 | 203 | _this.lookForJob(); |
| 204 | + return false; |
164 | 205 | }else{ |
165 | 206 | //update the delay msg: |
166 | | - $j('#tab-jobs .wah-gen-status').html( gM( 'wah-nojobfound', seconds2npt(i)) ); |
| 207 | + $j('#tab-jobs .wah-gen-status').html( gM( 'wah-nojobfound', seconds2npt( _this.jobsearch_delay - i )) ); |
167 | 208 | } |
| 209 | + setTimeout(delayJobUpdate, 1000); |
168 | 210 | } |
169 | | - setTimeout(delayJobUpdate, 1000) |
| 211 | + setTimeout(delayJobUpdate, 1000); |
170 | 212 | }, |
171 | 213 | doProccessJob:function( job ){ |
172 | 214 | var _this = this; |
— | — | @@ -177,6 +219,9 @@ |
178 | 220 | $j('#tab-jobs .progress-bar').progressbar({ |
179 | 221 | value: 0 |
180 | 222 | }); |
| 223 | + //set the jobKey: |
| 224 | + _this.jobKey = job.job_key; |
| 225 | + |
181 | 226 | //start proccessing the work flow based on work type |
182 | 227 | if( job.job_json.jobType == 'transcode' ){ |
183 | 228 | //download the source footage |
— | — | @@ -196,26 +241,94 @@ |
197 | 242 | },function(data){ |
198 | 243 | for(var i in data.query.pages){ |
199 | 244 | _this.source_url = data.query.pages[i].imageinfo[0].url; |
200 | | - } |
| 245 | + } |
201 | 246 | //have firefogg download the file: |
202 | | - _this.myFogg.selectVideoUrl( _this.source_url ); |
| 247 | + js_log("do selectVideoUrl:: " + _this.source_url); |
| 248 | + _this.fogg.selectVideoUrl( _this.source_url ); |
203 | 249 | //check firefogg state and update status: |
204 | | - var updateDownoadState = function(){ |
205 | | - if( _this.myFogg.state == 'downloading'){ |
206 | | - var percDone = _this.myFogg.downloadVideo.progress * 100; |
207 | | - $j('#tab-jobs .progress-bar').progressbar({ |
208 | | - value: percDone |
209 | | - }); |
| 250 | + var updateDownloadState = function(){ |
| 251 | + if( _this.fogg.state == 'downloading'){ |
| 252 | + //update progress |
| 253 | + _this.updateProgress(_this.fogg.progress(), 'wah-downloading'); |
| 254 | + //loop update: |
| 255 | + setTimeout(updateDownloadState, 100); |
| 256 | + }else if( _this.fogg.state == 'downloaded'){ |
| 257 | + js_log('downloaded is done, run encode'); |
| 258 | + //we can now issue the encode call |
| 259 | + _this.fogg.encode( |
| 260 | + JSON.stringify( |
| 261 | + job.job_json.encodeSettings |
| 262 | + ) |
| 263 | + ); |
| 264 | + updateEncodeState(); |
| 265 | + }else if( _this.fogg.state == "download failed"){ |
| 266 | + js_log('download state failed'); |
| 267 | + } |
| 268 | + } |
| 269 | + //do the initial call to downloading state updates |
| 270 | + if( _this.fogg.state == 'downloading'){ |
| 271 | + setTimeout(updateDownloadState, 100); |
| 272 | + } |
| 273 | + |
| 274 | + //our encode state update |
| 275 | + var updateEncodeState = function(){ |
| 276 | + _this.updateProgress( _this.fogg.progress(), 'wah-encoding'); |
| 277 | + if( _this.fogg.state == 'encoding done' ){ |
| 278 | + js_log('encoding done , do upload'); |
| 279 | + _this.fogg.post( mwGetLocalApiUrl(), |
| 280 | + 'file', |
| 281 | + JSON.stringify({ |
| 282 | + 'action' : 'wikiathome', |
| 283 | + 'token' : _this.eToken, |
| 284 | + 'jobkey' : _this.jobKey |
| 285 | + }) |
| 286 | + ); |
| 287 | + //do upload req |
| 288 | + updateUploadState(); |
| 289 | + return true; |
| 290 | + } |
| 291 | + setTimeout(updateEncodeState, 100); |
| 292 | + } |
| 293 | + //our updateUploadState update |
| 294 | + var updateUploadState = function(){ |
| 295 | + _this.updateProgress( _this.fogg.progress(), 'wah-uploading'); |
| 296 | + if( _this.fogg.state == 'upload done'){ |
| 297 | + //done uploading |
| 298 | + //congradulate the user and issue new job request |
210 | 299 | $j('#tab-jobs .prograss-status').html( |
211 | | - gM('wah-downloading',percDone) |
| 300 | + gM( 'wah-doneuploading' ) |
212 | 301 | ); |
| 302 | + var getNextTranscodeJob = function(){ |
| 303 | + _this.lookForJob( job.job_set_id ); |
| 304 | + } |
| 305 | + //display the msg for 3 seconds |
| 306 | + //setTimeout(getNextTranscodeJob, 3000); |
| 307 | + |
| 308 | + return true; |
| 309 | + }else if( _this.fogg.state == 'uplaod failed'){ |
| 310 | + $j('#tab-jobs .prograss-status').html( |
| 311 | + gM( 'wah-uploadfail' ) |
| 312 | + ); |
213 | 313 | } |
214 | | - } |
215 | | - setTimeout(updateDownoadState, 100); |
| 314 | + setTimeout(updateUploadState, 100); |
| 315 | + } |
216 | 316 | }); |
217 | 317 | |
218 | 318 | |
219 | 319 | //for transcode jobs we have to download (unless we already have the file) |
220 | 320 | |
| 321 | + }, |
| 322 | + updateProgress: function(perc, msgKey){ |
| 323 | + //get percent done with 2 decimals |
| 324 | + var percDone = Math.round(perc * 10000) /100; |
| 325 | + //update progress bar |
| 326 | + $j('#tab-jobs .progress-bar').progressbar( |
| 327 | + 'value', |
| 328 | + Math.round( percDone ) |
| 329 | + ); |
| 330 | + //update status |
| 331 | + $j('#tab-jobs .prograss-status').html( |
| 332 | + gM(msgKey, percDone) |
| 333 | + ); |
221 | 334 | } |
222 | 335 | } |
\ No newline at end of file |