Mercurial > babel > old > babel-test
annotate babel/util.py @ 164:84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
comment (or default to ascii) and convert message strings and comments to
unicode
fixes #23
author | pjenvey |
---|---|
date | Fri, 22 Jun 2007 00:38:54 +0000 |
parents | f2c78a271159 |
children | 650a6e996ede |
rev | line source |
---|---|
1 | 1 # -*- coding: utf-8 -*- |
2 # | |
3 # Copyright (C) 2007 Edgewall Software | |
4 # All rights reserved. | |
5 # | |
6 # This software is licensed as described in the file COPYING, which | |
7 # you should have received as part of this distribution. The terms | |
8 # are also available at http://babel.edgewall.org/wiki/License. | |
9 # | |
10 # This software consists of voluntary contributions made by many | |
11 # individuals. For the exact contribution history, see the revision | |
12 # history and logs, available at http://babel.edgewall.org/log/. | |
13 | |
14 """Various utility classes and functions.""" | |
15 | |
164
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
16 import codecs |
30 | 17 from datetime import timedelta, tzinfo |
1 | 18 import os |
164
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
19 import parser |
1 | 20 import re |
95
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
21 import time |
1 | 22 |
97 | 23 __all__ = ['pathmatch', 'relpath', 'UTC', 'LOCALTZ'] |
1 | 24 __docformat__ = 'restructuredtext en' |
25 | |
164
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
26 # Regexp to match python magic encoding line |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
27 PYTHON_MAGIC_COMMENT_re = re.compile( |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
28 r'[ \t\f]* \# .* coding[=:][ \t]*([-\w.]+)', re.VERBOSE) |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
29 def parse_encoding(fp): |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
30 """Deduce the encoding of a source file from magic comment. |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
31 |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
32 It does this in the same way as the `Python interpreter`__ |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
33 |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
34 .. __: http://docs.python.org/ref/encodings.html |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
35 |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
36 The ``fp`` argument should be a seekable file object. |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
37 |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
38 (From Jeff Dairiki) |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
39 """ |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
40 pos = fp.tell() |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
41 fp.seek(0) |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
42 try: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
43 line1 = fp.readline() |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
44 has_bom = line1.startswith(codecs.BOM_UTF8) |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
45 if has_bom: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
46 line1 = line1[len(codecs.BOM_UTF8):] |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
47 |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
48 m = PYTHON_MAGIC_COMMENT_re.match(line1) |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
49 if not m: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
50 try: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
51 parser.suite(line1) |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
52 except SyntaxError: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
53 # Either it's a real syntax error, in which case the source is |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
54 # not valid python source, or line2 is a continuation of line1, |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
55 # in which case we don't want to scan line2 for a magic |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
56 # comment. |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
57 pass |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
58 else: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
59 line2 = fp.readline() |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
60 m = PYTHON_MAGIC_COMMENT_re.match(line2) |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
61 |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
62 if has_bom: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
63 if m: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
64 raise SyntaxError( |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
65 "python refuses to compile code with both a UTF8 " |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
66 "byte-order-mark and a magic encoding comment") |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
67 return 'utf_8' |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
68 elif m: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
69 return m.group(1) |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
70 else: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
71 return None |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
72 finally: |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
73 fp.seek(pos) |
84a9e5f97658
made the python extractor detect source file encodings from the magic encoding
pjenvey
parents:
163
diff
changeset
|
74 |
44 | 75 def pathmatch(pattern, filename): |
76 """Extended pathname pattern matching. | |
1 | 77 |
44 | 78 This function is similar to what is provided by the ``fnmatch`` module in |
79 the Python standard library, but: | |
80 | |
81 * can match complete (relative or absolute) path names, and not just file | |
82 names, and | |
83 * also supports a convenience pattern ("**") to match files at any | |
84 directory level. | |
85 | |
86 Examples: | |
87 | |
88 >>> pathmatch('**.py', 'bar.py') | |
89 True | |
90 >>> pathmatch('**.py', 'foo/bar/baz.py') | |
91 True | |
92 >>> pathmatch('**.py', 'templates/index.html') | |
93 False | |
47
76381d4b3635
Support passing extraction method mapping and options from the frontends (see #4). No distutils/setuptools keyword supported yet, but the rest seems to be working okay.
cmlenz
parents:
44
diff
changeset
|
94 |
44 | 95 >>> pathmatch('**/templates/*.html', 'templates/index.html') |
96 True | |
97 >>> pathmatch('**/templates/*.html', 'templates/foo/bar.html') | |
98 False | |
1 | 99 |
100 :param pattern: the glob pattern | |
44 | 101 :param filename: the path name of the file to match against |
102 :return: `True` if the path name matches the pattern, `False` otherwise | |
103 :rtype: `bool` | |
1 | 104 """ |
105 symbols = { | |
106 '?': '[^/]', | |
107 '?/': '[^/]/', | |
108 '*': '[^/]+', | |
109 '*/': '[^/]+/', | |
110 '**/': '(?:.+/)*?', | |
44 | 111 '**': '(?:.+/)*?[^/]+', |
1 | 112 } |
113 buf = [] | |
114 for idx, part in enumerate(re.split('([?*]+/?)', pattern)): | |
115 if idx % 2: | |
116 buf.append(symbols[part]) | |
117 elif part: | |
118 buf.append(re.escape(part)) | |
134 | 119 match = re.match(''.join(buf) + '$', filename.replace(os.sep, '/')) |
120 return match is not None | |
1 | 121 |
29 | 122 |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
123 class odict(dict): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
124 """Ordered dict implementation. |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
125 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
126 :see: `http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747` |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
127 """ |
62
84d400066b71
The order of extraction methods is now preserved (see #10).
cmlenz
parents:
60
diff
changeset
|
128 def __init__(self, data=None): |
84d400066b71
The order of extraction methods is now preserved (see #10).
cmlenz
parents:
60
diff
changeset
|
129 dict.__init__(self, data or {}) |
163
f2c78a271159
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
134
diff
changeset
|
130 self._keys = dict.keys(self) |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
131 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
132 def __delitem__(self, key): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
133 dict.__delitem__(self, key) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
134 self._keys.remove(key) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
135 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
136 def __setitem__(self, key, item): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
137 dict.__setitem__(self, key, item) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
138 if key not in self._keys: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
139 self._keys.append(key) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
140 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
141 def __iter__(self): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
142 return iter(self._keys) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
143 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
144 def clear(self): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
145 dict.clear(self) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
146 self._keys = [] |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
147 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
148 def copy(self): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
149 d = odict() |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
150 d.update(self) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
151 return d |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
152 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
153 def items(self): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
154 return zip(self._keys, self.values()) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
155 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
156 def keys(self): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
157 return self._keys[:] |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
158 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
159 def setdefault(self, key, failobj = None): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
160 dict.setdefault(self, key, failobj) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
161 if key not in self._keys: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
162 self._keys.append(key) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
163 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
164 def update(self, dict): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
165 for (key, val) in dict.items(): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
166 self[key] = val |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
167 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
168 def values(self): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
169 return map(self.get, self._keys) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
170 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
47
diff
changeset
|
171 |
1 | 172 try: |
173 relpath = os.path.relpath | |
174 except AttributeError: | |
175 def relpath(path, start='.'): | |
29 | 176 """Compute the relative path to one path from another. |
177 | |
130 | 178 >>> relpath('foo/bar.txt', '').replace(os.sep, '/') |
44 | 179 'foo/bar.txt' |
130 | 180 >>> relpath('foo/bar.txt', 'foo').replace(os.sep, '/') |
44 | 181 'bar.txt' |
130 | 182 >>> relpath('foo/bar.txt', 'baz').replace(os.sep, '/') |
44 | 183 '../foo/bar.txt' |
184 | |
29 | 185 :return: the relative path |
186 :rtype: `basestring` | |
187 """ | |
1 | 188 start_list = os.path.abspath(start).split(os.sep) |
189 path_list = os.path.abspath(path).split(os.sep) | |
190 | |
191 # Work out how much of the filepath is shared by start and path. | |
192 i = len(os.path.commonprefix([start_list, path_list])) | |
193 | |
194 rel_list = [os.path.pardir] * (len(start_list) - i) + path_list[i:] | |
195 return os.path.join(*rel_list) | |
29 | 196 |
106
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
197 ZERO = timedelta(0) |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
198 |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
199 |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
200 class FixedOffsetTimezone(tzinfo): |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
201 """Fixed offset in minutes east from UTC.""" |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
202 |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
203 def __init__(self, offset, name=None): |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
204 self._offset = timedelta(minutes=offset) |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
205 if name is None: |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
206 name = 'Etc/GMT+%d' % offset |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
207 self.zone = name |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
208 |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
209 def __str__(self): |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
210 return self.zone |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
211 |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
212 def __repr__(self): |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
213 return '<FixedOffset "%s" %s>' % (self.zone, self._offset) |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
214 |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
215 def utcoffset(self, dt): |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
216 return self._offset |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
217 |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
218 def tzname(self, dt): |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
219 return self.zone |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
220 |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
221 def dst(self, dt): |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
222 return ZERO |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
223 |
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
224 |
29 | 225 try: |
226 from pytz import UTC | |
227 except ImportError: | |
106
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
228 UTC = FixedOffsetTimezone(0, 'UTC') |
29 | 229 """`tzinfo` object for UTC (Universal Time). |
230 | |
231 :type: `tzinfo` | |
232 """ | |
95
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
233 |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
234 STDOFFSET = timedelta(seconds = -time.timezone) |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
235 if time.daylight: |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
236 DSTOFFSET = timedelta(seconds = -time.altzone) |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
237 else: |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
238 DSTOFFSET = STDOFFSET |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
239 |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
240 DSTDIFF = DSTOFFSET - STDOFFSET |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
241 |
106
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
242 |
95
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
243 class LocalTimezone(tzinfo): |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
244 |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
245 def utcoffset(self, dt): |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
246 if self._isdst(dt): |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
247 return DSTOFFSET |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
248 else: |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
249 return STDOFFSET |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
250 |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
251 def dst(self, dt): |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
252 if self._isdst(dt): |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
253 return DSTDIFF |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
254 else: |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
255 return ZERO |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
256 |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
257 def tzname(self, dt): |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
258 return time.tzname[self._isdst(dt)] |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
259 |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
260 def _isdst(self, dt): |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
261 tt = (dt.year, dt.month, dt.day, |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
262 dt.hour, dt.minute, dt.second, |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
263 dt.weekday(), 0, -1) |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
264 stamp = time.mktime(tt) |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
265 tt = time.localtime(stamp) |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
266 return tt.tm_isdst > 0 |
008cd3f7d485
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
62
diff
changeset
|
267 |
106
9b22b36066f6
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
97
diff
changeset
|
268 |
97 | 269 LOCALTZ = LocalTimezone() |
270 """`tzinfo` object for local time-zone. | |
271 | |
272 :type: `tzinfo` | |
273 """ |