~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/translations/model/translationimportqueue.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-12-21 04:51:50 UTC
  • mfrom: (14527.5.3 bug-905178)
  • Revision ID: launchpad@pqm.canonical.com-20111221045150-7adn159cdofhr673
[r=adeuring][bug=905178] Speed up main translations import queue page.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2009-2010 Canonical Ltd.  This software is licensed under the
 
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
2
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
3
 
4
4
# pylint: disable-msg=E0611,W0212, W0403
13
13
from cStringIO import StringIO
14
14
import datetime
15
15
import logging
 
16
from operator import attrgetter
16
17
import os.path
17
18
import re
18
19
import tarfile
29
30
from storm.expr import (
30
31
    And,
31
32
    Or,
 
33
    Select,
32
34
    )
33
35
from storm.locals import (
34
36
    Int,
53
55
    SQLBase,
54
56
    sqlvalues,
55
57
    )
56
 
from canonical.launchpad.helpers import shortlist
57
58
from canonical.launchpad.interfaces.lpstorm import (
58
59
    IMasterStore,
59
60
    ISlaveStore,
 
61
    IStore,
60
62
    )
61
63
from canonical.librarian.interfaces import ILibrarianClient
62
64
from lp.app.errors import NotFoundError
846
848
        return elapsedtime_text
847
849
 
848
850
 
 
851
def list_product_request_targets(status_condition):
 
852
    """Return list of Products with import queue entries.
 
853
 
 
854
    :param status_condition: Storm conditional restricting the
 
855
        queue-entry status to look for.
 
856
    :return: A list of `Product`, distinct and ordered by name.
 
857
    """
 
858
    # Avoid circular imports.
 
859
    from lp.registry.model.product import Product
 
860
    from lp.registry.model.productseries import ProductSeries
 
861
 
 
862
    products = IStore(Product).find(
 
863
        Product,
 
864
        Product.id == ProductSeries.productID,
 
865
        Product.active == True,
 
866
        ProductSeries.id.is_in(Select(
 
867
            TranslationImportQueueEntry.productseries_id,
 
868
            And(
 
869
                TranslationImportQueueEntry.productseries_id != None,
 
870
                status_condition),
 
871
            distinct=True)))
 
872
 
 
873
    # Products may occur multiple times due to the join with
 
874
    # ProductSeries.
 
875
    products = products.config(distinct=True)
 
876
 
 
877
    # Sort python-side; doing it in SQL conflicts with the
 
878
    # "distinct."
 
879
    return sorted(products, key=attrgetter('name'))
 
880
 
 
881
 
 
882
def list_distroseries_request_targets(status_condition):
 
883
    """Return list of DistroSeries with import queue entries.
 
884
 
 
885
    :param status_condition: Storm conditional restricting the
 
886
        queue-entry status to look for.
 
887
    :return: A list of `DistroSeries`, distinct and ordered by
 
888
        (`Distribution.name`, `DistroSeries.name`).
 
889
    """
 
890
    # Avoid circular imports.
 
891
    from lp.registry.model.distribution import Distribution
 
892
    from lp.registry.model.distroseries import DistroSeries
 
893
 
 
894
    # DistroSeries with queue entries.
 
895
    distroseries = IStore(DistroSeries).find(
 
896
        DistroSeries,
 
897
        DistroSeries.defer_translation_imports == False,
 
898
        Distribution.id == DistroSeries.distributionID,
 
899
        DistroSeries.id.is_in(Select(
 
900
            TranslationImportQueueEntry.distroseries_id,
 
901
            And(
 
902
                TranslationImportQueueEntry.distroseries_id != None,
 
903
                status_condition),
 
904
            distinct=True)))
 
905
    distroseries = distroseries.order_by(Distribution.name, DistroSeries.name)
 
906
    return list(distroseries)
 
907
 
 
908
 
849
909
class TranslationImportQueue:
850
910
    implements(ITranslationImportQueue)
851
911
 
1223
1283
 
1224
1284
    def getRequestTargets(self, status=None):
1225
1285
        """See `ITranslationImportQueue`."""
1226
 
        # XXX DaniloSegan 2007-05-22: When imported on the module level,
1227
 
        # it errs out with: "ImportError: cannot import name Person"
1228
 
        from lp.registry.model.distroseries import DistroSeries
1229
 
        from lp.registry.model.product import Product
1230
1286
 
1231
1287
        if status is None:
1232
 
            status_clause = "TRUE"
 
1288
            status_clause = True
1233
1289
        else:
1234
 
            status_clause = (
1235
 
                "TranslationImportQueueEntry.status = %s" % sqlvalues(status))
1236
 
 
1237
 
        def distroseries_sort_key(distroseries):
1238
 
            return (distroseries.distribution.name, distroseries.name)
1239
 
 
1240
 
        query = [
1241
 
            'ProductSeries.product = Product.id',
1242
 
            'TranslationImportQueueEntry.productseries = ProductSeries.id',
1243
 
            'Product.active IS TRUE']
1244
 
        if status is not None:
1245
 
            query.append(status_clause)
1246
 
 
1247
 
        products = list(Product.select(
1248
 
            ' AND '.join(query),
1249
 
            clauseTables=['ProductSeries', 'TranslationImportQueueEntry'],
1250
 
            distinct=True, orderBy='Product.name'))
1251
 
 
1252
 
        distroseriess = shortlist(DistroSeries.select("""
1253
 
            defer_translation_imports IS FALSE AND
1254
 
            id IN (
1255
 
                SELECT DISTINCT distroseries
1256
 
                FROM TranslationImportQueueEntry
1257
 
                WHERE %s
1258
 
                )
1259
 
            """ % status_clause))
1260
 
        distroseriess.sort(key=distroseries_sort_key)
1261
 
 
1262
 
        return distroseriess + products
 
1290
            status_clause = (TranslationImportQueueEntry.status == status)
 
1291
 
 
1292
        distroseries = list_distroseries_request_targets(status_clause)
 
1293
        products = list_product_request_targets(status_clause)
 
1294
 
 
1295
        return distroseries + products
1263
1296
 
1264
1297
    def _attemptToSet(self, entry, potemplate=None, pofile=None):
1265
1298
        """Set potemplate or pofile on a `TranslationImportQueueEntry`.