Added a --localize-output flag.

The default behaviour is now not to localize the output, only the help
text and error messages (all the user interaction).

The way localized messages are fetched in the modules has been modified
as well; to allow for the ability to enable and disable the localization.
This commit is contained in:
Adam Waldenberg 2013-07-10 05:24:18 +02:00
parent 109fefb978
commit 3b82acdfa1
12 changed files with 84 additions and 64 deletions

View File

@ -75,7 +75,7 @@ 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}%")
PROGRESS_TEXT = "Checking how many rows belong to each author (Progress): {0:.0f}%"
class Blame:
def __init__(self, hard):
@ -108,7 +108,7 @@ class Blame:
def output_progress(pos, length):
if sys.stdout.isatty() and format.is_interactive_format():
terminal.clear_row()
print(__progress_text__.format(100 * pos / length), end="")
print("\b" + _(PROGRESS_TEXT).format(100 * pos / length), end="")
sys.stdout.flush()
@staticmethod
@ -145,8 +145,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):
@ -157,7 +157,7 @@ class BlameOutput(Outputable):
get(self.hard)
blame_xml = "<div><div class=\"box\">"
blame_xml += "<p>" + __blame_info_text__ + ".</p><div><table id=\"blame\" class=\"git\">"
blame_xml += "<p>" + _(BLAME_INFO_TEXT) + ".</p><div><table id=\"blame\" class=\"git\">"
blame_xml += "<thead><tr> <th>{0}</th> <th>{1}</th> <th>{2}</th> </tr></thead>".format(_("Author"),
_("Rows"), _("% in comments"))
blame_xml += "<tbody>"
@ -210,7 +210,7 @@ class BlameOutput(Outputable):
if self.hard and sys.stdout.isatty():
terminal.clear_row()
print(textwrap.fill(__blame_info_text__ + ":", width=terminal.get_size()[0]) + "\n")
print(textwrap.fill(_(BLAME_INFO_TEXT) + ":", width=terminal.get_size()[0]) + "\n")
terminal.printb(_("Author").ljust(21) + _("Rows").rjust(10) + _("% in comments").rjust(20))
for i in sorted(__blame__.get_summed_blames().items()):
print(i[0].ljust(20)[0:20], end=" ")
@ -220,7 +220,7 @@ class BlameOutput(Outputable):
def output_xml(self):
get(self.hard)
message_xml = "\t\t<message>" + __blame_info_text__ + "</message>\n"
message_xml = "\t\t<message>" + _(BLAME_INFO_TEXT) + "</message>\n"
blame_xml = ""
for i in sorted(__blame__.get_summed_blames().items()):

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_text__ = _("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):
@ -176,7 +176,7 @@ class ChangesOutput(Outputable):
total_changes += authorinfo_list.get(i).deletions
if authorinfo_list:
changes_xml += "<p>" + __historical_info_text__ + ".</p><div><table id=\"changes\" class=\"git\">"
changes_xml += "<p>" + _(HISTORICAL_INFO_TEXT) + ".</p><div><table id=\"changes\" class=\"git\">"
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>"
@ -216,7 +216,7 @@ class ChangesOutput(Outputable):
changes_xml += " });"
changes_xml += "</script>"
else:
changes_xml += "<p>" + __no_commited_files_text__ + ".</p>"
changes_xml += "<p>" + _(NO_COMMITED_FILES_TEXT) + ".</p>"
changes_xml += "</div></div>"
print(changes_xml)
@ -230,7 +230,7 @@ class ChangesOutput(Outputable):
total_changes += authorinfo_list.get(i).deletions
if authorinfo_list:
print(textwrap.fill(__historical_info_text__ + ":", width=terminal.get_size()[0]) + "\n")
print(textwrap.fill(_(HISTORICAL_INFO_TEXT) + ":", width=terminal.get_size()[0]) + "\n")
terminal.printb(_("Author").ljust(21) + _("Commits").rjust(13) + _("Insertions").rjust(14) +
_("Deletions").rjust(15) + _("% of changes").rjust(16))
@ -244,7 +244,7 @@ class ChangesOutput(Outputable):
print(str(authorinfo.deletions).rjust(14), end=" ")
print("{0:.2f}".format(percentage).rjust(15))
else:
print(__no_commited_files_text__ + ".")
print(_(NO_COMMITED_FILES_TEXT) + ".")
def output_xml(self):
authorinfo_list = get(self.hard).get_authorinfo_list()
@ -255,7 +255,7 @@ class ChangesOutput(Outputable):
total_changes += authorinfo_list.get(i).deletions
if authorinfo_list:
message_xml = "\t\t<message>" + __historical_info_text__ + "</message>\n"
message_xml = "\t\t<message>" + _(HISTORICAL_INFO_TEXT) + "</message>\n"
changes_xml = ""
for i in sorted(authorinfo_list):
@ -273,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_text__ + "</exception>\n\t</changes>")
print("\t<changes>\n\t\t<exception>" + _(NO_COMMITED_FILES_TEXT) + "</exception>\n\t</changes>")

