# Copyright (C) 2000-2018 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 sys import time import locale import gettext from types import StringType, UnicodeType from Mailman import mm_cfg from Mailman.SafeDict import SafeDict _translation = None def _get_ctype_charset(): old = locale.setlocale(locale.LC_CTYPE, '') charset = locale.nl_langinfo(locale.CODESET) locale.setlocale(locale.LC_CTYPE, old) return charset if not mm_cfg.DISABLE_COMMAND_LOCALE_CSET: _ctype_charset = _get_ctype_charset() else: _ctype_charset = None def set_language(language=None): global _translation if language is not None: language = [language] try: _translation = gettext.translation('mailman', mm_cfg.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 # Set up the global translation based on environment variables. Mostly used # for command line scripts. if _translation is None: set_language() def _(s, frame=1): if s == '': return s assert s # Do translation of the given string into the current language, and do # Ping-string interpolation into the resulting string. # # This lets you write something like: # # now = time.ctime(time.time()) # print _('The current time is: %(now)s') # # and have it Just Work. Note that the lookup order for keys in the # original string is 1) locals dictionary, 2) globals dictionary. # # First, get the frame of the caller frame = sys._getframe(frame) # A `safe' dictionary is used so we won't get an exception if there's a # missing key in the dictionary. dict = SafeDict(frame.f_globals.copy()) dict.update(frame.f_locals) # Translating the string returns an encoded 8-bit string. Rather than # turn that into a Unicode, we turn any Unicodes in the dictionary values # into encoded 8-bit strings. BAW: Returning a Unicode here broke too # much other stuff and _() has many tentacles. Eventually I think we want # to use Unicode everywhere. tns = _translation.gettext(s) charset = _translation.charset() if not charset: charset = 'us-ascii' for k, v in dict.items(): if isinstance(v, UnicodeType): dict[k] = v.encode(charset, 'replace') try: return tns % dict except (ValueError, TypeError): # Bad interpolation format. Punt. return tns def tolocale(s): global _ctype_charset if isinstance(s, UnicodeType) or _ctype_charset is None: return s source = _translation.charset () if not source: return s return unicode(s, source, 'replace').encode(_ctype_charset, 'replace') if mm_cfg.DISABLE_COMMAND_LOCALE_CSET: C_ = _ else: def C_(s): return tolocale(_(s, 2)) 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, StringType): 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')