~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/translations/doc/translationimportqueue.txt

  • 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:
6
6
 
7
7
    >>> from zope.security.proxy import removeSecurityProxy
8
8
    >>> from canonical.launchpad.interfaces.lpstorm import IStore
 
9
    >>> from lp.registry.interfaces.distroseries import IDistroSeries
 
10
    >>> from lp.translations.interfaces.translationimportqueue import (
 
11
    ...     ITranslationImportQueue)
9
12
    >>> from lp.translations.model.translationimportqueue import (
10
13
    ...     TranslationImportQueueEntry)
11
14
 
 
15
    >>> translationimportqueue = getUtility(ITranslationImportQueue)
 
16
 
12
17
    >>> def clear_queue(queue):
13
18
    ...     """Remove all entries off the import queue."""
14
19
    ...     store = IStore(TranslationImportQueueEntry)
15
20
    ...     store.find(TranslationImportQueueEntry).remove()
16
21
 
 
22
    >>> def get_target_names(status=None):
 
23
    ...     """Call getRequestTargets, return list of names/titles."""
 
24
    ...     result = []
 
25
    ...     queue = translationimportqueue.getRequestTargets(status)
 
26
    ...     for object in queue:
 
27
    ...         if IDistroSeries.providedBy(object):
 
28
    ...             name = "%s/%s" % (object.distribution.name, object.name)
 
29
    ...         else:
 
30
    ...             name = object.name
 
31
    ...         result.append("%s %s" % (name, object.displayname))
 
32
    ...     return result
 
33
 
 
34
    >>> def print_list(strings):
 
35
    ...     """Print list of strings as list of lines."""
 
36
    ...     for string in strings:
 
37
    ...         print string
 
38
 
17
39
 
18
40
getGuessedPOFile
19
41
----------------
29
51
    >>> from canonical.database.sqlbase import flush_database_updates
30
52
    >>> from lp.app.interfaces.launchpad import ILaunchpadCelebrities
31
53
    >>> from lp.registry.interfaces.distribution import IDistributionSet
32
 
    >>> from lp.registry.interfaces.distroseries import IDistroSeries
33
54
    >>> from lp.registry.interfaces.product import IProductSet
34
55
    >>> from lp.registry.interfaces.sourcepackagename import (
35
56
    ...     ISourcePackageNameSet)
36
57
    >>> from lp.translations.enums import RosettaImportStatus
37
 
    >>> from lp.translations.interfaces.translationimportqueue import (
38
 
    ...     ITranslationImportQueue)
39
58
    >>> from lp.registry.model.distroseries import DistroSeries
40
59
    >>> from lp.registry.model.productseries import ProductSeries
41
60
    >>> from lp.registry.model.sourcepackagename import SourcePackageName
42
61
    >>> from canonical.launchpad.ftests import login
43
62
 
44
 
    >>> translationimportqueue = getUtility(ITranslationImportQueue)
45
63
    >>> rosetta_experts = getUtility(ILaunchpadCelebrities).rosetta_experts
46
64
 
47
65
    >>> distroset = getUtility(IDistributionSet)
931
949
    0
932
950
 
933
951
 
934
 
getRequestTargets
935
 
-----------------
936
 
 
937
 
    >>> # Helper functions
938
 
    >>> def get_target_names(status=None):
939
 
    ...     """Call getRequestTargets, return list of names/titles.
940
 
    ...     """
941
 
    ...     result = []
942
 
    ...     queue = translationimportqueue.getRequestTargets(status)
943
 
    ...     for object in queue:
944
 
    ...         if IDistroSeries.providedBy(object):
945
 
    ...             name = "%s/%s" % (object.distribution.name, object.name)
946
 
    ...         else:
947
 
    ...             name = object.name
948
 
    ...         result.append("%s %s" % (name, object.displayname))
949
 
    ...     return result
950
 
 
951
 
    >>> def print_list(strings):
952
 
    ...     """Print list of strings as list of lines."""
953
 
    ...     for string in strings:
954
 
    ...         print string
955
 
 
956
 
getRequestTargets() returns all objects that have entries in the
957
 
translation import queue waiting to be imported.  Object can be a
958
 
Product or a DistroSeries.
959
 
 
960
 
The user uploads two translations into Hoary and Warty respectively, as
961
 
well as one for the Firefox trunk series.
962
 
 
963
 
    >>> from lp.registry.interfaces.distribution import (
964
 
    ...     IDistributionSet)
965
 
    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
966
 
    >>> hoary_distroseries = ubuntu.getSeries('hoary')
967
 
    >>> evolution_sourcepackagename = (
968
 
    ...     SourcePackageName.selectOne("name='evolution'"))
969
 
    >>> entry1 = translationimportqueue.addOrUpdateEntry(
970
 
    ...     u'po/sr.po', 'foo', True, rosetta_experts,
971
 
    ...      distroseries=hoary_distroseries,
972
 
    ...      sourcepackagename=evolution_sourcepackagename)
973
 
 
974
 
    >>> warty_distroseries = ubuntu.getSeries('warty')
975
 
    >>> entry3 = translationimportqueue.addOrUpdateEntry(
976
 
    ...     u'po/sr.po', 'foo', True, rosetta_experts,
977
 
    ...      distroseries=warty_distroseries,
978
 
    ...      sourcepackagename=evolution_sourcepackagename)
979
 
    >>> print entry3.status.name
980
 
    NEEDS_REVIEW
981
 
 
982
 
    >>> firefox = productset['firefox']
983
 
    >>> productseries = firefox.getSeries('trunk')
984
 
    >>> entry2 = translationimportqueue.addOrUpdateEntry(
985
 
    ...     'foo/bar.pot', 'foo content', True,
986
 
    ...     rosetta_experts, productseries=productseries)
987
 
    >>> flush_database_updates()
988
 
 
989
 
The list of objects with approved entries is still empty, since we haven't
990
 
approved any.
991
 
 
992
 
    >>> print_list(sorted(get_target_names(RosettaImportStatus.APPROVED)))
993
 
 
994
 
    >>> print entry3.status.name
995
 
    NEEDS_REVIEW
996
 
 
997
 
Now we approve these entries (we need to be Rosetta administrator to do this).
998
 
We also need to set an import target.
999
 
 
1000
 
    >>> login('carlos@canonical.com')
1001
 
    >>> entry1.potemplate = factory.makePOTemplate(
1002
 
    ...     name=u"evolution",
1003
 
    ...     distroseries=hoary_distroseries,
1004
 
    ...     sourcepackagename=evolution_sourcepackagename)
1005
 
    >>> entry1.pofile = factory.makePOFile('sr', potemplate=entry1.potemplate)
1006
 
    >>> entry1.setStatus(RosettaImportStatus.APPROVED, rosetta_experts)
1007
 
    >>> entry2.potemplate = factory.makePOTemplate(
1008
 
    ...     name=u"firefox",
1009
 
    ...     productseries=productseries)
1010
 
    >>> entry2.setStatus(RosettaImportStatus.APPROVED, rosetta_experts)
1011
 
 
1012
 
    >>> flush_database_updates()
1013
 
    >>> translationimportqueue = getUtility(ITranslationImportQueue)
1014
 
 
1015
 
If we re-get the list of objects which have approved entries, we'll
1016
 
get these recently approved ones.
1017
 
 
1018
 
    >>> print_list(sorted(get_target_names(RosettaImportStatus.APPROVED)))
1019
 
    firefox         Mozilla Firefox
1020
 
    ubuntu/hoary    Hoary
1021
 
 
1022
 
Lets check that the returned entries are actually the same ones we submitted.
1023
 
Each of the objects returned provides a getFirstEntryToImport method
1024
 
which returns the TranslationImportQueueEntry which is next up for import.
1025
 
 
1026
 
    >>> importqueues = translationimportqueue.getRequestTargets(
1027
 
    ...     RosettaImportStatus.APPROVED)
1028
 
    >>> sortedqueues = sorted(importqueues,
1029
 
    ...                       cmp=lambda x,y: cmp(y.title, x.title))
1030
 
    >>> queue1 = sortedqueues[0]
1031
 
    >>> queue1.title
1032
 
    u'The Hoary Hedgehog Release'
