summaryrefslogtreecommitdiff
path: root/mailman/i18n.py
diff options
context:
space:
mode:
authorBarry Warsaw2008-02-27 01:26:18 -0500
committerBarry Warsaw2008-02-27 01:26:18 -0500
commita1c73f6c305c7f74987d99855ba59d8fa823c253 (patch)
tree65696889450862357c9e05c8e9a589f1bdc074ac /mailman/i18n.py
parent3f31f8cce369529d177cfb5a7c66346ec1e12130 (diff)
downloadmailman-a1c73f6c305c7f74987d99855ba59d8fa823c253.tar.gz
mailman-a1c73f6c305c7f74987d99855ba59d8fa823c253.tar.zst
mailman-a1c73f6c305c7f74987d99855ba59d8fa823c253.zip
Diffstat (limited to 'mailman/i18n.py')
-rw-r--r--mailman/i18n.py185
1 files changed, 185 insertions, 0 deletions
diff --git a/mailman/i18n.py b/mailman/i18n.py
new file mode 100644
index 000000000..cab0f78ab
--- /dev/null
+++ b/mailman/i18n.py
@@ -0,0 +1,185 @@
+# Copyright (C) 2000-2008 by the Free Software Foundation, Inc.
+#
+# This program 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 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+
+import os
+import sys
+import time
+import string
+import gettext
+
+import mailman.messages
+from mailman.SafeDict import SafeDict
+from mailman.configuration import config
+
+_translation = None
+_missing = object()
+
+MESSAGES_DIR = os.path.dirname(mailman.messages.__file__)
+
+
+
+class Template(string.Template):
+ idpattern = r'[_a-z][_a-z0-9.]*'
+
+
+class attrdict(dict):
+ def __getitem__(self, key):
+ parts = key.split('.')
+ value = super(attrdict, self).__getitem__(parts.pop(0))
+ while parts:
+ value = getattr(value, parts.pop(0), _missing)
+ if value is _missing:
+ raise KeyError(key)
+ return value
+
+
+
+def set_language(language=None):
+ global _translation
+ if language is not None:
+ language = [language]
+ try:
+ _translation = gettext.translation('mailman', MESSAGES_DIR, language)
+ except IOError:
+ # The selected language was not installed in messages, so fall back to
+ # untranslated English.
+ _translation = gettext.NullTranslations()
+
+
+def get_translation():
+ return _translation
+
+
+def set_translation(translation):
+ global _translation
+ _translation = translation
+
+
+class using_language(object):
+ """Context manager for Python 2.5's `with` statement."""
+ def __init__(self, language):
+ self._language = language
+ self._old_translation = None
+
+ def __enter__(self):
+ self._old_translation = _translation
+ set_language(self._language)
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ global _translation
+ _translation = self._old_translation
+
+
+# Set up the global translation based on environment variables. Mostly used
+# for command line scripts.
+if _translation is None:
+ _translation = gettext.NullTranslations()
+
+
+
+def _(s):
+ if s == '':
+ return u''
+ assert s, 'Cannot translate: %s' % s
+ # Do translation of the given string into the current language, and do PEP
+ # 292 style $-string interpolation into the resulting string.
+ #
+ # This lets you write something like:
+ #
+ # now = time.ctime(time.time())
+ # print _('The current time is: $now')
+ #
+ # and have it Just Work. Note that the lookup order for keys in the
+ # original string is 1) locals dictionary, 2) globals dictionary.
+ #
+ # Get the frame of the caller.
+ frame = sys._getframe(1)
+ # A `safe' dictionary is used so we won't get an exception if there's a
+ # missing key in the dictionary.
+ d = frame.f_globals.copy()
+ d.update(frame.f_locals)
+ # Mailman must be unicode safe internally (i.e. all strings inside Mailman
+ # must be unicodes). The translation service is one boundary to the
+ # outside world, so to honor this constraint, make sure that all strings
+ # to come out of _() are unicodes, even if the translated string or
+ # dictionary values are 8-bit strings.
+ tns = _translation.ugettext(s)
+ charset = _translation.charset() or 'us-ascii'
+ for k, v in d.items():
+ if isinstance(v, str):
+ d[k] = unicode(v, charset, 'replace')
+ translated_string = Template(tns).safe_substitute(attrdict(d))
+ if isinstance(translated_string, str):
+ translated_string = unicode(translated_string, charset)
+ return translated_string
+
+
+
+def ctime(date):
+ # Don't make these module globals since we have to do runtime translation
+ # of the strings anyway.
+ daysofweek = [
+ _('Mon'), _('Tue'), _('Wed'), _('Thu'),
+ _('Fri'), _('Sat'), _('Sun')
+ ]
+ months = [
+ '',
+ _('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May'), _('Jun'),
+ _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')
+ ]
+
+ tzname = _('Server Local Time')
+ if isinstance(date, str):
+ try:
+ year, mon, day, hh, mm, ss, wday, ydat, dst = time.strptime(date)
+ if dst in (0,1):
+ tzname = time.tzname[dst]
+ else:
+ # MAS: No exception but dst = -1 so try
+ return ctime(time.mktime((year, mon, day, hh, mm, ss, wday,
+ ydat, dst)))
+ except (ValueError, AttributeError):
+ try:
+ wday, mon, day, hms, year = date.split()
+ hh, mm, ss = hms.split(':')
+ year = int(year)
+ day = int(day)
+ hh = int(hh)
+ mm = int(mm)
+ ss = int(ss)
+ except ValueError:
+ return date
+ else:
+ for i in range(0, 7):
+ wconst = (1999, 1, 1, 0, 0, 0, i, 1, 0)
+ if wday.lower() == time.strftime('%a', wconst).lower():
+ wday = i
+ break
+ for i in range(1, 13):
+ mconst = (1999, i, 1, 0, 0, 0, 0, 1, 0)
+ if mon.lower() == time.strftime('%b', mconst).lower():
+ mon = i
+ break
+ else:
+ year, mon, day, hh, mm, ss, wday, yday, dst = time.localtime(date)
+ if dst in (0, 1):
+ tzname = time.tzname[dst]
+
+ wday = daysofweek[wday]
+ mon = months[mon]
+ return _('%(wday)s %(mon)s %(day)2i %(hh)02i:%(mm)02i:%(ss)02i '
+ '%(tzname)s %(year)04i')