Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
219 commits
Select commit Hold shift + click to select a range
879ab9a
feat(effects): Expose more gradient overlay options
pappnu Mar 13, 2025
eeceb73
fix(saga.py): Fix Saga layout check
pappnu Mar 13, 2025
09bdfdd
feat(colors.py): Allow generating pinline gradients for 5 and more co…
pappnu Mar 13, 2025
7e54af7
fix(cast): Remove erroneous type casts
pappnu Mar 13, 2025
e75a7bb
Merge branch '5+-colors' into mix
pappnu Mar 13, 2025
855c994
Merge branch 'saga-fix' into mix
pappnu Mar 13, 2025
467a98c
Merge branch 'gradient-overlay-options' into mix
pappnu Mar 13, 2025
1af7524
feat(process_card_data): Assign Saga layout to Saga Creature cards
pappnu Apr 12, 2025
8b14989
Merge branch 'saga-creatures' into mix
pappnu Apr 12, 2025
f0a753e
feat(CaseLayout): Add support for rendering Case cards
pappnu Apr 13, 2025
f8b4a58
Merge branch 'case-layout' into mix
pappnu Apr 13, 2025
1c80a61
fix(update_template): Unpack 7zipped template updates after download
pappnu Apr 14, 2025
5e3820a
Merge branch 'fix-template-updater' into mix
pappnu Apr 14, 2025
953778e
fix(CaseMod): Allow case templates not to use a text divider
pappnu Apr 16, 2025
75431aa
feat(scale_text_layers_to_height): Allow finer control of text scalin…
pappnu Apr 19, 2025
c2f6a3f
feat(PlaneswalkerMod): Allow inheriting Planeswalker templates to mor…
pappnu Apr 19, 2025
352ab1c
Merge branch 'case-layout' into mix
pappnu Apr 19, 2025
4b695b1
Merge branch 'pw-scaling-steps' into mix
pappnu Apr 19, 2025
6dd7b7b
fix(get_pinline_gradient): Fix getting Artifact pinline gradient
pappnu Apr 21, 2025
c652e13
Merge branch '5+-colors' into mix
pappnu Apr 21, 2025
d553867
fix(SagaLayout): Fix SagaLayout text when reminder text removal is ac…
pappnu Apr 27, 2025
14fce05
Merge branch 'fix-saga-template-reminder-removal' into mix
pappnu Apr 27, 2025
4cee51f
fix(ClassLayout): Fix ClassLayout text when reminder text removal is …
pappnu May 5, 2025
afc9b5e
Merge branch 'fix-saga-template-reminder-removal' into mix
pappnu May 5, 2025
d740049
Merge branch 'fix-saga-template-reminder-removal' into saga-creature-…
pappnu May 11, 2025
0914a73
feat(SagaLayout): Separeta non-chapter ability text for Saga creatures
pappnu May 11, 2025
ffaf6ec
Merge branch 'saga-creature-support' into mix
pappnu May 11, 2025
eb9f1ea
fix(SagaLayout): Prevent chapter abilities from ending up in saga_des…
pappnu May 16, 2025
169f6c5
Merge branch 'saga-creature-support' into mix
pappnu May 16, 2025
5c8f61b
fix(Case): Import Case templates in the template module's __init__.py
pappnu May 17, 2025
0802a69
Merge branch 'case-layout' into mix
pappnu May 17, 2025
71ba535
fix(get_pinline_gradient): Fix lookup of color keywords from color map
pappnu May 17, 2025
126d07a
Merge branch '5+-colors' into mix
pappnu May 17, 2025
572e157
feat(LevelerMod): Improve LevelerMod compatibility with other Mod cla…
pappnu May 24, 2025
434775a
Merge branch 'leveler-mod-compatibility' into mix
pappnu May 24, 2025
a81790f
refactor(Split): Refactor Split template related code for type safe i…
pappnu May 31, 2025
d0d576d
Merge branch 'split-refactor' into mix
pappnu Jun 1, 2025
4b546dc
feat(Photoshop): Adds an option to minimize Photoshop when rendering …
pappnu Jun 15, 2025
290ce68
Merge branch 'minimize-photoshop' into mix
pappnu Jun 15, 2025
4941daa
feat(Photoshop): Simplify await_choice usage in relation to Photoshop…
pappnu Jun 15, 2025
e04dd16
Merge branch 'minimize-photoshop' into mix
pappnu Jun 15, 2025
5d6dbd4
feat(NormalLayout): Improve robustness of card face matching
pappnu Jun 21, 2025
b524e1c
Merge branch 'card-face-matching' into mix
pappnu Jun 21, 2025
0086a17
feat(Station): Add support for Station layout
pappnu Jul 12, 2025
e772b25
Merge branch 'station-cards' into mix
pappnu Jul 12, 2025
759a925
feat(TemplateModule): Show all category tabs irrespective of the amou…
pappnu Jul 21, 2025
3478a93
Merge branch 'show-all-category-tabs' into mix
pappnu Jul 21, 2025
e9dc46a
feat: Adds an option to open Scryfall data in a text editor for manua…
pappnu Aug 13, 2025
6f26452
Merge branch 'manual-card-data-edit' into mix
pappnu Aug 13, 2025
5d965c1
fix(assign_layout): Fix manual card data edit being always activated
pappnu Aug 16, 2025
7b47fdc
Merge branch 'manual-card-data-edit' into dev
pappnu Aug 16, 2025
e3269a6
feat: Add stricter type annotations to most of the codebase excluding…
pappnu Aug 24, 2025
56546b5
feat(pyproject.toml): Update dependencies and make the configuration …
pappnu Aug 24, 2025
539ad2a
docs(README.md): Clarify Python environment setup
pappnu Aug 24, 2025
4c0157b
feat: Asynchronize startup checks in order to allow the user to inter…
pappnu Aug 29, 2025
efcbf7e
docs(README.md): Update Python setup guide
pappnu Aug 29, 2025
fcf1448
refactor(rate_limit): Switch to rate limiting library `limits`, which…
pappnu Aug 31, 2025
e2e6fda
refactor(rate_limit): Simplify rescheduling of rate limited calls
pappnu Aug 31, 2025
65476fb
fix(process_card_data): Set card as front after failing to match the …
pappnu Sep 2, 2025
c6ab895
fix(ProxyshopGUIApp): Fix app crashing in test mode
pappnu Sep 4, 2025
501a66f
fix(ClassicModernTemplate): Enable the crown for only legendary cards
pappnu Sep 4, 2025
7196336
fix(FormattedTextArea): Width scaling should be off by default
pappnu Sep 6, 2025
d3def46
test(template_renders.toml): Add test cases for Saga Creatures, Cases…
pappnu Sep 6, 2025
25fa59f
fix(AdventureLayout): Sort Adventure color identity in the MTG canoni…
pappnu Sep 6, 2025
538cd30
refactor(app.py): Improve type annotations
pappnu Sep 6, 2025
7e5630a
feat(ClassMod): Fall back to default rules text and pt logic if the c…
pappnu Sep 7, 2025
d90b8be
feat(SagaMod): Fall back to default rules text and pt logic if the ca…
pappnu Sep 7, 2025
6e56e6f
feat(text_layers.py): Assign blank text to text item if that is what …
pappnu Sep 7, 2025
93f7ca7
fix(ENV): Override the defaults with `env.yml` and not the other way …
pappnu Sep 7, 2025
c871565
test(ProxyshopGUIApp): Fix test image assignment for Split layout
pappnu Sep 8, 2025
7583d6b
test(template_renders.toml): Add test cases for Tokens
pappnu Sep 8, 2025
1238fa6
feat: Add support for pawprint symbol
pappnu Sep 13, 2025
8429278
fix(process_card_data): Add a temporary workaround for incorrect mana…
pappnu Sep 13, 2025
964fb35
feat: Add a setting to use the printed name of the card when it's ava…
pappnu Sep 27, 2025
d06f5f5
feat: Validate Scryfall data using Pydantic models and assign normal …
pappnu Sep 29, 2025
05728a7
feat(layouts.py): Expand printed text setting to apply to type line a…
pappnu Sep 29, 2025
f811365
feat: Support rendering Class cards using languages other than English
pappnu Oct 6, 2025
aa7fb72
build(poetry): Update dependencies
pappnu Oct 7, 2025
f872c44
refactor(rate_limit): Import rate_limit decorator from omnitils
pappnu Oct 7, 2025
d78235d
fix(ScryfallCard): Don't validate the non-official `front` field
pappnu Oct 25, 2025
5632522
feat: Allow fetching symbols and checking app updates from user defin…
pappnu Oct 25, 2025
ee14282
refactor(scryfall.py): Do not use the `type` keyword for defining Lit…
pappnu Oct 25, 2025
aef6e2d
feat: Add a setting for forcing a symbol of a specified rarity to be …
pappnu Oct 26, 2025
f54baff
refactor(ENV): Use pydantic-settings instead of dynaconf for app envi…
pappnu Oct 26, 2025
faf79ac
feat: Replace the Kivy GUI with a PySide6 GUI
pappnu Feb 17, 2026
8ebf381
docs(README.md): Update the README's descriptions to match the new Py…
pappnu Feb 17, 2026
d735b2b
feat: Write better log messages for test calls
pappnu Feb 17, 2026
edc5879
fix(AssembledTemplate): Mark partially installed templates as usable …
pappnu Feb 17, 2026
321d94b
fix(FormattedTextField): Fix right aligning of quote credit
pappnu Feb 18, 2026
90eba95
fix(AppConfig): Correctly use default template config if template spe…
pappnu Feb 18, 2026
535b1eb
feat: Allow using Photoshop's "Remove" action for filling and expose …
pappnu Feb 20, 2026
cc0f7ad
fix(scryfall.py): Prevent validation errors from getting obscured whe…
pappnu Feb 20, 2026
2b688c9
feat: Allow adjusting the PNG compression level
pappnu Feb 20, 2026
f3a6724
fix(remove_content_fill_edges): Prevent "Remove Content" fill from sa…
pappnu Feb 22, 2026
dda1f22
feat: Allow hooking into the art fill area selection process
pappnu Feb 25, 2026
0594159
fix: Save app and default template configs on quit
pappnu Mar 2, 2026
a187ff9
feat: Reuse the same Photoshop document if the next render uses the s…
pappnu Mar 2, 2026
7004936
fix(PlaneswalkerLayout): Remove reminder text from Planeswalker abili…
pappnu Mar 2, 2026
600310f
fix(RenderQueue): Take active render operation into account when orde…
pappnu Mar 2, 2026
4a608de
build(poetry.lock): Update dependencies
pappnu Mar 2, 2026
78ef13a
fix(AppPlugin): Ensure that a plugin's _module attribute can be acces…
pappnu Mar 2, 2026
9157f60
feat(ENV): Allow specifying the logging level via LOG_LEVEL env varia…
pappnu Mar 14, 2026
6f0465b
feat(selection.py): Allow extending selection with selection helpers
pappnu Mar 14, 2026
d126e6e
feat: Make message severity more apparent at a glance in the GUI's co…
pappnu Mar 14, 2026
cac5a4f
feat(fonts.py): Add `is_font_available_in_ps` for easily checking ava…
pappnu Mar 14, 2026
1794914
feat(text.py): Add `override_text_style_ranges` for restyling specifi…
pappnu Mar 14, 2026
a109474
fix: Try to thread safely handle Future results
pappnu Mar 14, 2026
9fa6651
fix: Use list instead of Literal["QVariantList"] as Qt Property type …
pappnu Mar 14, 2026
2751118
feat: Allow supplying nickname via the art filename and generalize ni…
pappnu Mar 14, 2026
b8237ba
fix(SettingsWindow.qml): Correctly update bool settings and ensure mo…
pappnu Mar 26, 2026
673dffd
feat(SettingsWindow.qml): Show default values for settings
pappnu Mar 26, 2026
bdf4bcc
style(base.toml): Remove trailing line break from "Allow Nickname" se…
pappnu Mar 26, 2026
f219e50
Implement basic render-spec
Malacath-92 Apr 1, 2026
d4955a9
Add option to specify art file in additional_cfg
Malacath-92 Jan 6, 2024
3ddeba9
Add groups in a render-spec
Malacath-92 Jan 6, 2024
d65fbd9
Add inner and outer group index variables
Malacath-92 Jan 6, 2024
e577aee
Allow inline configurations in render specs instead of requiring ever…
Malacath-92 Jan 6, 2024
c9bb973
Add support for globs in render spec
Malacath-92 Jan 13, 2024
542bcf7
Fix for globbed files loosing their ability to load artwork when appl…
Malacath-92 Jan 15, 2024
11355ed
Fix issues withb `art=` tag and relative paths
Malacath-92 Jan 15, 2024
ed72846
Fix some issues with globs
Malacath-92 Jan 19, 2024
ce98ed0
Add option to maintain folder structure in out folder
Malacath-92 Jan 15, 2024
e68b3ed
Add ability to override set symbol from additional config
Malacath-92 Apr 2, 2026
78d42fc
Cleanup render_spec.py
Malacath-92 Apr 2, 2026
3d019e6
Fix render spec with groups
Malacath-92 Apr 2, 2026
7c5bb17
Make sure you can have an full filename/path in a render spec
Malacath-92 Apr 3, 2026
4ecae7c
Fix Pylance errors
Malacath-92 Apr 4, 2026
dda31cd
refactor: Code cleanup and auto formatting
pappnu Apr 5, 2026
e918108
build(pyproject.toml): Update dependencies, import formatting rules a…
pappnu Apr 5, 2026
157fdcb
Make sure render spec contain the absolute path to images
Malacath-92 Apr 5, 2026
49ace5f
Remove Maintain.Folder.Structure and instead imply this when render f…
Malacath-92 Apr 5, 2026
03d2869
Include .txt files when opening a file dialog for "images and data"
Malacath-92 Apr 5, 2026
23aea41
Port support for 'tmpl' argument that allows selecting a template for…
Malacath-92 Apr 5, 2026
16be42d
Move handling of 'art' argument to NormalLayout
Malacath-92 Apr 7, 2026
d651cbe
Port render specs to validated YAML
Malacath-92 Apr 8, 2026
91ac919
Add a schema for render spec
Malacath-92 Apr 8, 2026
fb278b7
Avoid a number of list[T] | T in render spec model types
Malacath-92 Apr 9, 2026
9476c81
Change configs to be of type dict[str, str]
Malacath-92 Apr 9, 2026
24d7697
Turn RenderSpec into a @dataclass
Malacath-92 Apr 9, 2026
e80f3a2
Add details about render specs to the README
Malacath-92 Apr 10, 2026
3ac69a4
feat: Add rudimentary support for Prepare cards
pappnu Apr 10, 2026
39cd910
refactor: Remove redundant code
pappnu Apr 10, 2026
0fab385
Add notes on supported kwargs
Malacath-92 Apr 10, 2026
704c4c9
fix: Ensure image transform output folder exists and discard alpha wh…
pappnu Apr 11, 2026
215caeb
refactor: Simplify code
pappnu Apr 8, 2026
96cfe38
fix(match_images_with_data_files): Retain exception information when …
pappnu Apr 8, 2026
e441680
Merge branch 'RenderSpec-AttemptFour' into dev
pappnu Apr 14, 2026
5086ba7
fix(BaseTemplate): Fix Pyright type error by providing an explicit ty…
pappnu Apr 14, 2026
fc126de
Add basic single-card panorama mode (broken commit)
Malacath-92 Nov 1, 2023
f86b1b5
Proof of concept multi-card panorama mode
Malacath-92 Nov 3, 2023
25411d8
Add vertical panorama support
Malacath-92 Dec 14, 2023
89e0bfb
Fix panorama mode
Malacath-92 Jan 6, 2024
68a7752
Hide border on vertical panoramas
Malacath-92 Apr 15, 2026
b88ad8f
Remove printout of render spec schema
Malacath-92 Apr 15, 2026
f66a120
Remove accidental double-cards when rendering a render spec
Malacath-92 Apr 15, 2026
5d6fd25
Add API to get document/card dimensions as if they were layers
Malacath-92 Apr 15, 2026
6bea456
Frame panorama within card area as opposed to a reference layer
Malacath-92 Apr 15, 2026
775eb56
Remove some accidentally merged code
Malacath-92 Apr 15, 2026
b1f3faa
fix(scryfall.py): Limit Scryfall requests to 2 per second as that is …
pappnu Apr 15, 2026
217f03b
Merge branch 'dev' of https://github.com/pappnu/Proxyshop into Panora…
Malacath-92 Apr 29, 2026
64fa88a
Add instructions for panoramas via an example to the README
Malacath-92 Apr 29, 2026
df214bc
Suggested refactors
Malacath-92 Apr 29, 2026
af7e293
Merge pull request #2 from Malacath-92/PanoramaModeAttemptTwo
pappnu Apr 29, 2026
45f123c
feat: Use Scryfall's `/cards/collection` endpoint to batch fetch (Eng…
pappnu May 4, 2026
42751b7
test: Separate tests that aren't aimed at plugin authors from the app…
pappnu May 6, 2026
0eca640
style(render_spec.py): Code formatting
pappnu May 6, 2026
ec5106c
fix(update_template): Fix download unpacking logic
pappnu May 6, 2026
1e1ceac
docs(README.md): Document how to run tests
pappnu May 6, 2026
a09d97e
fix(update_hexproof_cache): Fix asset timestamp comparison
pappnu May 6, 2026
987db9c
feat(masks.py): Add helper function for deleting layer mask from a so…
pappnu May 7, 2026
0156f68
feat(selection.py): Return Selection object from functions that selec…
pappnu May 7, 2026
2c4745f
feat: Add stricter typing to `get_option`
pappnu May 7, 2026
f9a6a8b
test(text_file_name.toml): Move file name test data under tests direc…
pappnu May 7, 2026
aa34a8d
build: Separate commands from the main app code
pappnu May 7, 2026
5acae70
build: Use uv instead of Poetry for dependency management
pappnu May 7, 2026
8f8c8eb
docs(README.md): Document how to use uv for setting up the Python env…
pappnu May 7, 2026
c79bf04
fix(templates/__init__.py): Re-export the prepare module so that it u…
pappnu May 10, 2026
04d74a2
fix(ConfigHandler): Create the config ini directory if it doesn't exist
pappnu May 10, 2026
e0b72fc
feat: Add support for filtering settings
pappnu May 18, 2026
fa150c9
feat: Allow clicking links in selectable text components
pappnu May 21, 2026
b5fddd3
perf(colors.py): Avoid unnecessary Photoshop API object instantiations
pappnu May 21, 2026
54f5bc9
refactor(ClassicTemplate): Remove redundant override of collector_inf…
pappnu May 21, 2026
851836f
feat(prepare_test_render): Disable Scryfall scan import in test renders
pappnu May 21, 2026
a079ac7
fix(_loader.py): Disable interpolation in config parsers as it causes…
pappnu May 21, 2026
090004e
feat: Allow spcifying user defined custom formats for collector info …
pappnu May 21, 2026
45133ca
test: Add tests for format_string_with_indices
pappnu May 21, 2026
320f2a5
refactor: Fix type checking and linting errors
pappnu May 21, 2026
5956970
fix(SettingsWindow.qml): Fix changing setting values when filtering i…
pappnu May 21, 2026
b73dd4c
feat: Apply custom formatting to specific word end characters in Bele…
pappnu May 22, 2026
2d4469d
fix(selection.py): Fix extending selection to the pixels covered by a…
pappnu May 22, 2026
4456bd9
feat(SettingsModel): Add stricter typing to `setData`
pappnu May 22, 2026
efe8eb8
feat(FormattedTextField): Revert paragraph justification change if it…
pappnu May 22, 2026
86b9339
feat(align_text): Use stricter typing
pappnu May 22, 2026
89611e3
fix(get_font_size): Fix scaling being skipped when using the layer's …
pappnu May 24, 2026
e02b4cb
fix: Preserve whitespace when replacing trailing characters in Belere…
pappnu May 24, 2026
c654656
fix(process_card_data): Ensure idempotency for Planeswalker Transform…
pappnu May 25, 2026
8c394ac
feat(SplitMod): Rotate the render in the hooks step
pappnu May 25, 2026
5f958bd
feat(BaseTemplate): Add a property for collector info set text layer
pappnu May 25, 2026
7f1a883
feat(Proxyglyph.ttf): Update the numbers 0-9 to more closely match re…
pappnu May 26, 2026
909f50b
fix(NormalLayout): Fix modern collector mode option not working
pappnu May 31, 2026
cc7cfe0
feat(BaseTemplate): Allow templates to more easily access collector t…
pappnu Jun 8, 2026
6b6b4fa
feat: Add support for programmatically executing UXP scripts in Photo…
pappnu Jun 8, 2026
03296a9
feat(layers.py): Add function for getting stroke size from layer effects
pappnu Jun 8, 2026
37f7657
feat: Use a shaped text layer to more space efficiently avoid overlap…
pappnu Jun 8, 2026
0420234
fix(CustomFileDialog.qml): Ignore unsupported folder paths instead of…
pappnu Jun 11, 2026
96a49e4
docs(env.default.yml): Clarify the format of values that PS_VERSION e…
pappnu Jun 11, 2026
9138906
fix: More accurately offset Planeswalker rules text away from startin…
pappnu Jun 11, 2026
a36f7dc
feat: Allow running specific render test cases via the GUI
pappnu Jun 23, 2026
7f553ff
feat(apply_mask_to_layer_fx): Allow applying vector mask to layer eff…
pappnu Jun 23, 2026
24c5919
feat(get_bounds_no_effects): Propagate the error when getting bounds …
pappnu Jun 23, 2026
1ae101e
perf(BaseTemplate): Avoid redundantly getting the type text layer twice
pappnu Jun 23, 2026
977eed7
feat(SagaVectorTemplate): Properly call the super implementation of e…
pappnu Jun 23, 2026
67b0915
fix(get_card_data): Correctly extract collector number from the card …
pappnu Jul 14, 2026
5140b42
feat(assign_layout): Always manually modify Scryfall data if the sett…
pappnu Jul 14, 2026
fcf4ff7
fix: match json data files whose stem still carries artist/set/number…
lukegothic Jul 13, 2026
435c39f
fix: address review feedback (reuse parse_card_info, fix tests types)
lukegothic Jul 14, 2026
6be5b9f
Merge pull request #4 from lukegothic/fix/json-stem-tag-matching-dev
pappnu Jul 14, 2026
c9d28af
perf(match_images_with_data_files): Parse information from card data …
pappnu Jul 14, 2026
6829877
feat(FormattedTextArea): Allow disabling vertical centering of text
pappnu Jul 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ __pycache__/
build/
develop-eggs/
dist/
dist_js/
downloads/
eggs/
.eggs/
Expand Down Expand Up @@ -151,11 +152,17 @@ cython_debug/
# VSCode
.vscode/

