decksmith 0.1.15__py3-none-any.whl → 0.9.2__py3-none-any.whl

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.
decksmith/validate.py CHANGED
@@ -1,132 +1,132 @@
1
- """
2
- This module provides functions for validating and transforming card specifications.
3
- """
4
-
5
- from typing import Dict, Any
6
-
7
- import pandas as pd
8
- from jval import validate
9
-
10
- ELEMENT_SPEC: Dict[str, Any] = {
11
- "?*id": "<?str>",
12
- "*type": "<?str>",
13
- "?*position": ["<?float>"],
14
- "?*relative_to": ["<?str>"],
15
- "?*anchor": "<?str>",
16
- }
17
-
18
- SPECS_FOR_TYPE: Dict[str, Dict[str, Any]] = {
19
- "text": {
20
- "*text": "<?str>",
21
- "?*color": ["<?int>"],
22
- "?*font_path": "<?str>",
23
- "?*font_size": "<?int>",
24
- "?*font_variant": "<?str>",
25
- "?*line_spacing": "<?int>",
26
- "?*width": "<?int>",
27
- "?*align": "<?str>",
28
- "?*stroke_width": "<?int>",
29
- "?*stroke_color": ["<?int>"],
30
- },
31
- "image": {
32
- "*path": "<?str>",
33
- "?*filters": {
34
- "?*crop_top": "<?int>",
35
- "?*crop_bottom": "<?int>",
36
- "?*crop_left": "<?int>",
37
- "?*crop_right": "<?int>",
38
- "?*crop_box": ["<?int>"],
39
- "?*rotate": "<?int>",
40
- "?*flip": "<?str>",
41
- "?*resize": ["<?int>"],
42
- },
43
- },
44
- "circle": {
45
- "*radius": "<?int>",
46
- "?*color": ["<?int>"],
47
- "?*outline_color": ["<?int>"],
48
- "?*outline_width": "<?int>",
49
- },
50
- "ellipse": {
51
- "*size": ["<?int>"],
52
- "?*color": ["<?int>"],
53
- "?*outline_color": ["<?int>"],
54
- "?*outline_width": "<?int>",
55
- },
56
- "polygon": {
57
- "*points": [["<?int>"]],
58
- "?*color": ["<?int>"],
59
- "?*outline_color": ["<?int>"],
60
- "?*outline_width": "<?int>",
61
- },
62
- "regular-polygon": {
63
- "*radius": "<?int>",
64
- "*sides": "<?int>",
65
- "?*rotation": "<?int>",
66
- "?*color": ["<?int>"],
67
- "?*outline_color": ["<?int>"],
68
- "?*outline_width": "<?int>",
69
- },
70
- "rectangle": {
71
- "*size": ["<?int>"],
72
- "?*corners": ["<?bool>"],
73
- "?*corner_radius": "<?int>",
74
- "?*color": ["<?int>"],
75
- "?*outline_color": ["<?int>"],
76
- "?*outline_width": "<?int>",
77
- },
78
- }
79
-
80
- CARD_SPEC: Dict[str, Any] = {
81
- "?*id": "<?str>",
82
- "*width": "<?int>",
83
- "*height": "<?int>",
84
- "?*background_color": ["<?int>"],
85
- "*elements": [],
86
- }
87
-
88
-
89
- def validate_element(element: Dict[str, Any], element_type: str):
90
- """
91
- Validates an element of a card against a spec, raising an exception
92
- if it does not meet the spec.
93
- Args:
94
- element (dict): The card element.
95
- element_type (str): The type of the element
96
- """
97
- spec = ELEMENT_SPEC | SPECS_FOR_TYPE[element_type]
98
- validate(element, spec)
99
-
100
-
101
- def validate_card(card: Dict[str, Any]):
102
- """
103
- Validates a card against a spec, raising an exception
104
- if it does not meet the spec.
105
- Args:
106
- card (Dict[str, Any]): The card.
107
- """
108
- # print(f"DEBUG:\n{card=}")
109
- validate(card, CARD_SPEC)
110
- for element in card["elements"]:
111
- # print(f"DEBUG: {element['type']}")
112
- validate_element(element, element["type"])
113
-
114
-
115
- def transform_card(card: Dict[str, Any]) -> Dict[str, Any]:
116
- """
117
- Perform certain automatic type casts on the card and its
118
- elements. For example, cast the "text" property of elements
119
- of type "text" to str, to support painting numbers as text.
120
- Args:
121
- card (Dict[str, Any]): The card.
122
- Return:
123
- Dict[str, Any]: The transformed card with all automatic casts applied.
124
- """
125
- for element in card.get("elements", []):
126
- if element.get("type") == "text" and "text" in element:
127
- if pd.isna(element["text"]):
128
- element["text"] = None
129
- else:
130
- element["text"] = str(element["text"])
131
-
132
- return card
1
+ """
2
+ This module provides functions for validating and transforming card specifications.
3
+ """
4
+
5
+ from typing import Any, Dict
6
+
7
+ import pandas as pd
8
+ from jval import validate
9
+
10
+ ELEMENT_SPEC: Dict[str, Any] = {
11
+ "?*id": "<?str>",
12
+ "*type": "<?str>",
13
+ "?*position": ["<?float>"],
14
+ "?*relative_to": ["<?str>"],
15
+ "?*anchor": "<?str>",
16
+ }
17
+
18
+ SPECS_FOR_TYPE: Dict[str, Dict[str, Any]] = {
19
+ "text": {
20
+ "*text": "<?str>",
21
+ "?*color": ["<?int>"],
22
+ "?*font_path": "<?str>",
23
+ "?*font_size": "<?int>",
24
+ "?*font_variant": "<?str>",
25
+ "?*line_spacing": "<?int>",
26
+ "?*width": "<?int>",
27
+ "?*align": "<?str>",
28
+ "?*stroke_width": "<?int>",
29
+ "?*stroke_color": ["<?int>"],
30
+ },
31
+ "image": {
32
+ "*path": "<?str>",
33
+ "?*filters": {
34
+ "?*crop_top": "<?int>",
35
+ "?*crop_bottom": "<?int>",
36
+ "?*crop_left": "<?int>",
37
+ "?*crop_right": "<?int>",
38
+ "?*crop_box": ["<?int>"],
39
+ "?*rotate": "<?int>",
40
+ "?*flip": "<?str>",
41
+ "?*resize": ["<?int>"],
42
+ },
43
+ },
44
+ "circle": {
45
+ "*radius": "<?int>",
46
+ "?*color": ["<?int>"],
47
+ "?*outline_color": ["<?int>"],
48
+ "?*outline_width": "<?int>",
49
+ },
50
+ "ellipse": {
51
+ "*size": ["<?int>"],
52
+ "?*color": ["<?int>"],
53
+ "?*outline_color": ["<?int>"],
54
+ "?*outline_width": "<?int>",
55
+ },
56
+ "polygon": {
57
+ "*points": [["<?int>"]],
58
+ "?*color": ["<?int>"],
59
+ "?*outline_color": ["<?int>"],
60
+ "?*outline_width": "<?int>",
61
+ },
62
+ "regular-polygon": {
63
+ "*radius": "<?int>",
64
+ "*sides": "<?int>",
65
+ "?*rotation": "<?int>",
66
+ "?*color": ["<?int>"],
67
+ "?*outline_color": ["<?int>"],
68
+ "?*outline_width": "<?int>",
69
+ },
70
+ "rectangle": {
71
+ "*size": ["<?int>"],
72
+ "?*corners": ["<?bool>"],
73
+ "?*corner_radius": "<?int>",
74
+ "?*color": ["<?int>"],
75
+ "?*outline_color": ["<?int>"],
76
+ "?*outline_width": "<?int>",
77
+ },
78
+ }
79
+
80
+ CARD_SPEC: Dict[str, Any] = {
81
+ "?*id": "<?str>",
82
+ "*width": "<?int>",
83
+ "*height": "<?int>",
84
+ "?*background_color": ["<?int>"],
85
+ "*elements": [],
86
+ }
87
+
88
+
89
+ def validate_element(element: Dict[str, Any], element_type: str):
90
+ """
91
+ Validates an element of a card against a spec, raising an exception
92
+ if it does not meet the spec.
93
+ Args:
94
+ element (dict): The card element.
95
+ element_type (str): The type of the element
96
+ """
97
+ spec = ELEMENT_SPEC | SPECS_FOR_TYPE[element_type]
98
+ validate(element, spec)
99
+
100
+
101
+ def validate_card(card: Dict[str, Any]):
102
+ """
103
+ Validates a card against a spec, raising an exception
104
+ if it does not meet the spec.
105
+ Args:
106
+ card (Dict[str, Any]): The card.
107
+ """
108
+ # print(f"DEBUG:\n{card=}")
109
+ validate(card, CARD_SPEC)
110
+ for element in card["elements"]:
111
+ # print(f"DEBUG: {element['type']}")
112
+ validate_element(element, element["type"])
113
+
114
+
115
+ def transform_card(card: Dict[str, Any]) -> Dict[str, Any]:
116
+ """
117
+ Perform certain automatic type casts on the card and its
118
+ elements. For example, cast the "text" property of elements
119
+ of type "text" to str, to support painting numbers as text.
120
+ Args:
121
+ card (Dict[str, Any]): The card.
122
+ Return:
123
+ Dict[str, Any]: The transformed card with all automatic casts applied.
124
+ """
125
+ for element in card.get("elements", []):
126
+ if element.get("type") == "text" and "text" in element:
127
+ if pd.isna(element["text"]):
128
+ element["text"] = None
129
+ else:
130
+ element["text"] = str(element["text"])
131
+
132
+ return card
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: decksmith
3
- Version: 0.1.15
4
- Summary: A command-line application to dynamically generate decks of cards from a JSON specification and a CSV data file, inspired by nandeck.
3
+ Version: 0.9.2
4
+ Summary: A command-line application to dynamically generate decks of cards from a YAML specification and a CSV data file, inspired by nandeck.
5
5
  License-Expression: GPL-2.0-only
