Apply 01_defaults.debian.patch
[mspang/vmailman.git] / Mailman / i18n.py
1 # Copyright (C) 2000-2006 by the Free Software Foundation, Inc.
2 #
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
16 # USA.
17
18 import sys
19 import time
20 import gettext
21 from types import StringType, UnicodeType
22
23 from Mailman import mm_cfg
24 from Mailman.SafeDict import SafeDict
25
26 _translation = None
27
28
29 \f
30 def set_language(language=None):
31     global _translation
32     if language is not None:
33         language = [language]
34     try:
35         _translation = gettext.translation('mailman', mm_cfg.MESSAGES_DIR,
36                                            language)
37     except IOError:
38         # The selected language was not installed in messages, so fall back to
39         # untranslated English.
40         _translation = gettext.NullTranslations()
41
42 def get_translation():
43     return _translation
44
45 def set_translation(translation):
46     global _translation
47     _translation = translation
48
49
50 # Set up the global translation based on environment variables.  Mostly used
51 # for command line scripts.
52 if _translation is None:
53     set_language()
54
55
56 \f
57 def _(s):
58     if s == '':
59         return s
60     assert s
61     # Do translation of the given string into the current language, and do
62     # Ping-string interpolation into the resulting string.
63     #
64     # This lets you write something like:
65     #
66     #     now = time.ctime(time.time())
67     #     print _('The current time is: %(now)s')
68     #
69     # and have it Just Work.  Note that the lookup order for keys in the
70     # original string is 1) locals dictionary, 2) globals dictionary.
71     #
72     # First, get the frame of the caller
73     frame = sys._getframe(1)
74     # A `safe' dictionary is used so we won't get an exception if there's a
75     # missing key in the dictionary.
76     dict = SafeDict(frame.f_globals.copy())
77     dict.update(frame.f_locals)
78     # Translating the string returns an encoded 8-bit string.  Rather than
79     # turn that into a Unicode, we turn any Unicodes in the dictionary values
80     # into encoded 8-bit strings.  BAW: Returning a Unicode here broke too
81     # much other stuff and _() has many tentacles.  Eventually I think we want
82     # to use Unicode everywhere.
83     tns = _translation.gettext(s)
84     charset = _translation.charset()
85     if not charset:
86         charset = 'us-ascii'
87     for k, v in dict.items():
88         if isinstance(v, UnicodeType):
89             dict[k] = v.encode(charset, 'replace')
90     return tns % dict
91
92
93 \f
94 def ctime(date):
95     # Don't make these module globals since we have to do runtime translation
96     # of the strings anyway.
97     daysofweek = [
98         _('Mon'), _('Tue'), _('Wed'), _('Thu'),
99         _('Fri'), _('Sat'), _('Sun')
100         ]
101     months = [
102         '',
103         _('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May'), _('Jun'),
104         _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')
105         ]
106
107     tzname = _('Server Local Time')
108     if isinstance(date, StringType):
109         try:
110             year, mon, day, hh, mm, ss, wday, ydat, dst = time.strptime(date)
111             if dst in (0,1):
112                 tzname = time.tzname[dst]
113             else:
114                 # MAS: No exception but dst = -1 so try
115                 return ctime(time.mktime((year, mon, day, hh, mm, ss, wday,
116                                           ydat, dst)))
117         except (ValueError, AttributeError):
118             try:
119                 wday, mon, day, hms, year = date.split()
120                 hh, mm, ss = hms.split(':')
121                 year = int(year)
122                 day = int(day)
123                 hh = int(hh)
124                 mm = int(mm)
125                 ss = int(ss)
126             except ValueError:
127                 return date
128             else:
129                 for i in range(0, 7):
130                     wconst = (1999, 1, 1, 0, 0, 0, i, 1, 0)
131                     if wday.lower() == time.strftime('%a', wconst).lower():
132                         wday = i
133                         break
134                 for i in range(1, 13):
135                     mconst = (1999, i, 1, 0, 0, 0, 0, 1, 0)
136                     if mon.lower() == time.strftime('%b', mconst).lower():
137                         mon = i
138                         break
139     else:
140         year, mon, day, hh, mm, ss, wday, yday, dst = time.localtime(date)
141         if dst in (0,1):
142             tzname = time.tzname[dst]
143
144     wday = daysofweek[wday]
145     mon = months[mon]
146     return _('%(wday)s %(mon)s %(day)2i %(hh)02i:%(mm)02i:%(ss)02i '
147              '%(tzname)s %(year)04i')