View File

@ -51,6 +51,7 @@ def init(run):
__read_git_config__(run, "format")
__read_git_config__(run, "hard")
__read_git_config__(run, "list-file-types", "list_file_types")
__read_git_config__(run, "localize-output", "localize_output")
__read_git_config__(run, "metrics")
__read_git_config__(run, "responsibilities")
__read_git_config__(run, "weeks", "useweeks")

View File

@ -39,14 +39,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_marked_text__ = _("(extensions used during statistical analysis are marked)")
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>{0} {1}.</p><p>".format(__extensions_info_text__, __extensions_marked_text__)
extensions_xml += "<p>{0} {1}.</p><p>".format(_(EXTENSIONS_INFO_TEXT), _(EXTENSIONS_MARKED_TEXT))
for i in __located_extensions__:
if i in __extensions__:
@ -60,7 +60,7 @@ class Extensions(Outputable):
def output_text(self):
if __located_extensions__:
print("\n" + textwrap.fill("{0} {1}:".format(__extensions_info_text__, __extensions_marked_text__),
print("\n" + textwrap.fill("{0} {1}:".format(_(EXTENSIONS_INFO_TEXT), _(EXTENSIONS_MARKED_TEXT)),
width=terminal.get_size()[0]))
for i in __located_extensions__:
@ -72,7 +72,7 @@ class Extensions(Outputable):
def output_xml(self):
if __located_extensions__:
message_xml = "\t\t<message>" + __extensions_info_text__ + "</message>\n"
message_xml = "\t\t<message>" + _(EXTENSIONS_INFO_TEXT) + "</message>\n"
used_extensions_xml = ""
unused_extensions_xml = ""

View File

@ -49,14 +49,13 @@ def set_filtered(file_name):
raise ValueError("Invalid regular expression specified")
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):
if __filtered_files__:
filtering_xml = "<div><div class=\"box\">"
filtering_xml += "<p>" + __filtering_info_text__ + "."+ "</p>"
filtering_xml += "<p>" + _(FILTERING_INFO_TEXT) + "."+ "</p>"
for i in __filtered_files__:
filtering_xml += "<p>" + i + "</p>"
@ -66,15 +65,15 @@ class Filtering(Outputable):
def output_text(self):
if __filtered_files__:
print("\n" + textwrap.fill(__filtering_info_text__ + ":", width=terminal.get_size()[0]))
print("\n" + textwrap.fill(_(FILTERING_INFO_TEXT) + ":", width=terminal.get_size()[0]))
for i in __filtered_files__:
(width, _) = terminal.get_size()
(width, _unused) = terminal.get_size()
print("...%s" % i[-width+3:] if len(i) > width else i)
def output_xml(self):
if __filtered_files__:
message_xml = "\t\t<message>" + __filtering_info_text__ + "</message>\n"
message_xml = "\t\t<message>" + _(FILTERING_INFO_TEXT) + "</message>\n"
filtering_xml = ""
for i in __filtered_files__:

View File

@ -35,7 +35,6 @@ import interval
import metrics
import missing
import os
import optparse
import optval
import outputable
import responsibilities
@ -58,6 +57,9 @@ class Runner:
if not format.select(self.opts.format):
raise format.InvalidFormatError(_("specified output format not supported."))
if not self.opts.localize_output:
localization.disable()
missing.set_checkout_missing(self.opts.checkout_missing)
extensions.define(self.opts.file_types)
@ -114,6 +116,7 @@ def main():
parser.add_option("-c", action="store_true", dest="checkout_missing")
parser.add_option("-H", action="store_true", dest="hard")
parser.add_option("-l", action="store_true", dest="list_file_types")
parser.add_option("-L", action="store_true", dest="localize_output")
parser.add_option("-m", action="store_true", dest="metrics")
parser.add_option("-r", action="store_true", dest="responsibilities")
parser.add_option("-T", action="store_true", dest="timeline")
@ -127,6 +130,7 @@ def main():
parser.add_option( "-h", "--help", action="callback", callback=__handle_help__)
optval.add_option(parser, "--hard", boolean=True)
optval.add_option(parser, "--list-file-types", boolean=True)
optval.add_option(parser, "--localize-output", boolean=True)
optval.add_option(parser, "--metrics", boolean=True)
optval.add_option(parser, "--responsibilities", boolean=True)
parser.add_option( "--since", type="string")
@ -148,6 +152,8 @@ def main():
parser.parse_args(values=opts)
except (format.InvalidFormatError, optval.InvalidOptionArgument, optval.OptionParsingError) as msg:
localization.enable()
print(sys.argv[0], "\b:", end=" ")
print(msg)
print(_("Try `{0} --help' for more information.").format(sys.argv[0]))

View File

@ -47,6 +47,9 @@ Boolean arguments can only be given to long options.
this can be quite slow with big repositories
-l, --list-file-types[=BOOL] list all the file extensions available in the
current branch of the repository
-L, --localize-output[=BOOL] localize the generated output to the selected
system language if a translation is
available
-m --metrics[=BOOL] include checks for certain metrics during the
analysis of commits
-r --responsibilities[=BOOL] show which files the different authors seem

View File

@ -25,15 +25,17 @@ import locale
import os
__installed__ = False
__translation__ = None
def init():
global __installed__
global __translation__
if not __installed__:
try:
locale.setlocale(locale.LC_ALL, "")
except locale.Error:
translation = gettext.NullTranslations()
__translation__ = gettext.NullTranslations()
else:
lang = locale.getlocale()
@ -45,9 +47,17 @@ def init():
filename = basedir.get_basedir() + "/translations/messages_%s.mo" % lang[0][0:2]
try:
translation = gettext.GNUTranslations(open(filename, "rb"))
__translation__ = gettext.GNUTranslations(open(filename, "rb"))
except IOError:
translation = gettext.NullTranslations()
__translation__ = gettext.NullTranslations()
__installed__ = True
translation.install(True)
__translation__.install(True)
def enable():
if __installed__ and type(__translation__) is not gettext.GNUTranslations:
__translation__.install(True)
def disable():
if __installed__:
gettext.NullTranslations().install(True)

View File

@ -64,17 +64,17 @@ 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):
metrics_logic = MetricsLogic()
if not metrics_logic.eloc:
print("\n" + __metrics_missing_info_text__ + ".")
print("\n" + _(METRICS_MISSING_INFO_TEXT) + ".")
else:
print("\n" + __eloc_info_text__ + ":")
print("\n" + _(ELOC_INFO_TEXT) + ":")
for i in sorted(set([(j, i) for (i, j) in metrics_logic.eloc.items()]), reverse = True):
print(i[1] + " (" + str(i[0]) + " eloc)")
@ -83,9 +83,9 @@ class Metrics(Outputable):
metrics_xml = "<div><div class=\"box\">"
if not metrics_logic.eloc:
metrics_xml += "<p>" + __metrics_missing_info_text__ + ".</p>"
metrics_xml += "<p>" + _(METRICS_MISSING_INFO_TEXT) + ".</p>"
else:
metrics_xml += "<p>" + __eloc_info_text__ + ".</p>"
metrics_xml += "<p>" + _(ELOC_INFO_TEXT) + ".</p>"
for i in sorted(set([(j, i) for (i, j) in metrics_logic.eloc.items()]), reverse = True):
metrics_xml += "<p>" + i[1] + " (" + str(i[0]) + " eloc)</p>"
@ -96,7 +96,7 @@ class Metrics(Outputable):
metrics_logic = MetricsLogic()
if not metrics_logic.eloc:
print("\t<metrics>\n\t\t<message>" + __metrics_missing_info_text__ + "</message>\n\t</metrics>")
print("\t<metrics>\n\t\t<message>" + _(METRICS_MISSING_INFO_TEXT) + "</message>\n\t</metrics>")
else:
eloc_xml = ""
for i in sorted(set([(j, i) for (i, j) in metrics_logic.eloc.items()]), reverse = True):
@ -105,5 +105,5 @@ class Metrics(Outputable):
eloc_xml += "\t\t\t\t\t\t<lines-of-code>" + str(i[0]) + "</lines-of-code>\n"
eloc_xml += "\t\t\t\t\t</violation>\n"
print("\t\t<metrics>\n\t\t\t<eloc>\n\t\t\t\t<message>" + __eloc_info_text__ +
print("\t\t<metrics>\n\t\t\t<eloc>\n\t\t\t\t<message>" + _(ELOC_INFO_TEXT) +
"</message>\n\t\t\t\t<violations>\n" + eloc_xml + "\t\t\t\t</violations>\n\t\t\t</eloc>\n\t\t</metrics>")

View File

@ -42,15 +42,15 @@ 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):
if __missing_files__:
missing_xml = "<div><div class=\"box\">"
missing_xml += "<p>" + __missing_info_text__ + ".</p>"
missing_xml += "<p>" + _(MISSING_INFO_TEXT) + ".</p>"
for missing in __missing_files__:
missing_xml += "<p class=\"error\">" + missing + "</p>"
@ -60,15 +60,15 @@ class Missing(Outputable):
def output_text(self):
if __missing_files__:
print("\n" + textwrap.fill(__missing_info_text__ + ":", width=terminal.get_size()[0]))
print("\n" + textwrap.fill(_(MISSING_INFO_TEXT) + ":", width=terminal.get_size()[0]))
for missing in __missing_files__:
(width, _) = terminal.get_size()
(width, _unused) = terminal.get_size()
print("...%s" % missing[-width+3:] if len(missing) > width else missing)
def output_xml(self):
if __missing_files__:
message_xml = "\t\t<message>" + __missing_info_text__ + "</message>\n"
message_xml = "\t\t<message>" + _(MISSING_INFO_TEXT) + "</message>\n"
missing_xml = ""
for missing in __missing_files__:

