2009-03-19 12:02:43 +00:00
#!/usr/bin/perl
2012-10-06 13:10:25 +02:00
###########################################################################
# tsstat.pl
# ---------------------
# begin : March 2009
# copyright : (C) 2009 by Juergen E. Fischer
# email : jef at norbit dot de
###########################################################################
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 2 of the License, or #
# (at your option) any later version. #
# #
###########################################################################
2009-03-19 12:02:43 +00:00
use strict ;
2013-06-06 22:59:37 +02:00
use warnings ;
2009-03-19 12:02:43 +00:00
use Locale::Language ;
use Locale::Country ;
2009-03-20 22:21:10 +00:00
my @ lang ;
2014-07-11 18:49:35 +02:00
# script to generate a html list of the qgis application translations
2012-04-14 15:10:00 +02:00
# showing the percentage finished and the names of the translators
# without argument it generates html which is used in the about-dialog of the application
# output to std-out, to be piped to doc/TRANSLATORS so it can be used in dialog
# scripts/tsstat.pl > doc/TRANSLATORS
# this version needs flag images from the resources
# with argument 'site' a more complete html page is create to be used on a website
# scripts/tsstat.pl site > page.html
# this version needs flag images in a directory 'flags'
# translator names here as a hash where the key is the lang_country code used for the ts file name
my $ translators = {
2015-02-21 23:34:18 +01:00
'af' = > '' ,
'ar' = > 'Ichaouia Amine, Hosham Munier' ,
'bg' = > 'Захари Савов, Jordan Tzvetkov' ,
'bs' = > 'Almir Karabegovic' ,
'ca' = > 'Albert F, Pau Reguant Ridó, Xavier Roijals' ,
'cs' = > 'Jan Helebrant, Martin Landa, Peter Antolik, Martin Dzurov, Stanislav Horáček' ,
'da' = > 'Jacob Overgaard Madsen, Bo Victor Thomsen' ,
'de' = > 'Jürgen E. Fischer, Stephan Holl, Otto Dassau, Werner Macho' ,
'es' = > 'Carlos Dávila, Javier César Aldariz, Gabriela Awad, Edwin Amado, Mayeul Kauffmann, Diana Galindo' ,
'el' = > 'Theodoros Vakkas, Ioannis Tsimpiris, Evripidis Argyropoulos, Mike Pegnigiannis, Nikos Ves' ,
'et' = > 'Veiko Viil' ,
'eu' = > 'Asier Sarasua Garmendia, Irantzu Alvarez' ,
'fa' = > 'Mola Pahnadayan, Masoud Pashotan , Masoud Erfanyan' ,
'fi' = > 'Kari Salovaara, Marko Järvenpää' ,
2015-03-16 23:03:49 +01:00
'fr' = > 'Arnaud Morvan, Augustin Roche, Jean-Roc Morreale, Loïc Buscoz, Marc-André Saia, Mathieu Bossaert, Mayeul Kauffmann, Médéric Ribreux, Michael Douchin, Nicolas Rochard, Robin Prest, DelazJ, Stéphane Possamai, Sylvain Badey, Sylvain_M, Sylvain Maillard, Xavier Tardieu, Marie Silvestre, Vincent Picavet' ,
2015-02-21 23:34:18 +01:00
'gl' = > 'Xan Vieiro' ,
'hi' = > 'Harish Kumar Solanki' ,
'hu' = > 'Zoltan Siki' ,
'hr' = > 'Zoran Jankovic' ,
'is' = > 'Ásta Kristín Óladóttir, Thordur Ivarsson' ,
'id' = > 'Emir Hartato, Muhammad Iqnaul Haq Siregar, Trias Aditya, Januar V. Simarmata, I Made Anombawa' ,
'it' = > 'Roberto Angeletti, Michele Beneventi, Marco Braida, Stefano Campus, Luca Casagrande, Paolo Cavallini, Giuliano Curti, Luca Delucchi, Alessandro Fanna, Michele Ferretti, Matteo Ghetta, Anne Gishla, Maurizio Napolitano, Flavio Rigolon' ,
'ja' = > 'BABA Yoshihiko, Yoichi Kayama, Minoru Akagi, Takayuki Nuimura, Takayuki Mizutani, Norihiro Yamate' ,
'ka' = > 'Shota Murtskhvaladze, George Machitidze' ,
'km' = > 'Khoem Sokhem' ,
'ko' = > 'OSGeo Korean Chapter' ,
'lo' = > 'Anousak Souphavanh, Soukanh Lathsavong' ,
'lv' = > 'Maris Nartiss, Pēteris Brūns' ,
'lt' = > 'Paulius Litvinas, Tomas Straupis, Kestas M' ,
'ml' = > 'Vinayan Parameswaran' ,
'mn' = > 'Bayarmaa Enkhtur' ,
'mr' = > '' ,
'nb' = > 'James Stott, Maléne Peterson' ,
'nl' = > 'Richard Duivenvoorde, Raymond Nijssen, Carlo van Rijswijk, Diethard Jansen, Willem Hoffmans, Dick Groskamp' ,
'pl' = > 'Robert Szczepanek, Milena Nowotarska, Borys Jurgiel, Mateusz Łoskot, Tomasz Paul, Andrzej Świąder, Radosław Pasiok' ,
'pt_BR' = > 'Sidney Schaberle Goveia, Arthur Nanni, Marcelo Soares Souza, Narcélio de Sá Pereira Filho, Leônidas Descovi Filho, Felipe Sodré Barros ' ,
'pt_PT' = > 'Giovanni Manghi, Joana Simões, Duarte Carreira, Alexandre Neto, Pedro Pereira, Pedro Palheiro, Nelson Silva, Ricardo Sena, Leandro Infantini, João Gaspar' ,
2015-03-09 19:37:31 +01:00
'ro' = > 'Sorin Călinică, Tudor Bărăscu, Georgiana Ioanovici, Alex Bădescu, Lonut Losifescu-Enescu, Bogdan Pacurar' ,
2015-02-21 23:34:18 +01:00
'ru' = > 'Alexander Bruy, Artem Popov' ,
'sk' = > 'Lubos Balazovic, Jana Kormanikova, Ivan Mincik' ,
'sl' = > 'Jože Detečnik, Dejan Gregor, Jaka Kranjc' ,
'sq' = > '' ,
2014-11-16 22:49:13 +01:00
'sr@latin' = > 'Goran Ivanković' ,
2015-02-21 23:34:18 +01:00
'sr' = > 'Goran Ivanković' ,
2015-03-09 18:41:16 +01:00
'sv' = > 'Victor Axbom, Lars Luthman, Magnus Homann, Klas Karlsson, Isabelle J Wigren, Daniel Rosander, Anders Ekwall, Magnus Nilsson, Jonas Svensson, Christian Brinkenberg' ,
2015-02-21 23:34:18 +01:00
'sw' = > '' ,
'ta' = > '' ,
'te' = > '' ,
'th' = > 'Man Chao' ,
'tl' = > 'Kathrina Gregana' ,
'tr' = > 'Osman Yalçı n YILMAZ, Omur Saygin' ,
'uk' = > 'Alexander Bruy' ,
2015-06-04 19:58:53 +02:00
'vi' = > 'Phùng Văn Doanh, Bùi Hữu Mạnh, Nguyễn Văn Thanh, Nguyễn Hữu Phúc, Cao Minh Tu' ,
2015-02-21 23:34:18 +01:00
'zh_CN' = > 'Calvin Ngei, Zhang Jun, Richard Xie' ,
'zh-Hans' = > 'Calvin Ngei, Lisashen' ,
'zh_TW' = > 'Nung-yao Lin' ,
2012-04-14 15:10:00 +02:00
} ;
2009-03-19 12:02:43 +00:00
2012-05-25 16:42:20 +02:00
my $ maxn ;
2009-03-19 12:02:43 +00:00
for my $ i ( <i18n/qgis_*.ts> ) {
2012-05-25 16:42:20 +02:00
my ( $ langcode ) = $ i =~ /i18n\/qgis_(.*).ts/ ;
2013-05-19 19:23:52 +02:00
next if $ langcode eq "en" ;
2009-03-19 12:02:43 +00:00
2013-06-06 22:59:37 +02:00
my $ translator = $ translators - > { $ langcode } || "(orphaned)" ;
my $ charset = "" ;
my $ lc = $ langcode ;
2014-11-16 22:49:13 +01:00
if ( $ langcode =~ /(.*)\@latin/ ) {
2013-06-06 22:59:37 +02:00
$ charset = " (latin)" ;
$ langcode = $ 1 ;
}
2015-02-21 23:34:18 +01:00
if ( $ langcode =~ /(.*)\-Hans/ ) {
$ charset = " simplified" ;
$ langcode = $ 1 ;
}
if ( $ langcode =~ /(.*)\-Hant/ ) {
$ charset = " traditional" ;
$ langcode = $ 1 ;
}
2012-05-25 16:42:20 +02:00
my $ name ;
if ( $ langcode =~ /(.*)_(.*)/ ) {
my $ lang = code2language ( lc $ 1 ) ;
my $ country = code2country ( lc $ 2 ) ;
$ name = "$lang ($country)" ;
} else {
$ name = code2language ( lc $ langcode ) ;
}
2009-03-19 12:02:43 +00:00
2013-06-06 22:59:37 +02:00
$ name . = $ charset ;
2009-03-19 12:02:43 +00:00
2012-05-25 16:42:20 +02:00
open F , "lrelease $i|" ;
2009-03-19 12:02:43 +00:00
2013-06-06 22:59:37 +02:00
my ( $ translations , $ finished , $ unfinished ) ;
my $ untranslated = 0 ;
2009-03-19 12:02:43 +00:00
2012-05-25 16:42:20 +02:00
while ( <F> ) {
if ( /Generated (\d+) translation\(s\) \((\d+) finished and (\d+) unfinished\)/ ) {
$ translations = $ 1 ;
$ finished = $ 2 ;
$ unfinished = $ 3 ;
} elsif ( /Ignored (\d+) untranslated source text\(s\)/ ) {
$ untranslated = $ 1 ;
}
}
2009-03-19 12:02:43 +00:00
2012-05-25 16:42:20 +02:00
close F ;
2009-03-19 12:02:43 +00:00
2012-05-25 16:42:20 +02:00
my $ n = $ translations + $ untranslated ;
2012-06-03 18:05:26 +02:00
$ maxn = $ n unless defined $ maxn ;
if ( $ n > $ maxn ) {
2014-06-13 00:52:30 +02:00
print STDERR "$i: more translations than others. ($n>$maxn)\n" ;
2012-06-03 18:05:26 +02:00
$ maxn = $ n ;
}
2009-03-19 12:02:43 +00:00
2013-06-06 22:59:37 +02:00
push @ lang , {
code = > $ langcode ,
2014-10-05 15:49:07 +02:00
origcode = > $ lc ,
2013-06-06 22:59:37 +02:00
name = > $ name , n = > $ n ,
translations = > $ translations ,
finished = > $ finished ,
unfinished = > $ unfinished ,
untranslated = > $ untranslated ,
translator = > $ translator
} ;
2009-03-20 22:21:10 +00:00
}
2012-05-25 16:42:20 +02:00
foreach my $ l ( @ lang ) {
$ l - > { diff } = $ l - > { n } - $ maxn ;
2012-06-03 18:05:26 +02:00
$ l - > { percentage } = ( $ l - > { finished } + $ l - > { unfinished } /2)/ $ maxn * 100 ;
2012-04-14 15:10:00 +02:00
}
2012-05-25 16:42:20 +02:00
2013-06-06 22:59:37 +02:00
if ( @ ARGV && $ ARGV [ 0 ] eq "site" ) {
2012-05-25 16:42:20 +02:00
print "<html><body>" ;
print "<head>" ;
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>" ;
print "<style>" ;
print "body{font-family:sans-serif;}" ;
print "table {font-size:80%;border-collapse: collapse;}" ;
print "td {border-left:solid 1px #aaaaaa;border-right:solid 1px #aaaaaa;padding:1px 10px;}" ;
print ".bartodo{ background-color:red;width:100px;height:20px;}" ;
print ".bardone{ background-color:green;width:80px;height:20px;font-size:80%;text-align:center;padding-top:4px;height:16px;color:white;}" ;
print "</style></head>" ;
print "<table>" ;
print "<tr><td colspan=\"2\" style=\"width:250px;\">Language</td><td>Count</td><td>Finished</td><td>Unfinished</td><td>Untranslated</td><td>Percentage</td><td>Translators</td></tr>\n" ;
for my $ l ( sort { $ b - > { percentage } <=> $ a - > { percentage } } @ lang ) {
2014-10-05 14:46:41 +02:00
last if $ l - > { percentage } < 35 ;
2012-05-25 16:42:20 +02:00
printf "\n<tr>"
. '<td><img src="flags/%s.png"></td><td nowrap>%s</td>'
. '<td nowrap>%s</td><td>%d</td><td>%d</td><td>%d</td>'
. '<td><div class="bartodo"><div class="bardone" style="width:%dpx">%.1f</div></div></td>'
. '<td>%s</td>'
. '</tr>' ,
$ l - > { code } , $ l - > { name } ,
$ l - > { diff } == 0 ? $ l - > { n } : "$l->{n} ($l->{diff})" ,
$ l - > { finished } , $ l - > { unfinished } , $ l - > { untranslated } ,
$ l - > { percentage } , $ l - > { percentage } ,
2013-06-06 22:59:37 +02:00
$ l - > { translator } ;
2012-05-25 16:42:20 +02:00
}
print "</table></body></html>\n" ;
} else {
print "<style>" ;
print "table {font-size:80%;}" ;
print "th {text-align:left; }" ;
print ".bartodo{ background-color:red;width:100px;height:20px;}" ;
print ".bardone{ background-color:green;width:80px;height:20px;font-size:80%;text-align:center;padding-top:4px;height:16px;color:white;}" ;
print "</style>" ;
print "<table>" ;
print "<tr><th colspan=\"2\" style=\"width:250px;\">Language</th><th>Finished %</th><th>Translators</th></tr>\n" ;
for my $ l ( sort { $ b - > { percentage } <=> $ a - > { percentage } } @ lang ) {
2014-10-05 14:46:41 +02:00
last if $ l - > { percentage } < 35 ;
2012-05-25 16:42:20 +02:00
printf "\n<tr>"
. '<td><img src="qrc:/images/flags/%s.png"></td><td>%s</td>'
2012-05-31 09:09:16 +02:00
. '<td><div title="finished:%d unfinished:%d untranslated:%d" class="bartodo"><div class="bardone" style="width:%dpx">%.1f</div></div></td>'
2012-05-25 16:42:20 +02:00
. '<td>%s</td>'
. '</tr>' ,
$ l - > { code } , $ l - > { name } ,
2012-05-31 09:09:16 +02:00
$ l - > { finished } , $ l - > { unfinished } , $ l - > { untranslated } ,
2012-05-25 16:42:20 +02:00
$ l - > { percentage } , $ l - > { percentage } ,
2013-06-06 22:59:37 +02:00
$ l - > { translator } ;
2012-05-25 16:42:20 +02:00
}
print "</table>\n" ;
2009-03-19 12:02:43 +00:00
}
2014-10-05 14:46:41 +02:00
my @ ts ;
for my $ l ( sort { $ a - > { code } cmp $ b - > { code } } @ lang ) {
next if $ l - > { percentage } < 35 ;
2014-10-05 15:49:07 +02:00
push @ ts , $ l - > { origcode } ;
2014-10-05 14:46:41 +02:00
}
rename "i18n/CMakeLists.txt" , "i18n/CMakeLists.txt.temp" || die "cannot rename i18n/CMakeLists.txt: $!" ;
open I , "i18n/CMakeLists.txt.temp" ;
open O , ">i18n/CMakeLists.txt" ;
while ( <I> ) {
2014-10-05 15:49:07 +02:00
if ( /^SET\(TS_FILES / || /^FILE \(GLOB TS_FILES \*\.ts\)/ ) {
2014-10-05 14:46:41 +02:00
print O "SET(TS_FILES " . join ( " " , map { "qgis_$_\.ts" ; } @ ts ) . ")\n" ;
} else {
print O ;
}
}
close O ;
close I ;
unlink "i18n/CMakeLists.txt.temp" ;