28 public function __construct() {
29 parent::__construct();
30 $this->addDescription(
'Script to show number of characters translated .' );
33 '(optional) Show given number of language codes (default: show all)',
39 '(optional) Calculate for given number of days (default: 30)',
45 '(optional) Comma separated list of namespace IDs',
49 $this->requireExtension(
'Translate' );
52 public function execute() {
53 global $wgSitename, $wgTranslateMessageNamespaces;
55 $days = (int)$this->getOption(
'days', 30 );
56 $top = (int)$this->getOption(
'top', -1 );
59 if ( $this->hasOption(
'ns' ) ) {
60 $input = explode(
',', $this->getOption(
'ns' ) );
62 foreach ( $input as $namespace ) {
63 if ( is_numeric( $namespace ) ) {
64 $namespaces[] = $namespace;
68 $namespaces = $wgTranslateMessageNamespaces;
72 $rows = $this->getRevisionsFromHistory( $days, $namespaces );
77 foreach ( $rows as $_ ) {
79 if ( $_->user_text === FuzzyBot::getName() ) {
83 $handle =
new MessageHandle( Title::newFromText( $_->title ) );
84 $code = $handle->getCode();
86 if ( !isset( $codes[$code] ) ) {
90 $codes[$code] += $_->length;
97 $this->output(
"Character edit stats for last $days days in $wgSitename\n" );
98 $this->output(
"code\tname\tedit\n" );
99 $this->output(
"-----------------------\n" );
100 $languageNameUtils = MediaWikiServices::getInstance()->getLanguageNameUtils();
101 foreach ( $codes as $code => $num ) {
102 if ( $i++ === $top ) {
105 $language = $languageNameUtils->getLanguageName( $code );
110 $charRatio = mb_strlen( $language,
'UTF-8' ) / strlen( $language );
111 $num = (int)( $num * $charRatio );
113 $this->output(
"$code\t$language\t$num\n" );
115 $this->output(
"-----------------------\n" );
116 $this->output(
"Total\t\t$total\n" );
119 private function getRevisionsFromHistory( $days, array $namespaces ) {
120 $dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_REPLICA );
121 $cutoff = $dbr->addQuotes( $dbr->timestamp( time() - $days * 24 * 3600 ) );
123 $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
124 $result = $revisionStore->newSelectQueryBuilder( $dbr )
127 'title' =>
'page_title',
128 'user_text' =>
'actor_rev_user.actor_name',
129 'length' =>
'rev_len',
134 "rev_timestamp > $cutoff",
135 'page_namespace' => $namespaces,
137 ->caller( __METHOD__ )
139 return iterator_to_array( $result );