1#! /usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (C) 2007 Michael Gerz <michael.gerz@teststep.org>
4# Copyright (C) 2007 José Matos <jamatos@lyx.org>
5#
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU General Public License
8# as published by the Free Software Foundation; either version 2
9# of the License, or (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20"""
21This script extracts some information from the po file headers (last
22translator, revision date), generates the corresponding gmo files
23to retrieve the number of translated/fuzzy/untranslated messages,
24and generates a PHP web page.
25
26Invocation:
27   postats.py lyx_version po_files > "pathToWebPages"/i18n.inc
28"""
29from __future__ import print_function
30
31# modify this when you change branch
32# Note that an empty lyx_branch variable (ie svn trunk)
33# will "do the right thing".
34lyx_branch="2.3.x"
35# these po-files will be skipped:
36ommitted = ('en.po')
37
38import os
39import sys
40
41# Reset the locale
42import locale
43locale.setlocale(locale.LC_ALL, 'C')
44os.environ['LC_ALL'] = 'C'
45
46def extract_number(line, issues, prop):
47    """
48    line is a string like
49    '588 translated messages, 1248 fuzzy translations, 2 untranslated messages.'
50    Any one of these substrings may not appear if the associated number is 0.
51
52    issues is the set of words following the number to be extracted,
53    ie, 'translated', 'fuzzy', or 'untranslated'.
54
55    extract_number returns a list with those numbers, or sets it to
56    zero if the word is not found in the string.
57    """
58
59    for issue in issues:
60        i = line.find(issue)
61
62        if i == -1:
63            prop[issue] = 0
64        else:
65            prop[issue] = int(line[:i].split()[-1])
66
67
68def read_pofile(pofile):
69    """ Read the header of the pofile and return it as a dictionary"""
70    header = {}
71    read_header = False
72    for line in open(pofile):
73        line = line[:-1]
74        if line[:5] == 'msgid':
75            if read_header:
76                break
77            read_header = True
78            continue
79
80        if not line or line[0] == '#' or line == 'msgstr ""' or not read_header:
81            continue
82
83        line = line.strip('"')
84        args = line.split(': ')
85        if len(args) == 1:
86            continue
87        header[args[0]] = args[1].strip()[:-2]
88
89    return header
90
91
92def run_msgfmt(pofile):
93    """ pofile is the name of the po file.
94 The function runs msgfmt on it and returns corresponding php code.
95"""
96    if not pofile.endswith('.po'):
97        print("%s is not a po file" % pofile, file=sys.stderr)
98        sys.exit(1)
99
100    dirname = os.path.dirname(pofile)
101    gmofile = pofile.replace('.po', '.gmo')
102
103    header = read_pofile(pofile)
104    charset= header['Content-Type'].split('charset=')[1]
105
106    # po file properties
107    prop = {}
108    prop["langcode"] = os.path.basename(pofile)[:-3]
109    prop["date"] = header['PO-Revision-Date'].split()[0]
110    prop["email"] = header['Last-Translator'].split('<')[1][:-1]
111    prop["email"] = prop["email"].replace("@", " () ")
112    prop["email"] = prop["email"].replace(".", " ! ")
113    translator = header['Last-Translator'].split('<')[0].strip()
114    try:
115        prop["translator"] = translator.decode(charset).encode('ascii','xmlcharrefreplace')
116    except LookupError:
117        prop["translator"] = translator
118
119    p_in, p_out = os.popen4("msgfmt --statistics -o %s %s" % (gmofile, pofile))
120    extract_number(p_out.readline(),
121                   ('translated', 'fuzzy', 'untranslated'),
122                   prop)
123    return """
124array ( 'langcode' => '%(langcode)s', "date" => "%(date)s",
125"msg_tr" => %(translated)d, "msg_fu" => %(fuzzy)d, "msg_nt" => %(untranslated)d,
126"translator" => "%(translator)s", "email" => "%(email)s")""" % prop
127
128
129if __name__ == "__main__":
130    if lyx_branch:
131        branch_tag = lyx_branch
132    else:
133        branch_tag = "master"
134
135
136    print("""<?php
137// The current version
138$lyx_version = "%s";
139// The branch tag
140$branch_tag = "%s";
141
142// The data itself
143$podata = array (%s
144)?>""" % (sys.argv[1], branch_tag, ",".join([run_msgfmt(po) for po in sys.argv[2:] if po not in ommitted])))
145