)]}'
{"/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"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"e7653be57a89bdc903a0c6df75e69e8b3c53c600","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"34f07b67_4d04f930","updated":"2026-08-04 15:56:18.000000000","message":"@cboylan@sapwetik.org I\u0027ve made some minor refactoring in the recent patchset. I\u0027ve finished testing propose_translation_update_weblate.sh as well.","commit_id":"19c4b2fa31229dc220f928145234a20321eeda3f"}],"roles/prepare-weblate-client/README.rst":[{"author":{"_account_id":14482,"name":"Ian Y. Choi","email":"ianyrchoi@gmail.com","username":"ianychoi"},"change_message_id":"a572fa7232d3846321bfa9b6483d477fb93f3061","unresolved":true,"context_lines":[{"line_number":1,"context_line":"Prepare weblate client use"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"**Role Variables**"},{"line_number":4,"context_line":""}],"source_content_type":"text/x-rst","patch_set":9,"id":"7d3bf64e_fcec96c4","line":1,"updated":"2026-06-19 13:16:06.000000000","message":"This file solves \"WARNING: Missing role documentation: /home/zuul/src/opendev.org/openstack/openstack-zuul-jobs/roles/prepare-weblate-client/README.rst\" warning. @ppiyakk2@printf.kr Please double-check the content for this file.","commit_id":"28fb8bce24a8ba6a84dc81ed3ed01d4c379fb72a"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"016abea50a19c413b4dd13390a80959714d7c46e","unresolved":true,"context_lines":[{"line_number":1,"context_line":"Prepare weblate client use"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"**Role Variables**"},{"line_number":4,"context_line":""}],"source_content_type":"text/x-rst","patch_set":9,"id":"5b6a0c9d_f1cfe6a5","line":1,"in_reply_to":"7d3bf64e_fcec96c4","updated":"2026-06-19 14:11:24.000000000","message":"Thank you for checking. I updated doc in patchset 10.","commit_id":"28fb8bce24a8ba6a84dc81ed3ed01d4c379fb72a"},{"author":{"_account_id":14482,"name":"Ian Y. Choi","email":"ianyrchoi@gmail.com","username":"ianychoi"},"change_message_id":"8d7e7690f9a1482b649dc3a435d967569b9c99ec","unresolved":true,"context_lines":[{"line_number":1,"context_line":"Prepare weblate client use"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":".. note:: This role is only available for Debian based platforms"},{"line_number":4,"context_line":"          currently."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"**Role Variables**"},{"line_number":7,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"7eb7d606_9b2e7137","line":4,"range":{"start_line":3,"start_character":0,"end_line":4,"end_character":20},"updated":"2026-06-20 02:09:52.000000000","message":"Q: Does it really only available for Debian based platforms?","commit_id":"163fda89fca0b7c4bc1fffae034046e38a6b744f"},{"author":{"_account_id":14482,"name":"Ian Y. Choi","email":"ianyrchoi@gmail.com","username":"ianychoi"},"change_message_id":"ea9843cf64db102d21f087f65dac252e71abdd7a","unresolved":true,"context_lines":[{"line_number":1,"context_line":"Prepare weblate client use"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":".. note:: This role is only available for Debian based platforms"},{"line_number":4,"context_line":"          currently."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"**Role Variables**"},{"line_number":7,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"73563f7b_fbda56c5","line":4,"range":{"start_line":3,"start_character":0,"end_line":4,"end_character":20},"in_reply_to":"4158878f_6ae1dcc2","updated":"2026-06-20 22:18:32.000000000","message":"In Zanata, the similar comment is mentioned due to https://opendev.org/openstack/openstack-zuul-jobs/src/branch/master/roles/prepare-zanata-client/vars/Debian.yaml . On the other hand, I am not sure whether such note is useful or not after comparing to other roles since this Weblate role has no explicit dependency with Debian.","commit_id":"163fda89fca0b7c4bc1fffae034046e38a6b744f"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"8867a4cdfa1e1163fc283ffb9db3a2d3a82e4b82","unresolved":true,"context_lines":[{"line_number":1,"context_line":"Prepare weblate client use"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":".. note:: This role is only available for Debian based platforms"},{"line_number":4,"context_line":"          currently."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"**Role Variables**"},{"line_number":7,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"e268b6b2_270ffcc0","line":4,"range":{"start_line":3,"start_character":0,"end_line":4,"end_character":20},"in_reply_to":"73563f7b_fbda56c5","updated":"2026-06-29 16:27:20.000000000","message":"Thanks for checking this. I agree with your comment, the Zanata role has vars/Debian.yaml, but this Weblate role does not have any Debian-specific vars. So the note does not fit here. I removed it.","commit_id":"163fda89fca0b7c4bc1fffae034046e38a6b744f"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"08d1f593f3b3f6dab5e2293b92a83f62e9be1fe3","unresolved":true,"context_lines":[{"line_number":1,"context_line":"Prepare weblate client use"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":".. note:: This role is only available for Debian based platforms"},{"line_number":4,"context_line":"          currently."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"**Role Variables**"},{"line_number":7,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"4158878f_6ae1dcc2","line":4,"range":{"start_line":3,"start_character":0,"end_line":4,"end_character":20},"in_reply_to":"7eb7d606_9b2e7137","updated":"2026-06-20 02:18:23.000000000","message":"Looking at the jobs that currently use this role:\n\nhttps://zuul.opendev.org/t/openstack/job/upstream-translation-update\nhttps://zuul.opendev.org/t/openstack/job/propose-translation-update\n\ntheir nodeset is ubuntu-noble only, so these jobs run exclusively on Ubuntu.","commit_id":"163fda89fca0b7c4bc1fffae034046e38a6b744f"},{"author":{"_account_id":14482,"name":"Ian Y. Choi","email":"ianyrchoi@gmail.com","username":"ianychoi"},"change_message_id":"8d7e7690f9a1482b649dc3a435d967569b9c99ec","unresolved":true,"context_lines":[{"line_number":7,"context_line":""},{"line_number":8,"context_line":".. zuul:rolevar:: weblate_api_credentials"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"  Complex argument which contains the Weblate server connection"},{"line_number":11,"context_line":"  information. It is expected that this argument comes from a `Secret`."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"    .. zuul:rolevar:: url"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"        The url to the weblate server"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3cce38c9_ca085b33","line":12,"range":{"start_line":10,"start_character":34,"end_line":12,"end_character":0},"updated":"2026-06-20 02:09:52.000000000","message":"Q: Is just URL a secret?","commit_id":"163fda89fca0b7c4bc1fffae034046e38a6b744f"},{"author":{"_account_id":14482,"name":"Ian Y. Choi","email":"ianyrchoi@gmail.com","username":"ianychoi"},"change_message_id":"ea9843cf64db102d21f087f65dac252e71abdd7a","unresolved":true,"context_lines":[{"line_number":7,"context_line":""},{"line_number":8,"context_line":".. zuul:rolevar:: weblate_api_credentials"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"  Complex argument which contains the Weblate server connection"},{"line_number":11,"context_line":"  information. It is expected that this argument comes from a `Secret`."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"    .. zuul:rolevar:: url"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"        The url to the weblate server"}],"source_content_type":"text/x-rst","patch_set":10,"id":"ca7125a8_3fd221b1","line":12,"range":{"start_line":10,"start_character":34,"end_line":12,"end_character":0},"in_reply_to":"2be9f1d3_cca413c9","updated":"2026-06-20 22:18:32.000000000","message":"Thanks for the clarification. Then how about mentioning that API token will be added in future like below?\n\n```\nComplex argument which contains the Weblate server connection information. Currently this includes the Weblate server URL and may be extended with additional configuration values in the future. It is expected that this argument comes from a `Secret`.\n```","commit_id":"163fda89fca0b7c4bc1fffae034046e38a6b744f"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"08d1f593f3b3f6dab5e2293b92a83f62e9be1fe3","unresolved":true,"context_lines":[{"line_number":7,"context_line":""},{"line_number":8,"context_line":".. zuul:rolevar:: weblate_api_credentials"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"  Complex argument which contains the Weblate server connection"},{"line_number":11,"context_line":"  information. It is expected that this argument comes from a `Secret`."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"    .. zuul:rolevar:: url"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"        The url to the weblate server"}],"source_content_type":"text/x-rst","patch_set":10,"id":"2be9f1d3_cca413c9","line":12,"range":{"start_line":10,"start_character":34,"end_line":12,"end_character":0},"in_reply_to":"3cce38c9_ca085b33","updated":"2026-06-20 02:18:23.000000000","message":"Yes. The secret is in zuul.d/secrets.yaml in the project-config repo. For now it only has the url.\n\nUpload needs an API token. That will come later, and I will add it to the secret then.","commit_id":"163fda89fca0b7c4bc1fffae034046e38a6b744f"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"8867a4cdfa1e1163fc283ffb9db3a2d3a82e4b82","unresolved":true,"context_lines":[{"line_number":7,"context_line":""},{"line_number":8,"context_line":".. zuul:rolevar:: weblate_api_credentials"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"  Complex argument which contains the Weblate server connection"},{"line_number":11,"context_line":"  information. It is expected that this argument comes from a `Secret`."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"    .. zuul:rolevar:: url"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"        The url to the weblate server"}],"source_content_type":"text/x-rst","patch_set":10,"id":"c5cdafbb_52502df7","line":12,"range":{"start_line":10,"start_character":34,"end_line":12,"end_character":0},"in_reply_to":"ca7125a8_3fd221b1","updated":"2026-06-29 16:27:20.000000000","message":"Thanks for the suggestion. Your wording is clearer, so I used it as is.","commit_id":"163fda89fca0b7c4bc1fffae034046e38a6b744f"}],"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":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"cf6a211d_219b14e6","line":18,"in_reply_to":"a657556f_fce9eaee","updated":"2026-06-18 13:22:23.000000000","message":"Thanks for confirming — yes, this relies on copy-proposal-common-scripts from project-config, and it\u0027s exercised by the jobs proposed 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":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"c5872a0c_ea50dff5","line":45,"in_reply_to":"f0e88476_93f8bf29","updated":"2026-06-18 13:22:23.000000000","message":"Done. Added i18n to DOC_TARGETS since that\u0027s our initial test target. Also removed a stray comma after \u0027operations-guide\u0027 that the linter flagged.","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"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"a5b176fe_4c1da3a8","line":251,"in_reply_to":"d8ae8144_00a0dc2f","updated":"2026-06-18 13:22:23.000000000","message":"Correct — this is intentional. The new flow passes the project name from the calling environment rather than parsing .gitreview. Keeping it as-is.","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":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"312f82a4_53a6fcd8","line":25,"in_reply_to":"e5822008_ea5d1bc1","updated":"2026-06-18 13:22:23.000000000","message":"Done. Added it to the usage example.","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":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"546d65fc_3b8eff62","line":111,"in_reply_to":"1bcc619b_aae3dbb0","updated":"2026-06-18 13:22:23.000000000","message":"Done. Switched to the try/except AttributeError pattern you suggested — much more readable, thanks.","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":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"3459e833_0245fb2d","line":171,"range":{"start_line":171,"start_character":17,"end_line":171,"end_character":19},"in_reply_to":"c043db4a_1479be88","updated":"2026-06-18 13:22:23.000000000","message":"Done. Now exits non-zero so Ansible can detect the failure.","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":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"81d3ee22_17309160","line":184,"range":{"start_line":184,"start_character":16,"end_line":184,"end_character":19},"in_reply_to":"3cb89bf0_e7a74f49","updated":"2026-06-18 13:22:23.000000000","message":"Done. Now exits non-zero so Ansible can detect the failure.","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"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"f9e1b22e_211e9305","line":236,"range":{"start_line":230,"start_character":0,"end_line":236,"end_character":17},"in_reply_to":"d7254978_fc927045","updated":"2026-06-18 13:22:23.000000000","message":"Used shutil.move instead of os.replace, since the temp file lives in a TemporaryDirectory that may be on a different filesystem from the source tree (os.replace would raise OSError across filesystems). Fixed in patch set 8","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"8dc56a44524ae1fedc8be7a93996cb17c0240295","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#!/usr/bin/env python3"},{"line_number":2,"context_line":" # Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":3,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":4,"context_line":"# a copy of the License at"},{"line_number":5,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":12,"id":"a9689a85_9b1a3128","line":2,"updated":"2026-08-04 16:01:11.000000000","message":"linters: E114 indentation is not a multiple of 4 (comment)","commit_id":"19c4b2fa31229dc220f928145234a20321eeda3f"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"8dc56a44524ae1fedc8be7a93996cb17c0240295","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#!/usr/bin/env python3"},{"line_number":2,"context_line":" # Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":3,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":4,"context_line":"# a copy of the License at"},{"line_number":5,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":12,"id":"011d05ee_7373046f","line":2,"updated":"2026-08-04 16:01:11.000000000","message":"linters: E116 unexpected indentation (comment)","commit_id":"19c4b2fa31229dc220f928145234a20321eeda3f"}],"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"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"b6e6e50b_d45bceba","line":1,"in_reply_to":"d9a7dc57_7bdb1306","updated":"2026-06-18 13:22:23.000000000","message":"Thanks for checking! Yes, Patchset7 brought it up to the latest version. I\u0027ve also resolved the lint issues in Patchset8.","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"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"7d583aa1_5aa59041","line":357,"range":{"start_line":357,"start_character":13,"end_line":357,"end_character":19},"in_reply_to":"f98be107_20b93238","updated":"2026-06-18 13:22:23.000000000","message":"Done. Fixed to use the global $BRANCH.","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"},{"author":{"_account_id":23279,"name":"Seongsoo Cho","display_name":"Seongsoo Cho","email":"ppiyakk2@printf.kr","username":"seongsoo.cho"},"change_message_id":"c5571a954f8f4e92579d50ebb434934fde1f51e6","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":"7d13c614_0202eaf1","line":8,"in_reply_to":"1c2c0fe7_49e87175","updated":"2026-06-18 13:22:23.000000000","message":"Done. Added python3-requests to the installed packages. The scripts rely on requests and nothing else was installing it. Since this job runs on an ubuntu-noble nodeset, I used the Ubuntu package name python3-requests.","commit_id":"fc759f4aa2e966fa57638123bde66345389b8c49"}]}
