The `Catalog` class now also includes an extra attribute, '''`fuzzy`''', which is the fuzzy bit of the catalog header.
The above change allows the `compile_catalog` frontends to only compile catalogs '''not''' marked as fuzzy, unless `--use-fuzzy` is passed.
Added tests to check header fuzzy bit parsing.
self.user_comments = list(user_comments)
def __repr__(self):
- return '<%s %r>' % (type(self).__name__, self.id)
+ return '<%s %r (Flags: %r)>' % (type(self).__name__, self.id,
+ ', '.join([flag for flag in self.flags]))
def fuzzy(self):
return 'fuzzy' in self.flags
>>> Message('foo').fuzzy
False
- >>> Message('foo', 'foo', flags=['fuzzy']).fuzzy
+ >>> msg = Message('foo', 'foo', flags=['fuzzy'])
+ >>> msg.fuzzy
True
+ >>> msg
+ <Message 'foo' (Flags: 'fuzzy')>
:type: `bool`
""")
def __init__(self, locale=None, domain=None, header_comment=DEFAULT_HEADER,
project=None, version=None, copyright_holder=None,
msgid_bugs_address=None, creation_date=None,
- revision_date=None, last_translator=None, charset='utf-8'):
+ revision_date=None, last_translator=None, charset='utf-8',
+ fuzzy=True):
"""Initialize the catalog object.
:param locale: the locale identifier or `Locale` object, or `None`
:param revision_date: the date the catalog was revised
:param last_translator: the name and email of the last translator
:param charset: the encoding to use in the output
+ :param fuzzy: the fuzzy bit on the catalog header
"""
self.domain = domain #: The message domain
if locale:
elif isinstance(revision_date, datetime) and not revision_date.tzinfo:
revision_date = revision_date.replace(tzinfo=LOCALTZ)
self.revision_date = revision_date #: Last revision date of the catalog
+ self.fuzzy = fuzzy #: Catalog Header fuzzy bit(True or False)
def _get_header_comment(self):
comment = self._header_comment
buf = []
for name, value in self.mime_headers:
buf.append('%s: %s' % (name, value))
- yield Message('', '\n'.join(buf), flags=set(['fuzzy']))
+ if self.fuzzy:
+ flags = set(['fuzzy'])
+ else:
+ flags = set()
+ yield Message('', '\n'.join(buf), flags=flags)
for key in self._messages:
yield self._messages[key]
>>> catalog = Catalog()
>>> catalog[u'foo'] = Message(u'foo')
>>> catalog[u'foo']
- <Message u'foo'>
+ <Message u'foo' (Flags: '')>
If a message with that ID is already in the catalog, it is updated
to include the locations and flags of the new message.
>>> catalog = Catalog()
>>> catalog.add(u'foo')
>>> catalog[u'foo']
- <Message u'foo'>
+ <Message u'foo' (Flags: '')>
This method simply constructs a `Message` object with the given
arguments and invokes `__setitem__` with that object.
>>> 'head' in catalog
False
>>> rest
- [<Message 'head'>]
+ [<Message 'head' (Flags: '')>]
:param template: the reference catalog, usually read from a POT file
:param fuzzy_matching: whether to use fuzzy matching of message IDs
po_path = os.path.join(self.directory, locale,
'LC_MESSAGES', self.domain + '.po')
if os.path.exists(po_path):
- self._available_pos.append(po_path)
+ self._available_pos.append((locale, po_path))
else:
raise DistutilsOptionError('you must specify the locale for the'
' catalog to compile')
if not self.directory and not self.input_file:
raise DistutilsOptionError('you must specify the input file')
- if not self.input_file:
+ if not self.input_file and not self.compile_all:
self.input_file = os.path.join(self.directory, self.locale,
'LC_MESSAGES', self.domain + '.po')
def run(self):
if self.compile_all:
- for po in self._available_pos:
- log.info('compiling catalog to %s', po.replace('.po', '.mo'))
-
+ for locale, po in self._available_pos:
+ loc_name = Locale.parse(locale).english_name
infile = open(po, 'r')
try:
catalog = read_po(infile)
finally:
infile.close()
-
+ if catalog.fuzzy and not self.use_fuzzy:
+ log.error('%s catalog %r is marked as fuzzy, not compiling'
+ ' it', loc_name, po)
+ continue
+
+ log.info('compiling %s catalog to %s',
+ loc_name,
+ po.replace('.po', '.mo'))
+
outfile = open(po.replace('.po', '.mo'), 'w')
try:
write_mo(outfile, catalog, use_fuzzy=self.use_fuzzy)
finally:
outfile.close()
else:
- log.info('compiling catalog to %s', self.output_file)
-
infile = open(self.input_file, 'r')
try:
catalog = read_po(infile)
finally:
infile.close()
-
+ if catalog.fuzzy:
+ log.error('catalog is marked as fuzzy, not compiling it')
+ sys.exit(0)
+
+ log.info('compiling catalog to %s', self.output_file)
outfile = open(self.output_file, 'w')
try:
write_mo(outfile, catalog, use_fuzzy=self.use_fuzzy)
'LC_MESSAGES',
options.domain + '.po')
if os.path.exists(po_path):
- available_pos.append(po_path)
+ available_pos.append((locale, po_path))
else:
parser.error('you must provide a locale for the new catalog')
else:
if not options.directory and not options.input_file:
parser.error('you must specify the base directory or input file')
- if not options.input_file:
+ if not options.input_file and not options.compile_all:
options.input_file = os.path.join(options.directory,
options.locale, 'LC_MESSAGES',
options.domain + '.po')
catalog = read_po(infile)
finally:
infile.close()
+
+ if catalog.fuzzy and not options.use_fuzzy:
+ print 'catalog is marked as fuzzy, not compiling it'
+ sys.exit(0)
print 'compiling catalog to %r' % options.output_file
finally:
outfile.close()
else:
- for po in available_pos:
+ for locale, po in available_pos:
+ loc_name = Locale.parse(locale).english_name
infile = open(po, 'r')
try:
catalog = read_po(infile)
finally:
infile.close()
-
- print 'compiling catalog to %r' % po.replace('.po', '.mo')
+
+ if catalog.fuzzy:
+ print '%s catalog %r is marked as fuzzy, not compiling it' \
+ % (loc_name, po)
+ continue
+
+ print 'compiling %s catalog to %r' % (loc_name,
+ po.replace('.po', '.mo'))
outfile = open(po.replace('.po', '.mo'), 'w')
try:
user_comments = []
auto_comments = []
in_msgid = in_msgstr = False
+ fuzzy_header = False
+ in_header = True
def _add_message():
translations.sort()
locations.append((filename, int(lineno)))
elif line[1:].startswith(','):
for flag in line[2:].lstrip().split(','):
+ if in_header:
+ if flag.strip() == 'fuzzy':
+ fuzzy_header = True
flags.append(flag.strip())
+
+
elif line[1:].startswith('.'):
# These are called auto-comments
comment = line[2:].strip()
messages.append(msg)
elif line.startswith('msgid'):
in_msgid = True
+ txt = line[5:].lstrip()
+ if txt == '""':
+ in_header = True
if messages:
_add_message()
- messages.append(line[5:].lstrip())
+ messages.append(txt)
elif line.startswith('msgstr'):
in_msgid = False
in_msgstr = True
translations.append([0, msg])
elif line.startswith('"'):
if in_msgid:
+ in_header = False
messages[-1] += u'\n' + line.rstrip()
elif in_msgstr:
translations[-1][1] += u'\n' + line.rstrip()
if messages:
_add_message()
+
+ catalog.fuzzy = fuzzy_header
return catalog
WORD_SEP = re.compile('('
self.assertEqual("Here's some text that\nincludesareallylongwordthat"
"mightbutshouldnt throw us into an infinite loop\n",
message.id)
+
+ def test_fuzzy_header(self):
+ buf = StringIO(r'''\
+# Translations template for AReallyReallyLongNameForAProject.
+# Copyright (C) 2007 ORGANIZATION
+# This file is distributed under the same license as the
+# AReallyReallyLongNameForAProject project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
+#
+#, fuzzy
+''')
+ catalog = pofile.read_po(buf)
+ self.assertEqual(1, len(list(catalog)))
+ self.assertEqual(True, list(catalog)[0].fuzzy)
+
+ def test_not_fuzzy_header(self):
+ buf = StringIO(r'''\
+# Translations template for AReallyReallyLongNameForAProject.
+# Copyright (C) 2007 ORGANIZATION
+# This file is distributed under the same license as the
+# AReallyReallyLongNameForAProject project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
+#
+''')
+ catalog = pofile.read_po(buf)
+ self.assertEqual(1, len(list(catalog)))
+ self.assertEqual(False, list(catalog)[0].fuzzy)
class WritePoTestCase(unittest.TestCase):