def setUp(self): # Add a new entry for testing purposes. It's a template one. self.translation_import_queue = getUtility(ITranslationImportQueue) template_path = 'po/testing.pot' by_maintainer = True personset = getUtility(IPersonSet) importer = personset.getByName('carlos') productset = getUtility(IProductSet) firefox = productset.getByName('firefox') productseries = firefox.getSeries('trunk') template_entry = self.translation_import_queue.addOrUpdateEntry( template_path, test_template, by_maintainer, importer, productseries=productseries) # Add another one, a translation file. pofile_path = 'po/es.po' translation_entry = self.translation_import_queue.addOrUpdateEntry( pofile_path, test_translation_file, by_maintainer, importer, productseries=productseries) transaction.commit() self.template_importer = GettextPOImporter() self.template_file = self.template_importer.parse(template_entry) self.translation_importer = GettextPOImporter() self.translation_file = self.translation_importer.parse( translation_entry)
class GettextPOImporterTestCase(unittest.TestCase): """Class test for gettext's .po file imports""" layer = LaunchpadZopelessLayer def setUp(self): # Add a new entry for testing purposes. It's a template one. self.translation_import_queue = getUtility(ITranslationImportQueue) template_path = 'po/testing.pot' by_maintainer = True personset = getUtility(IPersonSet) importer = personset.getByName('carlos') productset = getUtility(IProductSet) firefox = productset.getByName('firefox') productseries = firefox.getSeries('trunk') template_entry = self.translation_import_queue.addOrUpdateEntry( template_path, test_template, by_maintainer, importer, productseries=productseries) # Add another one, a translation file. pofile_path = 'po/es.po' translation_entry = self.translation_import_queue.addOrUpdateEntry( pofile_path, test_translation_file, by_maintainer, importer, productseries=productseries) transaction.commit() self.template_importer = GettextPOImporter() self.template_file = self.template_importer.parse(template_entry) self.translation_importer = GettextPOImporter() self.translation_file = self.translation_importer.parse( translation_entry) def testInterface(self): """Check whether the object follows the interface.""" self.failUnless( verifyObject(ITranslationFormatImporter, self.template_importer), "GettextPOImporter doesn't conform to ITranslationFormatImporter" "interface.") def testFormat(self): # GettextPOImporter reports that it handles the PO file format. format = self.template_importer.getFormat(test_template) self.failUnless( format == TranslationFileFormat.PO, 'GettextPOImporter format expected PO but got %s' % format.name)
def parse(self, translation_import_queue_entry): """See `ITranslationFormatImporter`.""" translation_file = GettextPOImporter.parse( self, translation_import_queue_entry) plural_prefix = u'_n: ' context_prefix = u'_: ' for message in translation_file.messages: msgid = message.msgid_singular if msgid.startswith(plural_prefix) and '\n' in msgid: # This is a KDE plural form singular, plural = msgid[len(plural_prefix):].split('\n') message.msgid_singular = singular message.msgid_plural = plural msgstrs = message._translations if len(msgstrs) > 0: message._translations = msgstrs[0].split('\n') self.internal_format = TranslationFileFormat.KDEPO elif msgid.startswith(context_prefix) and '\n' in msgid: # This is a KDE context message message.context, message.msgid_singular = ( msgid[len(context_prefix):].split('\n', 1)) self.internal_format = TranslationFileFormat.KDEPO else: # Other messages are left as they are parsed by # GettextPOImporter pass return translation_file
def _createPOTFileImporter(self, pot_content, by_maintainer): """Create queue entries from POT content string. Create an importer from the entry.""" potemplate = self.factory.makePOTemplate() template_entry = self.translation_import_queue.addOrUpdateEntry( potemplate.path, pot_content, by_maintainer, self.importer_person, productseries=potemplate.productseries, potemplate=potemplate) self.fake_librarian.pretendCommit() return POTFileImporter(template_entry, GettextPOImporter(), None)
def testKDEPriorityIsHigherThanPOPriority(self): """Check if KdePOImporter has precedence over GettextPOImporter.""" # For import queue to properly recognise KDEPO files which are # otherwise just regular PO files, KdePOImporter has to have higher # priority over GettextPOImporter gettext_importer = GettextPOImporter() self.failUnless( self.template_importer.priority > gettext_importer.priority, 'KdePOImporter priority is not higher than priority of ' 'GettextPOImporter')
def _createFileImporter(self): """Create just an (incomplete) FileImporter for basic tests. The importer is based on a template. These tests don't care about Imported or Upstream.""" potemplate = self.factory.makePOTemplate() template_entry = self.translation_import_queue.addOrUpdateEntry( potemplate.path, TEST_TEMPLATE_EXPORTED, False, self.importer_person, productseries=potemplate.productseries, potemplate=potemplate) self.fake_librarian.pretendCommit() return FileImporter(template_entry, GettextPOImporter(), None)
def _createPOFileImporter(self, pot_importer, po_content, by_maintainer, existing_pofile=None, person=None): """Create a PO entry from content, relating to a template_entry. Create an importer for the entry.""" potemplate = pot_importer.translation_import_queue_entry.potemplate if existing_pofile == None: pofile = self.factory.makePOFile( TEST_LANGUAGE, potemplate=potemplate) else: pofile = existing_pofile person = person or self.importer_person translation_entry = self.translation_import_queue.addOrUpdateEntry( pofile.path, po_content, by_maintainer, person, productseries=potemplate.productseries, pofile=pofile) self.fake_librarian.pretendCommit() return POFileImporter(translation_entry, GettextPOImporter(), None)
def test_old_upstream_upload_not_changes_header(self): queue_entry = self._make_queue_entry(True) pofile = queue_entry.pofile old_raw_header = pofile.header POFileImporter(queue_entry, GettextPOImporter(), None) self.assertEqual(old_raw_header, pofile.header)
def test_not_raises_OutdatedTranslationError_on_upstream_uploads(self): queue_entry = self._make_queue_entry(True) try: POFileImporter(queue_entry, GettextPOImporter(), None) except OutdatedTranslationError: self.fail("OutdatedTranslationError raised.")
def test_raises_OutdatedTranslationError_on_user_uploads(self): queue_entry = self._make_queue_entry(False) self.assertRaises( OutdatedTranslationError, POFileImporter, queue_entry, GettextPOImporter(), None)
from lp.translations.interfaces.translations import TranslationConstants from lp.translations.utilities.gettext_po_importer import GettextPOImporter from lp.translations.utilities.kde_po_importer import KdePOImporter from lp.translations.utilities.mozilla_xpi_importer import MozillaXpiImporter from lp.translations.utilities.sanitize import ( sanitize_translations_from_import, ) from lp.translations.utilities.translation_common_format import ( TranslationMessageData, ) from lp.translations.utilities.validate import ( GettextValidationError, validate_translation, ) importers = { TranslationFileFormat.KDEPO: KdePOImporter(), TranslationFileFormat.PO: GettextPOImporter(), TranslationFileFormat.XPI: MozillaXpiImporter(), } def is_identical_translation(existing_msg, new_msg): """Is a new translation substantially the same as the existing one? Compares msgid and msgid_plural, and all translations. :param existing_msg: a `TranslationMessageData` representing a translation message currently kept in the database. :param new_msg: an alternative `TranslationMessageData` translating the same original message. :return: True if the new message is effectively identical to the existing one, or False if replacing existing_msg with new_msg