1010# For more information on the license, see COPYING.
1111# For more information on free software, see
1212# <https://www.gnu.org/philosophy/free-sw.en.html>.
13+ #
14+ # This module provides utility functions for interacting with Zanata
15+ # translations of Fedora-style modules.
1316
17+ import sys
1418import gi
15- import koji
19+ import requests
1620
17- from collections import defaultdict
1821from babel .messages import Catalog
1922from datetime import datetime
2023
2124gi .require_version ('Modulemd' , '1.0' )
2225from gi .repository import Modulemd
2326
2427
25- def get_koji_session ():
26- return koji .ClientSession ('https://koji.fedoraproject.org/kojihub' )
27-
28-
29- def get_rawhide_version (session ):
30- return session .getBuildTargets ('rawhide' )[0 ]['build_tag_name' ].partition ('-build' )[0 ]
31-
32-
33- def get_tags_for_branch (branch ):
34- return ['%s-modular' % branch ,
35- '%s-modular-override' % branch ,
36- '%s-modular-pending' % branch ,
37- '%s-modular-signing-pending' % branch ,
38- '%s-modular-updates' % branch ,
39- '%s-modular-updates-candidate' % branch ,
40- '%s-modular-updates-pending' % branch ,
41- '%s-modular-updates-testing' % branch ,
42- '%s-modular-updates-testing-pending' % branch ]
28+ def get_latest_modules_in_tag (session , tag , debug = False ):
29+ """
30+ Get the most-recently built versions of each (module,stream) pair from
31+ a Koji tag
32+ :param session: A Koji session
33+ :param tag: A koji tag
34+ :return: A list of the most recent build of all modules in the tag.
35+ """
4336
44-
45- def get_latest_modules_in_tag (session , tag ):
46- tagged = session .listTagged (tag , latest = False )
37+ # Koji sometimes disconnects for no apparent reason. Retry up to 5
38+ # times before failing.
39+ for attempt in range (5 ):
40+ try :
41+ tagged = session .listTagged (tag , latest = False )
42+ except requests .exceptions .ConnectionError :
43+ if debug :
44+ print ("Connection lost while retrieving builds for tag %s, "
45+ "retrying..." % tag ,
46+ file = sys .stderr )
47+ else :
48+ # Succeeded this time, so break out of the loop
49+ break
4750
4851 # Find the latest, in module terms. Pungi does this.
4952 # Collect all contexts that share the same NSV.
@@ -66,22 +69,53 @@ def get_latest_modules_in_tag(session, tag):
6669 return latest
6770
6871
69- def get_module_catalog (session , builds ):
70- catalog = Catalog (project = "fedora-modularity-translations" )
72+ def get_module_catalog_from_tags (session , tags , debug = False ):
73+ """
74+ Construct a Babel translation source catalog from the contents of the
75+ provided tags.
76+ :param session: A Koji session
77+ :param tags: A set of Koji tags from which module metadata should be pulled
78+ :param debug: Whether to print debugging information to the console
79+ :return: A babel.messages.Catalog containing extracted translatable strings
80+ from any modules in the provided tags. Raises an exception if any of the
81+ retrieved modulemd is invalid.
82+ """
7183
72- for build_id in builds .keys ():
73- build = session .getBuild (build_id )
74- print ("Processing %s:%s" % (build ['package_name' ], build ['nvr' ]))
84+ catalog = Catalog (project = "fedora-modularity-translations" )
7585
76- module_stream = "%s:%s" % (
77- build ['extra' ]['typeinfo' ]['module' ]['name' ],
78- build ['extra' ]['typeinfo' ]['module' ]['stream' ])
86+ tagged_builds = []
87+ for tag in tags :
88+ tagged_builds .extend (get_latest_modules_in_tag (session , tag , debug ))
89+
90+ # Make the list unique since some modules may have multiple tags
91+ unique_builds = {}
92+ for build in tagged_builds :
93+ unique_builds [build ['id' ]] = build
94+
95+ for build_id in unique_builds .keys ():
96+ # Koji sometimes disconnects for no apparent reason. Retry up to 5
97+ # times before failing.
98+ for attempt in range (5 ):
99+ try :
100+ build = session .getBuild (build_id )
101+ except requests .exceptions .ConnectionError :
102+ if debug :
103+ print ("Connection lost while processing buildId %s, "
104+ "retrying..." % build_id ,
105+ file = sys .stderr )
106+ else :
107+ # Succeeded this time, so break out of the loop
108+ break
109+ if debug :
110+ print ("Processing %s:%s" % (build ['package_name' ], build ['nvr' ]))
79111
80112 modulemds = Modulemd .objects_from_string (
81113 build ['extra' ]['typeinfo' ]['module' ]['modulemd_str' ])
82114
83115 # We should only get a single modulemd document from Koji
84- assert len (modulemds ) == 1
116+ if len (modulemds ) != 1 :
117+ raise ValueError ("Koji build %s returned multiple modulemd YAML "
118+ "documents." % build ['nvr' ])
85119
86120 mmd = modulemds [0 ]
87121
0 commit comments