1033
 
    >>> entry = queue1.getFirstEntryToImport()
1034
 
    >>> entry == entry1
1035
 
    True
1036
 
 
1037
 
    >>> queue2 = sortedqueues[1]
1038
 
    >>> queue2.title
1039
 
    u'Mozilla Firefox'
1040
 
    >>> entry = queue2.getFirstEntryToImport()
1041
 
    >>> entry == entry2
1042
 
    True
1043
 
 
1044
 
Note that our third entry never received approval, so it is still awaiting
1045
 
review.
1046
 
 
1047
 
    >>> print entry3.status.name
1048
 
    NEEDS_REVIEW
1049
 
 
1050
 
    >>> print_list(sorted(get_target_names()))
1051
 
    evolution       Evolution
1052
 
    firefox         Mozilla Firefox
1053
 
    ubuntu/hoary    Hoary
1054
 
    ubuntu/warty    Warty
1055
 
 
1056
 
Administrators temporarily block translation imports to Warty.
1057
 
 
1058
 
    >>> warty_distroseries.defer_translation_imports = True
1059
 
 
1060
 
While imports are blocked, Warty does not show up as having pending
1061
 
imports.
1062
 
 
1063
 
    >>> print_list(sorted(get_target_names()))
1064
 
    evolution       Evolution
1065
 
    firefox         Mozilla Firefox
1066
 
    ubuntu/hoary    Hoary
1067
 
 
1068
 
An administrator deactivates Firefox, thinking that the project is being
1069
 
run in violation of Launchpad policies.
1070
 
 
1071
 
    # Unlink the source packages so the project can be deactivated.
1072
 
    >>> from lp.testing import unlink_source_packages
1073
 
    >>> unlink_source_packages(firefox)
1074
 
    >>> firefox.active = False
1075
 
 
1076
 
Now that Firefox is inactive, it no longer shows up as having pending
1077
 
imports.
1078
 
 
1079
 
    >>> print_list(sorted(get_target_names()))
1080
 
    evolution       Evolution
1081
 
    ubuntu/hoary    Hoary
1082
 
 
1083
 
The administrator realizes that there has been a mistake, and makes
1084
 
Firefox active again.
1085
 
 
1086
 
    >>> firefox.active = True
1087
 
 
1088
 
The import request for Firefox was not removed, so Firefox is listed as
1089
 
having pending imports again.
1090
 
 
1091
 
    >>> print_list(sorted(get_target_names()))
1092
 
    evolution       Evolution
1093
 
    firefox         Mozilla Firefox
1094
 
    ubuntu/hoary    Hoary
1095
 
 
1096
952
addOrUpdateEntry()
1097
953
------------------
1098
954
 
1137
993
 
1138
994
    >>> queue = getUtility(ITranslationImportQueue)
1139
995
    >>> print_queue_entries(queue)
1140
 
    hoary evolution | evolution          | po/sr.po
1141
 
    firefox         | firefox            | foo/bar.pot
1142
996
    evolution       | evolution-2.2-test | po/evolution-2.2-test.pot
1143
997
    evolution       | evolution-2.2-test | po/pt_BR.po
1144
998
    firefox         | None               | foo/bar.po
1145
999
    evolution       | None               | po/sr.po
 
1000
    hoary evolution | None               | po/sr.po
1146
1001
    hoary evolution | None               | po/evolution-2.2.pot
1147
 
    warty evolution | None               | po/sr.po
1148
1002
 
1149
1003
Attach the sample tarball to the 'evolution-2.2-test' template in evolution
1150
1004
product. We can ask to only upload the template from the tarball and ignore
1160
1014
And this new entry in the queue appears in the list.
1161
1015
 
1162
1016
    >>> print_queue_entries(queue)
1163
 
    hoary evolution | evolution          | po/sr.po
1164
 
    firefox         | firefox            | foo/bar.pot
1165
1017
    evolution       | evolution-2.2-test | po/evolution-2.2-test.pot
1166
1018
    evolution       | evolution-2.2-test | po/pt_BR.po
1167
1019
    firefox         | None               | foo/bar.po
1168
1020
    evolution       | None               | po/sr.po
 
