27 public function __construct() {
28 parent::__construct();
29 $this->addDescription(
'Script to show number of characters translated .' );
32 '(optional) Show given number of language codes (default: show all)',
38 '(optional) Calculate for given number of days (default: 30)',
44 '(optional) Comma separated list of namespace IDs',
48 $this->requireExtension(
'Translate' );
51 public function execute() {
52 global $wgSitename, $wgTranslateMessageNamespaces;
54 $days = (int)$this->getOption(
'days', 30 );
55 $top = (int)$this->getOption(
'top', -1 );
58 if ( $this->hasOption(
'ns' ) ) {
59 $input = explode(
',', $this->getOption(
'ns' ) );
61 foreach ( $input as $namespace ) {
62 if ( is_numeric( $namespace ) ) {
63 $namespaces[] = $namespace;
67 $namespaces = $wgTranslateMessageNamespaces;
71 $rows = $this->getRevisionsFromHistory( $days, $namespaces );
76 foreach ( $rows as $_ ) {
78 if ( $_->user_text === FuzzyBot::getName() ) {
82 $handle =
new MessageHandle( Title::newFromText( $_->title ) );
83 $code = $handle->getCode();
85 if ( !isset( $codes[$code] ) ) {
89 $codes[$code] += $_->length;
96 $this->output(
"Character edit stats for last $days days in $wgSitename\n" );
97 $this->output(
"code\tname\tedit\n" );
98 $this->output(
"-----------------------\n" );
99 $languageNameUtils = MediaWikiServices::getInstance()->getLanguageNameUtils();
100 foreach ( $codes as $code => $num ) {
101 if ( $i++ === $top ) {
104 $language = $languageNameUtils->getLanguageName( $code );
109 $charRatio = mb_strlen( $language,
'UTF-8' ) / strlen( $language );
110 $num = (int)( $num * $charRatio );
112 $this->output(
"$code\t$language\t$num\n" );
114 $this->output(
"-----------------------\n" );
115 $this->output(
"Total\t\t$total\n" );
118 private function getRevisionsFromHistory( $days, array $namespaces ) {
119 $dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_REPLICA );
120 $cutoff = $dbr->addQuotes( $dbr->timestamp( time() - $days * 24 * 3600 ) );
122 $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
123 $result = $revisionStore->newSelectQueryBuilder( $dbr )
126 'title' =>
'page_title',
127 'user_text' =>
'actor_rev_user.actor_name',
128 'length' =>
'rev_len',
133 "rev_timestamp > $cutoff",
134 'page_namespace' => $namespaces,
136 ->caller( __METHOD__ )
138 return iterator_to_array( $result );