Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 88 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
ApiTranscodeReset | |
0.00% |
0 / 88 |
|
0.00% |
0 / 9 |
552 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 45 |
|
0.00% |
0 / 1 |
72 | |||
checkTimeSinceLastReset | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
30 | |||
getStateResetTime | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
mustBePosted | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isWriteMode | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getAllowedParams | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
needsToken | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getExamplesMessages | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\TimedMediaHandler; |
4 | |
5 | use ApiBase; |
6 | use ApiMain; |
7 | use File; |
8 | use ManualLogEntry; |
9 | use MediaWiki\TimedMediaHandler\WebVideoTranscode\WebVideoTranscode; |
10 | use MediaWiki\Title\Title; |
11 | use RepoGroup; |
12 | use Wikimedia\ParamValidator\ParamValidator; |
13 | use Wikimedia\Rdbms\IConnectionProvider; |
14 | |
15 | /** |
16 | * Allows users with the 'transcode-reset' right to reset / re-run a transcode job. |
17 | * |
18 | * You can specify must specify a media asset title. You optionally can specify |
19 | * a transcode key, to only reset a single transcode job for a particular media asset. |
20 | * @ingroup API |
21 | */ |
22 | class ApiTranscodeReset extends ApiBase { |
23 | /** @var IConnectionProvider */ |
24 | private $dbProvider; |
25 | |
26 | /** @var RepoGroup */ |
27 | private $repoGroup; |
28 | |
29 | /** @var TranscodableChecker */ |
30 | private $transcodableChecker; |
31 | |
32 | /** |
33 | * @param ApiMain $main |
34 | * @param string $action |
35 | * @param IConnectionProvider $dbProvider |
36 | * @param RepoGroup $repoGroup |
37 | */ |
38 | public function __construct( |
39 | ApiMain $main, |
40 | $action, |
41 | IConnectionProvider $dbProvider, |
42 | RepoGroup $repoGroup |
43 | ) { |
44 | parent::__construct( $main, $action ); |
45 | $this->dbProvider = $dbProvider; |
46 | $this->repoGroup = $repoGroup; |
47 | $this->transcodableChecker = new TranscodableChecker( |
48 | $this->getConfig(), |
49 | $repoGroup |
50 | ); |
51 | } |
52 | |
53 | public function execute() { |
54 | // Check if transcoding is enabled on this wiki at all: |
55 | if ( !$this->getConfig()->get( 'EnableTranscode' ) ) { |
56 | $this->dieWithError( 'apierror-timedmedia-disabledtranscode', 'disabledtranscode' ); |
57 | } |
58 | |
59 | $params = $this->extractRequestParams(); |
60 | $titleObj = Title::newFromText( $params['title'] ); |
61 | |
62 | // Make sure we have a valid Title |
63 | if ( !$titleObj || $titleObj->isExternal() ) { |
64 | $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] ); |
65 | } |
66 | |
67 | // Check that the user has permmission to reset transcodes on the file |
68 | $this->checkTitleUserPermissions( $titleObj, 'transcode-reset' ); |
69 | |
70 | // Make sure the title can be transcoded |
71 | if ( !$this->transcodableChecker->isTranscodableTitle( $titleObj ) ) { |
72 | $this->dieWithError( |
73 | [ |
74 | 'apierror-timedmedia-invalidtranscodetitle', |
75 | wfEscapeWikiText( $titleObj->getPrefixedText() ) |
76 | ], |
77 | 'invalidtranscodetitle' |
78 | ); |
79 | } |
80 | $transcodeKey = false; |
81 | // Make sure it's an enabled transcode key we are trying to remove: |
82 | // ( if you update your transcode keys the api is not how you purge the database of expired keys ) |
83 | if ( isset( $params['transcodekey'] ) ) { |
84 | $transcodeSet = WebVideoTranscode::enabledTranscodes(); |
85 | if ( !in_array( $params['transcodekey'], $transcodeSet, true ) ) { |
86 | $this->dieWithError( |
87 | [ 'apierror-timedmedia-badtranscodekey', wfEscapeWikiText( $params['transcodekey'] ) ], |
88 | 'badtranscodekey' |
89 | ); |
90 | } else { |
91 | $transcodeKey = $params['transcodekey']; |
92 | } |
93 | } |
94 | |
95 | // Don't reset if less than 1 hour has passed and we have no error ) |
96 | $file = $this->repoGroup->findFile( $titleObj ); |
97 | $timeSinceLastReset = $this->checkTimeSinceLastReset( $file, $transcodeKey ); |
98 | $waitTimeForTranscodeReset = $this->getConfig()->get( 'WaitTimeForTranscodeReset' ); |
99 | if ( $timeSinceLastReset < $waitTimeForTranscodeReset ) { |
100 | $msg = $this->msg( |
101 | 'apierror-timedmedia-notenoughtimereset', |
102 | )->durationParams( $waitTimeForTranscodeReset - $timeSinceLastReset ); |
103 | $this->dieWithError( $msg, 'notenoughtimereset' ); |
104 | } |
105 | |
106 | // All good do the transcode removal: |
107 | WebVideoTranscode::removeTranscodes( $file, $transcodeKey ); |
108 | |
109 | // Oh and we wanted to reset it, right? Trigger again. |
110 | $options = [ |
111 | 'manualOverride' => true, |
112 | ]; |
113 | WebVideoTranscode::updateJobQueue( $file, $transcodeKey, $options ); |
114 | |
115 | $logEntry = new ManualLogEntry( 'timedmediahandler', 'resettranscode' ); |
116 | $logEntry->setPerformer( $this->getUser() ); |
117 | $logEntry->setTarget( $titleObj ); |
118 | $logEntry->setParameters( [ |
119 | '4::transcodekey' => $transcodeKey, |
120 | ] ); |
121 | $logEntry->insert(); |
122 | |
123 | $this->getResult()->addValue( null, 'success', 'removed transcode' ); |
124 | } |
125 | |
126 | /** |
127 | * @param File $file |
128 | * @param string|false $transcodeKey |
129 | * @return int|string |
130 | */ |
131 | public function checkTimeSinceLastReset( $file, $transcodeKey ) { |
132 | $dbw = $file->repo->getPrimaryDB(); |
133 | $transcodeStates = WebVideoTranscode::getTranscodeState( $file, $dbw ); |
134 | if ( $transcodeKey ) { |
135 | if ( !$transcodeStates[$transcodeKey] ) { |
136 | // transcode key not found |
137 | return $this->getConfig()->get( 'WaitTimeForTranscodeReset' ) + 1; |
138 | } |
139 | return $this->getStateResetTime( $transcodeStates[$transcodeKey] ); |
140 | } |
141 | // least wait is set to reset time: |
142 | $leastWait = $this->getConfig()->get( 'WaitTimeForTranscodeReset' ) + 1; |
143 | // else check for lowest reset time |
144 | foreach ( $transcodeStates as $state ) { |
145 | $ctime = $this->getStateResetTime( $state ); |
146 | if ( $ctime < $leastWait ) { |
147 | $leastWait = $ctime; |
148 | } |
149 | } |
150 | return $leastWait; |
151 | } |
152 | |
153 | /** |
154 | * @param array $state |
155 | * @return int|string |
156 | */ |
157 | public function getStateResetTime( $state ) { |
158 | $db = $this->dbProvider->getReplicaDatabase(); |
159 | // if an error return waitTime +1 |
160 | if ( $state['time_error'] !== null ) { |
161 | return $this->getConfig()->get( 'WaitTimeForTranscodeReset' ) + 1; |
162 | } |
163 | // return wait time from most recent event |
164 | foreach ( [ 'time_success', 'time_startwork', 'time_addjob' ] as $timeField ) { |
165 | if ( ( $state[ $timeField ] ) !== null ) { |
166 | return (int)$db->timestamp() - (int)$db->timestamp( $state[ $timeField ] ); |
167 | } |
168 | } |
169 | // No time info, return resetWaitTime |
170 | return $this->getConfig()->get( 'WaitTimeForTranscodeReset' ) + 1; |
171 | } |
172 | |
173 | /** @inheritDoc */ |
174 | public function mustBePosted() { |
175 | return true; |
176 | } |
177 | |
178 | /** @inheritDoc */ |
179 | public function isWriteMode() { |
180 | return true; |
181 | } |
182 | |
183 | /** @inheritDoc */ |
184 | protected function getAllowedParams() { |
185 | return [ |
186 | 'title' => [ |
187 | ParamValidator::PARAM_TYPE => 'string', |
188 | ParamValidator::PARAM_REQUIRED => true |
189 | ], |
190 | 'transcodekey' => null, |
191 | 'token' => null, |
192 | ]; |
193 | } |
194 | |
195 | /** @inheritDoc */ |
196 | public function needsToken() { |
197 | return 'csrf'; |
198 | } |
199 | |
200 | /** |
201 | * @see ApiBase::getExamplesMessages() |
202 | * @return array |
203 | */ |
204 | protected function getExamplesMessages() { |
205 | return [ |
206 | 'action=transcodereset&title=File:Clip.webm&token=123ABC' |
207 | => 'apihelp-transcodereset-example-1', |
208 | 'action=transcodereset&title=File:Clip.webm&transcodekey=360_560kbs.webm&token=123ABC' |
209 | => 'apihelp-transcodereset-example-2', |
210 | ]; |
211 | } |
212 | } |