|
18 | 18 | import gi |
19 | 19 | import requests |
20 | 20 |
|
21 | | -from babel.messages import Catalog |
| 21 | +from babel.messages import Catalog, pofile |
22 | 22 | from datetime import datetime |
| 23 | +from io import BytesIO |
23 | 24 |
|
24 | 25 | gi.require_version('Modulemd', '1.0') |
25 | 26 | from gi.repository import Modulemd |
26 | 27 |
|
27 | 28 |
|
| 29 | +############################################################################## |
| 30 | +# Exceptions # |
| 31 | +############################################################################## |
| 32 | + |
| 33 | + |
| 34 | +class MmdZanataError(Exception): |
| 35 | + pass |
| 36 | + |
| 37 | + |
| 38 | +class NonexistentProjectError(MmdZanataError): |
| 39 | + def __init__(self, project, version): |
| 40 | + """ |
| 41 | + Exception thrown when the user has requested a Zanata project that |
| 42 | + does not exist |
| 43 | + :param project: The nonexistent project name |
| 44 | + :param version: The version of the project in Zanata |
| 45 | + """ |
| 46 | + self.project = project |
| 47 | + self.version = version |
| 48 | + self.message = "The project %s does not exist in Zanata" % project |
| 49 | + |
| 50 | +class UnexpectedHTTPResponse(MmdZanataError): |
| 51 | + def __init__(self, status_code, body): |
| 52 | + """ |
| 53 | + Exception thrown when an unexpected response is received from an HTTP |
| 54 | + request. |
| 55 | + :param body: The response body |
| 56 | + """ |
| 57 | + self.status_code = status_code |
| 58 | + self.body = body |
| 59 | + |
| 60 | + |
28 | 61 | def get_latest_modules_in_tag(session, tag, debug=False): |
29 | 62 | """ |
30 | 63 | Get the most-recently built versions of each (module,stream) pair from |
@@ -158,6 +191,36 @@ def get_module_catalog_from_tags(session, tags, debug=False): |
158 | 191 | return catalog |
159 | 192 |
|
160 | 193 |
|
| 194 | +def get_translated_locales(zanata_rest_url, zanata_project, |
| 195 | + zanata_project_version, |
| 196 | + debug=False): |
| 197 | + # Get the statistics on the translation project for this version |
| 198 | + stats_url = zanata_rest_url + "/stats/proj/%s/iter/%s" % ( |
| 199 | + zanata_project, zanata_project_version) |
| 200 | + |
| 201 | + r = requests.get(stats_url, headers={"Accept": "application/json"}) |
| 202 | + if r.status_code == 404: |
| 203 | + print("Project '%s:%s' does not exist." % ( |
| 204 | + zanata_project, zanata_project_version), |
| 205 | + file=sys.stderr) |
| 206 | + raise NonexistentProjectError(zanata_project, zanata_project_version) |
| 207 | + elif r.status_code != 200: |
| 208 | + raise UnexpectedHTTPResponse(r.status_code, r.content) |
| 209 | + |
| 210 | + # We will pull down information for any locale that is at least partially |
| 211 | + # translated |
| 212 | + translated_locales = [t["locale"] |
| 213 | + for t in r.json()['stats'] |
| 214 | + if t["translated"] > 0] |
| 215 | + |
| 216 | + if debug: |
| 217 | + print("Available locales: ") |
| 218 | + for locale in translated_locales: |
| 219 | + print("* %s" % locale) |
| 220 | + |
| 221 | + return translated_locales |
| 222 | + |
| 223 | + |
161 | 224 | def get_modulemd_translations_from_catalog_dict(catalog_dict): |
162 | 225 | now = datetime.utcnow() |
163 | 226 | modified = int("%04d%02d%02d%02d%02d%02d" % ( |
@@ -230,3 +293,41 @@ def get_modulemd_translations_from_catalog_dict(catalog_dict): |
230 | 293 | mmd_translations[(module_name, module_stream)] = mmdtranslation |
231 | 294 |
|
232 | 295 | return mmd_translations.values() |
| 296 | + |
| 297 | +def get_modulemd_translations(zanata_rest_url, zanata_project, |
| 298 | + os_branch, zanata_translation_file, |
| 299 | + debug=False): |
| 300 | + translated_locales = get_translated_locales(zanata_rest_url, |
| 301 | + zanata_project, |
| 302 | + os_branch, |
| 303 | + debug) |
| 304 | + |
| 305 | + catalogs = dict() |
| 306 | + for loc in translated_locales: |
| 307 | + # Get the translation data for this locale |
| 308 | + pofile_url = zanata_rest_url + \ |
| 309 | + "/file/translation/%s/%s/%s/po?docId=%s" % ( |
| 310 | + zanata_project, os_branch, loc, |
| 311 | + zanata_translation_file) |
| 312 | + r = requests.get(pofile_url, |
| 313 | + headers={"Accept": "application/octet-stream"}) |
| 314 | + if r.status_code != 200: |
| 315 | + print("Could not retrieve translations for %s" % loc, |
| 316 | + file=sys.stderr) |
| 317 | + continue |
| 318 | + |
| 319 | + if debug: |
| 320 | + print("PO content for locale '%s'" % loc) |
| 321 | + print(r.text) |
| 322 | + |
| 323 | + # Read the po file into a catalog, indexed by the locale |
| 324 | + catalogs[loc] = pofile.read_po( |
| 325 | + BytesIO(r.content), |
| 326 | + domain="fedora-modularity-translations") |
| 327 | + |
| 328 | + translations = get_modulemd_translations_from_catalog_dict(catalogs) |
| 329 | + if debug: |
| 330 | + for translation in translations: |
| 331 | + print(translation.dumps()) |
| 332 | + |
| 333 | + return translations |
0 commit comments