1021
    hoary evolution | None               | po/sr.po
1169
1022
    hoary evolution | None               | po/evolution-2.2.pot
1170
 
    warty evolution | None               | po/sr.po
1171
1023
    evolution       | evolution-2.2-test | foo.pot
1172
1024
 
1173
1025
 
1183
1035
And those new entries in the queue appear in the list.
1184
1036
 
1185
1037
    >>> print_queue_entries(queue)
1186
 
    hoary evolution | evolution          | po/sr.po
1187
 
    firefox         | firefox            | foo/bar.pot
1188
1038
    evolution       | evolution-2.2-test | po/evolution-2.2-test.pot
1189
1039
    evolution       | evolution-2.2-test | po/pt_BR.po
1190
1040
    firefox         | None               | foo/bar.po
1191
1041
    evolution       | None               | po/sr.po
 
1042
    hoary evolution | None               | po/sr.po
1192
1043
    hoary evolution | None               | po/evolution-2.2.pot
1193
 
    warty evolution | None               | po/sr.po
1194
1044
    evolution       | evolution-2.2-test | foo.pot
1195
1045
    evolution       | evolution-2.2-test | es.po
1196
1046
    evolution       | evolution-2.2-test | fr.po
1263
1113
the extra three entries.
1264
1114
 
1265
1115
    >>> print_queue_entries(queue)
 
1116
    evolution ...
1266
1117
    hoary ...
1267
1118
    ...
1268
1119
    evolution       | evolution-2.2-test | foo.pot
1295
1146
These files are put into different entries.
1296
1147
 
1297
1148
    >>> print_queue_entries(queue)
 
1149
    evolution ...
1298
1150
    hoary ...
1299
1151
    ...
1300
1152
    evolution       | evolution-2.2      | fr.po
1350
1202
tarball were exactly as the filename filter returned them.
1351
1203
 
1352
1204
    >>> print_queue_entries(queue)
 
1205
    evolution ...
1353
1206
    hoary evolution | ...
1354
1207
    ...
1355
1208
    evolution       | evolution-2.2      | bar.pot
1436
1289
    >>> clear_queue(translationimportqueue)
1437
1290
 
1438
1291
 
1439
 
getRequestTargets output ordering
1440
 
---------------------------------
1441
 
 
1442
 
The queue is populated with a wild mix of requests: for packages in
1443
 
different release series of Ubuntu, for packages in different distros,
1444
 
for product series, with different statuses; some were imported from
1445
 
upstream, some were produced right here in Launchpad.
1446
 
 
1447
 
    >>> def create_distro_request(distro_name, series_name):
1448
 
    ...     """Enqueue an import request for given distro package."""
1449
 
    ...     distro = distroset[distro_name]
1450
 
    ...     series = distro.getSeries(series_name)
1451
 
    ...     package = packageset['pmount']
1452
 
    ...     template = factory.makePOTemplate(distroseries=series,
1453
 
    ...                                       sourcepackagename=package)
1454
 
    ...     # In a completely arbitrary move, we make all import requests for
1455
 
    ...     # distro series imported.
1456
 
    ...     return translationimportqueue.addOrUpdateEntry('messages.pot',
1457
 
    ...         'dummy file', True, rosetta_experts, distroseries=series,
1458
 
    ...         sourcepackagename=package, potemplate=template)
1459
 
 
1460
 
    >>> def create_product_request(product_name, template_name):
1461
 
    ...     """Enqueue an import request for given product and template."""
1462
 
    ...     product = productset[product_name]
1463
 
    ...     series = product.primary_translatable
1464
 
    ...     assert series is not None, (
1465
 
    ...         "Product %s has no translatable series." % product_name)
1466
 
    ...     template = series.getPOTemplate(template_name)
1467
 
    ...     # In another completely arbitrary move, we make all import
1468
 
    ...     # requests for products non-imported.
1469
 
    ...     return translationimportqueue.addOrUpdateEntry('messages.pot',
1470
 
    ...         'dummy file', False, rosetta_experts, productseries=series,
1471
 
    ...         potemplate=template)
1472
 
 
1473
 
    >>> # Populate import queue with wild mix of requests.