View File

@ -40,10 +40,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)")
__mostly_responsible_for_text__ = _("is mostly responsible for")
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):
@ -51,15 +51,15 @@ class ResponsibilitiesOutput(Outputable):
Outputable.__init__(self)
def output_text(self):
print("\n" + textwrap.fill(__responsibilities_info_text__ + ":", width=terminal.get_size()[0]))
print("\n" + textwrap.fill(_(RESPONSIBILITIES_INFO_TEXT) + ":", width=terminal.get_size()[0]))
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, __mostly_responsible_for_text__ + ":")
print("\n" + i, _(MOSTLY_RESPONSIBLE_FOR_TEXT) + ":")
for j, entry in enumerate(responsibilities):
(width, _) = terminal.get_size()
(width, _unused) = terminal.get_size()
width -= 7
print(str(entry[0]).rjust(6), end=" ")
@ -70,12 +70,12 @@ class ResponsibilitiesOutput(Outputable):
def output_html(self):
resp_xml = "<div><div class=\"box\">"
resp_xml += "<p>" + __responsibilities_info_text__ + ".</p>"
resp_xml += "<p>" + _(RESPONSIBILITIES_INFO_TEXT) + ".</p>"
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 + " " + __mostly_responsible_for_text__ + "</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>"
@ -87,7 +87,7 @@ class ResponsibilitiesOutput(Outputable):
print(resp_xml)
def output_xml(self):
message_xml = "\t\t<message>" + __responsibilities_info_text__ + "</message>\n"
message_xml = "\t\t<message>" + _(RESPONSIBILITIES_INFO_TEXT) + "</message>\n"
resp_xml = ""
for i in sorted(set(i[0] for i in blame.get(self.hard).blames)):

View File

@ -102,8 +102,9 @@ class TimelineData:
return True
return False
__timeline_info_text__ = _("The following history timeline has been gathered from the repository")
__modified_rows_text__ = _("Modified Rows:")
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=" ")
@ -124,7 +125,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_text__.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)
@ -155,7 +156,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_TEXT) + "</strong></td>"
for period in periods:
total_changes = timeline_data.get_total_changes_in_period(period)
@ -172,12 +173,12 @@ class Timeline(Outputable):
def output_text(self):
if self.changes.get_commits():
print("\n" + textwrap.fill(__timeline_info_text__ + ":", width=terminal.get_size()[0]))
print("\n" + textwrap.fill(_(TIMELINE_INFO_TEXT) + ":", width=terminal.get_size()[0]))
timeline_data = TimelineData(self.changes, self.useweeks)
periods = timeline_data.get_periods()
names = timeline_data.get_authors()
(width, _) = terminal.get_size()
(width, _unused) = terminal.get_size()
max_periods_per_row = int((width - 21) / 11)
for i in range(0, len(periods), max_periods_per_row):
@ -191,7 +192,7 @@ class Timeline(Outputable):
max_periods_per_row = 8
timeline_xml = "<div><div id=\"timeline\" class=\"box\">"
timeline_xml += "<p>" + __timeline_info_text__ + ".</p>"
timeline_xml += "<p>" + _(TIMELINE_INFO_TEXT) + ".</p>"
print(timeline_xml)
for i in range(0, len(periods), max_periods_per_row):
@ -202,7 +203,7 @@ class Timeline(Outputable):
def output_xml(self):
if self.changes.get_commits():
message_xml = "\t\t<message>" + __timeline_info_text__ + "</message>\n"
message_xml = "\t\t<message>" + _(TIMELINE_INFO_TEXT) + "</message>\n"
timeline_xml = ""
periods_xml = "\t\t<periods length=\"{0}\">\n".format("week" if self.useweeks else "month")