)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":14482,"name":"Ian Y. Choi","email":"ianyrchoi@gmail.com","username":"ianychoi"},"change_message_id":"27bd84fe3dbca8cff2137579bc1096e6fc27f106","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"5ff1bd09_7cba0c2b","updated":"2026-06-03 16:40:24.000000000","message":"This patch set does not include upstream_translateion_update_weblate.sh intentionally as the commit message describes. The version looks good to me based on my comments here: https://review.opendev.org/c/openstack/i18n/+/991285/5 .","commit_id":"365897e14cf85cb81cebc576a2f617d37dfbf682"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"84f37b94_f8739621","updated":"2026-06-03 18:32:54.000000000","message":"I\u0027ve got some inline suggestions. Some of them are nits that I don\u0027t think are critical. Others I think are worth considering and probably making updates for. Then we will also need to make the updates that the linter calls out so that this is a mergeable change.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"}],"roles/prepare-weblate-client/files/common_translation_update_weblate.sh":[{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":15,"context_line":"# under the License."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"SCRIPTSDIR\u003d\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" \u0026\u0026 pwd )\""},{"line_number":18,"context_line":"source $SCRIPTSDIR/common.sh"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"# Set start of timestamp for logging"},{"line_number":21,"context_line":"TRANS_START_TIME\u003d$(date +%s)"}],"source_content_type":"text/x-sh","patch_set":7,"id":"a657556f_fce9eaee","line":18,"updated":"2026-06-03 18:32:54.000000000","message":"This common.sh script lives in role copy-proposal-common-scripts in openstack/project-config. The openstack/project-config/playbooks/translation/pre.yaml and playbooks/proposal/pre.yaml playbooks run that role to include this file. All that to say this should work within the proposed jobs in 961499","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":42,"context_line":"             \u0027horizon\u0027"},{"line_number":43,"context_line":"             \u0027openstack-ansible\u0027"},{"line_number":44,"context_line":"             \u0027operations-guide\u0027,"},{"line_number":45,"context_line":"             \u0027swift\u0027)"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"# We need a UTF-8 locale, set it properly in case it\u0027s not set."},{"line_number":48,"context_line":"export LANG\u003den_US.UTF-8"}],"source_content_type":"text/x-sh","patch_set":7,"id":"f0e88476_93f8bf29","line":45,"updated":"2026-06-03 18:32:54.000000000","message":"Do we need to add i18n to this list? I know we plan on testing this role and the jobs against i18n to start.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":248,"context_line":"    # Note we cannot rely on the default branch in .gitreview being"},{"line_number":249,"context_line":"    # correct so we are very explicit here."},{"line_number":250,"context_line":"    local branch\u003d${1:-master}"},{"line_number":251,"context_line":"    FULL_PROJECT\u003d${FULL_PROJECT:-$PROJECT}"},{"line_number":252,"context_line":"    set +e"},{"line_number":253,"context_line":"    read -d \u0027\u0027 INITIAL_COMMIT_MSG \u003c\u003cEOF"},{"line_number":254,"context_line":"Imported Translations from Weblate"}],"source_content_type":"text/x-sh","patch_set":7,"id":"d8ae8144_00a0dc2f","line":251,"updated":"2026-06-03 18:32:54.000000000","message":"Note that the zanata code parsed the project name out of the .gitreview file. Now we\u0027re getting it from the calling environment. This is probably fine.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"}],"roles/prepare-weblate-client/files/download_translations_weblate.py":[{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":22,"context_line":"Usage:"},{"line_number":23,"context_line":"    python3 download_translations_weblate.py \\"},{"line_number":24,"context_line":"        --project contributor-guide \\"},{"line_number":25,"context_line":"        --category master"},{"line_number":26,"context_line":"\"\"\""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"import argparse"}],"source_content_type":"text/x-python","patch_set":7,"id":"e5822008_ea5d1bc1","line":25,"updated":"2026-06-03 18:32:54.000000000","message":"Nit: you need to configure the weblate client config with a url or pass --url or set WEBLATE_URL to point at the weblate server.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":108,"context_line":"    )"},{"line_number":109,"context_line":"    resp \u003d setup.session.get("},{"line_number":110,"context_line":"        url, headers\u003dsetup.headers, verify\u003dsetup.verify, stream\u003dTrue"},{"line_number":111,"context_line":"    ) if hasattr(setup, \u0027session\u0027) else __import__(\u0027requests\u0027).get("},{"line_number":112,"context_line":"        url, headers\u003dsetup.headers, verify\u003dsetup.verify, stream\u003dTrue"},{"line_number":113,"context_line":"    )"},{"line_number":114,"context_line":"    if resp.status_code \u003d\u003d 200 and len(resp.content) \u003e 0:"}],"source_content_type":"text/x-python","patch_set":7,"id":"1bcc619b_aae3dbb0","line":111,"updated":"2026-06-03 18:32:54.000000000","message":"Can we do a try except and avoid the use of __import__ as a statement to fallback to requests? The docs push people away from using low level __import__ and suggest importlib as another alternative: https://docs.python.org/3/reference/import.html#importlib I think something like this is easy to read though:\n\n```\ntry:\n    resp \u003d setup.session.get(...)\nexcept AttributeError:\n    import requests\n    resp \u003d requests.get(...)\n```","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":168,"context_line":"    all_components \u003d setup.list_components(project_slug)"},{"line_number":169,"context_line":"    if not all_components:"},{"line_number":170,"context_line":"        print(f\"[download] No components found for project {project_slug}\")"},{"line_number":171,"context_line":"        sys.exit(0)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"    # Filter to components in our target category"},{"line_number":174,"context_line":"    target_cat_url \u003d setup.get_category_url(project_slug, category_slug)"}],"source_content_type":"text/x-python","patch_set":7,"id":"c043db4a_1479be88","line":171,"range":{"start_line":171,"start_character":17,"end_line":171,"end_character":19},"updated":"2026-06-03 18:32:54.000000000","message":"Should we exit non zero if there are no components and we exit before downloading anything? That will signal ansible or other scripts that something went wrong.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":181,"context_line":"    if not components:"},{"line_number":182,"context_line":"        print(f\"[download] No components in category \u0027{category_slug}\u0027\")"},{"line_number":183,"context_line":"        print(f\"  (total components in project: {len(all_components)})\")"},{"line_number":184,"context_line":"        sys.exit(0)"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"    print(f\"[download] Found {len(components)} component(s) \""},{"line_number":187,"context_line":"          f\"in {project_slug}/{category_slug}\")"}],"source_content_type":"text/x-python","patch_set":7,"id":"3cb89bf0_e7a74f49","line":184,"range":{"start_line":184,"start_character":16,"end_line":184,"end_character":19},"updated":"2026-06-03 18:32:54.000000000","message":"See above about exiting non zero.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":222,"context_line":"                    os.makedirs(target_dir, exist_ok\u003dTrue)"},{"line_number":223,"context_line":"                    dest \u003d os.path.join(target_dir, po_filename)"},{"line_number":224,"context_line":"                    with open(temp_file, \u0027rb\u0027) as src, open(dest, \u0027wb\u0027) as dst:"},{"line_number":225,"context_line":"                        dst.write(src.read())"},{"line_number":226,"context_line":"                    results[\"downloaded\"] +\u003d 1"},{"line_number":227,"context_line":"                else:"},{"line_number":228,"context_line":"                    results[\"failed\"] +\u003d 1"}],"source_content_type":"text/x-python","patch_set":7,"id":"824f83ca_595000ba","line":225,"updated":"2026-06-03 18:32:54.000000000","message":"Nit: I think this open and read write can be replaced with python os.replace: https://docs.python.org/3/library/os.html#os.replace that may be slightly faster if the filesystems are shared though you\u0027re writing to a tempdir so they probably won\u0027t be shared.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":227,"context_line":"                else:"},{"line_number":228,"context_line":"                    results[\"failed\"] +\u003d 1"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"            # Git add locale files for this component"},{"line_number":231,"context_line":"            locale_dir \u003d target_base"},{"line_number":232,"context_line":"            if os.path.isdir(locale_dir):"},{"line_number":233,"context_line":"                subprocess.run("},{"line_number":234,"context_line":"                    [\"git\", \"add\", \"--all\", locale_dir],"},{"line_number":235,"context_line":"                    check\u003dFalse,"},{"line_number":236,"context_line":"                )"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    print(f\"\\n{\u0027\u003d\u0027 * 50}\")"},{"line_number":239,"context_line":"    print(f\"Download complete:\")"}],"source_content_type":"text/x-python","patch_set":7,"id":"d7254978_fc927045","line":236,"range":{"start_line":230,"start_character":0,"end_line":236,"end_character":17},"updated":"2026-06-03 18:32:54.000000000","message":"I think it would be better to separate the process of adding files to the git repo from the file download process. I wouldn\u0027t expect a tool that downloads po files from weblate to also modify my git state beyond downloading the files.\n\nBut this is a minor thing as we get stuff going. Maybe this is best addressed in a followup once things work as expected.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"}],"roles/prepare-weblate-client/files/get-modulename.py":[{"author":{"_account_id":14482,"name":"Ian Y. Choi","email":"ianyrchoi@gmail.com","username":"ianychoi"},"change_message_id":"27bd84fe3dbca8cff2137579bc1096e6fc27f106","unresolved":true,"context_lines":[{"line_number":1,"context_line":"#!/usr/bin/env python3"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"# not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":4,"id":"d9a7dc57_7bdb1306","line":1,"updated":"2026-06-03 16:40:24.000000000","message":"During I18n Sprint, I shared that this version is old. I see that PatchSet 7 has the latest version.","commit_id":"5e03ec64f9ee6ef9ff038daddf58f9cc11531739"}],"roles/prepare-weblate-client/files/propose_translation_update_weblate.sh":[{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":354,"context_line":""},{"line_number":355,"context_line":"filter_commits"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"send_patch \"$branch\""},{"line_number":358,"context_line":""},{"line_number":359,"context_line":"if [ $INVALID_PO_FILE -eq 1 ] ; then"},{"line_number":360,"context_line":"    echo \"At least one po file in invalid. Fix all invalid files on the\""}],"source_content_type":"text/x-sh","patch_set":7,"id":"f98be107_20b93238","line":357,"range":{"start_line":357,"start_character":13,"end_line":357,"end_character":19},"updated":"2026-06-03 18:32:54.000000000","message":"I think this may need to be $BRANCH which is defined globally but $branch is only defined in rename_django_chinese_locales as a local","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"}],"roles/prepare-weblate-client/tasks/main.yaml":[{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"0e5becc879375bd7f85cceac46aa2ae5c4152ebf","unresolved":true,"context_lines":[{"line_number":5,"context_line":"    name:"},{"line_number":6,"context_line":"      - gettext"},{"line_number":7,"context_line":"    state: present"},{"line_number":8,"context_line":"  become: yes"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"- name: Ensure weblate config dir"},{"line_number":11,"context_line":"  file:"}],"source_content_type":"text/x-yaml","patch_set":7,"id":"1c2c0fe7_49e87175","line":8,"updated":"2026-06-03 18:32:54.000000000","message":"Do we also need to install a python requests package? We seem to be relying on it within the scripts and I don\u0027t know if anything else is installing it.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"}]}
