← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jtv/launchpad/pre-675426 into lp:launchpad/devel

 

Jeroen T. Vermeulen has proposed merging lp:~jtv/launchpad/pre-675426 into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers): code


= Remove dead Translations code =

This gets rid of some dead, untested, obsolete Translations script code that we're only carrying around out of historical interest.  We have bzr for historical interests.


Jeroen
-- 
https://code.launchpad.net/~jtv/launchpad/pre-675426/+merge/40953
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/launchpad/pre-675426 into lp:launchpad/devel.
=== modified file 'lib/lp/services/scripts/tests/__init__.py'
--- lib/lp/services/scripts/tests/__init__.py	2010-08-20 20:31:18 +0000
+++ lib/lp/services/scripts/tests/__init__.py	2010-11-16 13:00:24 +0000
@@ -30,7 +30,6 @@
     'scripts/clean-sourceforge-project-entries.py',
     'scripts/import-zope-specs.py',
     'scripts/rosetta/gettext_check_messages.py',
-    'scripts/rosetta/remove-obsolete-translations.py',
     # sqlobject.DatbaseIndex ?
     'scripts/linkreport.py',
     # Python executable without '.py' extension.
@@ -38,7 +37,6 @@
     'scripts/queue',
     # Bad script, no help.
     'scripts/librarian-report.py',
-    'scripts/rosetta/message-sharing-populate-test.py',
     'scripts/get-stacked-on-branches.py',
     'scripts/start-loggerhead.py',
     'scripts/stop-loggerhead.py',

=== removed file 'lib/lp/translations/scripts/migrate_kde_potemplates.py'
--- lib/lp/translations/scripts/migrate_kde_potemplates.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/scripts/migrate_kde_potemplates.py	1970-01-01 00:00:00 +0000
@@ -1,339 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Migrate KDE POTemplates to native support for plural forms and context ."""
-
-__metaclass__ = type
-
-__all__ = [
-    'migrate_potemplates',
-    ]
-
-from sqlobject import SQLObjectNotFound
-from zope.security.proxy import removeSecurityProxy
-
-from canonical.database.sqlbase import (
-    cursor,
-    sqlvalues,
-    )
-from lp.translations.interfaces.translationfileformat import (
-    TranslationFileFormat,
-    )
-from lp.translations.interfaces.translations import TranslationConstants
-from lp.translations.model.pomsgid import POMsgID
-from lp.translations.model.potemplate import POTemplate
-from lp.translations.model.potmsgset import POTMsgSet
-from lp.translations.model.potranslation import POTranslation
-from lp.translations.model.translationmessage import TranslationMessage
-
-
-def getOrCreatePOMsgID(msgid):
-    try:
-        pomsgid = POMsgID.byMsgid(msgid)
-    except SQLObjectNotFound:
-        pomsgid = POMsgID(msgid=msgid)
-    return pomsgid
-
-def get_potranslations(translations):
-    potranslations = {}
-    for index, translation in enumerate(translations):
-        if translation != '':
-            potranslations[index] = (
-                POTranslation.getOrCreateTranslation(translation))
-        else:
-            potranslations[index] = None
-    for index in range(len(potranslations),
-                       TranslationConstants.MAX_PLURAL_FORMS):
-        potranslations[index] = None
-    return potranslations
-
-
-def find_existing_translation(potmsgset, pofile, potranslations):
-    unprotected_potmsgset = removeSecurityProxy(potmsgset)
-    existing_message = (
-        unprotected_potmsgset._findTranslationMessage(
-            pofile=pofile, potranslations=potranslations,
-            pluralforms=TranslationConstants.MAX_PLURAL_FORMS))
-    return existing_message
-
-
-def migrate_translations_for_potmsgset(potmsgset, from_potmsgset,
-                                       logger, ztm):
-    """Migrate translations from `from_potmsgset` to `potmsgset`.
-
-    `from_potmsgset` is an old, unmigrated POTMsgSet we are migrating
-    translations from.  Translations are migrated to native context
-    and plural forms support along the way.
-
-    `from_potmsgset` and `potmsgset` might be the same, which happens when
-    we are migrating templates as well.
-    """
-    messages = TranslationMessage.select(
-        "potmsgset = %s" % sqlvalues(from_potmsgset))
-    logger.debug("Migrating %d translations for '%s'..." % (
-        messages.count(), potmsgset.singular_text))
-    for message in messages:
-        msgstrs = message.translations
-        # Let's see if translations have only the first plural
-        # form defined: if they do, then they need migration.
-        single_string = False
-        if len(msgstrs) > 0 and msgstrs[0] is not None:
-            single_string = True
-            for msgstr in msgstrs[1:]:
-                if msgstr is not None:
-                    single_string = False
-
-        if single_string:
-            translations = msgstrs[0].split('\n')
-
-            # If there's only a single plural form, no need to change
-            # anything.  If POTMsgSets are different, we still need
-            # to move the translation from one to the other.
-            if len(translations) == 1 and potmsgset == from_potmsgset:
-                continue
-
-            # If there is an existing TranslationMessage with
-            # these translations, re-use that and remove this one,
-            # otherwise modify this one in-place.
-            potranslations = get_potranslations(translations)
-            existing_message = find_existing_translation(
-                potmsgset, message.pofile, potranslations)
-            if existing_message:
-                if existing_message.id != message.id:
-                    # Only transfer is_current and is_imported
-                    # properties to an existing translation.
-                    if message.is_current:
-                        existing_message.is_current = True
-                    if message.is_imported:
-                        existing_message.is_imported = True
-                    # And remove the current message.
-                    message.destroySelf()
-            else:
-                # Modify `message` in-place.
-                message.msgstr0 = potranslations[0]
-                message.msgstr1 = potranslations[1]
-                message.msgstr2 = potranslations[2]
-                message.msgstr3 = potranslations[3]
-                message.msgstr4 = potranslations[4]
-                message.msgstr5 = potranslations[5]
-                if potmsgset.id != from_potmsgset.id:
-                    # Point TranslationMessage to a new POTMsgSet.
-                    # To avoid hitting constraints, first unset
-                    # the is_current and is_imported flags, and
-                    # restore them afterwards.
-                    stored_is_current = message.is_current
-                    stored_is_imported = message.is_imported
-                    message.is_current = False
-                    message.is_imported = False
-                    message.potmsgset = potmsgset
-                    message.sync()
-                    message.is_current = stored_is_current
-                    message.is_imported = stored_is_imported
-                    message.sync()
-
-
-def migrate_kde_potemplate_translations(potemplate, logger, ztm):
-    assert potemplate.source_file_format == TranslationFileFormat.KDEPO, (
-        "Trying to move translations for non-KDEPO template.")
-    cur = cursor()
-    cur.execute("""
-      SELECT old_msg.id, new_msg.id
-        FROM POTMsgSet AS old_msg, POMsgID AS old_msgid,
-             POTMsgSet AS new_msg, POMsgID AS singular, POMsgID AS plural
-        WHERE
-          -- they are both from this template
-          old_msg.potemplate=%s AND
-          new_msg.potemplate=old_msg.potemplate AND
-          -- old one is obsolete
-          old_msg.sequence=0 AND
-          -- old POTMsgSet has a singular form of the form '_n:...',
-          -- and no plural form
-          old_msg.msgid_singular=old_msgid.id AND
-          old_msg.msgid_plural IS NULL AND
-          old_msgid.msgid LIKE E'\\\\_n: %%' AND
-          -- and new POTMsgSet has singular and plural which when joined
-          -- give the old plural form
-          new_msg.msgid_singular=singular.id AND
-          new_msg.msgid_plural=plural.id AND
-          '_n: ' || singular.msgid || E'\\n' || plural.msgid = old_msgid.msgid
-          """ % sqlvalues(potemplate))
-    plural_potmsgsets = cur.fetchall()
-
-    logger.info("Migrating translations for %d plural POTMsgSets..." % (
-        len(plural_potmsgsets)))
-    for old_potmsgset_id, new_potmsgset_id in plural_potmsgsets:
-        old_potmsgset = POTMsgSet.get(old_potmsgset_id)
-        new_potmsgset = POTMsgSet.get(new_potmsgset_id)
-        migrate_translations_for_potmsgset(new_potmsgset, old_potmsgset,
-                                           logger, ztm)
-
-    cur.execute("""
-      SELECT old_msg.id, new_msg.id
-        FROM POTMsgSet AS old_msg, POMsgID AS old_msgid,
-             POTMsgSet AS new_msg, POMsgID AS new_msgid
-        WHERE
-          -- they are both from this template
-          old_msg.potemplate=%s AND
-          new_msg.potemplate=old_msg.potemplate AND
-          -- old one is obsolete
-          old_msg.sequence=0 AND
-          -- old POTMsgSet has a singular form of the form '_:...',
-          -- and no plural form
-          old_msg.msgid_singular=old_msgid.id AND
-          old_msg.msgid_plural IS NULL AND
-          old_msgid.msgid LIKE E'\\\\_: %%' AND
-          -- and new POTMsgSet has singular and context which when joined
-          -- give the old contextual message
-          new_msg.msgid_singular=new_msgid.id AND
-          '_: ' || new_msg.context || E'\\n' || new_msgid.msgid = old_msgid.msgid
-          """ % sqlvalues(potemplate))
-
-    plural_potmsgsets = cur.fetchall()
-
-    logger.info("Migrating translations for %d context POTMsgSets..." % (
-        len(plural_potmsgsets)))
-    for old_potmsgset_id, new_potmsgset_id in plural_potmsgsets:
-        old_potmsgset = POTMsgSet.get(old_potmsgset_id)
-        new_potmsgset = POTMsgSet.get(new_potmsgset_id)
-        messages = TranslationMessage.select(
-            "potmsgset=%s" % sqlvalues(old_potmsgset))
-        logger.debug(
-            "Moving %d context translations from POTMsgSet %d to %d..." % (
-                messages.count(), old_potmsgset_id, new_potmsgset_id))
-        migrate_translations_for_potmsgset(new_potmsgset, old_potmsgset,
-                                           logger, ztm)
-
-    ztm.commit()
-
-
-def existing_potmsgset(potemplate, msgid_singular, context):
-    clauses = ['potemplate=%s' % sqlvalues(potemplate),
-               'msgid_singular=%s' % sqlvalues(msgid_singular)]
-    if context is None:
-        clauses.append("context IS NULL")
-    else:
-        clauses.append("context=%s" % sqlvalues(context))
-
-    return POTMsgSet.selectOne(" AND ".join(clauses))
-
-
-def migrate_potemplate(potemplate, logger, ztm):
-    """Migrate PO templates to KDEPO format if needed."""
-
-    plural_prefix = u'_n: '
-    context_prefix = u'_: '
-
-    assert(potemplate.source_file_format == TranslationFileFormat.PO)
-
-    potmsgsets = POTMsgSet.select("""
-      POTMsgSet.potemplate = %s AND
-      POTMsgSet.msgid_singular=POMsgID.id AND
-      POTMsgSet.msgid_plural IS NULL AND
-      (POMsgID.msgid LIKE E'\\\\_n: %%' OR POMsgID.msgid LIKE E'\\\\_: %%')
-      """ % sqlvalues(potemplate),
-      clauseTables=['POMsgID'])
-
-    logger.debug("Fixing %d POTMsgSets..." % potmsgsets.count())
-
-    # We go potmsgset by potmsgset because it's easier to preserve
-    # correctness.  It'd be faster to go through translation messages
-    # but then we'd be fixing potmsgsets after fixing translation messages.
-    for potmsgset in potmsgsets:
-        msgid = potmsgset.singular_text
-        fix_plurals = fix_context = False
-
-        # Detect plural form and context messages: use the same
-        # logic as in utilities/kde_po_importer.py.
-        if msgid.startswith(plural_prefix) and '\n' in msgid:
-            # This is a KDE plural form.
-            singular_text, plural_text = (
-                msgid[len(plural_prefix):].split('\n', 1))
-
-            msgid_singular = getOrCreatePOMsgID(singular_text)
-
-            if existing_potmsgset(potemplate, msgid_singular, None):
-                logger.warn("POTMsgSet %d conflicts with another one." % (
-                    potmsgset.id))
-            else:
-                potmsgset.msgid_singular = msgid_singular
-                potmsgset.msgid_plural = getOrCreatePOMsgID(plural_text)
-                potmsgset.sync()
-                fix_plurals = True
-        elif msgid.startswith(context_prefix) and '\n' in msgid:
-            # This is a KDE context message: it needs no fixing apart
-            # from changing msgid_singular.
-            context, singular_text = (
-                msgid[len(context_prefix):].split('\n', 1))
-            msgid_singular = getOrCreatePOMsgID(singular_text)
-
-            if existing_potmsgset(potemplate, msgid_singular, context):
-                logger.warn("POTMsgSet %d conflicts with another one." % (
-                    potmsgset.id))
-            else:
-                potmsgset.context = context
-                potmsgset.msgid_singular = msgid_singular
-                potmsgset.sync()
-                fix_context = True
-        else:
-            # Other messages here are the ones which begin like
-            # context or plural form messages, but are actually neither.
-            pass
-
-        if fix_plurals:
-            # Fix translations for this potmsgset.
-            migrate_translations_for_potmsgset(potmsgset, potmsgset,
-                                               logger, ztm)
-
-    potemplate.source_file_format = TranslationFileFormat.KDEPO
-    # Commit a PO template one by one.
-    ztm.commit()
-
-
-def migrate_translations_for_kdepo_templates(ztm, logger):
-    """Migrate translations for already re-imported KDE PO templates."""
-    potemplates = POTemplate.select("""
-    source_file_format=%s AND
-    POTemplate.id IN
-        (SELECT DISTINCT potemplate
-          FROM POTMsgSet
-          WHERE POTMsgSet.potemplate = POTemplate.id AND
-                (POTMsgSet.msgid_plural IS NOT NULL OR
-                 POTMsgSet.context IS NOT NULL))
-      """ % sqlvalues(TranslationFileFormat.KDEPO))
-
-    count = potemplates.count()
-    index = 0
-    for potemplate in potemplates:
-        index += 1
-        logger.info("Migrating translations for KDE POTemplate %s [%d/%d]" % (
-            potemplate.displayname, index, count))
-        migrate_kde_potemplate_translations(potemplate, logger, ztm)
-
-
-def migrate_unmigrated_templates_to_kdepo(ztm, logger):
-    """Go through all non-KDE PO templates and migrate to KDEPO as needed."""
-
-    potemplates = POTemplate.select("""
-    source_file_format=%s AND
-    POTemplate.id IN
-        (SELECT DISTINCT potemplate
-          FROM POTMsgSet
-          JOIN POMsgID ON POMsgID.id = POTMsgSet.msgid_singular
-          WHERE POTMsgSet.potemplate = POTemplate.id AND
-                POTMsgSet.msgid_plural IS NULL AND
-                (POMsgID.msgid LIKE E'\\\\_n: %%' OR
-                 POMsgID.msgid LIKE E'\\\\_: %%'))
-      """ % sqlvalues(TranslationFileFormat.PO))
-
-    count = potemplates.count()
-    index = 0
-    for potemplate in potemplates:
-        index += 1
-        logger.info("Migrating POTemplate %s [%d/%d]" % (
-            potemplate.displayname, index, count))
-        migrate_potemplate(potemplate, logger, ztm)
-
-
-def migrate_potemplates(ztm, logger):
-    migrate_translations_for_kdepo_templates(ztm, logger)
-    migrate_unmigrated_templates_to_kdepo(ztm, logger)

=== removed file 'lib/lp/translations/scripts/remove_obsolete_translations.py'
--- lib/lp/translations/scripts/remove_obsolete_translations.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/scripts/remove_obsolete_translations.py	1970-01-01 00:00:00 +0000
@@ -1,383 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-__metaclass__ = type
-
-__all__ = ['RemoveObsoleteTranslations']
-
-from zope.component import getUtility
-from zope.interface import implements
-
-from canonical.database.sqlbase import quote
-from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
-from canonical.launchpad.interfaces.looptuner import ITunableLoop
-from canonical.launchpad.utilities.looptuner import DBLoopTuner
-from canonical.launchpad.webapp.interfaces import (
-    IStoreSelector,
-    MAIN_STORE,
-    MASTER_FLAVOR,
-    )
-from lp.registry.interfaces.series import SeriesStatus
-from lp.services.scripts.base import LaunchpadScript
-
-
-collect_order = [
-    'POTemplate',
-    'POFile',
-    'TranslationImportQueueEntry',
-    'POTMsgSet',
-    'TranslationTemplateItem',
-    'TranslationMessage',
-    'POFileTranslator',
-    ]
-
-
-remove_order = list(reversed(collect_order))
-
-
-collection_query = """
-    DROP TABLE IF EXISTS %(temporary_table)s;
-    CREATE TEMP TABLE %(temporary_table)s
-        AS SELECT %(table)s.id AS id
-        FROM %(table)s
-        JOIN %(join_table)s ON %(table)s.%(join_column)s = %(join_table)s.id;
-    CREATE UNIQUE INDEX %(temporary_table)s_idx ON %(temporary_table)s (id);
-    ANALYZE %(temporary_table)s"""
-
-
-# POTemplate
-collect_obsolete_potemplates_query = """
-    DROP TABLE IF EXISTS %(temporary_table)s;
-    CREATE TEMP TABLE %(temporary_table)s
-    AS SELECT %(table)s.id AS id
-    FROM %(table)s
-        JOIN %(join_table)s ON %(table)s.%(join_column)s = %(join_table)s.id
-    WHERE distroseries.distribution = %(distribution)s
-          AND distroseries.releasestatus = %(releasestatus)s;
-    CREATE UNIQUE INDEX %(temporary_table)s_idx ON %(temporary_table)s (id);
-    ANALYZE %(temporary_table)s"""
-
-
-# Query to remove subset of entries based on a temporary table.
-deletion_query = """
-    DELETE FROM %(table)s
-    WHERE id IN (
-        SELECT id
-        FROM %(temporary_table)s
-        ORDER BY id
-        LIMIT %%d OFFSET %%d
-        )"""
-
-
-def commit_transaction(transaction, logger, dry_run=False):
-    """Commit ongoing transaction, start a new one.
-
-    Pauses process execution to give the database slave a chance
-    to keep up.
-    """
-    if transaction is None:
-        return
-
-    if not dry_run:
-        transaction.commit()
-        transaction.begin()
-
-
-class DeletionLoopRunner(object):
-    """Generic loop tuner for removal of obsolete translations data."""
-    implements(ITunableLoop)
-
-    def __init__(self, table_entry, transaction, logger, store,
-                 dry_run=False):
-        """Initialize the loop."""
-        size = table_entry['total']
-        self.table = table_entry['table']
-        self.removal_sql = deletion_query % table_entry
-
-        self._txn = transaction
-        self._logger = logger
-        self._store = store
-        self._dry_run = dry_run
-        self._iteration_end = size
-        self._iterations_done = 0
-        self._commit_count = 0
-
-    def isDone(self):
-        """See `ITunableLoop`."""
-        return self._iterations_done >= self._iteration_end
-
-    def __call__(self, chunk_size):
-        """See `ITunableLoop`."""
-        chunk_size = int(chunk_size)
-        query = self.removal_sql % (chunk_size, self._iterations_done)
-        result = self._store.execute(query)
-        self._logger.debug(
-            " * Removed another %d %ss (%d of %d)." % (
-                result._raw_cursor.rowcount,
-                self.table,
-                self._iterations_done + result._raw_cursor.rowcount,
-                self._iteration_end))
-        self._iterations_done += result._raw_cursor.rowcount
-        commit_transaction(self._txn, self._logger, dry_run=self._dry_run)
-        self._commit_count += 1
-
-    def getTotalCommits(self):
-        return self._commit_count
-
-
-class TranslationsStatusChecker:
-    """Check if translations data is consistent after removal."""
-    check_methods = {
-        'productseries_potemplates' : 'collectProductSeriesStats',
-        'other_distroseries_potemplates' : 'collectOtherDistroSeriesStats',
-        'potemplate_potmsgsets' : 'collectPOTemplatePOTMsgSetStats',
-        'potemplate_pofiles' : 'collectPOTemplatePOFileStats',
-        'pofile_pofiletranslators' : 'collectPOFileTranslatorStats',
-        'translationimportqueue_size' : 'getTranslationImportQueueSize',
-        }
-
-    def __init__(self, store, logger):
-        self.store = store
-        self.logger = logger
-        self.problems = 0
-        for attribute in self.check_methods:
-            method = getattr(self, self.check_methods[attribute])
-            self.logger.debug("Collecting %s..." % attribute)
-            setattr(self, attribute, method())
-
-    def postCheck(self):
-        self.checkObsoletePOTemplates()
-
-        for attribute in self.check_methods:
-            self.genericCheck(attribute)
-
-        if self.problems > 0:
-            self.logger.info("%d problems found." % self.problems)
-        else:
-            self.logger.info("All checks passed.")
-
-    def genericCheck(self, attribute_name):
-        method = getattr(self, self.check_methods[attribute_name])
-        new_stats = method()
-        old_stats = getattr(self, attribute_name)
-        if old_stats != new_stats:
-            if not isinstance(old_stats, int):
-                old_stats = len(old_stats)
-                new_stats = len(new_stats)
-            self.logger.warn(
-                "Mismatch in %s (was %d long, now %d)." % (
-                    attribute_name, old_stats, new_stats))
-            self.problems += 1
-
-    def checkObsoletePOTemplates(self):
-        query = """SELECT COUNT(POTemplate.id) FROM POTemplate
-                   JOIN DistroSeries
-                     ON POTemplate.distroseries=DistroSeries.id
-                   WHERE DistroSeries.releasestatus=%s AND
-                         DistroSeries.distribution=%s""" % (
-            quote(SeriesStatus.OBSOLETE),
-            quote(getUtility(ILaunchpadCelebrities).ubuntu))
-        result = self.store.execute(query)
-        count = result.get_one()
-        if int(count[0]) != 0:
-            self.logger.warn("\tObsolete POTemplates remaining: %s." % count)
-            self.problems += 1
-
-    def collectProductSeriesStats(self):
-        query = """SELECT ProductSeries.id, COUNT(POTemplate.id)
-                     FROM ProductSeries
-                     JOIN POTemplate
-                       ON POTemplate.productseries=ProductSeries.id
-                     GROUP BY ProductSeries.id
-                     ORDER BY ProductSeries.id"""
-        result = self.store.execute(query)
-        return result.get_all()
-
-    def collectOtherDistroSeriesStats(self):
-        query = """SELECT DistroSeries.id, COUNT(POTemplate.id)
-                     FROM DistroSeries
-                     JOIN POTemplate
-                       ON POTemplate.distroseries=DistroSeries.id
-                     WHERE DistroSeries.releasestatus != %s
-                     GROUP BY DistroSeries.id
-                     ORDER BY DistroSeries.id""" % quote(
-            SeriesStatus.OBSOLETE)
-        result = self.store.execute(query)
-        return result.get_all()
-
-    def collectPOTemplatePOFileStats(self):
-        query = """SELECT POTemplate.id, COUNT(POFile.id)
-                     FROM POTemplate
-                     LEFT OUTER JOIN DistroSeries
-                       ON POTemplate.distroseries=DistroSeries.id
-                     JOIN POFile
-                       ON POFile.potemplate=POTemplate.id
-                     WHERE (distroseries IS NOT NULL AND
-                            DistroSeries.releasestatus != %s) OR
-                           productseries IS NOT NULL
-                     GROUP BY POTemplate.id
-                     ORDER BY POTemplate.id""" % quote(
-            SeriesStatus.OBSOLETE)
-        result = self.store.execute(query)
-        return result.get_all()
-
-    def collectPOTemplatePOTMsgSetStats(self):
-        query = """SELECT POTemplate.id, COUNT(POTMsgSet.id)
-                     FROM POTemplate
-                     LEFT OUTER JOIN DistroSeries
-                       ON POTemplate.distroseries=DistroSeries.id
-                     JOIN POTMsgSet
-                       ON POTMsgSet.potemplate=POTemplate.id
-                     WHERE (distroseries IS NOT NULL AND
-                            DistroSeries.releasestatus != %s) OR
-                           productseries IS NOT NULL
-                     GROUP BY POTemplate.id
-                     ORDER BY POTemplate.id""" % quote(
-            SeriesStatus.OBSOLETE)
-        result = self.store.execute(query)
-        return result.get_all()
-
-    def collectPOFileTranslatorStats(self):
-        query = """SELECT POFile.id, COUNT(POFileTranslator.id)
-                     FROM POFile
-                     JOIN POTemplate
-                       ON POFile.potemplate=POTemplate.id
-                     LEFT OUTER JOIN DistroSeries
-                       ON POTemplate.distroseries=DistroSeries.id
-                     JOIN POFileTranslator
-                       ON POFileTranslator.pofile=POFile.id
-                     WHERE (distroseries IS NOT NULL AND
-                            DistroSeries.releasestatus != %s) OR
-                           productseries IS NOT NULL
-                     GROUP BY POFile.id
-                     ORDER BY POFile.id""" % quote(
-            SeriesStatus.OBSOLETE)
-        result = self.store.execute(query)
-        return result.get_all()
-
-    def getTranslationImportQueueSize(self):
-        query = """SELECT count(id) FROM TranslationImportQueueEntry"""
-        result = self.store.execute(query)
-        return int(result.get_one()[0])
-
-
-class RemoveObsoleteTranslations(LaunchpadScript):
-
-    def add_my_options(self):
-        self.parser.add_option(
-            '-d', '--dry-run', action="store_true", dest='dry_run',
-            default=False, help="Don't really make any database changes.")
-
-        self.parser.add_option(
-            '-l', '--loop-timing', dest='loop_time',
-            default=5, help="Time in seconds for the loop to run.")
-
-    def main(self):
-        removal_traits = {
-            'TranslationMessage' :
-                { 'table' : 'TranslationMessage',
-                  'temporary_table' : 'obsolete_translationmessage',
-                  'join_table' : 'obsolete_pofile',
-                  'join_column' : 'pofile',
-                  },
-            'TranslationTemplateItem' :
-                { 'table' : 'TranslationTemplateItem',
-                  'temporary_table' : 'obsolete_tti',
-                  'join_table' : 'obsolete_potemplate',
-                  'join_column' : 'potemplate',
-                  },
-            'POTMsgSet' :
-                { 'table' : 'POTMsgSet',
-                  'temporary_table' : 'obsolete_potmsgset',
-                  'join_table' : 'obsolete_potemplate',
-                  'join_column' : 'potemplate',
-                  },
-            'POFileTranslator' :
-                { 'table' : 'POFileTranslator',
-                  'temporary_table' : 'obsolete_pofiletranslator',
-                  'join_table' : 'obsolete_pofile',
-                  'join_column' : 'pofile',
-                  },
-            'POFile' :
-                { 'table' : 'POFile',
-                  'temporary_table' : 'obsolete_pofile',
-                  'join_table' : 'obsolete_potemplate',
-                  'join_column' : 'potemplate',
-                  },
-            'TranslationImportQueueEntry' :
-                { 'table' : 'TranslationImportQueueEntry',
-                  'temporary_table' : 'obsolete_queueentries',
-                  'join_table' : 'obsolete_potemplate',
-                  'join_column' : 'potemplate',
-                  },
-            'POTemplate' :
-                { 'table' : 'POTemplate',
-                  'temporary_table' : 'obsolete_potemplate',
-                  'join_table' : 'distroseries',
-                  'join_column' : 'distroseries',
-                  'distribution' :
-                    quote(getUtility(ILaunchpadCelebrities).ubuntu),
-                  'releasestatus' : quote(SeriesStatus.OBSOLETE),
-                  'collection_sql' : collect_obsolete_potemplates_query,
-                  },
-            }
-
-        if self.options.dry_run:
-            self.logger.info("Dry run.  Not making any changes.")
-
-        self.logger.debug(
-            "Removing translations of obsolete Ubuntu versions")
-
-        self._commit_count = 0
-
-        # Working on the writable master store
-        store = getUtility(IStoreSelector).get(MAIN_STORE, MASTER_FLAVOR)
-        self._store = store
-
-        checker = TranslationsStatusChecker(store, self.logger)
-        for table in collect_order:
-            entry = removal_traits[table]
-            collect_sql = entry.get('collection_sql', collection_query)
-            collect = store.execute(collect_sql % entry)
-            count = self._count_rows(entry['temporary_table'])
-            entry['total'] = count
-        self._do_commit()
-
-        for table in remove_order:
-            entry = removal_traits[table]
-            self.logger.info(
-                "Removing %d %s rows." % (entry['total'], table))
-            loop = DeletionLoopRunner(
-                entry, self.txn, self.logger, store,
-                dry_run=self.options.dry_run)
-            DBLoopTuner(loop, self.options.loop_time, log=self.logger).run()
-            self._commit_count += loop.getTotalCommits()
-
-        self.logger.info("Done with %d commits." % self._commit_count)
-        self.logger.info("Statistics:")
-        for table in remove_order:
-            self.logger.info("\t%-30s: %d removed" % (
-                    table, removal_traits[table]['total']))
-
-        self.logger.info("Checks:")
-        checker.postCheck()
-
-        if self.options.dry_run:
-            self.txn.abort()
-
-    def _count_rows(self, tablename):
-        """Helper to count all rows in a table."""
-        count_query = "SELECT count(*) FROM %s"
-        result = self._store.execute(
-            count_query % tablename).get_one()
-        return result[0]
-
-    def _do_commit(self):
-        """Commit ongoing transaction, start a new one.
-
-        Pauses process execution to give the database slave a chance
-        to keep up.
-        """
-        commit_transaction(self.txn, self.logger,
-                           dry_run=self.options.dry_run)
-        self._commit_count += 1

=== removed file 'scripts/rosetta/message-sharing-populate-test.py'
--- scripts/rosetta/message-sharing-populate-test.py	2010-07-13 15:40:33 +0000
+++ scripts/rosetta/message-sharing-populate-test.py	1970-01-01 00:00:00 +0000
@@ -1,134 +0,0 @@
-#!/usr/bin/python -S
-#
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# pylint: disable-msg=W0403
-
-"""Test Translation Message Sharing schema initializations.
-
-This script verifies the results of the message-sharing-populate.py
-one-off script.  It checks that all schema elements that were added for
-translation message sharing were initialized correctly.
-
-Run this after message-sharing-populate.py, but also occasionally
-afterwards to ensure that the code that initializes the added schema
-elements on new data is working correctly.
-
-The new schema elements are not used yet.  Once they are, a next step is
-to start unifying TranslationMessages that are common between
-POTemplates.  When that happens, this script will start reporting errors
-at points marked in the source below.  Change those points & run again!
-"""
-
-import _pythonpath
-
-from canonical.database.sqlbase import cursor
-from canonical.launchpad.scripts import execute_zcml_for_scripts
-
-
-class SchemaElementsInitializationFailure(Exception):
-    """Convenience exception class for errors found in our data."""
-    pass
-
-
-def check(query, error_message, expected_result=0):
-    """Report error if `query` result does not match `expected_result`."""
-    cur = cursor()
-    cur.execute(query)
-    result, = cur.fetchone()
-
-    if result != expected_result:
-        counts = "expected %s, found %s" % (expected_result, result)
-        raise SchemaElementsInitializationFailure(
-            "%s (%s)" % (error_message, counts))
-
-
-def test_schema():
-    """Test schema initializations."""
-    cur = cursor()
-
-    # Are all TranslationMessage.language fields initialized?
-    query = """
-        SELECT count(*)
-        FROM TranslationMessage
-        WHERE language IS NULL
-       """
-    check(query, "Found uninitialized TranslationMessage.language")
-
-    # Are all TranslationMessages.potemplate fields initialized?
-    # XXX JeroenVermeulen 2008-10-06 spec=message-sharing-migration:
-    # potemplate will be allowed to be null later on, when we really
-    # start sharing messages.  The field means "this message is specific
-    # to this potemplate, rather than shared").  Remove this check then.
-    query = """
-        SELECT count(*)
-        FROM TranslationMessage
-        WHERE potemplate IS NULL OR language IS NULL
-       """
-    check(query, "Found uninitialized TranslationMessages.potemplate.")
-
-    # Are all TranslationMessages linked to the right languages?
-    query = """
-        SELECT count(*)
-        FROM TranslationMessage
-        LEFT JOIN POFile ON POFile.id = TranslationMessage.pofile
-        WHERE
-            POFile.id IS NULL OR
-            POFile.language <> TranslationMessage.language
-        """
-    check(query, "Found TranslationMessages with incorrect language.")
-
-    # Do all POTMsgSets with nonzero sequence numbers have linking-table
-    # entries linking them to their POTemplates?  (Zero sequence number
-    # means "does not participate in this POTemplate," a wart that will
-    # go away with this schema change)
-    query = """
-        SELECT count(*)
-        FROM POTMsgSet
-        LEFT JOIN TranslationTemplateItem AS i ON i.potmsgset = POTMsgSet.id
-        WHERE POTMsgSet.sequence <> 0 AND i.id IS NULL
-        """
-    check(query, "Found unlinked POTMsgSets.")
-
-    # Conversely, is the linking table free of unexpected rows?
-    query = """
-        SELECT count(*)
-        FROM TranslationTemplateItem i
-        LEFT JOIN POTMsgSet ON i.potmsgset = POTMsgSet.id
-        WHERE POTMsgSet.id IS NULL or POTMsgSet.sequence = 0
-        """
-    check(query, "Found unexpected TranslationTemplateItem rows.")
-
-    # Are all TranslationTemplateItems correct?
-    query = """
-        SELECT count(*)
-        FROM POTMsgSet
-        JOIN TranslationTemplateItem AS i ON i.potmsgset = POTMsgSet.id
-        WHERE
-            i.potemplate <> POTMsgSet.potemplate OR
-            i.sequence <> POTMsgSet.sequence
-        """
-    check(query, "Found incorrect TranslationTemplateItem contents.")
-
-    # Is each POTMsgSet linked to no more than one POTemplate?
-    # XXX JeroenVermeulen 2008-10-06 spec=message-sharing-migration:
-    # Once we start sharing messages across templates, this will become
-    # a real m:n relationship between POTMsgSet and POTemplate.  At that
-    # point, remove his check.
-    query = """
-        SELECT count(*)
-        FROM (
-            SELECT count(*)
-            FROM TranslationTemplateItem
-            GROUP BY potmsgset
-            HAVING count(*) > 1
-            ) AS shared_potmsgset
-        """
-    check(query, "Found shared POTMsgSets.")
-
-
-if __name__ == '__main__':
-    execute_zcml_for_scripts()
-    test_schema()
-    print "Done."

=== removed file 'scripts/rosetta/message-sharing-populate.py'
--- scripts/rosetta/message-sharing-populate.py	2010-08-06 07:02:32 +0000
+++ scripts/rosetta/message-sharing-populate.py	1970-01-01 00:00:00 +0000
@@ -1,209 +0,0 @@
-#!/usr/bin/python -S
-#
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# pylint: disable-msg=W0403
-
-"""Populate schema additions for Translations Message Sharing.
-
-This fills two new `TranslationMessage` columns: potemplate, language.
-It also creates linking table entries connecting the existing `POTMsgSet`s
-to their `POTemplate`s.
-
-Since the schema additions are not in use yet, this script doesn't need
-to be careful about grouping by template, preserving any kind of order,
-and so on.
-
-On the other hand, the Python code tree should already be initializing
-the new columns and the linking table by the time this script is run.
-So we do have to be careful not to interfere with that, or stumble when
-some records have already been initialized properly.
-"""
-
-import _pythonpath
-
-from zope.interface import implements
-
-from canonical.database.postgresql import drop_tables
-from canonical.database.sqlbase import cursor, sqlvalues
-from canonical.launchpad.interfaces.looptuner import ITunableLoop
-from lp.services.scripts.base import LaunchpadScript
-from canonical.launchpad.utilities.looptuner import DBLoopTuner
-
-
-class PopulateTranslationMessage:
-    """`ITunableLoop` to populate new TranslationMessage columns."""
-
-    implements(ITunableLoop)
-    def __init__(self, txn, logger):
-        self.txn = txn
-        self.logger = logger
-        self.last_id = 0
-
-        cur = cursor()
-        cur.execute("""
-            SELECT id
-            INTO TEMP TABLE temp_todo
-            FROM TranslationMessage
-            WHERE potemplate IS NULL
-            ORDER BY id
-            """)
-        cur.execute(
-            "CREATE UNIQUE INDEX temp_todo__pkey ON temp_todo(id)")
-        cur.execute("ANALYZE temp_todo(id)")
-
-        cur.execute("SELECT max(id) FROM temp_todo")
-        max_id, = cur.fetchone()
-        if max_id is None:
-            self.finish_id = 0
-        else:
-            self.finish_id = max_id + 1
-
-    def isDone(self):
-        """See `ITunableLoop`."""
-        done = (self.last_id >= self.finish_id)
-        if done:
-            drop_tables(cursor(), 'temp_todo')
-        return done
-
-    def __call__(self, chunk_size):
-        """See `ITunableLoop`."""
-        chunk_size = int(chunk_size)
-
-        cur = cursor()
-        cur.execute("""
-            SELECT id
-            FROM temp_todo
-            WHERE id >= %s
-            ORDER BY id
-            OFFSET %s
-            LIMIT 1
-            """ % sqlvalues(self.last_id, chunk_size))
-        batch_limit = cur.fetchone()
-        if batch_limit is None:
-            end_id = self.finish_id
-        else:
-            end_id, = batch_limit
-
-        cur.execute("""
-            UPDATE TranslationMessage AS Msg
-            SET
-                potemplate = POFile.potemplate,
-                language = POFile.language
-            FROM POFile
-            WHERE
-                POFile.id = Msg.pofile AND
-                Msg.potemplate IS NULL AND
-                Msg.id IN (
-                    SELECT id
-                    FROM temp_todo
-                    WHERE id >= %s AND id < %s
-                )
-            """ % sqlvalues(self.last_id, end_id))
-        self.logger.info(
-            "Updated %d rows: %d - %d." % (
-                cur.rowcount, self.last_id, end_id))
-        self.txn.commit()
-        self.txn.begin()
-        self.last_id = end_id
-
-
-class PopulateTranslationTemplateItem:
-    """`ITunableLoop` to populate TranslationTemplateItem linking table."""
-
-    implements(ITunableLoop)
-    def __init__(self, txn, logger):
-        self.txn = txn
-        self.done = False
-        self.logger = logger
-        self.last_id = 0
-
-        cur = cursor()
-        cur.execute("""
-            SELECT POTMsgSet.id
-            INTO TEMP TABLE temp_todo
-            FROM POTMsgSet
-            LEFT JOIN TranslationTemplateItem AS ExistingEntry ON
-                ExistingEntry.potmsgset = potmsgset.id
-            WHERE
-                POTMsgSet.sequence > 0 AND
-                ExistingEntry.id IS NULL
-            ORDER BY id
-            """)
-        cur.execute(
-            "CREATE UNIQUE INDEX temp_todo__pkey ON temp_todo(id)")
-        cur.execute("ANALYZE temp_todo(id)")
-
-        cur.execute("SELECT max(id) FROM temp_todo")
-        max_id, = cur.fetchone()
-        if max_id is None:
-            self.finish_id = 0
-        else:
-            self.finish_id = max_id + 1
-
-    def isDone(self):
-        """See `ITunableLoop`."""
-        done = (self.last_id >= self.finish_id)
-        if done:
-            drop_tables(cursor(), 'temp_todo')
-        return done
-
-    def __call__(self, chunk_size):
-        """See `ITunableLoop`."""
-        chunk_size = int(chunk_size)
-        cur = cursor()
-
-        cur.execute("""
-            SELECT id
-            FROM temp_todo
-            WHERE id >= %s
-            ORDER BY id
-            OFFSET %s
-            LIMIT 1
-            """ % sqlvalues(self.last_id, chunk_size))
-        batch_limit = cur.fetchone()
-        if batch_limit is None:
-            end_id = self.finish_id
-        else:
-            end_id, = batch_limit
-
-        cur.execute("""
-            INSERT INTO TranslationTemplateItem(
-                potemplate, sequence, potmsgset)
-            SELECT POTMsgSet.potemplate, POTMsgSet.sequence, POTMsgSet.id
-            FROM POTMsgSet
-            LEFT JOIN TranslationTemplateItem AS ExistingEntry ON
-                ExistingEntry.potmsgset = potmsgset.id
-            WHERE
-                POTMsgSet.id >= %s AND
-                POTMsgSet.id < %s AND
-                POTMsgSet.sequence > 0 AND
-                ExistingEntry.id IS NULL
-            """ % sqlvalues(self.last_id, end_id))
-        self.logger.info("Inserted %d rows." % cur.rowcount)
-        self.txn.commit()
-        self.txn.begin()
-        self.last_id = end_id
-
-
-class PopulateMessageSharingSchema(LaunchpadScript):
-    description = (
-        "Populate columns and linking table added for Translations Message "
-        "sharing.")
-
-    def main(self):
-        self.logger.info("Populating new TranslationMessage columns.")
-        tm_loop = PopulateTranslationMessage(self.txn, self.logger)
-        DBLoopTuner(tm_loop, 2, log=self.logger).run()
-
-        self.logger.info("Populating TranslationTemplateItem.")
-        tti_loop = PopulateTranslationTemplateItem(self.txn, self.logger)
-        DBLoopTuner(tti_loop, 2, log=self.logger).run()
-
-
-if __name__ == '__main__':
-    script = PopulateMessageSharingSchema(
-        'canonical.launchpad.scripts.message-sharing-populate')
-    script.run()
-

=== removed file 'scripts/rosetta/remove-obsolete-translations.py'
--- scripts/rosetta/remove-obsolete-translations.py	2010-04-27 19:48:39 +0000
+++ scripts/rosetta/remove-obsolete-translations.py	1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-#!/usr/bin/python -S
-#
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# pylint: disable-msg=W0403
-# (Suppressing pylint "relative import" warning 0403 for _pythonpath)
-
-__metaclass__ = type
-
-import _pythonpath
-
-from lp.translations.scripts.remove_obsolete_translations import (
-    RemoveObsoleteTranslations)
-
-
-if __name__ == '__main__':
-    script = RemoveObsoleteTranslations(
-        'canonical.launchpad.scripts.remove-obsolete-translations',
-        dbuser='rosettaadmin')
-    script.run()

=== modified file 'utilities/migrater/file-ownership.txt'
--- utilities/migrater/file-ownership.txt	2010-10-31 20:18:45 +0000
+++ utilities/migrater/file-ownership.txt	2010-11-16 13:00:24 +0000
@@ -604,7 +604,6 @@
 reg ./scripts/listteammembers.py
     ./scripts/logger.py
     ./scripts/loghandlers.py
-    ./scripts/migrate_kde_potemplates.py
     ./scripts/mlistimport.py
     ./scripts/oops.py
     ./scripts/packagecopier.py
@@ -623,7 +622,6 @@
     ./scripts/publishdistro.py
     ./scripts/questionexpiration.py
     ./scripts/queue.py
-    ./scripts/remove_obsolete_translations.py
     ./scripts/remove_translations.py
     ./scripts/revisionkarma.py
     ./scripts/runlaunchpad.py