# SPECIFIC TO THIS PROJECT
# Node modules
node_modules/

## SPECIFIC TO THIS PROJECT

# Art input folder
/art
# Render output folder
/out
# Temporary files
/tmp
# Temporary logging directory
/logs
# For personal testing
Expand All @@ -166,6 +173,8 @@ cython_debug/
/src/data/versions.yml
# User defined environment
/src/data/env.yml
# User preferences
/src/data/preferences
# Generated new release
/release
# Environmental variables
Expand All @@ -175,6 +184,7 @@ cython_debug/
!/plugins/Investigamer
!/plugins/SilvanMTG
/plugins/*/config_ini
/plugins/*/__init__.py
# PSD templates directories
/templates/*
!/templates/tools
Expand All @@ -191,3 +201,12 @@ cython_debug/
/src/data/hexproof
# Allow the internal build tools
!src/data/build/
# Backups
/backup
# Built executable
proxyshop.exe
# Autogenerated Qt files
src/gui/qml/models/*.json
src/gui/qml/models/*.cpp
src/gui/qml/models/*.qmltypes
src/gui/qml/models/qmldir
270 changes: 195 additions & 75 deletions README.md

Large diffs are not rendered by default.

Binary file modified fonts/Proxyglyph.ttf
Binary file not shown.
165 changes: 115 additions & 50 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,133 @@
"""
* Proxyshop Application Launcher
"""
# Standard Library Imports
import os
import sys

"""
* Launcher Funcs
"""
from pathlib import Path

from PySide6.QtGui import QIcon

def launch_cli():
"""Launch the app in CLI mode."""
from src import APP, CFG, CON, ENV
from src._loader import (
AppPlugin,
TemplateLibrary,
get_all_plugins,
get_template_file_versions,
)
from src.startup import run_startup_checks

# Enable headless mode, remove cli marker
os.environ['PROXYSHOP_HEADLESS'] = '1'
if 'cli' in sys.argv:
sys.argv.remove('cli')

# Local Imports
from src.commands import ProxyshopCLI
def launch_gui(template_library: TemplateLibrary, plugins: dict[str, AppPlugin]):
"""Launch the app in GUI mode."""

# Run the CLI application
ProxyshopCLI.main()
from PySide6 import QtAsyncio
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQuickControls2 import QQuickStyle

from src.gui.qml.models.batch_rendering_model import BatchRenderingModel
from src.gui.qml.models.console_model import ConsoleModel
from src.gui.qml.models.file_dialog_model import FileDialogModel
from src.gui.qml.models.file_path_model import FilePathModel
from src.gui.qml.models.image_transform_model import ImageTransformModel
from src.gui.qml.models.message_dialog_content_model import (
MessageDialogContentModel,
)
from src.gui.qml.models.render_operations_model import RenderOperationsModel
from src.gui.qml.models.settings_model import SettingsModel
from src.gui.qml.models.settings_tree_model import SettingsTreeModel
from src.gui.qml.models.template_list_model import TemplateListModel
from src.gui.qml.models.template_updater_model import TemplateUpdaterModel
from src.gui.qml.models.test_renders_model import TestRendersModel
from src.render.render_queue import RenderQueue

def launch_gui():
"""Launch the app in GUI mode."""
app = QGuiApplication(applicationDisplayName="Proxyshop")
app.setWindowIcon(QIcon("src/img/favicon.ico"))
engine = QQmlApplicationEngine()

# Local Imports
os.environ['PROXYSHOP_HEADLESS'] = '0'
from src import (
APP, CFG, CON, CONSOLE, ENV,
PLUGINS, TEMPLATES, TEMPLATE_MAP, TEMPLATE_DEFAULTS)
from src.gui._state import register_kv_classes, load_kv_config
from src.gui.app import ProxyshopGUIApp
file_path_model = FilePathModel()
render_queue = RenderQueue()
file_dialog_model = FileDialogModel()
console_model = ConsoleModel()
render_message_dialog_content_model = MessageDialogContentModel()
render_operations_model = RenderOperationsModel(
render_queue, render_message_dialog_content_model
)
template_updater_model = TemplateUpdaterModel(
app_env=ENV, template_library=template_library
)
test_renders_model = TestRendersModel(
render_queue,
template_library,
file_dialog_model,
render_message_dialog_content_model,
CFG,
)
template_list_model = TemplateListModel(
render_queue,
file_dialog_model,
render_message_dialog_content_model,
template_library,
test_renders_model,
CFG,
)
batch_render_model = BatchRenderingModel(
file_dialog_model,
render_message_dialog_content_model,
render_queue,
plugins,
template_library,
test_renders_model,
CFG,
)
settings_tree_model = SettingsTreeModel(
app_config=CFG, template_library=template_library
)
settings_model = SettingsModel(settings_tree_model)
image_transform_model = ImageTransformModel(file_dialog_model=file_dialog_model)

# Kivy Imported Last
from kivy.resources import resource_add_path
root_context = engine.rootContext()
root_context.setContextProperty("filePathModel", file_path_model)
root_context.setContextProperty("fileDialogModel", file_dialog_model)
root_context.setContextProperty("consoleModel", console_model)
root_context.setContextProperty(
"renderMessageDialogContentModel", render_message_dialog_content_model
)
root_context.setContextProperty("renderOperationsModel", render_operations_model)
root_context.setContextProperty("testRendersModel", test_renders_model)
root_context.setContextProperty("templateUpdaterModel", template_updater_model)
root_context.setContextProperty("templateListModel", template_list_model)
root_context.setContextProperty("batchRenderModel", batch_render_model)
root_context.setContextProperty("settingsTreeModel", settings_tree_model)
root_context.setContextProperty("settingsModel", settings_model)
root_context.setContextProperty("imageTransformModel", image_transform_model)
root_context.setContextProperty(
"github_url", f"https://github.com/{ENV.APP_UPDATES_REPO}"
)

# Kivy packaging for PyInstaller
if hasattr(sys, '_MEIPASS'):
resource_add_path(os.path.join(sys._MEIPASS))
# This points to the extracted bundle directory in a distributable build
engine.addImportPath(Path(__file__).parent / "src" / "gui")
QQuickStyle.setStyle("Fusion")
QQuickStyle.setFallbackStyle("Basic")
engine.loadFromModule("qml", "App")

# Load KV files and utilities
load_kv_config()
register_kv_classes()
# Ensure that the root context is available at QML destruction
app.aboutToQuit.connect(engine.deleteLater)

# Run the GUI application
ProxyshopGUIApp(
app=APP,
run_startup_checks(APP)

QtAsyncio.run(handle_sigint=True)


if __name__ == "__main__":
initial_versions = get_template_file_versions()
versions = initial_versions.model_copy(deep=True)
plugins = get_all_plugins(con=CON, env=ENV, template_file_versions=versions.root)
template_library = TemplateLibrary(
con=CON,
cfg=CFG,
env=ENV,
console=CONSOLE,
plugins=PLUGINS,
templates=TEMPLATES,
template_map=TEMPLATE_MAP,
templates_default=TEMPLATE_DEFAULTS,
).run()


if __name__ == '__main__':
"""Route to a qualified launcher."""
if 'cli' in sys.argv:
sys.exit(launch_cli())
launch_gui()
plugins=plugins,
initial_template_file_versions=initial_versions,
template_file_versions=versions,
)

launch_gui(template_library, plugins)
102 changes: 102 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"type": "module",
"scripts": {
"build": "tsc && node --experimental-transform-types scripts_js/build.ts",
"type-check": "pyright ./plugins/** ./src/** ./tests/** ./scripts/** && tsc --noEmit && npx tsc --project tsconfig.tools.json --noEmit"
},
"devDependencies": {
"@types/node": "^25.9.1",
"@types/photoshop": "^25.0.4",
"prettier": "^3.8.3",
"pyright": "^1.1.409",
"typescript": "^6.0.3"
}
}
Loading