mtg-print 0.1.1__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.
@@ -0,0 +1,84 @@
1
+ name: PR Checks
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+
7
+ env:
8
+ PYTHON_VERSION: "3.12"
9
+
10
+ jobs:
11
+ branch-name:
12
+ name: Branch Name
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Check branch name
16
+ run: |
17
+ BRANCH_NAME="${{ github.head_ref }}"
18
+ PATTERN="^(patch|minor|major)/.*$"
19
+ if [[ ! "$BRANCH_NAME" =~ $PATTERN ]]; then
20
+ echo "Branch name '$BRANCH_NAME' does not match pattern: $PATTERN"
21
+ echo "Use: patch/*, minor/*, or major/*"
22
+ exit 1
23
+ fi
24
+ echo "Branch name '$BRANCH_NAME' is valid"
25
+
26
+ lint:
27
+ name: Lint & Type Check
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+
32
+ - name: Install uv
33
+ uses: astral-sh/setup-uv@v4
34
+ with:
35
+ enable-cache: true
36
+
37
+ - name: Set up Python
38
+ run: uv python install ${{ env.PYTHON_VERSION }}
39
+
40
+ - name: Install dependencies
41
+ run: uv sync --dev
42
+
43
+ - name: Run pre-commit
44
+ run: uv run pre-commit run --all-files
45
+
46
+ test:
47
+ name: Test
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+
52
+ - name: Install uv
53
+ uses: astral-sh/setup-uv@v4
54
+ with:
55
+ enable-cache: true
56
+
57
+ - name: Set up Python
58
+ run: uv python install ${{ env.PYTHON_VERSION }}
59
+
60
+ - name: Install dependencies
61
+ run: uv sync --dev
62
+
63
+ - name: Run tests
64
+ run: uv run pytest tests/ -v
65
+
66
+ build:
67
+ name: Build
68
+ runs-on: ubuntu-latest
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+
72
+ - name: Install uv
73
+ uses: astral-sh/setup-uv@v4
74
+ with:
75
+ enable-cache: true
76
+
77
+ - name: Set up Python
78
+ run: uv python install ${{ env.PYTHON_VERSION }}
79
+
80
+ - name: Build package
81
+ run: uv build
82
+
83
+ - name: Check dist files created
84
+ run: ls -la dist/
@@ -0,0 +1,76 @@
1
+ name: Release
2
+
3
+ on:
4
+ pull_request:
5
+ types: [closed]
6
+ branches: [main]
7
+
8
+ env:
9
+ PYTHON_VERSION: "3.12"
10
+
11
+ jobs:
12
+ release:
13
+ name: Release
14
+ if: github.event.pull_request.merged == true
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: write
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ with:
21
+ token: ${{ secrets.GITHUB_TOKEN }}
22
+
23
+ - name: Determine bump type from branch name
24
+ id: bump-type
25
+ run: |
26
+ BRANCH_NAME="${{ github.event.pull_request.head.ref }}"
27
+ if [[ "$BRANCH_NAME" == patch/* ]]; then
28
+ echo "type=patch" >> $GITHUB_OUTPUT
29
+ elif [[ "$BRANCH_NAME" == minor/* ]]; then
30
+ echo "type=minor" >> $GITHUB_OUTPUT
31
+ elif [[ "$BRANCH_NAME" == major/* ]]; then
32
+ echo "type=major" >> $GITHUB_OUTPUT
33
+ else
34
+ echo "Branch '$BRANCH_NAME' does not match patch/*/minor/*/major/*"
35
+ echo "type=none" >> $GITHUB_OUTPUT
36
+ fi
37
+
38
+ - name: Install uv
39
+ if: steps.bump-type.outputs.type != 'none'
40
+ uses: astral-sh/setup-uv@v4
41
+ with:
42
+ enable-cache: true
43
+
44
+ - name: Set up Python
45
+ if: steps.bump-type.outputs.type != 'none'
46
+ run: uv python install ${{ env.PYTHON_VERSION }}
47
+
48
+ - name: Bump version
49
+ if: steps.bump-type.outputs.type != 'none'
50
+ id: version
51
+ run: |
52
+ OLD_VERSION=$(uvx hatch version)
53
+ uvx hatch version ${{ steps.bump-type.outputs.type }}
54
+ NEW_VERSION=$(uvx hatch version)
55
+ echo "old=$OLD_VERSION" >> $GITHUB_OUTPUT
56
+ echo "new=$NEW_VERSION" >> $GITHUB_OUTPUT
57
+ echo "Bumped version: $OLD_VERSION -> $NEW_VERSION"
58
+
59
+ - name: Commit and push
60
+ if: steps.bump-type.outputs.type != 'none'
61
+ run: |
62
+ git config user.name "github-actions[bot]"
63
+ git config user.email "github-actions[bot]@users.noreply.github.com"
64
+ git add mtg_print/__version__.py
65
+ git commit -m "Bump version to ${{ steps.version.outputs.new }}"
66
+ git push
67
+
68
+ - name: Build package
69
+ if: steps.bump-type.outputs.type != 'none'
70
+ run: uv build
71
+
72
+ - name: Publish to PyPI
73
+ if: steps.bump-type.outputs.type != 'none'
74
+ run: uv publish
75
+ env:
76
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,214 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+ #poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ #pdm.lock
116
+ #pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ #pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # SageMath parsed files
135
+ *.sage.py
136
+
137
+ # Environments
138
+ .env
139
+ .envrc
140
+ .venv
141
+ env/
142
+ venv/
143
+ ENV/
144
+ env.bak/
145
+ venv.bak/
146
+
147
+ # Spyder project settings
148
+ .spyderproject
149
+ .spyproject
150
+
151
+ # Rope project settings
152
+ .ropeproject
153
+
154
+ # mkdocs documentation
155
+ /site
156
+
157
+ # mypy
158
+ .mypy_cache/
159
+ .dmypy.json
160
+ dmypy.json
161
+
162
+ # Pyre type checker
163
+ .pyre/
164
+
165
+ # pytype static type analyzer
166
+ .pytype/
167
+
168
+ # Cython debug symbols
169
+ cython_debug/
170
+
171
+ # PyCharm
172
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
173
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
174
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
175
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
176
+ #.idea/
177
+
178
+ # Abstra
179
+ # Abstra is an AI-powered process automation framework.
180
+ # Ignore directories containing user credentials, local state, and settings.
181
+ # Learn more at https://abstra.io/docs
182
+ .abstra/
183
+
184
+ # Visual Studio Code
185
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
188
+ # you could uncomment the following to ignore the entire vscode folder
189
+ # .vscode/
190
+
191
+ # Ruff stuff:
192
+ .ruff_cache/
193
+
194
+ # PyPI configuration file
195
+ .pypirc
196
+
197
+ # Cursor
198
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
199
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
200
+ # refer to https://docs.cursor.com/context/ignore-files
201
+ .cursorignore
202
+ .cursorindexingignore
203
+
204
+ # Marimo
205
+ marimo/_static/
206
+ marimo/_lsp/
207
+ __marimo__/
208
+
209
+ # Vim
210
+ *.swo
211
+ *.swp
212
+
213
+ # macOS
214
+ .DS_STORE
@@ -0,0 +1,23 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.0.0
4
+ hooks:
5
+ - id: check-merge-conflict
6
+ - id: end-of-file-fixer
7
+ - id: check-toml
8
+ - id: check-yaml
9
+ - id: trailing-whitespace
10
+ - repo: https://github.com/astral-sh/ruff-pre-commit
11
+ rev: "v0.9.3"
12
+ hooks:
13
+ - id: ruff
14
+ args: [--fix, --exit-non-zero-on-fix]
15
+ - id: ruff-format
16
+ - repo: local
17
+ hooks:
18
+ - id: ty
19
+ name: ty
20
+ entry: uv run ty check
21
+ language: system
22
+ types: [python]
23
+ pass_filenames: false
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jamie McMillan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,18 @@
1
+ .PHONY: bootstrap build test demo
2
+
3
+ bootstrap:
4
+ @command -v uv >/dev/null 2>&1 || { echo "Installing uv..."; curl -LsSf https://astral.sh/uv/install.sh | sh; }
5
+ @command -v vhs >/dev/null 2>&1 || { echo "Installing vhs..."; brew install vhs; }
6
+ uv sync --dev
7
+
8
+ build:
9
+ uv build
10
+
11
+ test:
12
+ uv run pre-commit run --all-files
13
+ uv run pytest tests/ -v
14
+
15
+ demo:
16
+ @command -v vhs >/dev/null 2>&1 || { echo "VHS not installed. Run 'make bootstrap' first."; exit 1; }
17
+ cd docs && vhs demo.tape
18
+ @echo "Generated docs/demo.gif"
@@ -0,0 +1,117 @@
1
+ Metadata-Version: 2.4
2
+ Name: mtg-print
3
+ Version: 0.1.1
4
+ Summary: CLI tool for printing MTG proxy sheets from decklists
5
+ Project-URL: Repository, https://github.com/jamiemc1/mtg-print
6
+ Project-URL: Issues, https://github.com/jamiemc1/mtg-print/issues
7
+ Author: Jamie McMillan
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: decklist,magic,mtg,printing,proxy,scryfall
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: End Users/Desktop
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Games/Entertainment
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: httpx>=0.27
21
+ Requires-Dist: pillow>=10.0
22
+ Requires-Dist: reportlab>=4.0
23
+ Requires-Dist: tomli-w>=1.0
24
+ Requires-Dist: typer>=0.9
25
+ Description-Content-Type: text/markdown
26
+
27
+ # mtg-print
28
+
29
+ CLI tool for printing Magic: The Gathering proxy sheets. Parses decklists, fetches card images from Scryfall, and generates printable PDFs.
30
+
31
+ ![Demo](docs/demo.gif)
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ pipx install mtg-print
37
+ ```
38
+
39
+ Or run directly:
40
+
41
+ ```bash
42
+ uvx mtg-print --help
43
+ ```
44
+
45
+ ## Quick start
46
+
47
+ ```bash
48
+ mtg-print build docs/example.txt --interactive
49
+ ```
50
+
51
+ ## Usage
52
+
53
+ ### Build a PDF from a decklist
54
+
55
+ ```bash
56
+ mtg-print build deck.txt
57
+ mtg-print build deck.txt -o output.pdf
58
+ ```
59
+
60
+ Basic lands are automatically filtered. Cards default to their oldest printing.
61
+
62
+ ### Interactive art selection
63
+
64
+ ```bash
65
+ mtg-print build deck.txt --interactive
66
+ ```
67
+
68
+ Displays available printings with thumbnails and lets you choose. Selections are saved for future builds.
69
+
70
+ ### Override specific card art
71
+
72
+ ```bash
73
+ mtg-print build deck.txt -s "Swords to Plowshares=ICE"
74
+ ```
75
+
76
+ ### Search card printings
77
+
78
+ ```bash
79
+ mtg-print search "Sylvan Library"
80
+ mtg-print search "Elvish Reclaimer" --preview
81
+ ```
82
+
83
+ ### Manage preferences
84
+
85
+ ```bash
86
+ mtg-print prefs # View saved art preferences
87
+ mtg-print prefs --clear # Clear all preferences
88
+ ```
89
+
90
+ ### Manage cache
91
+
92
+ ```bash
93
+ mtg-print cache --stats # Show cache size
94
+ mtg-print cache --clear # Clear cached images
95
+ ```
96
+
97
+ ## Supported decklist formats
98
+
99
+ - Moxfield / MTG Arena: `4 Elvish Reclaimer (MH2) 166`
100
+ - MTGGoldfish: `4 Elvish Reclaimer <mh2>`
101
+ - DeckedBuilder: `4 Elvish Reclaimer`
102
+ - Manabox: `1 Card Name (SET) 123 *F*`
103
+ - TopDecked: `4 Spyglass Siren`
104
+
105
+ ## Development
106
+
107
+ ```bash
108
+ git clone https://github.com/jamiemc1/mtg-print.git
109
+ cd mtg-print
110
+ uv sync --dev
111
+ uv run pytest
112
+ uv run pre-commit run --all-files
113
+ ```
114
+
115
+ ---
116
+
117
+ Card images © Wizards of the Coast
@@ -0,0 +1,91 @@
1
+ # mtg-print
2
+
3
+ CLI tool for printing Magic: The Gathering proxy sheets. Parses decklists, fetches card images from Scryfall, and generates printable PDFs.
4
+
5
+ ![Demo](docs/demo.gif)
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pipx install mtg-print
11
+ ```
12
+
13
+ Or run directly:
14
+
15
+ ```bash
16
+ uvx mtg-print --help
17
+ ```
18
+
19
+ ## Quick start
20
+
21
+ ```bash
22
+ mtg-print build docs/example.txt --interactive
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Build a PDF from a decklist
28
+
29
+ ```bash
30
+ mtg-print build deck.txt
31
+ mtg-print build deck.txt -o output.pdf
32
+ ```
33
+
34
+ Basic lands are automatically filtered. Cards default to their oldest printing.
35
+
36
+ ### Interactive art selection
37
+
38
+ ```bash
39
+ mtg-print build deck.txt --interactive
40
+ ```
41
+
42
+ Displays available printings with thumbnails and lets you choose. Selections are saved for future builds.
43
+
44
+ ### Override specific card art
45
+
46
+ ```bash
47
+ mtg-print build deck.txt -s "Swords to Plowshares=ICE"
48
+ ```
49
+
50
+ ### Search card printings
51
+
52
+ ```bash
53
+ mtg-print search "Sylvan Library"
54
+ mtg-print search "Elvish Reclaimer" --preview
55
+ ```
56
+
57
+ ### Manage preferences
58
+
59
+ ```bash
60
+ mtg-print prefs # View saved art preferences
61
+ mtg-print prefs --clear # Clear all preferences
62
+ ```
63
+
64
+ ### Manage cache
65
+
66
+ ```bash
67
+ mtg-print cache --stats # Show cache size
68
+ mtg-print cache --clear # Clear cached images
69
+ ```
70
+
71
+ ## Supported decklist formats
72
+
73
+ - Moxfield / MTG Arena: `4 Elvish Reclaimer (MH2) 166`
74
+ - MTGGoldfish: `4 Elvish Reclaimer <mh2>`
75
+ - DeckedBuilder: `4 Elvish Reclaimer`
76
+ - Manabox: `1 Card Name (SET) 123 *F*`
77
+ - TopDecked: `4 Spyglass Siren`
78
+
79
+ ## Development
80
+
81
+ ```bash
82
+ git clone https://github.com/jamiemc1/mtg-print.git
83
+ cd mtg-print
84
+ uv sync --dev
85
+ uv run pytest
86
+ uv run pre-commit run --all-files
87
+ ```
88
+
89
+ ---
90
+
91
+ Card images © Wizards of the Coast
Binary file
@@ -0,0 +1,13 @@
1
+ # VHS demo script
2
+ # Run: vhs demo.tape
3
+
4
+ Output demo.gif
5
+
6
+ Set FontSize 14
7
+ Set Width 800
8
+ Set Height 500
9
+ Set Theme "Catppuccin Mocha"
10
+
11
+ Type "uv run mtg-print build example.txt"
12
+ Enter
13
+ Sleep 10s
@@ -0,0 +1,24 @@
1
+ // Example Legacy Maverick decklist
2
+ // Run: mtg-print build example.txt --interactive
3
+
4
+ Creatures
5
+ 4 Noble Hierarch
6
+ 4 Thalia, Guardian of Thraben
7
+ 3 Knight of the Reliquary
8
+ 2 Endurance
9
+ 1 Collector Ouphe
10
+ 1 Scavenging Ooze
11
+
12
+ Spells
13
+ 4 Swords to Plowshares
14
+ 4 Green Sun's Zenith
15
+ 3 Once Upon a Time
16
+
17
+ Lands
18
+ 4 Windswept Heath
19
+ 3 Wooded Foothills
20
+ 2 Savannah
21
+ 1 Bayou
22
+ 1 Dryad Arbor
23
+ 1 Karakas
24
+ 1 Gaea's Cradle
@@ -0,0 +1,3 @@
1
+ """MTG Print - CLI tool for printing MTG proxy sheets from decklists."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1 @@
1
+ __version__ = "0.1.1"