annotate roundup/cgi/TAL/talgettext.py @ 8575:b1024bf0d9f7

feature: add nonceless/tokenless CSRF protection Add tokenless CSRF protection following: https://words.filippo.io/csrf/ Must be enabled using use_tokenless_csrf_protection in config.ini. By default it's off. If enabled the older csrf_* settings are ignored. The allowed_api_origins setting is still used for Origin comparisons. This should also improve performance as a nonce isn't required so generating random nonce and saving it to the otks database is eliminated. doc/admin_guide.txt, doc/reference.txt doc/upgrading.txt doc updates. roundup/configuration.py add use_tokenless_csrf_protection setting. move allowed_api_origins directly after use_tokenless_csrf_protection and before the older csrf_* settings. It's used by both of them. Rewrite description of allowed_api_origins as its applied to all URLs with tokenless protection, not just API URLs. roundup/anypy/urllib_.py import urlsplit, it is used in new code. urlparse() is less efficient and splits params out of the path component. Since Roundup doesn't require that params be split from the path. I expect future patch will replace urlparse() with urlsplit() globally and not need urlparse(). roundup/cgi/client.py add handle_csrf_tokenless() and call from handle_csrf() if use_tokenless_csrf_protection is enabled. refactor code that expires csrf tokens when used with the wrong methods (i.e. GET) into expire_exposed_keys(). Call same from handle_csrf and handle_csrf_tokenless. Also improve logging if this happens including both Referer and Origin headers if available. Arguably we dont care about CSRF tokens exposed via GET/HEAD/OPTIONS in the tokenless case, but this cleans them up in case the admin has to switch back. At some future date we can delete all the nonce based CSRF from 2018. Update handle_csrf() docstring about calling/returning handle_csrf_tokenless() when enabled. Call expire_exposed_keys(method) if token is supplied with wrong method. roundup/cgi/templating.py disable nonce generation/save and always return "0" when use_tokenless_csrf_protection enabled.
author John Rouillard <rouilj@ieee.org>
date Sun, 19 Apr 2026 20:50:07 -0400
parents 9c3ec0a5c7fc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
1 #!/usr/bin/env python
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
2 ##############################################################################
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
3 #
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
4 # Copyright (c) 2002 Zope Corporation and Contributors.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
5 # All Rights Reserved.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
6 #
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
7 # This software is subject to the provisions of the Zope Public License,
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
8 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
9 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
10 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
11 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
12 # FOR A PARTICULAR PURPOSE.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
13 #
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
14 ##############################################################################
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
15 # Modifications for Roundup:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
16 # 1. commented out ITALES references
2385
85cbfc4a5946 escape newlines
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2382
diff changeset
17 # 2. escape quotes and line feeds in msgids
2802
e816a232f988 don't collect empty msgids
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2385
diff changeset
18 # 3. don't collect empty msgids
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
19
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
20 """Program to extract internationalization markup from Page Templates.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
21
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
22 Once you have marked up a Page Template file with i18n: namespace tags, use
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
23 this program to extract GNU gettext .po file entries.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
24
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
25 Usage: talgettext.py [options] files
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
26 Options:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
27 -h / --help
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
28 Print this message and exit.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
29 -o / --output <file>
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
30 Output the translation .po file to <file>.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
31 -u / --update <file>
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
32 Update the existing translation <file> with any new translation strings
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
33 found.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
34 """
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
35
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
36 import sys
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
37 import time
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
38 import getopt
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
39 import traceback
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
40
4572
3a407f0d5dad Add import for version info
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4570
diff changeset
41 from roundup import __version__
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
42 from roundup.cgi.TAL.HTMLTALParser import HTMLTALParser
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
43 from roundup.cgi.TAL.TALInterpreter import TALInterpreter
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
44 from roundup.cgi.TAL.DummyEngine import DummyEngine
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
45 #from ITALES import ITALESEngine
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
46 from roundup.cgi.TAL.TALDefs import TALESError
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
47
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
48 pot_header = '''\
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
49 # SOME DESCRIPTIVE TITLE.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
50 # Copyright (C) YEAR ORGANIZATION
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
51 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
52 #
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
53 msgid ""
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
54 msgstr ""
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
55 "Project-Id-Version: PACKAGE VERSION\\n"
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
56 "POT-Creation-Date: %(time)s\\n"
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
57 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
58 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
59 "Language-Team: LANGUAGE <LL@li.org>\\n"
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
60 "MIME-Version: 1.0\\n"
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
61 "Content-Type: text/plain; charset=CHARSET\\n"
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
62 "Content-Transfer-Encoding: ENCODING\\n"
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
63 "Generated-By: talgettext.py %(version)s\\n"
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
64 '''
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
65
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
66 NLSTR = '"\n"'
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
67
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
68 def usage(code, msg=''):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
69 # Python 2.1 required
5376
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
70 print(__doc__, file=sys.stderr)
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
71 if msg:
5376
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
72 print(msg, file=sys.stderr)
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
73 sys.exit(code)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
74
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
75
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
76 class POTALInterpreter(TALInterpreter):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
77 def translate(self, msgid, default, i18ndict=None, obj=None):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
78 # XXX is this right?
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
79 if i18ndict is None:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
80 i18ndict = {}
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
81 if obj:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
82 i18ndict.update(obj)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
83 # XXX Mmmh, it seems that sometimes the msgid is None; is that really
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
84 # possible?
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
85 if msgid is None:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
86 return None
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
87 # XXX We need to pass in one of context or target_language
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
88 return self.engine.translate(msgid, self.i18nContext.domain, i18ndict,
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
89 position=self.position, default=default)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
90
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
91
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
92 class POEngine(DummyEngine):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
93 #__implements__ = ITALESEngine
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
94
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
95 def __init__(self, macros=None):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
96 self.catalog = {}
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
97 DummyEngine.__init__(self, macros)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
98
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
99 def evaluate(*args):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
100 return '' # who cares
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
101
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
102 def evaluatePathOrVar(*args):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
103 return '' # who cares
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
104
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
105 def evaluateSequence(self, expr):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
106 return (0,) # dummy
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
107
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
108 def evaluateBoolean(self, expr):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
109 return True # dummy
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
110
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
111 def translate(self, msgid, domain=None, mapping=None, default=None,
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
112 # XXX position is not part of the ITALESEngine
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
113 # interface
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
114 position=None):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
115
2802
e816a232f988 don't collect empty msgids
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2385
diff changeset
116 if not msgid: return 'x'
e816a232f988 don't collect empty msgids
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2385
diff changeset
117
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
118 if domain not in self.catalog:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
119 self.catalog[domain] = {}
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
120 domain = self.catalog[domain]
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
121
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
122 if msgid not in domain:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
123 domain[msgid] = []
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
124 domain[msgid].append((self.file, position))
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
125 return 'x'
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
126
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
127
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
128 class UpdatePOEngine(POEngine):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
129 """A slightly-less braindead POEngine which supports loading an existing
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
130 .po file first."""
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
131
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
132 def __init__ (self, macros=None, filename=None):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
133 POEngine.__init__(self, macros)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
134
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
135 self._filename = filename
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
136 self._loadFile()
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
137 self.base = self.catalog
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
138 self.catalog = {}
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
139
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
140 def __add(self, id, s, fuzzy):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
141 "Add a non-fuzzy translation to the dictionary."
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
142 if not fuzzy and str:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
143 # check for multi-line values and munge them appropriately
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
144 if '\n' in s:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
145 lines = s.rstrip().split('\n')
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
146 s = NLSTR.join(lines)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
147 self.catalog[id] = s
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
148
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
149 def _loadFile(self):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
150 # shamelessly cribbed from Python's Tools/i18n/msgfmt.py
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
151 # 25-Mar-2003 Nathan R. Yergler (nathan@zope.org)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
152 # 14-Apr-2003 Hacked by Barry Warsaw (barry@zope.com)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
153
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
154 ID = 1
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
155 STR = 2
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
156
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
157 try:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
158 lines = open(self._filename).readlines()
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 4572
diff changeset
159 except IOError as msg:
5376
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
160 print(msg, file=sys.stderr)
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
161 sys.exit(1)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
162
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
163 section = None
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
164 fuzzy = False
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
165
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
166 # Parse the catalog
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
167 lno = 0
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
168 for l in lines:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
169 lno += True
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
170 # If we get a comment line after a msgstr, this is a new entry
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
171 if l[0] == '#' and section == STR:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
172 self.__add(msgid, msgstr, fuzzy)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
173 section = None
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
174 fuzzy = False
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
175 # Record a fuzzy mark
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
176 if l[:2] == '#,' and l.find('fuzzy'):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
177 fuzzy = True
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
178 # Skip comments
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
179 if l[0] == '#':
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
180 continue
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
181 # Now we are in a msgid section, output previous section
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
182 if l.startswith('msgid'):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
183 if section == STR:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
184 self.__add(msgid, msgstr, fuzzy)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
185 section = ID
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
186 l = l[5:]
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
187 msgid = msgstr = ''
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
188 # Now we are in a msgstr section
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
189 elif l.startswith('msgstr'):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
190 section = STR
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
191 l = l[6:]
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
192 # Skip empty lines
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
193 if not l.strip():
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
194 continue
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
195 # XXX: Does this always follow Python escape semantics?
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
196 l = eval(l)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
197 if section == ID:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
198 msgid += l
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
199 elif section == STR:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
200 msgstr += '%s\n' % l
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
201 else:
5376
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
202 print('Syntax error on %s:%d' % (infile, lno),
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
203 'before:', file=sys.stderr)
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
204 print(l, file=sys.stderr)
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
205 sys.exit(1)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
206 # Add last entry
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
207 if section == STR:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
208 self.__add(msgid, msgstr, fuzzy)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
209
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
210 def evaluate(self, expression):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
211 try:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
212 return POEngine.evaluate(self, expression)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
213 except TALESError:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
214 pass
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
215
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
216 def evaluatePathOrVar(self, expr):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
217 return 'who cares'
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
218
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
219 def translate(self, msgid, domain=None, mapping=None, default=None,
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
220 position=None):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
221 if msgid not in self.base:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
222 POEngine.translate(self, msgid, domain, mapping, default, position)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
223 return 'x'
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
224
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
225
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
226 def main():
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
227 try:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
228 opts, args = getopt.getopt(
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
229 sys.argv[1:],
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
230 'ho:u:',
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
231 ['help', 'output=', 'update='])
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 4572
diff changeset
232 except getopt.error as msg:
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
233 usage(1, msg)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
234
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
235 outfile = None
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
236 engine = None
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
237 update_mode = False
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
238 for opt, arg in opts:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
239 if opt in ('-h', '--help'):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
240 usage(0)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
241 elif opt in ('-o', '--output'):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
242 outfile = arg
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
243 elif opt in ('-u', '--update'):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
244 update_mode = True
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
245 if outfile is None:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
246 outfile = arg
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
247 engine = UpdatePOEngine(filename=arg)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
248
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
249 if not args:
5376
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
250 print('nothing to do')
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
251 return
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
252
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
253 # We don't care about the rendered output of the .pt file
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
254 class Devnull:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
255 def write(self, s):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
256 pass
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
257
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
258 # check if we've already instantiated an engine;
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
259 # if not, use the stupidest one available
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
260 if not engine:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
261 engine = POEngine()
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
262
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
263 # process each file specified
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
264 for filename in args:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
265 try:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
266 engine.file = filename
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
267 p = HTMLTALParser()
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
268 p.parseFile(filename)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
269 program, macros = p.getCode()
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
270 POTALInterpreter(program, macros, engine, stream=Devnull(),
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
271 metal=False)()
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
272 except: # Hee hee, I love bare excepts!
5376
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
273 print('There was an error processing', filename)
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
274 traceback.print_exc()
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
275
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
276 # Now output the keys in the engine. Write them to a file if --output or
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
277 # --update was specified; otherwise use standard out.
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
278 if (outfile is None):
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
279 outfile = sys.stdout
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
280 else:
5383
6fbb7d52e38f Python 3 preparation: use open() instead of file().
Joseph Myers <jsm@polyomino.org.uk>
parents: 5376
diff changeset
281 outfile = open(outfile, update_mode and "a" or "w")
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
282
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
283 catalog = {}
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
284 for domain in engine.catalog.keys():
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
285 catalog.update(engine.catalog[domain])
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
286
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
287 messages = catalog.copy()
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
288 try:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
289 messages.update(engine.base)
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
290 except AttributeError:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
291 pass
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
292 if '' not in messages:
5376
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
293 print(pot_header % {'time': time.ctime(),
64b05e24dbd8 Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
294 'version': __version__}, file=outfile)
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
295
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
296 # XXX: You should not sort by msgid, but by filename and position. (SR)
5395
23b8e6067f7c Python 3 preparation: update calls to dict methods.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5383
diff changeset
297 msgids = sorted(catalog.keys())
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
298 for msgid in msgids:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
299 positions = catalog[msgid]
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
300 for filename, position in positions:
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
301 outfile.write('#: %s:%s\n' % (filename, position[0]))
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
302
2385
85cbfc4a5946 escape newlines
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2382
diff changeset
303 outfile.write('msgid "%s"\n'
85cbfc4a5946 escape newlines
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2382
diff changeset
304 % msgid.replace('"', '\\"').replace("\n", '\\n"\n"'))
2352
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
305 outfile.write('msgstr ""\n')
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
306 outfile.write('\n')
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
307
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
308
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
309 if __name__ == '__main__':
0d302e93abd3 make unix
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
310 main()

Roundup Issue Tracker: http://roundup-tracker.org/