Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ConvertSubtitles
0.00% covered (danger)
0.00%
0 / 66
0.00% covered (danger)
0.00%
0 / 4
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
42
 processWork
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
20
 formatError
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Report on number and size of transcodes.
4 */
5$IP = getenv( 'MW_INSTALL_PATH' );
6if ( $IP === false ) {
7    $IP = __DIR__ . '/../../..';
8}
9require_once "$IP/maintenance/Maintenance.php";
10
11use MediaWiki\TimedMediaHandler\Handlers\TextHandler\TextHandler;
12use MediaWiki\TimedMediaHandler\TimedText;
13use MediaWiki\TimedMediaHandler\TimedTextPage;
14use MediaWiki\Title\Title;
15use Wikimedia\Rdbms\IExpression;
16use Wikimedia\Rdbms\LikeValue;
17
18class ConvertSubtitles extends Maintenance {
19
20    /** @var int */
21    private $count = 0;
22    /** @var int */
23    private $failed = 0;
24
25    public function __construct() {
26        parent::__construct();
27        $this->addOption( "file", "process a single given TimedText 'file'", false, true );
28        $this->addOption( "format", "output format, one of 'vtt' or 'srt'", false, true );
29        $this->addOption( "dump", "dump output to stdout along with status", false, false );
30        $this->addDescription( "convert one or more subtitle files and report on success." );
31        $this->requireExtension( 'TimedMediaHandler' );
32    }
33
34    public function execute() {
35        $services = $this->getServiceContainer();
36        $dbr = $services->getDBLoadBalancerFactory()->getReplicaDatabase();
37        $where = [ 'page_namespace' => $services->getMainConfig()->get( 'TimedTextNS' ) ];
38        if ( $this->hasOption( 'file' ) ) {
39            $file = Title::newFromText( $this->getOption( 'file' ), NS_FILE );
40            if ( $file ) {
41                $where[] = $dbr->expr( 'page_title', IExpression::LIKE,
42                    new LikeValue( $file->getDbKey() . '.', $dbr->anyString() ) );
43            } else {
44                $this->fatalError( "Invalid file title\n" );
45            }
46        }
47        $result = $dbr->newSelectQueryBuilder()
48            ->select( [ 'page_namespace', 'page_title' ] )
49            ->from( 'page' )
50            ->where( $where )
51            ->orderBy( [ 'page_namespace', 'page_title' ] )
52            ->caller( __METHOD__ )
53            ->fetchResultSet();
54        foreach ( $result as $row ) {
55            $data = $this->processWork( [
56                'page_namespace' => $row->page_namespace,
57                'page_title' => $row->page_title,
58            ] );
59            $this->count++;
60            if ( $data['result'] === 0 ) {
61                $this->output( "success on {$data['page_title']}\n" );
62            } else {
63                $err = implode( "\n    ", $data['errors'] );
64                $this->output( "failure on {$data['page_title']}$err\n" );
65                $this->failed++;
66            }
67            if ( $this->hasOption( 'dump' ) ) {
68                $this->output( $data['output'] . "\n" );
69            }
70        }
71
72        $this->output( "$this->count subtitle conversions, $this->failed failed\n" );
73    }
74
75    /**
76     * Actual converter work. Split out so it's easy to parallelize
77     * or reuse in future.
78     *
79     * @param array $data
80     * @return array
81     */
82    public function processWork( $data ) {
83        $title = Title::makeTitle( $data['page_namespace'], $data['page_title'] );
84        $wikiPageFactory = $this->getServiceContainer()->getWikiPageFactory();
85        $page = $wikiPageFactory->newFromTitle( $title );
86        if ( $page->isRedirect() ) {
87            $title = $page->getRedirectTarget();
88            $page = $wikiPageFactory->newFromTitle( $title );
89        }
90        $content = $page->getContent();
91        $raw = $content instanceof TextContent ? $content->getText() : '';
92
93        $errors = [];
94        $out = TextHandler::convertSubtitles(
95            TimedTextPage::SRT_SUBTITLE_FORMAT,
96            $this->getOption( 'format', TimedTextPage::VTT_SUBTITLE_FORMAT ),
97            $raw,
98            $errors
99        );
100        if ( count( $errors ) ) {
101            return $data + [
102                'result' => 1,
103                'errors' => array_map( [ $this, 'formatError' ], $errors ),
104                'output' => $out,
105            ];
106        } else {
107            return $data + [
108                'result' => 0,
109                'output' => $out,
110            ];
111        }
112    }
113
114    /**
115     * @param TimedText\ParseError $error
116     *
117     * @return string
118     */
119    public function formatError( TimedText\ParseError $error ) {
120        return $error->getError() .
121            " at line " .
122            $error->getLine() .
123            ": " .
124            $error->getInput();
125    }
126}
127
128// Tells it to run the class
129$maintClass = ConvertSubtitles::class;
130require_once RUN_MAINTENANCE_IF_MAIN;