From 9c0633f8ad4dbaff1097477f62644327c0adf02c Mon Sep 17 00:00:00 2001 From: Adam Waldenberg Date: Tue, 25 Jun 2013 14:38:40 +0200 Subject: [PATCH] Added gettext (GNU) localization support. --- gitinspector/blame.py | 13 ++++++---- gitinspector/changes.py | 21 ++++++++-------- gitinspector/extensions.py | 7 +++--- gitinspector/filtering.py | 4 ++-- gitinspector/gitinspector.py | 10 +++++--- gitinspector/help.py | 14 +++++------ gitinspector/localization.py | 41 ++++++++++++++++++++++++++++++++ gitinspector/metrics.py | 4 ++-- gitinspector/missing.py | 6 ++--- gitinspector/outputable.py | 6 ++--- gitinspector/responsibilities.py | 11 +++++---- gitinspector/timeline.py | 9 +++---- gitinspector/version.py | 16 +++++++------ 13 files changed, 108 insertions(+), 54 deletions(-) create mode 100644 gitinspector/localization.py diff --git a/gitinspector/blame.py b/gitinspector/blame.py index 3161f66..d4d6333 100644 --- a/gitinspector/blame.py +++ b/gitinspector/blame.py @@ -83,6 +83,8 @@ class BlameThread(threading.Thread): git_blame_r.close() __thread_lock__.release() # Lock controlling the number of threads running +__progress_text__ = "\b" + _("Checking how many rows belong to each author (Progress): {0:.0f}%") + class Blame: def __init__(self, hard): self.blames = {} @@ -114,7 +116,7 @@ class Blame: def output_progress(pos, length): if sys.stdout.isatty() and format.is_interactive_format(): terminal.clear_row() - print("\bChecking how many rows belong to each author (Progress): {0:.0f}%".format(100 * pos / length), end="") + print(__progress_text__.format(100 * pos / length), end="") sys.stdout.flush() @staticmethod @@ -151,8 +153,8 @@ def get(hard): return __blame__ -__blame_info_text__ = ("Below are the number of rows from each author that have survived and are still " - "intact in the current revision") +__blame_info_text__ = _("Below are the number of rows from each author that have survived and are still " + "intact in the current revision") class BlameOutput(Outputable): def __init__(self, hard): @@ -164,7 +166,8 @@ class BlameOutput(Outputable): blame_xml = "
" blame_xml += "

" + __blame_info_text__ + ".

" - blame_xml += "" + blame_xml += "".format(_("Author"), + _("Rows"), _("% in comments")) blame_xml += "" chart_data = "" blames = sorted(__blame__.get_summed_blames().items()) @@ -216,7 +219,7 @@ class BlameOutput(Outputable): terminal.clear_row() print(textwrap.fill(__blame_info_text__ + ":", width=terminal.get_size()[0]) + "\n") - terminal.printb("Author".ljust(21) + "Rows".rjust(10) + "% in comments".rjust(16)) + terminal.printb(_("Author").ljust(21) + _("Rows").rjust(10) + _("% in comments").rjust(16)) for i in sorted(__blame__.get_summed_blames().items()): print(i[0].ljust(20)[0:20], end=" ") print(str(i[1].rows).rjust(10), end=" ") diff --git a/gitinspector/changes.py b/gitinspector/changes.py index bca8951..695b3e2 100644 --- a/gitinspector/changes.py +++ b/gitinspector/changes.py @@ -157,8 +157,8 @@ def get(hard): return __changes__ -__historical_info_text__ = "The following historical commit information, by author, was found in the repository" -__no_commited_files__ = "No commited files with the specified extensions were found" +__historical_info_text__ = _("The following historical commit information, by author, was found in the repository") +__no_commited_files_text__ = _("No commited files with the specified extensions were found") class ChangesOutput(Outputable): def __init__(self, hard): @@ -177,9 +177,9 @@ class ChangesOutput(Outputable): if authorinfo_list: changes_xml += "

" + __historical_info_text__ + ".

