Merge ~cjwatson/launchpad:distroseries-translation-stats into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: d76c383c27f63f99f72450a2b816d88c884ebf96
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:distroseries-translation-stats
Merge into: launchpad:master
Diff against target: 198 lines (+124/-0)
3 files modified
lib/lp/registry/interfaces/distroseries.py (+50/-0)
lib/lp/registry/model/distroseries.py (+38/-0)
lib/lp/registry/tests/test_distroseries.py (+36/-0)
Reviewer Review Type Date Requested Status
Guruprasad Approve
Review via email: mp+435396@code.launchpad.net

Commit message

Add and export DistroSeries.getTranslationTemplateStatistics

Description of the change

This will allow us to generate the `*_potemplate-stats.json` files in https://people.canonical.com/~people-l10n/data/ubuntu-l10n/ using a simple webservice client rather than using a script with direct database access. (We could generate `*_package-stats.json` in a similar way, but so far I haven't found anything that uses those files.)

To post a comment you must log in.
Revision history for this message
Guruprasad (lgp171188) wrote :

LGTM 👍

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/registry/interfaces/distroseries.py b/lib/lp/registry/interfaces/distroseries.py
2index 03e6d68..22fddd0 100644
3--- a/lib/lp/registry/interfaces/distroseries.py
4+++ b/lib/lp/registry/interfaces/distroseries.py
5@@ -6,6 +6,7 @@
6 __all__ = [
7 "DerivationError",
8 "DistroSeriesNameField",
9+ "DistroSeriesTranslationTemplateStatistics",
10 "IDistroSeries",
11 "IDistroSeriesEditRestricted",
12 "IDistroSeriesPublic",
13@@ -13,6 +14,8 @@ __all__ = [
14 ]
15
16 import http.client
17+import typing
18+from datetime import datetime
19
20 from lazr.lifecycle.snapshot import doNotSnapshot
21 from lazr.restful.declarations import (
22@@ -31,6 +34,7 @@ from lazr.restful.declarations import (
23 rename_parameters_as,
24 )
25 from lazr.restful.fields import CollectionField, Reference, ReferenceChoice
26+from typing_extensions import TypedDict
27 from zope.component import getUtility
28 from zope.interface import Attribute, Interface
29 from zope.schema import Bool, Choice, Datetime, List, Object, TextLine
30@@ -165,6 +169,30 @@ class DistroSeriesVersionField(UniqueField):
31 raise LaunchpadValidationError("'%s': %s" % (version, error))
32
33
34+DistroSeriesTranslationTemplateStatistics = TypedDict(
35+ "DistroSeriesTranslationTemplateStatistics",
36+ {
37+ # The name of the source package that uses the template.
38+ "sourcepackage": str,
39+ # The translation domain for the template.
40+ "translation_domain": str,
41+ # The name of the template.
42+ "template_name": str,
43+ # The number of translation messages for the template.
44+ "total": int,
45+ # Whether the template is active.
46+ "enabled": bool,
47+ # Whether the template is part of a language pack.
48+ "languagepack": bool,
49+ # A number that describes how important this template is; templates
50+ # with higher priorities should be translated first.
51+ "priority": int,
52+ # When the template was last updated.
53+ "date_last_updated": datetime,
54+ },
55+)
56+
57+
58 class IDistroSeriesPublic(
59 ISeriesMixin,
60 IHasAppointedDriver,
61@@ -1098,6 +1126,28 @@ class IDistroSeriesPublic(
62 comment.
63 """
64
65+ @export_read_operation()
66+ @operation_for_version("devel")
67+ def getTranslationTemplateStatistics() -> typing.List[
68+ DistroSeriesTranslationTemplateStatistics
69+ ]:
70+ """Return statistics for translation templates in this series.
71+
72+ The return value is a list of dicts for each template in the series,
73+ each of which has this form::
74+
75+ {
76+ "sourcepackage": ...,
77+ "translation_domain": ...,
78+ "name": ...,
79+ "total": ...,
80+ "enabled": ...,
81+ "languagepack": ...,
82+ "priority": ...,
83+ "date_last_updated": ...,
84+ }
85+ """
86+
87
88 class IDistroSeriesEditRestricted(Interface):
89 """IDistroSeries properties which require launchpad.Edit."""
90diff --git a/lib/lp/registry/model/distroseries.py b/lib/lp/registry/model/distroseries.py
91index 7844249..68f102f 100644
92--- a/lib/lp/registry/model/distroseries.py
93+++ b/lib/lp/registry/model/distroseries.py
94@@ -13,6 +13,7 @@ __all__ = [
95 import collections
96 from io import BytesIO
97 from operator import itemgetter
98+from typing import List
99
100 import apt_pkg
101 from lazr.delegates import delegate_to
102@@ -41,6 +42,7 @@ from lp.buildmaster.model.processor import Processor
103 from lp.registry.errors import NoSuchDistroSeries
104 from lp.registry.interfaces.distroseries import (
105 DerivationError,
106+ DistroSeriesTranslationTemplateStatistics,
107 IDistroSeries,
108 IDistroSeriesSet,
109 )
110@@ -1704,6 +1706,42 @@ class DistroSeries(
111 self, since=since, source_package_name=source_package_name
112 )
113
114+ def getTranslationTemplateStatistics(
115+ self,
116+ ) -> List[DistroSeriesTranslationTemplateStatistics]:
117+ """See `IDistroSeries`."""
118+ rows = (
119+ IStore(POTemplate)
120+ .find(
121+ (
122+ SourcePackageName.name,
123+ POTemplate.translation_domain,
124+ POTemplate.name,
125+ POTemplate.messagecount,
126+ POTemplate.iscurrent,
127+ POTemplate.languagepack,
128+ POTemplate.priority,
129+ POTemplate.date_last_updated,
130+ ),
131+ POTemplate.distroseries == self,
132+ POTemplate.sourcepackagename == SourcePackageName.id,
133+ )
134+ .order_by(SourcePackageName.name, POTemplate.name)
135+ )
136+ return [
137+ {
138+ "sourcepackage": row[0],
139+ "translation_domain": row[1],
140+ "template_name": row[2],
141+ "total": row[3],
142+ "enabled": row[4],
143+ "languagepack": row[5],
144+ "priority": row[6],
145+ "date_last_updated": row[7],
146+ }
147+ for row in rows
148+ ]
149+
150
151 @implementer(IDistroSeriesSet)
152 class DistroSeriesSet:
153diff --git a/lib/lp/registry/tests/test_distroseries.py b/lib/lp/registry/tests/test_distroseries.py
154index ab3c6bf..2c7c329 100644
155--- a/lib/lp/registry/tests/test_distroseries.py
156+++ b/lib/lp/registry/tests/test_distroseries.py
157@@ -712,6 +712,42 @@ class TestDistroSeriesWebservice(TestCaseWithFactory):
158 self.assertEqual(209, response.status)
159 self.assertTrue(distroseries.language_pack_full_export_requested)
160
161+ def test_translation_template_statistics(self):
162+ distroseries = self.factory.makeDistroSeries()
163+ templates = [
164+ self.factory.makePOTemplate(distroseries=distroseries)
165+ for _ in range(3)
166+ ]
167+ removeSecurityProxy(templates[0]).messagecount = 100
168+ removeSecurityProxy(templates[0]).priority = 10
169+ removeSecurityProxy(templates[1]).iscurrent = False
170+ removeSecurityProxy(templates[2]).languagepack = True
171+ self.factory.makePOTemplate()
172+ distroseries_url = api_url(distroseries)
173+ webservice = webservice_for_person(None, default_api_version="devel")
174+ response = webservice.named_get(
175+ distroseries_url, "getTranslationTemplateStatistics"
176+ )
177+ self.assertEqual(200, response.status)
178+ self.assertEqual(
179+ [
180+ {
181+ "sourcepackage": template.sourcepackage.name,
182+ "translation_domain": template.translation_domain,
183+ "template_name": template.name,
184+ "total": template.messagecount,
185+ "enabled": template.iscurrent,
186+ "languagepack": template.languagepack,
187+ "priority": template.priority,
188+ "date_last_updated": (
189+ template.date_last_updated.isoformat()
190+ ),
191+ }
192+ for template in templates
193+ ],
194+ response.jsonBody(),
195+ )
196+
197
198 class TestDistroSeriesSet(TestCaseWithFactory):
199

Subscribers

People subscribed via source and target branches

to status/vote changes: