mtg-ssm 2.7.0__tar.gz → 2.7.1.dev5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/.github/dependabot.yml +1 -1
- mtg_ssm-2.7.1.dev5/.github/workflows/integration.yml +48 -0
- mtg_ssm-2.7.1.dev5/.github/workflows/pre-commit.yml +23 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/.github/workflows/publish.yml +5 -13
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/.github/workflows/run-tests.yml +15 -22
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/.pre-commit-config.yaml +5 -5
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/PKG-INFO +44 -37
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/README.rst +37 -8
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/TODO.md +0 -2
- mtg_ssm-2.7.1.dev5/mtg_ssm/_version.py +34 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/containers/bundles.py +20 -3
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/containers/indexes.py +6 -7
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/containers/legacy.py +3 -3
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/scryfall/fetcher.py +4 -4
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/scryfall/models.py +83 -90
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/serialization/csv_serializer.py +4 -4
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/serialization/interface.py +4 -4
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/serialization/xlsx_serializer.py +28 -17
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/ssm.py +1 -2
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm.egg-info/PKG-INFO +44 -37
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm.egg-info/SOURCES.txt +2 -0
- mtg_ssm-2.7.1.dev5/mtg_ssm.egg-info/requires.txt +9 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/pyproject.toml +10 -14
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/containers/test_bundles.py +82 -1
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/data/bulk_data.json +2 -2
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/data/cards.json +2304 -996
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/data/sets.json +171 -43
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/data/sets1.json +94 -21
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/data/sets2.json +95 -40
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/gen_testdata.py +9 -2
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/scryfall/test_fetcher.py +6 -4
- mtg_ssm-2.7.1.dev5/tests/scryfall/test_models.py +26 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/serialization/__snapshots__/test_xlsx_serializer.ambr +211 -211
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/serialization/test_csv_serializer.py +2 -6
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/serialization/test_xlsx_serializer.py +2 -3
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/test_ssm.py +44 -106
- mtg_ssm-2.7.1.dev5/uv.lock +1308 -0
- mtg_ssm-2.7.0/.github/workflows/integration.yml +0 -50
- mtg_ssm-2.7.0/.github/workflows/pre-commit.yml +0 -26
- mtg_ssm-2.7.0/mtg_ssm/_version.py +0 -21
- mtg_ssm-2.7.0/mtg_ssm.egg-info/requires.txt +0 -32
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/.editorconfig +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/.gitignore +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/LICENSE.txt +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/containers/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/containers/collection.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/containers/counts.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/mtg/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/mtg/util.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/py.typed +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/scryfall/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm/serialization/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm.egg-info/dependency_links.txt +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm.egg-info/entry_points.txt +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/mtg_ssm.egg-info/top_level.txt +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/setup.cfg +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/conftest.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/containers/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/containers/test_counts.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/containers/test_indexes.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/containers/test_legacy.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/data/LICENSE.txt +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/data/migrations.json +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/mtg/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/mtg/test_util.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/scryfall/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/serialization/__init__.py +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/serialization/__snapshots__/test_csv_serializer.ambr +0 -0
- {mtg_ssm-2.7.0 → mtg_ssm-2.7.1.dev5}/tests/serialization/test_interface.py +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: integration
|
|
2
|
+
concurrency: integration
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
# Run on every push to trunk
|
|
8
|
+
- trunk
|
|
9
|
+
schedule:
|
|
10
|
+
# Run every Saturday at 4:05 AM UTC
|
|
11
|
+
- cron: "5 4 * * SAT"
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
end-to-end:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
include:
|
|
19
|
+
- name: base
|
|
20
|
+
sync-args: ""
|
|
21
|
+
- name: lxml
|
|
22
|
+
sync-args: "--extra lxml"
|
|
23
|
+
name: End-to-end tests (${{ matrix.name }})
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v6
|
|
26
|
+
|
|
27
|
+
- uses: astral-sh/setup-uv@v7
|
|
28
|
+
with:
|
|
29
|
+
enable-cache: true
|
|
30
|
+
python-version: "3.14"
|
|
31
|
+
|
|
32
|
+
- name: Sync runtime environment
|
|
33
|
+
run: uv sync --frozen --no-dev ${{ matrix.sync-args }}
|
|
34
|
+
|
|
35
|
+
- name: Create csv
|
|
36
|
+
run: uv run --frozen --no-dev mtg-ssm create collection1.csv
|
|
37
|
+
|
|
38
|
+
- name: Update csv
|
|
39
|
+
run: uv run --frozen --no-dev mtg-ssm update collection1.csv
|
|
40
|
+
|
|
41
|
+
- name: Create xlsx
|
|
42
|
+
run: uv run --frozen --no-dev mtg-ssm create collection2.xlsx
|
|
43
|
+
|
|
44
|
+
- name: Update xlsx
|
|
45
|
+
run: uv run --frozen --no-dev mtg-ssm update collection2.xlsx
|
|
46
|
+
|
|
47
|
+
- name: Merge csv and xlsx
|
|
48
|
+
run: uv run --frozen --no-dev mtg-ssm merge collection3.xlsx collection1.csv collection2.xlsx
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: lint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- trunk
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
pre-commit:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
name: Run all pre-commit checks
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v6
|
|
15
|
+
|
|
16
|
+
- uses: astral-sh/setup-uv@v7
|
|
17
|
+
with:
|
|
18
|
+
enable-cache: true
|
|
19
|
+
python-version: "3.14"
|
|
20
|
+
|
|
21
|
+
- run: uv sync --frozen
|
|
22
|
+
|
|
23
|
+
- run: uv run --frozen pre-commit run --all-files
|
|
@@ -16,26 +16,18 @@ jobs:
|
|
|
16
16
|
id-token: write
|
|
17
17
|
|
|
18
18
|
steps:
|
|
19
|
-
- uses: actions/checkout@
|
|
19
|
+
- uses: actions/checkout@v6
|
|
20
20
|
with:
|
|
21
21
|
# setuptools_scm needs the git history
|
|
22
22
|
fetch-depth: 0
|
|
23
23
|
|
|
24
|
-
- uses:
|
|
24
|
+
- uses: astral-sh/setup-uv@v7
|
|
25
25
|
with:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- name: Install pypa/build
|
|
29
|
-
run: >-
|
|
30
|
-
pip install --user
|
|
31
|
-
build
|
|
26
|
+
enable-cache: true
|
|
27
|
+
python-version: "3.14"
|
|
32
28
|
|
|
33
29
|
- name: Build a binary wheel and a source tarball
|
|
34
|
-
run:
|
|
35
|
-
python -m build
|
|
36
|
-
--sdist
|
|
37
|
-
--wheel
|
|
38
|
-
--outdir dist/
|
|
30
|
+
run: uv build --sdist --wheel --out-dir dist
|
|
39
31
|
|
|
40
32
|
- name: Publish distribution 📦 to Test PyPI
|
|
41
33
|
uses: pypa/gh-action-pypi-publish@release/v1.12
|
|
@@ -11,11 +11,11 @@ jobs:
|
|
|
11
11
|
strategy:
|
|
12
12
|
matrix:
|
|
13
13
|
python-version:
|
|
14
|
-
- "3.9"
|
|
15
14
|
- "3.10"
|
|
16
15
|
- "3.11"
|
|
17
16
|
- "3.12"
|
|
18
17
|
- "3.13"
|
|
18
|
+
- "3.14"
|
|
19
19
|
os:
|
|
20
20
|
- ubuntu-latest
|
|
21
21
|
- macos-latest
|
|
@@ -23,52 +23,46 @@ jobs:
|
|
|
23
23
|
runs-on: ${{ matrix.os }}
|
|
24
24
|
name: Can run on ${{ matrix.os }} - Python ${{ matrix.python-version }}
|
|
25
25
|
steps:
|
|
26
|
-
- uses: actions/checkout@
|
|
26
|
+
- uses: actions/checkout@v6
|
|
27
27
|
|
|
28
|
-
- uses:
|
|
28
|
+
- uses: astral-sh/setup-uv@v7
|
|
29
29
|
with:
|
|
30
|
+
enable-cache: true
|
|
30
31
|
python-version: "${{ matrix.python-version }}"
|
|
31
|
-
cache: pip
|
|
32
|
-
cache-dependency-path: pyproject.toml
|
|
33
32
|
|
|
34
|
-
- name:
|
|
35
|
-
run:
|
|
36
|
-
pip install -U pip setuptools
|
|
37
|
-
pip install -e .
|
|
33
|
+
- name: Sync runtime environment
|
|
34
|
+
run: uv sync --frozen --no-dev
|
|
38
35
|
|
|
39
36
|
- name: Run mtg-ssm
|
|
40
|
-
run: mtg-ssm --help
|
|
37
|
+
run: uv run --frozen --no-dev mtg-ssm --help
|
|
41
38
|
|
|
42
39
|
pytest:
|
|
43
40
|
runs-on: ubuntu-latest
|
|
44
41
|
strategy:
|
|
45
42
|
matrix:
|
|
46
43
|
python-version:
|
|
47
|
-
- "3.9"
|
|
48
44
|
- "3.10"
|
|
49
45
|
- "3.11"
|
|
50
46
|
- "3.12"
|
|
51
47
|
- "3.13"
|
|
48
|
+
- "3.14"
|
|
52
49
|
name: Python ${{ matrix.python-version }} pytest
|
|
53
50
|
steps:
|
|
54
|
-
- uses: actions/checkout@
|
|
51
|
+
- uses: actions/checkout@v6
|
|
55
52
|
|
|
56
|
-
- uses:
|
|
53
|
+
- uses: astral-sh/setup-uv@v7
|
|
57
54
|
with:
|
|
55
|
+
enable-cache: true
|
|
58
56
|
python-version: "${{ matrix.python-version }}"
|
|
59
|
-
cache: pip
|
|
60
|
-
cache-dependency-path: pyproject.toml
|
|
61
57
|
|
|
62
|
-
- name:
|
|
63
|
-
run:
|
|
64
|
-
pip install -U pip setuptools wheel
|
|
65
|
-
pip install -e .[lxml,dev]
|
|
58
|
+
- name: Sync test environment
|
|
59
|
+
run: uv sync --frozen --extra lxml
|
|
66
60
|
|
|
67
61
|
- name: Execute pytest
|
|
68
|
-
run: pytest tests/
|
|
62
|
+
run: uv run --frozen pytest tests/
|
|
69
63
|
|
|
70
64
|
- name: Convert coverage
|
|
71
|
-
run: coverage lcov
|
|
65
|
+
run: uv run --frozen coverage lcov
|
|
72
66
|
|
|
73
67
|
- name: Coveralls Parallel
|
|
74
68
|
uses: coverallsapp/github-action@v2.3.6
|
|
@@ -87,5 +81,4 @@ jobs:
|
|
|
87
81
|
uses: coverallsapp/github-action@v2.3.6
|
|
88
82
|
with:
|
|
89
83
|
github-token: ${{ secrets.github_token }}
|
|
90
|
-
path-to-lcov: coverage.lcov
|
|
91
84
|
parallel-finished: true
|
|
@@ -4,19 +4,19 @@ repos:
|
|
|
4
4
|
- id: black
|
|
5
5
|
name: black
|
|
6
6
|
description: "Black: The uncompromising Python code formatter"
|
|
7
|
-
entry: black
|
|
7
|
+
entry: uv run --frozen black
|
|
8
8
|
language: system
|
|
9
9
|
require_serial: true
|
|
10
10
|
types: [python]
|
|
11
11
|
- id: mypy
|
|
12
12
|
name: Type checking from mypy
|
|
13
13
|
language: system
|
|
14
|
-
entry: mypy
|
|
14
|
+
entry: uv run --frozen mypy
|
|
15
15
|
types: [python]
|
|
16
16
|
- id: ruff
|
|
17
17
|
name: ruff
|
|
18
18
|
description: "Run ruff on files"
|
|
19
|
-
entry: ruff check --force-exclude
|
|
19
|
+
entry: uv run --frozen ruff check --force-exclude
|
|
20
20
|
language: system
|
|
21
21
|
types_or: [python, pyi]
|
|
22
22
|
args: [--fix, --exit-non-zero-on-fix]
|
|
@@ -24,12 +24,12 @@ repos:
|
|
|
24
24
|
- id: doc8-python
|
|
25
25
|
name: Documentation checking from doc8 (Python)
|
|
26
26
|
language: system
|
|
27
|
-
entry: doc8
|
|
27
|
+
entry: uv run --frozen doc8
|
|
28
28
|
types: [python]
|
|
29
29
|
- id: doc8-rst
|
|
30
30
|
name: Documentation checking from doc8 (reStructuredText)
|
|
31
31
|
language: system
|
|
32
|
-
entry: doc8
|
|
32
|
+
entry: uv run --frozen doc8
|
|
33
33
|
types: [rst]
|
|
34
34
|
- id: eclint
|
|
35
35
|
name: EditorConfig file validation
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: mtg_ssm
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.1.dev5
|
|
4
4
|
Summary: A tool to manage Magic: the Gathering collection spreadsheets
|
|
5
5
|
Author-email: George Leslie-Waksman <waksman@gmail.com>
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/gwax/mtg_ssm
|
|
8
8
|
Project-URL: Bug Tracker, https://github.com/gwax/mtg_ssm/issues
|
|
9
9
|
Keywords: mtg,magic,collection,tracking,spreadsheet
|
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Environment :: Console
|
|
12
12
|
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
13
|
Classifier: Operating System :: MacOS
|
|
15
14
|
Classifier: Operating System :: Microsoft :: Windows
|
|
16
15
|
Classifier: Operating System :: OS Independent
|
|
@@ -19,45 +18,24 @@ Classifier: Operating System :: Unix
|
|
|
19
18
|
Classifier: Programming Language :: Python
|
|
20
19
|
Classifier: Programming Language :: Python :: 3
|
|
21
20
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
23
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
24
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
25
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
26
24
|
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
27
26
|
Classifier: Topic :: Games/Entertainment
|
|
28
|
-
Requires-Python: >=3.
|
|
27
|
+
Requires-Python: >=3.10
|
|
29
28
|
Description-Content-Type: text/x-rst
|
|
30
29
|
License-File: LICENSE.txt
|
|
31
|
-
Requires-Dist: appdirs~=1.4
|
|
32
30
|
Requires-Dist: msgspec~=0.15
|
|
33
31
|
Requires-Dist: openpyxl~=3.1
|
|
32
|
+
Requires-Dist: platformdirs~=4.0
|
|
34
33
|
Requires-Dist: requests~=2.27
|
|
35
34
|
Requires-Dist: requests-cache~=0.9.8
|
|
36
35
|
Requires-Dist: typing_extensions~=4.8.0
|
|
37
36
|
Provides-Extra: lxml
|
|
38
37
|
Requires-Dist: lxml>=3.7.2; extra == "lxml"
|
|
39
|
-
|
|
40
|
-
Requires-Dist: black; extra == "dev"
|
|
41
|
-
Requires-Dist: coverage[toml]; extra == "dev"
|
|
42
|
-
Requires-Dist: doc8; extra == "dev"
|
|
43
|
-
Requires-Dist: exceptiongroup; extra == "dev"
|
|
44
|
-
Requires-Dist: freezegun; extra == "dev"
|
|
45
|
-
Requires-Dist: lxml; extra == "dev"
|
|
46
|
-
Requires-Dist: mypy; extra == "dev"
|
|
47
|
-
Requires-Dist: openpyxl-stubs; extra == "dev"
|
|
48
|
-
Requires-Dist: pip; extra == "dev"
|
|
49
|
-
Requires-Dist: Pygments; extra == "dev"
|
|
50
|
-
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
51
|
-
Requires-Dist: pytest-cov; extra == "dev"
|
|
52
|
-
Requires-Dist: responses; extra == "dev"
|
|
53
|
-
Requires-Dist: ruff; extra == "dev"
|
|
54
|
-
Requires-Dist: setuptools>=45; extra == "dev"
|
|
55
|
-
Requires-Dist: setuptools-scm[toml]>=6.2; extra == "dev"
|
|
56
|
-
Requires-Dist: syrupy>=4.0; extra == "dev"
|
|
57
|
-
Requires-Dist: types-appdirs; extra == "dev"
|
|
58
|
-
Requires-Dist: types-freezegun; extra == "dev"
|
|
59
|
-
Requires-Dist: types-requests; extra == "dev"
|
|
60
|
-
Requires-Dist: wheel; extra == "dev"
|
|
38
|
+
Dynamic: license-file
|
|
61
39
|
|
|
62
40
|
mtg-ssm - Magic: the Gathering Spreadsheet Manager
|
|
63
41
|
===================================================
|
|
@@ -102,19 +80,28 @@ Please also check out my other major Magic: the Gathering project,
|
|
|
102
80
|
Installation
|
|
103
81
|
============
|
|
104
82
|
|
|
105
|
-
mtg-ssm is available on PyPI so, if you have
|
|
106
|
-
|
|
107
|
-
the following into a
|
|
83
|
+
mtg-ssm is available on PyPI so, if you have Python (>=3.10) and a
|
|
84
|
+
package installer such as uv or pip installed on your system, you
|
|
85
|
+
should be able to get mtg-ssm by entering one of the following into a
|
|
86
|
+
terminal:
|
|
108
87
|
|
|
109
88
|
.. code:: bash
|
|
110
89
|
|
|
111
|
-
|
|
90
|
+
uv tool install mtg_ssm
|
|
91
|
+
|
|
92
|
+
.. code:: bash
|
|
93
|
+
|
|
94
|
+
pip install mtg_ssm
|
|
112
95
|
|
|
113
96
|
Updates can be performed by entering:
|
|
114
97
|
|
|
115
98
|
.. code:: bash
|
|
116
99
|
|
|
117
|
-
|
|
100
|
+
uv tool upgrade mtg-ssm
|
|
101
|
+
|
|
102
|
+
.. code:: bash
|
|
103
|
+
|
|
104
|
+
pip install -U mtg_ssm
|
|
118
105
|
|
|
119
106
|
You can verify installation from the terminal by running:
|
|
120
107
|
|
|
@@ -210,8 +197,26 @@ Contributions
|
|
|
210
197
|
|
|
211
198
|
Pull requests are welcome and contributions are greatly appreciated. If you
|
|
212
199
|
would like to contribute, please be sure that all tests and lint checks
|
|
213
|
-
pass.
|
|
214
|
-
|
|
200
|
+
pass.
|
|
201
|
+
|
|
202
|
+
Development uses `uv`. A typical local setup is:
|
|
203
|
+
|
|
204
|
+
.. code:: bash
|
|
205
|
+
|
|
206
|
+
uv python install 3.14
|
|
207
|
+
uv sync --python 3.14 --extra lxml
|
|
208
|
+
|
|
209
|
+
Common development commands:
|
|
210
|
+
|
|
211
|
+
.. code:: bash
|
|
212
|
+
|
|
213
|
+
uv run --python 3.14 pre-commit run --all-files
|
|
214
|
+
uv run --python 3.14 pytest
|
|
215
|
+
uv run --python 3.14 python -m tests.gen_testdata
|
|
216
|
+
|
|
217
|
+
The package metadata and lint/type-check targets stay on Python 3.10, so
|
|
218
|
+
changes should remain compatible with that floor even when developed from
|
|
219
|
+
a Python 3.14 environment.
|
|
215
220
|
|
|
216
221
|
Issues can be reported via GitHub.
|
|
217
222
|
|
|
@@ -238,7 +243,9 @@ Changelog
|
|
|
238
243
|
Development
|
|
239
244
|
-----------
|
|
240
245
|
|
|
241
|
-
-
|
|
246
|
+
- Switch project development and CI workflows to uv.
|
|
247
|
+
- Set Python 3.10 as the supported package floor.
|
|
248
|
+
- Use Python 3.14 for development workflows.
|
|
242
249
|
|
|
243
250
|
2.7.0
|
|
244
251
|
-----
|
|
@@ -41,19 +41,28 @@ Please also check out my other major Magic: the Gathering project,
|
|
|
41
41
|
Installation
|
|
42
42
|
============
|
|
43
43
|
|
|
44
|
-
mtg-ssm is available on PyPI so, if you have
|
|
45
|
-
|
|
46
|
-
the following into a
|
|
44
|
+
mtg-ssm is available on PyPI so, if you have Python (>=3.10) and a
|
|
45
|
+
package installer such as uv or pip installed on your system, you
|
|
46
|
+
should be able to get mtg-ssm by entering one of the following into a
|
|
47
|
+
terminal:
|
|
47
48
|
|
|
48
49
|
.. code:: bash
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
uv tool install mtg_ssm
|
|
52
|
+
|
|
53
|
+
.. code:: bash
|
|
54
|
+
|
|
55
|
+
pip install mtg_ssm
|
|
51
56
|
|
|
52
57
|
Updates can be performed by entering:
|
|
53
58
|
|
|
54
59
|
.. code:: bash
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
uv tool upgrade mtg-ssm
|
|
62
|
+
|
|
63
|
+
.. code:: bash
|
|
64
|
+
|
|
65
|
+
pip install -U mtg_ssm
|
|
57
66
|
|
|
58
67
|
You can verify installation from the terminal by running:
|
|
59
68
|
|
|
@@ -149,8 +158,26 @@ Contributions
|
|
|
149
158
|
|
|
150
159
|
Pull requests are welcome and contributions are greatly appreciated. If you
|
|
151
160
|
would like to contribute, please be sure that all tests and lint checks
|
|
152
|
-
pass.
|
|
153
|
-
|
|
161
|
+
pass.
|
|
162
|
+
|
|
163
|
+
Development uses `uv`. A typical local setup is:
|
|
164
|
+
|
|
165
|
+
.. code:: bash
|
|
166
|
+
|
|
167
|
+
uv python install 3.14
|
|
168
|
+
uv sync --python 3.14 --extra lxml
|
|
169
|
+
|
|
170
|
+
Common development commands:
|
|
171
|
+
|
|
172
|
+
.. code:: bash
|
|
173
|
+
|
|
174
|
+
uv run --python 3.14 pre-commit run --all-files
|
|
175
|
+
uv run --python 3.14 pytest
|
|
176
|
+
uv run --python 3.14 python -m tests.gen_testdata
|
|
177
|
+
|
|
178
|
+
The package metadata and lint/type-check targets stay on Python 3.10, so
|
|
179
|
+
changes should remain compatible with that floor even when developed from
|
|
180
|
+
a Python 3.14 environment.
|
|
154
181
|
|
|
155
182
|
Issues can be reported via GitHub.
|
|
156
183
|
|
|
@@ -177,7 +204,9 @@ Changelog
|
|
|
177
204
|
Development
|
|
178
205
|
-----------
|
|
179
206
|
|
|
180
|
-
-
|
|
207
|
+
- Switch project development and CI workflows to uv.
|
|
208
|
+
- Set Python 3.10 as the supported package floor.
|
|
209
|
+
- Use Python 3.14 for development workflows.
|
|
181
210
|
|
|
182
211
|
2.7.0
|
|
183
212
|
-----
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '2.7.1.dev5'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 7, 1, 'dev5')
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = 'g6ae45693f'
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""Data bundle definitions."""
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
|
-
from
|
|
4
|
+
from collections import Counter
|
|
5
|
+
from typing import NamedTuple
|
|
5
6
|
|
|
6
7
|
from mtg_ssm.scryfall.models import ScryCard, ScryCardLayout, ScryMigration, ScrySet, ScrySetType
|
|
7
8
|
|
|
@@ -14,11 +15,26 @@ class ScryfallDataSet(NamedTuple):
|
|
|
14
15
|
migrations: list[ScryMigration]
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
def recount_sets(sets: list[ScrySet], cards: list[ScryCard]) -> list[ScrySet]:
|
|
19
|
+
"""Return sets with card counts updated to match the provided card list."""
|
|
20
|
+
set_code_to_count = Counter(card.set for card in cards)
|
|
21
|
+
recounted_sets = []
|
|
22
|
+
for set_ in sets:
|
|
23
|
+
card_count = set_code_to_count[set_.code]
|
|
24
|
+
if set_.card_count == card_count:
|
|
25
|
+
recounted_sets.append(set_)
|
|
26
|
+
continue
|
|
27
|
+
recounted_set = copy.copy(set_)
|
|
28
|
+
recounted_set.card_count = card_count
|
|
29
|
+
recounted_sets.append(recounted_set)
|
|
30
|
+
return recounted_sets
|
|
31
|
+
|
|
32
|
+
|
|
17
33
|
def filter_cards_and_sets( # noqa: C901
|
|
18
34
|
scryfall_data: ScryfallDataSet,
|
|
19
35
|
*,
|
|
20
|
-
exclude_set_types:
|
|
21
|
-
exclude_card_layouts:
|
|
36
|
+
exclude_set_types: set[ScrySetType] | None = None,
|
|
37
|
+
exclude_card_layouts: set[ScryCardLayout] | None = None,
|
|
22
38
|
exclude_digital: bool = False,
|
|
23
39
|
exclude_foreing_only: bool = False,
|
|
24
40
|
merge_promos: bool = False,
|
|
@@ -68,6 +84,7 @@ def filter_cards_and_sets( # noqa: C901
|
|
|
68
84
|
for s in scryfall_data.sets
|
|
69
85
|
if s.code in accepted_setcodes and s.code in nonempty_setcodes
|
|
70
86
|
]
|
|
87
|
+
accepted_sets = recount_sets(accepted_sets, accepted_cards)
|
|
71
88
|
|
|
72
89
|
return ScryfallDataSet(
|
|
73
90
|
sets=accepted_sets,
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import collections
|
|
4
4
|
import string
|
|
5
5
|
from collections.abc import Iterable
|
|
6
|
-
from typing import Optional
|
|
7
6
|
from uuid import UUID
|
|
8
7
|
|
|
9
8
|
from mtg_ssm.containers.bundles import ScryfallDataSet
|
|
@@ -23,9 +22,9 @@ def set_card_sort_key(card: ScryCard) -> tuple[str, int, str]:
|
|
|
23
22
|
|
|
24
23
|
def build_snnmas(
|
|
25
24
|
card: ScryCard,
|
|
26
|
-
) -> Iterable[tuple[
|
|
25
|
+
) -> Iterable[tuple[str | None, str, str | None, int | None, str | None]]:
|
|
27
26
|
"""Build set, name, number, multiverse id tuple keys."""
|
|
28
|
-
names_cnums: set[tuple[str,
|
|
27
|
+
names_cnums: set[tuple[str, str | None]] = {(card.name, card.collector_number)}
|
|
29
28
|
for i, card_face in enumerate(card.card_faces or ()):
|
|
30
29
|
names_cnums |= {
|
|
31
30
|
(card_face.name, card.collector_number),
|
|
@@ -33,11 +32,11 @@ def build_snnmas(
|
|
|
33
32
|
}
|
|
34
33
|
names_cnums |= {(n, None) for n, _ in names_cnums}
|
|
35
34
|
|
|
36
|
-
sets: set[
|
|
35
|
+
sets: set[str | None] = {card.set, None}
|
|
37
36
|
|
|
38
|
-
mvids: set[
|
|
37
|
+
mvids: set[int | None] = {None} | set(card.multiverse_ids or ())
|
|
39
38
|
|
|
40
|
-
artists: set[
|
|
39
|
+
artists: set[str | None] = {card.artist, None}
|
|
41
40
|
|
|
42
41
|
for name, number in names_cnums:
|
|
43
42
|
for set_ in sets:
|
|
@@ -60,7 +59,7 @@ class ScryfallDataIndex:
|
|
|
60
59
|
# TODO: convert to intersecting bitmap indexes
|
|
61
60
|
# TODO: do we really need artist?
|
|
62
61
|
self.snnma_to_id: dict[
|
|
63
|
-
tuple[
|
|
62
|
+
tuple[str | None, str, str | None, int | None, str | None],
|
|
64
63
|
set[UUID],
|
|
65
64
|
] = {}
|
|
66
65
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Legacy record lookup capabilities for older file versions."""
|
|
2
2
|
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any
|
|
4
4
|
from uuid import UUID
|
|
5
5
|
|
|
6
6
|
from mtg_ssm.containers.indexes import Oracle
|
|
@@ -93,7 +93,7 @@ OTHER_SET_CODE_TO_SET_CODE = {
|
|
|
93
93
|
"PCA": ["opca"],
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
PSUDONYM_TO_ARTIST: dict[
|
|
96
|
+
PSUDONYM_TO_ARTIST: dict[str | None, str] = {
|
|
97
97
|
"William Murai": "Willian Murai",
|
|
98
98
|
"Dave Seeley": "David Seeley",
|
|
99
99
|
}
|
|
@@ -113,7 +113,7 @@ def find_scryfall_id(card_row: dict[str, str], oracle: Oracle) -> UUID:
|
|
|
113
113
|
artist = card_row.get("artist") or None
|
|
114
114
|
artist = PSUDONYM_TO_ARTIST.get(artist, artist)
|
|
115
115
|
print(f"Searching => Set: {set_code}; Name: {name}; Number: {collector_number}; MVID: {mvid}")
|
|
116
|
-
snnma_keys: list[tuple[
|
|
116
|
+
snnma_keys: list[tuple[str | None, str, str | None, int | None, str | None]] = []
|
|
117
117
|
for set_ in set_codes:
|
|
118
118
|
snnma_keys += [
|
|
119
119
|
(set_, name, collector_number, None, None),
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""Scryfall data fetcher."""
|
|
2
2
|
|
|
3
3
|
import gzip
|
|
4
|
-
import
|
|
4
|
+
from pathlib import Path
|
|
5
5
|
|
|
6
|
-
import appdirs
|
|
7
6
|
import msgspec
|
|
7
|
+
from platformdirs import user_cache_dir
|
|
8
8
|
from requests_cache import CachedSession, SerializerPipeline, Stage, pickle_serializer
|
|
9
9
|
|
|
10
10
|
from mtg_ssm.containers.bundles import ScryfallDataSet
|
|
@@ -12,7 +12,7 @@ from mtg_ssm.scryfall.models import ScryBulkData, ScryCard, ScryList, ScryMigrat
|
|
|
12
12
|
|
|
13
13
|
APP_AUTHOR = "gwax"
|
|
14
14
|
APP_NAME = "mtg_ssm"
|
|
15
|
-
CACHE_DIR =
|
|
15
|
+
CACHE_DIR = Path(user_cache_dir(APP_NAME, APP_AUTHOR))
|
|
16
16
|
CACHE_SERIALIZER = SerializerPipeline(
|
|
17
17
|
[
|
|
18
18
|
pickle_serializer,
|
|
@@ -21,7 +21,7 @@ CACHE_SERIALIZER = SerializerPipeline(
|
|
|
21
21
|
is_binary=True,
|
|
22
22
|
)
|
|
23
23
|
SESSION = CachedSession(
|
|
24
|
-
|
|
24
|
+
str(CACHE_DIR / "requests_cache.sqlite"),
|
|
25
25
|
backend="sqlite",
|
|
26
26
|
serializer=CACHE_SERIALIZER,
|
|
27
27
|
cache_control=True,
|