Author Rows % in comments
{0} {1} {2}
" - changes_xml += ("" + - "") - changes_xml += "" + changes_xml += "".format( + _("Author"), _("Commits"), _("Insertions"), _("Deletions"), _("% of changes")) + changes_xml += "" for i, entry in enumerate(sorted(authorinfo_list)): authorinfo = authorinfo_list.get(entry) @@ -207,7 +207,7 @@ class ChangesOutput(Outputable): changes_xml += " show: true," changes_xml += " combine: {" changes_xml += " threshold: 0.01," - changes_xml += " label: \"Minor Authors\"" + changes_xml += " label: \"" + _("Minor Authors") + "\"" changes_xml += " }" changes_xml += " }" changes_xml += " }, grid: {" @@ -216,7 +216,7 @@ class ChangesOutput(Outputable): changes_xml += " });" changes_xml += "" else: - changes_xml += "

" + __no_commited_files__ + ".

" + changes_xml += "

" + __no_commited_files_text__ + ".

" changes_xml += "" print(changes_xml) @@ -231,7 +231,8 @@ class ChangesOutput(Outputable): if authorinfo_list: print(textwrap.fill(__historical_info_text__ + ":", width=terminal.get_size()[0]) + "\n") - terminal.printb("Author".ljust(21) + "Commits " + "Insertions " + "Deletions " + "% of changes") + terminal.printb(_("Author").ljust(21) + "{0} {1} {2} {3}".format(_("Commits"), _("Insertions"), + _("Deletions"), _("% of changes"))) for i in sorted(authorinfo_list): authorinfo = authorinfo_list.get(i) @@ -243,7 +244,7 @@ class ChangesOutput(Outputable): print(str(authorinfo.deletions).rjust(11), end=" ") print("{0:.2f}".format(percentage).rjust(14)) else: - print(__no_commited_files__ + ".") + print(__no_commited_files_text__ + ".") def output_xml(self): authorinfo_list = get(self.hard).get_authorinfo_list() @@ -272,4 +273,4 @@ class ChangesOutput(Outputable): print("\t\n" + message_xml + "\t\t\n" + changes_xml + "\t\t\n\t") else: - print("\t\n\t\t" + __no_commited_files__ + "\n\t") + print("\t\n\t\t" + __no_commited_files_text__ + "\n\t") diff --git a/gitinspector/extensions.py b/gitinspector/extensions.py index 0d3b219..3dfc955 100644 --- a/gitinspector/extensions.py +++ b/gitinspector/extensions.py @@ -37,13 +37,14 @@ def add_located(string): if len(string) > 0: __located_extensions__.add(string) -__extensions_info_text__ = "The extensions below were found in the repository history" +__extensions_info_text__ = _("The extensions below were found in the repository history") +__extensions_marked_text__ = _("(extensions used during statistical analysis are marked)") class Extensions(Outputable): def output_html(self): if __located_extensions__: extensions_xml = "
" - extensions_xml += "

" + __extensions_info_text__ + " (extensions used during statistical analysis are marked).

" + extensions_xml += "

{0} {1}.

".format(__extensions_info_text__, __extensions_marked_text__) for i in __located_extensions__: if i in __extensions__: @@ -57,7 +58,7 @@ class Extensions(Outputable): def output_text(self): if __located_extensions__: - print("\n" + textwrap.fill(__extensions_info_text__ + "\n(extensions used during statistical analysis are marked):", + print("\n" + textwrap.fill("{0} {1}:".format(__extensions_info_text__, __extensions_marked_text__), width=terminal.get_size()[0])) for i in __located_extensions__: diff --git a/gitinspector/filtering.py b/gitinspector/filtering.py index f8a6723..697053f 100644 --- a/gitinspector/filtering.py +++ b/gitinspector/filtering.py @@ -44,8 +44,8 @@ def set_filtered(file_name): return True return False -__filtering_info_text__ = ("The following files were excluded from the statistics due to the" - "specified exclusion patterns") +__filtering_info_text__ = _("The following files were excluded from the statistics due to the" + "specified exclusion patterns") class Filtering(Outputable): def output_html(self): diff --git a/gitinspector/gitinspector.py b/gitinspector/gitinspector.py index 5bb3895..8864ef6 100755 --- a/gitinspector/gitinspector.py +++ b/gitinspector/gitinspector.py @@ -19,6 +19,10 @@ # along with gitinspector. If not, see . from __future__ import print_function + +import localization +localization.init() + import blame import changes import extensions @@ -80,7 +84,7 @@ class Runner: def __check_python_version__(): if sys.version_info < (2, 6): python_version = str(sys.version_info[0]) + "." + str(sys.version_info[1]) - sys.exit("gitinspector requires at leat Python 2.6 to run (version " + python_version + " was found).") + sys.exit(_("gitinspector requires at leat Python 2.6 to run (version {0} was found).").format(python_version)) def main(): __run__ = Runner() @@ -100,7 +104,7 @@ def main(): extensions.define(a) elif o in("-F", "--format"): if not format.select(a): - raise format.InvalidFormatError("specified output format not supported.") + raise format.InvalidFormatError(_("specified output format not supported.")) elif o in("-H", "--hard"): __run__.hard = True elif o in("-l", "--list-file-types"): @@ -135,7 +139,7 @@ def main(): except (format.InvalidFormatError, getopt.error) as msg: print(sys.argv[0], "\b:", msg) - print("Try `", sys.argv[0], "--help' for more information.") + print(_("Try `{0} --help' for more information.").format(sys.argv[0])) sys.exit(2) __check_python_version__() diff --git a/gitinspector/help.py b/gitinspector/help.py index 362a06f..176722c 100644 --- a/gitinspector/help.py +++ b/gitinspector/help.py @@ -17,7 +17,12 @@ # You should have received a copy of the GNU General Public License # along with gitinspector. If not, see . -"""Usage: {0} [OPTION]... [DIRECTORY] +from __future__ import print_function +from extensions import __default_extensions__ +from format import __available_formats__ +import sys + +__doc__ = _("""Usage: {0} [OPTION]... [DIRECTORY] List information about the repository in DIRECTORY. If no directory is specified, the current directory is used. If multiple directories are given, information will be fetched from the last directory specified. @@ -60,12 +65,7 @@ add or remove one of the specified extensions, see -f or --file-types for more information. gitinspector requires that the git executable is available in your PATH. -Report gitinspector bugs to gitinspector@ejwa.se.""" - -from __future__ import print_function -from extensions import __default_extensions__ -from format import __available_formats__ -import sys +Report gitinspector bugs to gitinspector@ejwa.se.""") def output(): print(__doc__.format(sys.argv[0], ",".join(__default_extensions__), ",".join(__available_formats__))) diff --git a/gitinspector/localization.py b/gitinspector/localization.py new file mode 100644 index 0000000..fe21e6b --- /dev/null +++ b/gitinspector/localization.py @@ -0,0 +1,41 @@ +#!/usr/bin/python +# coding: utf-8 +# +# Copyright © 2013 Ejwa Software. All rights reserved. +# +# This file is part of gitinspector. +# +# gitinspector 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 3 of the License, or +# (at your option) any later version. +# +# gitinspector is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with gitinspector. If not, see . + +import gettext +import locale +import os + +def init(): + locale.setlocale(locale.LC_ALL, '') + lang = locale.getlocale() + + #Fix for non-POSIX-compliant systems (Windows et al.). + if os.getenv('LANG') is None: + lang, _ = locale.getdefaultlocale() + os.environ['LANG'] = lang + + filename = "translations/messages_%s.mo" % lang[0][0:2] + + try: + translation = gettext.GNUTranslations(open( filename, "rb" ) ) + except IOError: + translation = gettext.NullTranslations() + + translation.install() diff --git a/gitinspector/metrics.py b/gitinspector/metrics.py index 0940dfc..c80d4a1 100644 --- a/gitinspector/metrics.py +++ b/gitinspector/metrics.py @@ -67,8 +67,8 @@ class MetricsLogic: return eloc_counter -__eloc_info_text__ = "The following files are suspiciously big (in order of severity)" -__metrics_missing_info_text__ = "No metrics violations were found in the repository" +__eloc_info_text__ = _("The following files are suspiciously big (in order of severity)") +__metrics_missing_info_text__ = _("No metrics violations were found in the repository") class Metrics(Outputable): def output_text(self): diff --git a/gitinspector/missing.py b/gitinspector/missing.py index e18105b..d1c9f66 100644 --- a/gitinspector/missing.py +++ b/gitinspector/missing.py @@ -41,9 +41,9 @@ def set_checkout_missing(checkout): global __checkout_missing__ __checkout_missing__ = checkout -__missing_info_text__ = ("The following files were missing in the repository and were therefore not " - "completely included in the statistical analysis. To include them, you can " - "either checkout manually using git or use the -c option in gitinspector") +__missing_info_text__ = _("The following files were missing in the repository and were therefore not " + "completely included in the statistical analysis. To include them, you can " + "either checkout manually using git or use the -c option in gitinspector") class Missing(Outputable): def output_html(self): diff --git a/gitinspector/outputable.py b/gitinspector/outputable.py index d4fd3bb..0d8dbb0 100644 --- a/gitinspector/outputable.py +++ b/gitinspector/outputable.py @@ -22,13 +22,13 @@ import format class Outputable(object): def output_html(self): - print("HTML output not yet supported in \"" + self.__class__.__name__ + "\".") + print(_("HTML output not yet supported in \"") + self.__class__.__name__ + "\".") def output_text(self): - print("Text output not yet supported in \"" + self.__class__.__name__ + "\".") + print(_("Text output not yet supported in \"") + self.__class__.__name__ + "\".") def output_xml(self): - print("XML output not yet supported in \"" + self.__class__.__name__ + "\".") + print(_("XML output not yet supported in \"") + self.__class__.__name__ + "\".") def output(outputable): if format.get_selected() == "html": diff --git a/gitinspector/responsibilities.py b/gitinspector/responsibilities.py index 3416340..ba09c6b 100644 --- a/gitinspector/responsibilities.py +++ b/gitinspector/responsibilities.py @@ -39,9 +39,10 @@ class Responsibilities: return sorted(author_blames.items()) -__responsibilities_info_text__ = ("The following repsonsibilties, by author, were found in the current " - "revision of the repository (comments are exluded from the line count, " - "if possible)") +__responsibilities_info_text__ = _("The following repsonsibilties, by author, were found in the current " + "revision of the repository (comments are exluded from the line count, " + "if possible)") +__mostly_responsible_for_text__ = _("is mostly responsible for") class ResponsibilitiesOutput(Outputable): def __init__(self, hard): @@ -54,7 +55,7 @@ class ResponsibilitiesOutput(Outputable): for i in sorted(set(i[0] for i in blame.get(self.hard).blames)): responsibilities = sorted(((i[1], i[0]) for i in Responsibilities.get(self.hard, i)), reverse=True) if responsibilities: - print("\n" + i, "is mostly responsible for:") + print("\n" + i, __mostly_responsible_for_text__ + ":") for j, entry in enumerate(responsibilities): (width, _) = terminal.get_size() @@ -73,7 +74,7 @@ class ResponsibilitiesOutput(Outputable): for i in sorted(set(i[0] for i in blame.get(self.hard).blames)): responsibilities = sorted(((i[1], i[0]) for i in Responsibilities.get(self.hard, i)), reverse=True) if responsibilities: - resp_xml += "

" + i + "is mostly responsible for

" + resp_xml += "

" + i + __mostly_responsible_for_text__ + "

" for j, entry in enumerate(responsibilities): resp_xml += "

" + entry[1] + " (" + str(entry[0]) + " eloc)

" diff --git a/gitinspector/timeline.py b/gitinspector/timeline.py index 5f9ca42..8ee7ee4 100644 --- a/gitinspector/timeline.py +++ b/gitinspector/timeline.py @@ -101,7 +101,8 @@ class TimelineData: return True return False -__timeline_info_text__ = "The following history timeline has been gathered from the repository" +__timeline_info_text__ = _("The following history timeline has been gathered from the repository") +__modified_rows_text__ = _("Modified Rows:") def __output_row__text__(timeline_data, periods, names): print("\n" + terminal.__bold__ + "Author".ljust(20), end=" ") @@ -122,7 +123,7 @@ def __output_row__text__(timeline_data, periods, names): len(signs_str) == 0 else signs_str).rjust(10), end=" ") print("") - print(terminal.__bold__ + "Modified Rows:".ljust(20) + terminal.__normal__, end=" ") + print(terminal.__bold__ + __modified_rows_text__.ljust(20) + terminal.__normal__, end=" ") for period in periods: total_changes = timeline_data.get_total_changes_in_period(period) @@ -142,7 +143,7 @@ def __output_row__html__(timeline_data, periods, names): for name in names: if timeline_data.is_author_in_periods(periods, name): timeline_xml += "" if i % 2 == 1 else ">") - timeline_xml += "
" + timeline_xml += "" for period in periods: multiplier = timeline_data.get_multiplier(period, 14) signs = timeline_data.get_author_signs_in_period(name, period, multiplier) @@ -153,7 +154,7 @@ def __output_row__html__(timeline_data, periods, names): timeline_xml += "" i = i + 1 - timeline_xml += "" + timeline_xml += "" for period in periods: total_changes = timeline_data.get_total_changes_in_period(period) diff --git a/gitinspector/version.py b/gitinspector/version.py index 12d587e..25f78d0 100644 --- a/gitinspector/version.py +++ b/gitinspector/version.py @@ -17,16 +17,18 @@ # You should have received a copy of the GNU General Public License # along with gitinspector. If not, see . -"""Copyright © 2012-2013 Ejwa Software. All rights reserved. +from __future__ import print_function + +import localization +localization.init() + +__version__ = "0.2.2" + +__doc__ = _("""Copyright © 2012-2013 Ejwa Software. All rights reserved. License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. -Written by Adam Waldenberg.""" - -from __future__ import print_function - -__version__ = "0.2.2" - +Written by Adam Waldenberg.""") def output(): print("gitinspector {0}\n".format(__version__) + __doc__)
Author Commits Insertions Deletions% of changes
{0} {1} {2} {3} {4}
" + name + "" + __modified_rows_text__ + "
Modified Rows:
" + _("Modified Rows:") + "