X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=buildscripts%2Ftranslations-status.py;h=a3b6799f21f8b43777ed3e69229610395114062f;hb=3ead9c2be44a4f5bb6d32a776188931f7995048e;hp=2335d5d5e16c7dfd36af4560fedc6b33aac3eb8f;hpb=e80a3d7fa7d74a57f2a4003b0cc8ce3aab9b5b30;p=lilypond.git diff --git a/buildscripts/translations-status.py b/buildscripts/translations-status.py old mode 100644 new mode 100755 index 2335d5d5e1..a3b6799f21 --- a/buildscripts/translations-status.py +++ b/buildscripts/translations-status.py @@ -1,4 +1,4 @@ -#!@PYTHON@ +#!/usr/bin/env python """ USAGE: translations-status.py BUILDSCRIPT-DIR LOCALEDIR @@ -7,17 +7,18 @@ USAGE: translations-status.py BUILDSCRIPT-DIR LOCALEDIR Reads template files translations.template.html.in and for each LANG in LANGUAGES LANG/translations.template.html.in - Writes translations.html.in and for each LANG in LANGUAGES translations.LANG.html.in + Writes out/translations-status.txt + Updates word counts in TRANSLATION """ import sys import re import string import os -import gettext -import subprocess + +import langdefs def progress (str): sys.stderr.write (str + '\n') @@ -25,59 +26,50 @@ def progress (str): progress ("translations-status.py") buildscript_dir = sys.argv[1] -localedir = sys.argv[2] _doc = lambda s: s sys.path.append (buildscript_dir) -import langdefs +import buildlib # load gettext messages catalogs -translation = {} -for l in langdefs.LANGUAGES: - if l.enabled and l.code != 'en': - translation[l.code] = gettext.translation('lilypond-doc', localedir, [l.code]).gettext - -def read_pipe (command): - child = subprocess.Popen (command, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE, - shell = True) - (output, error) = child.communicate () - code = str (child.wait ()) - if not child.stdout or child.stdout.close (): - print "pipe failed: %(command)s" % locals () - if code != '0': - error = code + ' ' + error - return (output, error) +translation = langdefs.translation + +language_re = re.compile (r'^@documentlanguage (.+)', re.M) comments_re = re.compile (r'^@ignore\n(.|\n)*?\n@end ignore$|@c .*?$', re.M) space_re = re.compile (r'\s+', re.M) lilypond_re = re.compile (r'@lilypond({.*?}|(.|\n)*?\n@end lilypond$)', re.M) node_re = re.compile ('^@node .*?$', re.M) -title_re = re.compile ('^@(top|chapter|(?:sub){0,2}section|(?:unnumbered|appendix)(?:(?:sub){0,2}sec)?) (.*?)$', re.M) +title_re = re.compile ('^@(top|chapter|(?:sub){0,2}section|' + \ +'(?:unnumbered|appendix)(?:(?:sub){0,2}sec)?) (.*?)$', re.M) include_re = re.compile ('^@include (.*?)$', re.M) -committish_re = re.compile ('GIT [Cc]ommittish: ([a-f0-9]+)') translators_re = re.compile (r'^@c\s+Translators\s*:\s*(.*?)$', re.M | re.I) -checkers_re = re.compile (r'^@c\s+Translation\s*checkers\s*:\s*(.*?)$', re.M | re.I) +checkers_re = re.compile (r'^@c\s+Translation\s*checkers\s*:\s*(.*?)$', + re.M | re.I) status_re = re.compile (r'^@c\s+Translation\s*status\s*:\s*(.*?)$', re.M | re.I) post_gdp_re = re.compile ('post.GDP', re.I) untranslated_node_str = 'UNTRANSLATED NODE: IGNORE ME' skeleton_str = '-- SKELETON FILE --' -diff_cmd = 'git diff --no-color %(committish)s HEAD -- %(original)s | cat' - +section_titles_string = _doc ('Section titles') +last_updated_string = _doc ('
Last updated %s
\n') +detailed_status_heads = [_doc ('Translators'), _doc ('Translation checkers'), + _doc ('Translated'), _doc ('Up to date'), + _doc ('Other info')] format_table = { 'not translated': {'color':'d0f0f8', 'short':_doc ('no'), 'abbr':'NT', 'long':_doc ('not translated')}, - 'partially translated': {'color':'dfef77', 'short':_doc ('partially (%(p)d %%)'), - 'abbr':'%(p)d%%', 'long':_doc ('partially translated (%(p)d %%)')}, + 'partially translated': {'color':'dfef77', + 'short':_doc ('partially (%(p)d %%)'), + 'abbr':'%(p)d%%', + 'long':_doc ('partially translated (%(p)d %%)')}, 'fully translated': {'color':'1fff1f', 'short':_doc ('yes'), 'abbr':'FT', 'long': _doc ('translated')}, - 'up to date': {'short':_doc ('yes'), 'long':_doc ('up to date'), 'abbr':'100%%', - 'vague':_doc ('up to date')}, - 'outdated': {'short':_doc ('partially (%(p)d %%)'), 'abbr':'%(p)d%%', + 'up to date': {'short':_doc ('yes'), 'long':_doc ('up to date'), + 'abbr':'100%%', 'vague':_doc ('up to date')}, + 'outdated': {'short':_doc ('partially'), 'abbr':'%(p)d%%', 'vague':_doc ('partially up to date')}, 'N/A': {'short':_doc ('N/A'), 'abbr':'N/A', 'color':'d587ff', 'vague':''}, 'pre-GDP':_doc ('pre-GDP'), @@ -106,7 +98,8 @@ class SectionNumber (object): def __increase_last_index (self): type = self.__data[-1][1] if type == 'l': - self.__data[-1][0] = self.__data[-1][0].translate (appendix_number_trans) + self.__data[-1][0] = \ + self.__data[-1][0].translate (appendix_number_trans) elif type == 'n': self.__data[-1][0] += 1 @@ -138,13 +131,34 @@ class SectionNumber (object): def percentage_color (percent): p = percent / 100.0 if p < 0.33: - c = [hex (int (3 * p * b + (1 - 3 * p) * a))[2:] for (a, b) in [(0xff, 0xff), (0x5c, 0xa6), (0x5c, 0x4c)]] + c = [hex (int (3 * p * b + (1 - 3 * p) * a))[2:] + for (a, b) in [(0xff, 0xff), (0x5c, 0xa6), (0x5c, 0x4c)]] elif p < 0.67: - c = [hex (int ((3 * p - 1) * b + (2 - 3 * p) * a))[2:] for (a, b) in [(0xff, 0xff), (0xa6, 0xff), (0x4c, 0x3d)]] + c = [hex (int ((3 * p - 1) * b + (2 - 3 * p) * a))[2:] + for (a, b) in [(0xff, 0xff), (0xa6, 0xff), (0x4c, 0x3d)]] else: - c = [hex (int ((3 * p - 2) * b + 3 * (1 - p) * a))[2:] for (a, b) in [(0xff, 0x1f), (0xff, 0xff), (0x3d, 0x1f)]] + c = [hex (int ((3 * p - 2) * b + 3 * (1 - p) * a))[2:] + for (a, b) in [(0xff, 0x1f), (0xff, 0xff), (0x3d, 0x1f)]] return ''.join (c) + +def update_word_count (text, filename, word_count): + return re.sub (r'(?m)^(\d+) *' + filename, + str (word_count).ljust (6) + filename, + text) + +po_msgid_re = re.compile (r'^msgid "(.*?)"(?:\n"(.*?)")*', re.M) + +def po_word_count (po_content): + s = ' '.join ([''.join (t) for t in po_msgid_re.findall (po_content)]) + return len (space_re.split (s)) + +sgml_tag_re = re.compile (r'<.*?>', re.S) + +def sgml_word_count (sgml_doc): + s = sgml_tag_re.sub ('', sgml_doc) + return len (space_re.split (s)) + def tely_word_count (tely_doc): ''' Calculate word count of a Texinfo document node by node. @@ -174,7 +188,12 @@ class TelyDocument (object): self.title = 'Untitled' self.level = ('u', 1) - included_files = [os.path.join (os.path.dirname (filename), t) for t in include_re.findall (self.contents)] + m = language_re.search (self.contents) + if m: + self.language = m.group (1) + + included_files = [os.path.join (os.path.dirname (filename), t) + for t in include_re.findall (self.contents)] self.included_files = [p for p in included_files if os.path.exists (p)] def print_title (self, section_number): @@ -186,6 +205,14 @@ class TranslatedTelyDocument (TelyDocument): TelyDocument.__init__ (self, filename) self.masterdocument = masterdocument + if not hasattr (self, 'language') \ + and hasattr (parent_translation, 'language'): + self.language = parent_translation.language + if hasattr (self, 'language'): + self.translation = translation[self.language] + else: + self.translation = lambda x: x + self.title = self.translation (self.title) ## record authoring information m = translators_re.search (self.contents) @@ -215,40 +242,47 @@ class TranslatedTelyDocument (TelyDocument): ## calculate translation percentage master_total_word_count = sum (masterdocument.word_count) - translation_word_count = sum ([masterdocument.word_count[k] * self.translated_nodes[k] - for k in range (min (len (masterdocument.word_count), len (self.translated_nodes)))]) - self.translation_percentage = 100 * translation_word_count / master_total_word_count + translation_word_count = \ + sum ([masterdocument.word_count[k] * self.translated_nodes[k] + for k in range (min (len (masterdocument.word_count), + len (self.translated_nodes)))]) + self.translation_percentage = \ + 100 * translation_word_count / master_total_word_count ## calculate how much the file is outdated - m = committish_re.search (self.contents) - if not m: - sys.stderr.write ('error: ' + filename + \ - ": no 'GIT committish:%s | ''' % self.print_title (numbering) + s += ''.join (['%s | \n' % self.translation (h) + for h in detailed_status_heads]) + s += '||||||
---|---|---|---|---|---|---|---|
%s (%d) | \n' \
+ % (self.translation (section_titles_string),
+ sum (self.masterdocument.word_count))
+
+ else:
+ s = ' |||||||
%s (%d) | \n' \
+ % (self.print_title (numbering),
+ sum (self.masterdocument.word_count))
+
+ if self.partially_translated:
+ s += ' ' + ' \n '.join (self.translators) + ' | \n'
+ s += ' ' + ' \n '.join (self.checkers) + ' | \n'
+ else:
+ s += ' \n' * 2 + + c = self.completeness (['color', 'short'], translated=True) + s += ' | \ +%(short)s | \n' % {'color': c['color'], + 'short': c['short']} + + if self.partially_translated: + u = self.uptodateness (['short', 'color'], translated=True) + s += '\ +%(short)s | \n' % {'color': u['color'], + 'short': u['short']} + else: + s += '\n' + + s += ' | ' + self.gdp_status () + ' | \n
%s | ''' % self.print_title (numbering) - s += ''.join (['%s | \n' % l for l in self.translations.keys ()]) + s += ''.join (['%s | \n' % l for l in self.translations]) s += '
---|---|---|
Section titles (%d) | \n' \
% sum (self.word_count)
- else:
+ else: # if self is an included file
s = ' ||
%s (%d) | \n' \
% (self.print_title (numbering), sum (self.word_count))
- s += ''.join ([t.short_html_status () for t in self.translations.values ()])
+ s += ''.join ([t.short_html_status ()
+ for t in self.translations.values ()])
s += '
Last updated %s
\n' % date_time +main_status_html = last_updated_string % date_time main_status_html += '\n'.join ([doc.html_status () for doc in master_docs]) html_re = re.compile ('', re.I) end_body_re = re.compile ('', re.I) -main_status_page = html_re.sub (''' +html_header = ''' ''', main_status_page) +translations.template.html.in; DO NOT EDIT !-->''' + +main_status_page = html_re.sub (html_header, main_status_page) -main_status_page = end_body_re.sub (main_status_html + '\n', main_status_page) +main_status_page = end_body_re.sub (main_status_html + '\n', + main_status_page) open ('translations.html.in', 'w').write (main_status_page) +for l in enabled_languages: + date_time = buildlib.read_pipe ('LANG=%s date -u' % l)[0] + lang_status_pages[l] = translation[l] (last_updated_string) % date_time + lang_status_pages[l] + lang_status_page = html_re.sub (html_header, lang_status_pages[l]) + html_status = '\n'.join ([doc.translations[l].html_status () + for doc in master_docs + if l in doc.translations]) + lang_status_page = end_body_re.sub (html_status + '\n