6
6
  Author: Julio Cabria
7
7
  Author-email: juliocabria@tutanota.com
@@ -13,27 +13,28 @@ Classifier: Programming Language :: Python :: 3.13
13
13
  Classifier: Programming Language :: Python :: 3.14
14
14
  Provides-Extra: dev
15
15
  Requires-Dist: click
16
+ Requires-Dist: crossfiledialog (>=1.1.0)
17
+ Requires-Dist: flask (>=3.1.2)
16
18
  Requires-Dist: jval (==1.0.6)
17
19
  Requires-Dist: pandas
18
20
  Requires-Dist: pillow (>=11.3.0)
19
- Requires-Dist: poetry ; extra == "dev"
21
+ Requires-Dist: platformdirs (>=4.5.1)
20
22
  Requires-Dist: pytest ; extra == "dev"
23
+ Requires-Dist: pywin32 (>=311) ; sys_platform == "win32"
21
24
  Requires-Dist: reportlab (>=4.4.3)
22
- Project-URL: Homepage, https://github.com/Julynx/decksmith
25
+ Requires-Dist: ruamel-yaml (>=0.19.1)
26
+ Requires-Dist: waitress (>=3.0.2)
23
27
  Description-Content-Type: text/markdown
24
28
 
25
29
  # DeckSmith
26
30
 
27
- *A command-line application to dynamically generate decks of cards from a JSON specification and a CSV data file, inspired by nandeck.*
31
+ [julynx.github.io/decksmith](https://julynx.github.io/decksmith/)
28
32
 
29
- <br>
30
- <p align="center">
31
- <img width="600" src="https://raw.githubusercontent.com/Julynx/decksmith/refs/heads/main/docs/assets/decksmith.png">
32
- </p>
33
+ *A powerful application to dynamically generate decks of cards from a YAML specification and a CSV data file.*
33
34
 
34
35
  <br>
35
36
  <p align="center">
36
- <img width="600" src="https://raw.githubusercontent.com/Julynx/decksmith/refs/heads/main/docs/assets/banner.png">
37
+ <img src="https://raw.githubusercontent.com/Julynx/decksmith/refs/heads/main/docs/assets/screenshot.png" width='100%'>
37
38
  </p>
38
39
 
39
40
  <br>
@@ -44,12 +45,13 @@ DeckSmith is ideal for automating the creation of all kinds of decks, including
44
45
 
45
46
  - ✨ Consistent layout and formatting across all cards. Define once, edit anytime, generate as many cards as you need.
46
47
  - 🍳 Pure python, with easy installation via pip.
48
+ - 🖥️ User-friendly GUI for easy project management and generation.
47
49
  - ⚡ Highly performant card generation using parallel processing.
48
50
  - 📖 Intuitive syntax and extensive [documentation](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md) with examples to help you get started.
49
51
  - 🧰 Tons of powerful features such as:
50
52
  - [Start from a sample project and edit it instead of starting from scratch](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md#creating-a-project)
51
53
  - [Extensive support for images](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md#images), [text](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md#text), [and all kinds of different shapes](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md#shapes)
52
- - [Link any field to a column in the CSV file](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md#basic-example-with-deckcsv)
54
+ - [Link any field to a column in the CSV file](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md#example-with-deckcsv)
53
55
  - [Position elements absolutely or relative to other elements, using anchors to simplify placement](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md#positioning)
54
56
  - [Powerful image transformations using filters like crop, resize, rotate, or flip](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md#images)
55
57
  - [Export your deck as images or as a PDF for printing](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md#building-the-deck)
@@ -64,23 +66,29 @@ DeckSmith is ideal for automating the creation of all kinds of decks, including
64
66
  pip install decksmith
65
67
  ```
66
68
 
69
+ - To launch the GUI, run:
70
+
71
+ ```bash
72
+ decksmith --gui
73
+ ```
74
+
67
75
  ### Creating a project
68
76
 
69
- - Run the following command to start from sample `deck.json` and `deck.csv` files:
77
+ - Run the following command to start from sample `deck.yaml` and `deck.csv` files:
70
78
 
71
79
  ```text
72
80
  decksmith init
73
81
  ```
74
82
 
75
- - `deck.json` defines the layout for the cards in the deck.
83
+ - `deck.yaml` defines the layout for the cards in the deck.
76
84
  - `deck.csv` holds the data for each card, like the content of the text fields and the image paths.
77
85
 
78
86
  ### Defining the layout
79
87
 
80
- - Edit `deck.json` to include all the elements you want on your cards.
88
+ - Edit `deck.yaml` to include all the elements you want on your cards.
81
89
  You can find a complete list of all the available elements and their properties in the [documentation](https://github.com/Julynx/decksmith/blob/main/docs/DOCS.md).
82
90
 
83
- - You can reference any column from `deck.csv` in the `deck.json` file as `%column_name%`.
91
+ - You can reference any column from `deck.csv` in the `deck.yaml` file as `%column_name%`.
84
92
 
85
93
  ### Building the deck
86
94
 
@@ -0,0 +1,27 @@
1
+ decksmith/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ decksmith/card_builder.py,sha256=hxDVS7-dngCiT392pP2aiWgasfSp1ou3v3lzWmLXxL4,5618
3
+ decksmith/deck_builder.py,sha256=J_Zdj4m-tXPSZh67mEyOCQ_CTphRCsPiyHSh1HcNM0M,3305
4
+ decksmith/export.py,sha256=rzRGdyfK1YXu_k9cpkXvNFZZBkpfXW5zPr_iotlJxcY,5979
5
+ decksmith/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ decksmith/gui/app.py,sha256=NQPR_hfCVvrr0QnEUmJXQv_A4lFXXoF8_OostVLwZkU,10178
7
+ decksmith/gui/static/css/style.css,sha256=QZlE4UgTPqdflIa9poaDhIHZ5OlwcF6uACLKaEYjE4E,13837
8
+ decksmith/gui/static/img/decksmith.ico,sha256=bkz7MTDpQELzP2GSvR42Jn7OgIw_j0uBhN4L2i-m1uo,28366
9
+ decksmith/gui/static/js/main.js,sha256=A1Vz4kxlokqTadESYT7PlZf4XkVlaT0AXmSNNSrmixw,21680
10
+ decksmith/gui/templates/index.html,sha256=-rZ-eO7O35gh5bJrQrb-5M-tnYEqSVqGWJh5sCe2e5c,9551
11
+ decksmith/image_ops.py,sha256=8UzibqfoED_Jch-lt--l2LIAoIwdBrXH7so5UqY5pqw,4737
12
+ decksmith/logger.py,sha256=uSMzIpv7xT7ICMz4a88x_Z9-Izz0WU9MdZ9JEwWnOC4,1020
13
+ decksmith/macro.py,sha256=prHs0fTIqxE5kjT1usqnWg8CNZEoWUVNAezD-qJslRY,1584
14
+ decksmith/main.py,sha256=Jm98JBo3a2H_S7mwHEWg8NzyUBXdbFewFxzlpPxjDLI,4653
15
+ decksmith/project.py,sha256=QbhSOAveCuQ05P2Dp-uIc7hkC_o0-NAq3LIWQ4g-FnU,3885
16
+ decksmith/renderers/__init__.py,sha256=xF0SsNJSQEbY-NoSN0N4admLTGc_4JcZumDMpQahWBM,76
17
+ decksmith/renderers/image.py,sha256=SKj_21wlAjHGEG6M0GGu4OkwmJrxf0Nnk9TCu_2BP38,2218
18
+ decksmith/renderers/shapes.py,sha256=iSCCr4hn2lj4EGchq324_eHtuuYAhemYP9PSEUFBkxM,7855
19
+ decksmith/renderers/text.py,sha256=rN3vYUPWy_OpbxiGI5nydOu2V4O1CnoVKaqRIv64waU,4465
20
+ decksmith/templates/deck.csv,sha256=8P3XknSg6kXulNyAmqFHgJDIzGjMnvdMQ8ctTtUoIzE,782
21
+ decksmith/templates/deck.yaml,sha256=3BMpTUH1It25wrmQXZSrERoPo4-8TBKXKxfaRtYowt8,1034
22
+ decksmith/utils.py,sha256=-QHYbNKQeB1SXB5Ovswn6Yql9sfSb5CmSNVpsw3LiVM,2909
23
+ decksmith/validate.py,sha256=uNkBg0ruZp63gOu687Ed2hrtepV9Ez6NwnikKfvexzs,3813
24
+ decksmith-0.9.2.dist-info/entry_points.txt,sha256=-usRztjj2gnfmPubb8nFYHD22drzThAmSfM6geWI98Y,48
25
+ decksmith-0.9.2.dist-info/METADATA,sha256=XqfNoFFAmElTYvBHOLUl9vQkdyiMHHm3OqASmvPIixI,4316
26
+ decksmith-0.9.2.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
27
+ decksmith-0.9.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.2.1
2
+ Generator: poetry-core 2.3.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,31 +0,0 @@
1
- {
2
- "width": 250,
3
- "height": 350,
4
- "background_color": [200, 200, 200],
5
- "elements": [
6
- {
7
- "id": "title",
8
- "type": "text",
9
- "position": [125, 25],
10
- "anchor": "top-center",
11
- "text": "%title%",
12
- "color": [0, 0, 0],
13
- "font_path": "arial.ttf",
14
- "font_size": 20,
15
- "align": "center"
16
- },
17
- {
18
- "id": "description",
19
- "type": "text",
20
- "position": [0, 25],
21
- "relative_to": ["title", "bottom-center"],
22
- "anchor": "top-center",
23
- "text": "%description%",
24
- "color": [0, 0, 0],
25
- "font_path": "arial.ttf",
26
- "font_size": 16,
27
- "width": 200,
28
- "align": "center"
29
- }
30
- ]
31
- }
@@ -1,13 +0,0 @@
1
- decksmith/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- decksmith/card_builder.py,sha256=F8m4sMhwuSCcf16QFdWkZG3I8_n04ITeSFwIcyIWjtg,25163
3
- decksmith/deck_builder.py,sha256=vWjzGPu4OaoiyOdmQ4ONYWOHmiEzOZdubPWiXrxead4,3734
4
- decksmith/export.py,sha256=8hyYv4B-77OS6xnZ50VBJJNBDfBoQr_i1FR0HVXYpuQ,5463
5
- decksmith/main.py,sha256=88OTPGV5pmjIrKyAk55C8fkIybYcG2AF5Khs5I3gI7w,4404
6
- decksmith/templates/deck.csv,sha256=C-Fdeb_byPnGlZNoDq7VlI1aThsvfhMdkieGBA8vglQ,457
7
- decksmith/templates/deck.json,sha256=Yv-Bb_PmhuMpuDMTgus4swtgFxIjItMws9bKqXTjX_s,664
8
- decksmith/utils.py,sha256=UkXraPtT3HKlUUu_Cl4gs9SrZHoW-doLY5L-qNpYXFo,2232
9
- decksmith/validate.py,sha256=bN_SPk08vPeeyJjkzrXnH2sqh99Z3uQBI0BHY7j8ElQ,3681
10
- decksmith-0.1.15.dist-info/METADATA,sha256=q5aPwAv3Phc7XUk4CA5FY0sSag6PD2ANVXx5TSoTFhE,4150
11
- decksmith-0.1.15.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
12
- decksmith-0.1.15.dist-info/entry_points.txt,sha256=-usRztjj2gnfmPubb8nFYHD22drzThAmSfM6geWI98Y,48
13
- decksmith-0.1.15.dist-info/RECORD,,