Added gettext (GNU) localization support.

This commit is contained in:
Adam Waldenberg 2013-06-25 14:38:40 +02:00
parent bfc95231e2
commit 9c0633f8ad
13 changed files with 108 additions and 54 deletions

View file

@ -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 = "<div><div class=\"box\">"
blame_xml += "<p>" + __blame_info_text__ + ".</p><div><table id=\"blame\" class=\"git\">"
blame_xml += "<thead><tr> <th>Author</th> <th>Rows</th> <th>% in comments</th> </tr></thead>"
blame_xml += "<thead><tr> <th>{0}</th> <th>{1}</th> <th>{2}</th> </tr></thead>".format(_("Author"),
_("Rows"), _("% in comments"))
blame_xml += "<tbody>"
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=" ")

View file

@ -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 += "<p>" + __historical_info_text__ + ".</p><div><table id=\"changes\" class=\"git\">"
changes_xml += ("<thead><tr> <th>Author</th> <th>Commits</th> <th>Insertions</th> <th>Deletions</th>" +
"<th>% of changes</th> </tr></thead>")
changes_xml += "<tbody>"
changes_xml += "<thead><tr> <th>{0}</th> <th>{1}</th> <th>{2}</th> <th>{3}</th> <th>{4}</th>".format(
_("Author"), _("Commits"), _("Insertions"), _("Deletions"), _("% of changes"))
changes_xml += "</tr></thead><tbody>"
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 += "</script>"
else:
changes_xml += "<p>" + __no_commited_files__ + ".</p>"
changes_xml += "<p>" + __no_commited_files_text__ + ".</p>"
changes_xml += "</div></div>"
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<changes>\n" + message_xml + "\t\t<authors>\n" + changes_xml + "\t\t</authors>\n\t</changes>")
else:
print("\t<changes>\n\t\t<exception>" + __no_commited_files__ + "</exception>\n\t</changes>")
print("\t<changes>\n\t\t<exception>" + __no_commited_files_text__ + "</exception>\n\t</changes>")

View file

@ -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 = "<div><div class=\"box\">"
extensions_xml += "<p>" + __extensions_info_text__ + " (extensions used during statistical analysis are marked).</p><p>"
extensions_xml += "<p>{0} {1}.</p><p>".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__:

View file

@ -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):

View file

@ -19,6 +19,10 @@
# along with gitinspector. If not, see <http://www.gnu.org/licenses/>.
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__()

View file

@ -17,7 +17,12 @@
# You should have received a copy of the GNU General Public License
# along with gitinspector. If not, see <http://www.gnu.org/licenses/>.
"""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__)))

View file

@ -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 <http://www.gnu.org/licenses/>.
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()

View file

@ -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):

View file

@ -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):

View file

@ -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":

View file

@ -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 += "<h3>" + i + "is mostly responsible for</h3>"
resp_xml += "<h3>" + i + __mostly_responsible_for_text__ + "</h3>"
for j, entry in enumerate(responsibilities):
resp_xml += "<p>" + entry[1] + " (" + str(entry[0]) + " eloc)</p>"

View file

@ -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 += "<tr" + (" class=\"odd\">" if i % 2 == 1 else ">")
timeline_xml += "<td>" + name + "</td>"
timeline_xml += "<td>" + __modified_rows_text__ + "</td>"
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 += "</tr>"
i = i + 1
timeline_xml += "<tfoot><tr><td><strong>Modified Rows:</strong></td>"
timeline_xml += "<tfoot><tr><td><strong>" + _("Modified Rows:") + "</strong></td>"
for period in periods:
total_changes = timeline_data.get_total_changes_in_period(period)

View file

@ -17,16 +17,18 @@
# You should have received a copy of the GNU General Public License
# along with gitinspector. If not, see <http://www.gnu.org/licenses/>.
"""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 <http://gnu.org/licenses/gpl.html>.
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__)