1474
 
    >>> entry = create_product_request('evolution', 'evolution-2.2')
1475
 
    >>> entry.setStatus(RosettaImportStatus.APPROVED, rosetta_experts)
1476
 
    >>> entry = create_distro_request('debian', 'sarge')
1477
 
    >>> entry.setStatus(RosettaImportStatus.NEEDS_REVIEW, rosetta_experts)
1478
 
    >>> entry = create_product_request('alsa-utils', 'alsa-utils')
1479
 
    >>> entry.setStatus(RosettaImportStatus.FAILED, rosetta_experts)
1480
 
    >>> entry = create_distro_request('ubuntu', 'grumpy')
1481
 
    >>> entry.setStatus(RosettaImportStatus.BLOCKED, rosetta_experts)
1482
 
    >>> entry = create_distro_request('kubuntu', 'krunch')
1483
 
    >>> entry.setStatus(RosettaImportStatus.APPROVED, rosetta_experts)
1484
 
    >>> entry = create_product_request('evolution', 'evolution-2.2-test')
1485
 
    >>> entry.setStatus(RosettaImportStatus.IMPORTED, rosetta_experts)
1486
 
    >>> entry = create_distro_request('debian', 'woody')
1487
 
    >>> entry.setStatus(RosettaImportStatus.NEEDS_REVIEW, rosetta_experts)
1488
 
    >>> flush_database_updates()
1489
 
 
1490
 
TranslationImportQueue.getRequestTargets first lists distro series
1491
 
(ordered by distro name and series name), followed by products (ordered
1492
 
by name).
1493
 
 
1494
 
    >>> print_list(get_target_names())
1495
 
    debian/sarge        Sarge
1496
 
    debian/woody        Woody
1497
 
    kubuntu/krunch      Krunch
1498
 
    ubuntu/grumpy       Grumpy
1499
 
    alsa-utils          alsa-utils
1500
 
    evolution           Evolution
1501
 
 
1502
 
    >>> for status in RosettaImportStatus.items:
1503
 
    ...     print "%s:" % status.name
1504
 
    ...     print_list(get_target_names(status))
1505
 
    APPROVED:
1506
 
    kubuntu/krunch      Krunch
1507
 
    evolution           Evolution
1508
 
    IMPORTED:
1509
 
    evolution           Evolution
1510
 
    DELETED:
1511
 
    FAILED:
1512
 
    alsa-utils          alsa-utils
1513
 
    NEEDS_REVIEW:
1514
 
    debian/sarge        Sarge
1515
 
    debian/woody        Woody
1516
 
    BLOCKED:
1517
 
    ubuntu/grumpy       Grumpy
1518
 
    NEEDS_INFORMATION:
1519
 
 
1520
 
You can also select by status.
1521
 
 
1522
 
    >>> print_list(get_target_names(RosettaImportStatus.APPROVED))
1523
 
    kubuntu/krunch      Krunch
1524
 
    evolution           Evolution
1525
 
 
1526
 
 
1527
1292
cleanUpQueue
1528
1293
------------
1529
1294
 
1580
1345
 
1581
1346
    >>> from lp.app.enums import ServiceUsage
1582
1347
 
 
1348
    >>> def create_product_request(product_name, template_name):
 
1349
    ...     """Enqueue an import request for given product and template."""
 
1350
    ...     product = productset[product_name]
 
1351
    ...     series = product.primary_translatable
 
1352
    ...     assert series is not None, (
 
1353
    ...         "Product %s has no translatable series." % product_name)
 
1354
    ...     template = series.getPOTemplate(template_name)
 
1355
    ...     # In another completely arbitrary move, we make all import
 
1356
    ...     # requests for products non-imported.
 
1357
    ...     return translationimportqueue.addOrUpdateEntry('messages.pot',
 
1358
    ...         'dummy file', False, rosetta_experts, productseries=series,
 
1359
    ...         potemplate=template)
 
1360
 
1583
1361
    >>> jokosher = productset['jokosher']
1584
1362
    >>> jokosher_trunk = jokosher.getSeries('trunk')
1585
1363
    >>> jokosher.translations_usage = ServiceUsage.LAUNCHPAD