diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 691c7ca..eb56885 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,10 @@ updates: interval: daily time: "02:00" open-pull-requests-limit: 10 + +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + time: "02:00" + open-pull-requests-limit: 10 diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml new file mode 100644 index 0000000..7eb9179 --- /dev/null +++ b/.github/workflows/shellcheck.yml @@ -0,0 +1,30 @@ +name: shellcheck + +on: + push: + branches: + - master + paths: + - 'tools/**/*.sh' + - '.github/workflows/shellcheck.yml' + pull_request: + paths: + - 'tools/**/*.sh' + - '.github/workflows/shellcheck.yml' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ludeeus/action-shellcheck@2.0.0 + env: + SHELLCHECK_OPTS: --shell bash + with: + severity: style + check_together: 'yes' diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml new file mode 100644 index 0000000..8b8ff37 --- /dev/null +++ b/.github/workflows/tools.yml @@ -0,0 +1,48 @@ +name: test-tools + +on: + push: + branches: + - master + paths: + - "tools/**" + - '.github/workflows/tools.yml' + pull_request: + paths: + - "tools/**" + - '.github/workflows/tools.yml' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + mypy: + name: Run mypy + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install poetry + run: | + curl -sSL "https://install.python-poetry.org" | python + + # Adding `poetry` to `$PATH`: + echo "$HOME/.poetry/bin" >> $GITHUB_PATH + + - name: Install dependencies + run: | + cd tools + poetry config virtualenvs.in-project true + poetry run pip install -U pip + poetry install + + - run: cd tools && poetry run mypy *.py diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml new file mode 100644 index 0000000..4cad33d --- /dev/null +++ b/.github/workflows/validation.yml @@ -0,0 +1,42 @@ +name: validate + +on: + push: + branches: + - master + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + validate: + name: Run validation + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install poetry + run: | + curl -sSL "https://install.python-poetry.org" | python + + # Adding `poetry` to `$PATH`: + echo "$HOME/.poetry/bin" >> $GITHUB_PATH + + - name: Install dependencies + run: | + cd tools + poetry config virtualenvs.in-project true + poetry run pip install -U pip + poetry install + + - run: poetry run -C tools bash tools/validate.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 9de1c0b..6dbcca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,12 @@ - Clarified `Legacy` rules - Clarified `Redirect` rules - Simplified `Monitoring` and `Firewall` rules: they now don't interact with `sudo` +- Changed `Supply chain` card: it does not have ⚙️ effect anymore - Tweaked `Frontend` social interaction, again - Tweaked some minor wordings on multiple cards - Tweaked multiple other social interactions a bit +- Fixed fonts on multiple cards +- Added "Pytup" rule special card ## Version 0.0.8 diff --git a/ru/cards.numbers b/ru/cards.numbers index c243a7a..d41158c 100755 Binary files a/ru/cards.numbers and b/ru/cards.numbers differ diff --git a/ru/counts.numbers b/ru/counts.numbers index a8fd46e..c7e7a1b 100755 Binary files a/ru/counts.numbers and b/ru/counts.numbers differ diff --git a/tools/build.sh b/tools/build.sh index 7698458..c9c7447 100644 --- a/tools/build.sh +++ b/tools/build.sh @@ -13,6 +13,9 @@ set -x # Clean existing build: rm -rf build +# Run validation: +source tools/validate.sh + # Just all cards types in one pdf: CARDS_PDF="$1" # All cards in one pdf, with correct counts, useful for printing: diff --git a/tools/generate-images-from-pdf.py b/tools/generate-images-from-pdf.py index 146ceb8..c6731fb 100644 --- a/tools/generate-images-from-pdf.py +++ b/tools/generate-images-from-pdf.py @@ -2,7 +2,7 @@ import io import os -import pypdfium2 as pdf +import pypdfium2 as pdf # type: ignore[import-untyped] def _render_images(cards: io.BytesIO, output_dir: str) -> None: diff --git a/tools/generate-pdf.py b/tools/generate-pdf.py index fe5cae2..dc8fc25 100644 --- a/tools/generate-pdf.py +++ b/tools/generate-pdf.py @@ -23,20 +23,9 @@ import io import os -import numbers_parser -import pypdfium2 as pdf +import pypdfium2 as pdf # type: ignore[import-untyped] - -def _read_counts(counts_path: str) -> list[int]: - document = numbers_parser.Document(counts_path) - table = document.sheets[0].tables[0] - - read_counts = [] - for row in range(table.num_rows): - cell = table.cell(f"C{row + 1}").value - if cell: - read_counts.append(int(cell)) - return read_counts +from ship_it_tools import counts def _write_cards_with_counts( @@ -81,7 +70,7 @@ def main() -> None: parsed_args = parser.parse_args() _write_cards_with_counts( parsed_args.cards, - _read_counts(parsed_args.counts), + counts.read_counts(parsed_args.counts), parsed_args.output_file, ) diff --git a/tools/poetry.lock b/tools/poetry.lock index dee4bed..804e414 100644 --- a/tools/poetry.lock +++ b/tools/poetry.lock @@ -1,18 +1,20 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "compact-json" -version = "1.6.1" +version = "1.8.1" description = "A JSON formatter that produces compact but human-readable" optional = false -python-versions = ">=3.8,<4.0" +python-versions = "<4.0,>=3.9" files = [ - {file = "compact_json-1.6.1-py3-none-any.whl", hash = "sha256:867c1c0e331656400000f1a9a60c5e292f88608bb3f7987c0433124ab96b811a"}, - {file = "compact_json-1.6.1.tar.gz", hash = "sha256:ebe6eb983ca0391452a4d91c5b27a7494df587668c517e6836f8e6b451ee8663"}, + {file = "compact_json-1.8.1-py3-none-any.whl", hash = "sha256:1232321c1eb65d48a341265cd289996c02fe4ce213ffc4cfe948c3faf985ea0a"}, + {file = "compact_json-1.8.1.tar.gz", hash = "sha256:1dfcd53a05e27725fd73d694028c6d9a4b5e7fe8586d0980d0f7d5b5672ee144"}, ] [package.dependencies] -wcwidth = ">=0.2.5,<0.3.0" +importlib-resources = ">=6.1" +setuptools = ">=69.0.3" +wcwidth = ">0.2.8" [[package]] name = "cramjam" @@ -128,13 +130,13 @@ dev = ["black (==22.3.0)", "hypothesis", "numpy", "pytest (>=5.30)", "pytest-xdi [[package]] name = "enum-tools" -version = "0.11.0" +version = "0.12.0" description = "Tools to expand Python's enum module." optional = false python-versions = ">=3.6" files = [ - {file = "enum_tools-0.11.0-py3-none-any.whl", hash = "sha256:9e76186ff4fd1798a64a855d334e245a7d2b67970c40029acccff06c58bf0535"}, - {file = "enum_tools-0.11.0.tar.gz", hash = "sha256:ed10ae4c2109c52e6ca17505a3bdb173b2554f5f0449677621829023a9d8bd33"}, + {file = "enum_tools-0.12.0-py3-none-any.whl", hash = "sha256:d69b019f193c7b850b17d9ce18440db7ed62381571409af80ccc08c5218b340a"}, + {file = "enum_tools-0.12.0.tar.gz", hash = "sha256:13ceb9376a4c5f574a1e7c5f9c8eb7f3d3fbfbb361cc18a738df1a58dfefd460"}, ] [package.dependencies] @@ -147,18 +149,75 @@ sphinx = ["sphinx (>=3.4.0)", "sphinx-jinja2-compat (>=0.1.1)", "sphinx-toolbox [[package]] name = "importlib-resources" -version = "6.1.2" +version = "6.4.0" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.1.2-py3-none-any.whl", hash = "sha256:9a0a862501dc38b68adebc82970140c9e4209fc99601782925178f8386339938"}, - {file = "importlib_resources-6.1.2.tar.gz", hash = "sha256:308abf8474e2dba5f867d279237cd4076482c3de7104a40b41426370e891549b"}, + {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, + {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] +testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] + +[[package]] +name = "mypy" +version = "1.10.0" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, + {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, + {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, + {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, + {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, + {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, + {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, + {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, + {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, + {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, + {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, + {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, + {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, + {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, + {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, + {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, + {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, + {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +typing-extensions = ">=4.1.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] [[package]] name = "numbers-parser" @@ -370,37 +429,36 @@ xmp = ["defusedxml"] [[package]] name = "protobuf" -version = "4.25.3" +version = "5.26.1" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-4.25.3-cp310-abi3-win32.whl", hash = "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa"}, - {file = "protobuf-4.25.3-cp310-abi3-win_amd64.whl", hash = "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8"}, - {file = "protobuf-4.25.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c"}, - {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019"}, - {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d"}, - {file = "protobuf-4.25.3-cp38-cp38-win32.whl", hash = "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2"}, - {file = "protobuf-4.25.3-cp38-cp38-win_amd64.whl", hash = "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4"}, - {file = "protobuf-4.25.3-cp39-cp39-win32.whl", hash = "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4"}, - {file = "protobuf-4.25.3-cp39-cp39-win_amd64.whl", hash = "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c"}, - {file = "protobuf-4.25.3-py3-none-any.whl", hash = "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9"}, - {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, + {file = "protobuf-5.26.1-cp310-abi3-win32.whl", hash = "sha256:3c388ea6ddfe735f8cf69e3f7dc7611e73107b60bdfcf5d0f024c3ccd3794e23"}, + {file = "protobuf-5.26.1-cp310-abi3-win_amd64.whl", hash = "sha256:e6039957449cb918f331d32ffafa8eb9255769c96aa0560d9a5bf0b4e00a2a33"}, + {file = "protobuf-5.26.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:38aa5f535721d5bb99861166c445c4105c4e285c765fbb2ac10f116e32dcd46d"}, + {file = "protobuf-5.26.1-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:fbfe61e7ee8c1860855696e3ac6cfd1b01af5498facc6834fcc345c9684fb2ca"}, + {file = "protobuf-5.26.1-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:f7417703f841167e5a27d48be13389d52ad705ec09eade63dfc3180a959215d7"}, + {file = "protobuf-5.26.1-cp38-cp38-win32.whl", hash = "sha256:d693d2504ca96750d92d9de8a103102dd648fda04540495535f0fec7577ed8fc"}, + {file = "protobuf-5.26.1-cp38-cp38-win_amd64.whl", hash = "sha256:9b557c317ebe6836835ec4ef74ec3e994ad0894ea424314ad3552bc6e8835b4e"}, + {file = "protobuf-5.26.1-cp39-cp39-win32.whl", hash = "sha256:b9ba3ca83c2e31219ffbeb9d76b63aad35a3eb1544170c55336993d7a18ae72c"}, + {file = "protobuf-5.26.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ee014c2c87582e101d6b54260af03b6596728505c79f17c8586e7523aaa8f8c"}, + {file = "protobuf-5.26.1-py3-none-any.whl", hash = "sha256:da612f2720c0183417194eeaa2523215c4fcc1a1949772dc65f05047e08d5932"}, + {file = "protobuf-5.26.1.tar.gz", hash = "sha256:8ca2a1d97c290ec7b16e4e5dff2e5ae150cc1582f55b5ab300d45cb0dfa90e51"}, ] [[package]] name = "pygments" -version = "2.17.2" +version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [package.extras] -plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] [[package]] @@ -427,13 +485,13 @@ files = [ [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -554,18 +612,18 @@ files = [ [[package]] name = "setuptools" -version = "69.1.1" +version = "69.5.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, - {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, + {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"}, + {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -604,15 +662,26 @@ files = [ {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, ] +[[package]] +name = "types-pillow" +version = "10.2.0.20240520" +description = "Typing stubs for Pillow" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-Pillow-10.2.0.20240520.tar.gz", hash = "sha256:130b979195465fa1e1676d8e81c9c7c30319e8e95b12fae945e8f0d525213107"}, + {file = "types_Pillow-10.2.0.20240520-py3-none-any.whl", hash = "sha256:33c36494b380e2a269bb742181bea5d9b00820367822dbd3760f07210a1da23d"}, +] + [[package]] name = "typing-extensions" -version = "4.10.0" +version = "4.11.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, - {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, + {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, + {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, ] [[package]] @@ -640,4 +709,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "e87761739d87e5b5f7cb3f5303fa91ecf23c7de7ac57305d8530ec498fc78efc" +content-hash = "36b5a65e89042a768a4900079b1cf338990a696acba6d635cc3685ea22f89f92" diff --git a/tools/pyproject.toml b/tools/pyproject.toml index 94e1362..276d2a4 100644 --- a/tools/pyproject.toml +++ b/tools/pyproject.toml @@ -1,13 +1,12 @@ [tool.poetry] name = "ship-it-tools" -version = "0.0.8" +version = "0.0.1" description = "Internal tools we use for the game development" authors = ["sobolevn "] license = "CC BY-NC-SA 4.0" classifiers = [ "Private :: Do not Upload", ] -package-mode = false [tool.poetry.dependencies] python = "^3.11" @@ -16,6 +15,10 @@ numbers-parser = "^4.10.5" pypdfium2 = "^4.30.0" pillow = "^10.3.0" +[tool.poetry.group.dev.dependencies] +mypy = "^1.10" +types-pillow = "^10.2" + [tool.ruff] line-length = 80 @@ -25,6 +28,13 @@ fix = true select = ['F', 'I'] fixable = ['ALL'] +[tool.ruff.lint.isort] +known-first-party = ["ship_it_tools"] + + +[tool.mypy] +strict = true + [build-system] requires = ["poetry-core"] diff --git a/tools/ship_it_tools/__init__.py b/tools/ship_it_tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/ship_it_tools/counts.py b/tools/ship_it_tools/counts.py new file mode 100644 index 0000000..eb6ddc1 --- /dev/null +++ b/tools/ship_it_tools/counts.py @@ -0,0 +1,14 @@ +import numbers_parser # type: ignore[import-untyped] + + +def read_counts(counts_path: str) -> list[int]: + """Return the list of ints of cards' counts definned in `counts.numbers`.""" + document = numbers_parser.Document(counts_path) + table = document.sheets[0].tables[0] + + read_counts = [] + for row in range(table.num_rows): + cell = table.cell(f"C{row + 1}").value + if cell: + read_counts.append(int(cell)) + return read_counts diff --git a/tools/tts-exporter.py b/tools/tts-exporter.py index 4eb479a..b2223c3 100644 --- a/tools/tts-exporter.py +++ b/tools/tts-exporter.py @@ -89,6 +89,7 @@ def _create_sheet( current_image.close() # Resize to be 10k pixels max: + assert dest_image wpercent = TTS_MAX_SIZE / dest_image.size[0] hsize = int(dest_image.size[1] * wpercent) filename_suffix = "back" if is_back else "front" diff --git a/tools/validate-cards.py b/tools/validate-cards.py new file mode 100644 index 0000000..1191ee4 --- /dev/null +++ b/tools/validate-cards.py @@ -0,0 +1,51 @@ +import argparse +from typing import Final + +import numbers_parser # type: ignore[import-untyped] + +from ship_it_tools import counts + +_NUMBER_OF_PLAYERS: Final = 5 + + +def _read_card_counts(cards_path: str) -> list[int]: + document = numbers_parser.Document(cards_path) + + card_counts = [] + for card_sheet in document.sheets: + cell_value = card_sheet.tables[0].cell("E18").value + if cell_value.startswith(" ="): # `= number of players` + card_counts.append(_NUMBER_OF_PLAYERS) + else: + card_counts.append(int(cell_value.split(" ")[0])) + return card_counts + + +def _validate(cards_path: str, counts: list[int]) -> None: + card_counts = _read_card_counts(cards_path) + if card_counts != counts: + raise ValueError("Not equal", card_counts, counts) + + +def main() -> None: + """Run the script.""" + parser = argparse.ArgumentParser() + parser.add_argument( + "cards", + type=str, # TODO: use `filepath` type + help="Path to `cards.numbers` file with cards definitions", + ) + parser.add_argument( + "counts", + type=str, # TODO: use `filepath` type + help="Path to `counts.numbers` file with card counts", + ) + parsed_args = parser.parse_args() + _validate( + parsed_args.cards, + counts.read_counts(parsed_args.counts), + ) + + +if __name__ == "__main__": + main() diff --git a/tools/validate.sh b/tools/validate.sh new file mode 100644 index 0000000..cb837b7 --- /dev/null +++ b/tools/validate.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -e + +# Check if card counts are identical in `counts.numbers` and `cards.numbers`: +python tools/validate-cards.py ru/cards.numbers ru/counts.numbers