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
diff --git a/lib/lp/registry/interfaces/distroseries.py b/lib/lp/registry/interfaces/distroseries.py
index 03e6d68..22fddd0 100644
--- a/lib/lp/registry/interfaces/distroseries.py
+++ b/lib/lp/registry/interfaces/distroseries.py
@@ -6,6 +6,7 @@
6__all__ = [6__all__ = [
7 "DerivationError",7 "DerivationError",
8 "DistroSeriesNameField",8 "DistroSeriesNameField",
9 "DistroSeriesTranslationTemplateStatistics",
9 "IDistroSeries",10 "IDistroSeries",
10 "IDistroSeriesEditRestricted",11 "IDistroSeriesEditRestricted",
11 "IDistroSeriesPublic",12 "IDistroSeriesPublic",
@@ -13,6 +14,8 @@ __all__ = [
13]14]
1415
15import http.client16import http.client
17import typing
18from datetime import datetime
1619
17from lazr.lifecycle.snapshot import doNotSnapshot20from lazr.lifecycle.snapshot import doNotSnapshot
18from lazr.restful.declarations import (21from lazr.restful.declarations import (
@@ -31,6 +34,7 @@ from lazr.restful.declarations import (
31 rename_parameters_as,34 rename_parameters_as,
32)35)
33from lazr.restful.fields import CollectionField, Reference, ReferenceChoice36from lazr.restful.fields import CollectionField, Reference, ReferenceChoice
37from typing_extensions import TypedDict
34from zope.component import getUtility38from zope.component import getUtility
35from zope.interface import Attribute, Interface39from zope.interface import Attribute, Interface
36from zope.schema import Bool, Choice, Datetime, List, Object, TextLine40from zope.schema import Bool, Choice, Datetime, List, Object, TextLine
@@ -165,6 +169,30 @@ class DistroSeriesVersionField(UniqueField):
165 raise LaunchpadValidationError("'%s': %s" % (version, error))169 raise LaunchpadValidationError("'%s': %s" % (version, error))
166170
167171
172DistroSeriesTranslationTemplateStatistics = TypedDict(
173 "DistroSeriesTranslationTemplateStatistics",
174 {
175 # The name of the source package that uses the template.
176 "sourcepackage": str,
177 # The translation domain for the template.
178 "translation_domain": str,
179 # The name of the template.
180 "template_name": str,
181 # The number of translation messages for the template.
182 "total": int,
183 # Whether the template is active.
184 "enabled": bool,
185 # Whether the template is part of a language pack.
186 "languagepack": bool,
187 # A number that describes how important this template is; templates
188 # with higher priorities should be translated first.
189 "priority": int,
190 # When the template was last updated.
191 "date_last_updated": datetime,
192 },
193)
194
195
168class IDistroSeriesPublic(196class IDistroSeriesPublic(
169 ISeriesMixin,197 ISeriesMixin,
170 IHasAppointedDriver,198 IHasAppointedDriver,
@@ -1098,6 +1126,28 @@ class IDistroSeriesPublic(
1098 comment.1126 comment.
1099 """1127 """
11001128
1129 @export_read_operation()
1130 @operation_for_version("devel")
1131 def getTranslationTemplateStatistics() -> typing.List[
1132 DistroSeriesTranslationTemplateStatistics
1133 ]:
1134 """Return statistics for translation templates in this series.
1135
1136 The return value is a list of dicts for each template in the series,
1137 each of which has this form::
1138
1139 {
1140 "sourcepackage": ...,
1141 "translation_domain": ...,
1142 "name": ...,
1143 "total": ...,
1144 "enabled": ...,
1145 "languagepack": ...,
1146 "priority": ...,
1147 "date_last_updated": ...,
1148 }
1149 """
1150
11011151
1102class IDistroSeriesEditRestricted(Interface):1152class IDistroSeriesEditRestricted(Interface):
1103 """IDistroSeries properties which require launchpad.Edit."""1153 """IDistroSeries properties which require launchpad.Edit."""
diff --git a/lib/lp/registry/model/distroseries.py b/lib/lp/registry/model/distroseries.py
index 7844249..68f102f 100644
--- a/lib/lp/registry/model/distroseries.py
+++ b/lib/lp/registry/model/distroseries.py
@@ -13,6 +13,7 @@ __all__ = [
13import collections13import collections
14from io import BytesIO14from io import BytesIO
15from operator import itemgetter15from operator import itemgetter
16from typing import List
1617
17import apt_pkg18import apt_pkg
18from lazr.delegates import delegate_to19from lazr.delegates import delegate_to
@@ -41,6 +42,7 @@ from lp.buildmaster.model.processor import Processor
41from lp.registry.errors import NoSuchDistroSeries42from lp.registry.errors import NoSuchDistroSeries
42from lp.registry.interfaces.distroseries import (43from lp.registry.interfaces.distroseries import (
43 DerivationError,44 DerivationError,
45 DistroSeriesTranslationTemplateStatistics,
44 IDistroSeries,46 IDistroSeries,
45 IDistroSeriesSet,47 IDistroSeriesSet,
46)48)
@@ -1704,6 +1706,42 @@ class DistroSeries(
1704 self, since=since, source_package_name=source_package_name1706 self, since=since, source_package_name=source_package_name
1705 )1707 )
17061708
1709 def getTranslationTemplateStatistics(
1710 self,
1711 ) -> List[DistroSeriesTranslationTemplateStatistics]:
1712 """See `IDistroSeries`."""
1713 rows = (
1714 IStore(POTemplate)
1715 .find(
1716 (
1717 SourcePackageName.name,
1718 POTemplate.translation_domain,
1719 POTemplate.name,
1720 POTemplate.messagecount,
1721 POTemplate.iscurrent,
1722 POTemplate.languagepack,
1723 POTemplate.priority,
1724 POTemplate.date_last_updated,
1725 ),
1726 POTemplate.distroseries == self,
1727 POTemplate.sourcepackagename == SourcePackageName.id,
1728 )
1729 .order_by(SourcePackageName.name, POTemplate.name)
1730 )
1731 return [
1732 {
1733 "sourcepackage": row[0],
1734 "translation_domain": row[1],
1735 "template_name": row[2],
1736 "total": row[3],
1737 "enabled": row[4],
1738 "languagepack": row[5],
1739 "priority": row[6],
1740 "date_last_updated": row[7],
1741 }
1742 for row in rows
1743 ]
1744
17071745
1708@implementer(IDistroSeriesSet)1746@implementer(IDistroSeriesSet)
1709class DistroSeriesSet:1747class DistroSeriesSet:
diff --git a/lib/lp/registry/tests/test_distroseries.py b/lib/lp/registry/tests/test_distroseries.py
index ab3c6bf..2c7c329 100644
--- a/lib/lp/registry/tests/test_distroseries.py
+++ b/lib/lp/registry/tests/test_distroseries.py
@@ -712,6 +712,42 @@ class TestDistroSeriesWebservice(TestCaseWithFactory):
712 self.assertEqual(209, response.status)712 self.assertEqual(209, response.status)
713 self.assertTrue(distroseries.language_pack_full_export_requested)713 self.assertTrue(distroseries.language_pack_full_export_requested)
714714
715 def test_translation_template_statistics(self):
716 distroseries = self.factory.makeDistroSeries()
717 templates = [
718 self.factory.makePOTemplate(distroseries=distroseries)
719 for _ in range(3)
720 ]
721 removeSecurityProxy(templates[0]).messagecount = 100
722 removeSecurityProxy(templates[0]).priority = 10
723 removeSecurityProxy(templates[1]).iscurrent = False
724 removeSecurityProxy(templates[2]).languagepack = True
725 self.factory.makePOTemplate()
726 distroseries_url = api_url(distroseries)
727 webservice = webservice_for_person(None, default_api_version="devel")
728 response = webservice.named_get(
729 distroseries_url, "getTranslationTemplateStatistics"
730 )
731 self.assertEqual(200, response.status)
732 self.assertEqual(
733 [
734 {
735 "sourcepackage": template.sourcepackage.name,
736 "translation_domain": template.translation_domain,
737 "template_name": template.name,
738 "total": template.messagecount,
739 "enabled": template.iscurrent,
740 "languagepack": template.languagepack,
741 "priority": template.priority,
742 "date_last_updated": (
743 template.date_last_updated.isoformat()
744 ),
745 }
746 for template in templates
747 ],
748 response.jsonBody(),
749 )
750
715751
716class TestDistroSeriesSet(TestCaseWithFactory):752class TestDistroSeriesSet(TestCaseWithFactory):
717753

Subscribers

People subscribed via source and target branches

to status/vote changes: