From a0cd3fb9bb03727e355caf4ae57cc43335cb40df Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Sat, 25 Jan 2025 23:18:24 -0300 Subject: [PATCH 1/2] Get translation stats from local PO files --- .github/workflows/sync.yml | 8 +++--- README.rst | 28 +++++++++---------- scripts/stats.py | 55 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 19 deletions(-) create mode 100755 scripts/stats.py diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 034084f00..7ff462ff2 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -38,7 +38,7 @@ jobs: repository: 'python/cpython' ref: ${{ env.PYDOC_VERSION }} path: cpython - + - name: Set language dir variable run: echo "LANGUAGE_DIR=cpython/Doc/locales/${{ env.PYDOC_LANGUAGE }}/LC_MESSAGES" >> $GITHUB_ENV @@ -113,12 +113,10 @@ jobs: powrap *.po **/*.po - name: Update statistics - if: always() && steps.secret-check.outputs.available == 'true' + if: always() run: | - python ./scripts/tx_stats.py > ./${{ env.LANGUAGE_DIR }}/stats.json + ./scripts/stats.py git -C ./${{ env.LANGUAGE_DIR }} diff stats.json - env: - TX_TOKEN: ${{ secrets.TX_TOKEN }} - name: Update potodo.md if: always() diff --git a/README.rst b/README.rst index c114af9ee..608bd9b34 100644 --- a/README.rst +++ b/README.rst @@ -29,46 +29,46 @@ Maintained versions: * - `3.13 `_ - .. image:: https://github.com/python/python-docs-pt-br/workflows/python-313/badge.svg :target: https://github.com/python/python-docs-pt-br/actions?workflow=python-313 - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.13%2Fstats.json&query=translation&label=pt_BR + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.13%2Fstats.json&query=completion&label=pt_BR :alt: Brazilian Portuguese translation status for Python 3.13 :target: https://app.transifex.com/python-doc/python-newest/ - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.13%2Fstats.json&query=total&label=3.13 + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.13%2Fstats.json&query=entries&label=3.13 :alt: Total strings for Python 3.13 :target: https://app.transifex.com/python-doc/python-newest/ * - `3.12 `_ - .. image:: https://github.com/python/python-docs-pt-br/workflows/python-312/badge.svg :target: https://github.com/python/python-docs-pt-br/actions?workflow=python-312 - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.12%2Fstats.json&query=translation&label=pt_BR + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.12%2Fstats.json&query=completion&label=pt_BR :alt: Brazilian Portuguese translation status for Python 3.12 :target: https://app.transifex.com/python-doc/python-312/ - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.12%2Fstats.json&query=total&label=3.12 + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.12%2Fstats.json&query=entries&label=3.12 :alt: Total strings for Python 3.12 :target: https://app.transifex.com/python-doc/python-312/ * - `3.11 `_ - .. image:: https://github.com/python/python-docs-pt-br/workflows/python-311/badge.svg :target: https://github.com/python/python-docs-pt-br/actions?workflow=python-311 - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.11%2Fstats.json&query=translation&label=pt_BR + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.11%2Fstats.json&query=completion&label=pt_BR :alt: Brazilian Portuguese translation status for Python 3.11 :target: https://app.transifex.com/python-doc/python-311/ - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.11%2Fstats.json&query=total&label=3.11 + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.11%2Fstats.json&query=entries&label=3.11 :alt: Total strings for Python 3.11 :target: https://app.transifex.com/python-doc/python-311/ * - `3.10 `_ - .. image:: https://github.com/python/python-docs-pt-br/workflows/python-310/badge.svg :target: https://github.com/python/python-docs-pt-br/actions?workflow=python-310 - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.10%2Fstats.json&query=translation&label=pt_BR + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.10%2Fstats.json&query=completion&label=pt_BR :alt: Brazilian Portuguese translation status for Python 3.10 :target: https://app.transifex.com/python-doc/python-310/ - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.10%2Fstats.json&query=total&label=3.10 + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.10%2Fstats.json&query=entries&label=3.10 :alt: Total strings for Python 3.10 :target: https://app.transifex.com/python-doc/python-310/ * - `3.9 `_ - .. image:: https://github.com/python/python-docs-pt-br/workflows/python-39/badge.svg :target: https://github.com/python/python-docs-pt-br/actions?workflow=python-39 - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.9%2Fstats.json&query=translation&label=pt_BR + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.9%2Fstats.json&query=completion&label=pt_BR :alt: Brazilian Portuguese translation status for Python 3.9 :target: https://app.transifex.com/python-doc/python-39/ - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.9%2Fstats.json&query=total&label=3.9 + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.9%2Fstats.json&query=entries&label=3.9 :alt: Total strings for Python 3.9 :target: https://app.transifex.com/python-doc/python-39/ @@ -87,19 +87,19 @@ EOL versions: * - `3.8 `_ - .. image:: https://github.com/python/python-docs-pt-br/workflows/python-38/badge.svg :target: https://github.com/python/python-docs-pt-br/actions?workflow=python-38 - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.8%2Fstats.json&query=translation&label=pt_BR + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.8%2Fstats.json&query=completion&label=pt_BR :alt: Brazilian Portuguese translation status for Python 3.8 :target: https://app.transifex.com/python-doc/python-38/ - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.8%2Fstats.json&query=total&label=3.8 + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.8%2Fstats.json&query=entries&label=3.8 :alt: Total strings for Python 3.8 :target: https://app.transifex.com/python-doc/python-38/ * - `3.7 `_ - .. image:: https://github.com/python/python-docs-pt-br/workflows/python-37/badge.svg :target: https://github.com/python/python-docs-pt-br/actions?workflow=python-37 - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.7%2Fstats.json&query=translation&label=pt_BR + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.7%2Fstats.json&query=completion&label=pt_BR :alt: Brazilian Portuguese translation status for Python 3.7 :target: https://app.transifex.com/python-doc/python-37/ - - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.7%2Fstats.json&query=total&label=3.7 + - .. image:: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fpython%2Fpython-docs-pt-br%2Fraw%2F3.7%2Fstats.json&query=entries&label=3.7 :alt: Total strings for Python 3.7 :target: https://app.transifex.com/python-doc/python-37/ diff --git a/scripts/stats.py b/scripts/stats.py new file mode 100755 index 000000000..32564ba2d --- /dev/null +++ b/scripts/stats.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +""" +Obtain translation stats from the PO files directory and +store it with JSON format into 'stats.json'. +""" + +import json +import os +import logging +from datetime import datetime, timezone +from pathlib import Path + +from potodo.potodo import scan_path + +logging.basicConfig(level=logging.INFO) + + +def main() -> None: + """Main function to generate translation stats.""" + language = os.environ.get("PYDOC_LANGUAGE") + if not language: + raise ValueError("Environment variable PYDOC_LANGUAGE is not set.") + + pofiles_path = Path(f"cpython/Doc/locales/{language}/LC_MESSAGES") + if not pofiles_path.exists(): + raise FileNotFoundError(f"Path does not exist: {pofiles_path}") + + # Check for PO files inside the pofiles_path + if not list(pofiles_path.rglob("*.po")): + raise FileNotFoundError(f"No PO files found in {pofiles_path}") + + stats = scan_path(pofiles_path, no_cache=True, hide_reserved=False, api_url="") + + stats_data = { + "completion": str(round(stats.completion, 2)), + "translated": stats.translated, + "entries": stats.entries, + "updated_at": datetime.now(timezone.utc).isoformat(timespec="seconds") + "Z", + } + + stats_json = pofiles_path / "stats.json" + try: + with stats_json.open("w") as output_file: + json.dump(stats_data, output_file) + logging.info(f"Content written to {stats_json}") + except IOError as e: + logging.error(f"Failed to write to {stats_json}: {e}") + raise + + +if __name__ == "__main__": + try: + main() + except Exception as e: + logging.error(f"An error occurred: {e}") From edcc06950f840d978a23a364fca7dd4884f5fd82 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Sat, 25 Jan 2025 23:27:34 -0300 Subject: [PATCH 2/2] Add percentage sign --- scripts/stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/stats.py b/scripts/stats.py index 32564ba2d..ec2e7e285 100755 --- a/scripts/stats.py +++ b/scripts/stats.py @@ -32,7 +32,7 @@ def main() -> None: stats = scan_path(pofiles_path, no_cache=True, hide_reserved=False, api_url="") stats_data = { - "completion": str(round(stats.completion, 2)), + "completion": str(round(stats.completion, 2)) + "%", "translated": stats.translated, "entries": stats.entries, "updated_at": datetime.now(timezone.utc).isoformat(timespec="seconds") + "Z",