forked from ep1cman/DnD-Card-Generator
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCardGenerator.py
More file actions
executable file
·170 lines (150 loc) · 4.5 KB
/
CardGenerator.py
File metadata and controls
executable file
·170 lines (150 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import math
import yaml
import argparse
import pathlib
from reportlab.pdfbase.ttfonts import TTFError
from reportlab.lib.pagesizes import A4, A3, A2, A1
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
from fonts import FreeFonts, AccurateFonts
from generator import MonsterCard, ItemCard
from export import ExportCards
from card_item import *
from card_monster import *
ASSET_DIR = pathlib.Path(__file__).parent.resolve() / "assets"
def ExistingFile(p):
"""Argparse type for absolute paths that exist"""
p = pathlib.Path(p).absolute()
if p.exists():
return p
else:
raise argparse.ArgumentTypeError(f"`{p}` does not exist")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Generate D&D cards.")
parser.add_argument(
"-o",
"--out",
help="Output file path",
action="store",
default="cards.pdf",
dest="output_path",
metavar="output_path",
type=lambda p: pathlib.Path(p).absolute(),
)
parser.add_argument(
"input",
help="Path to input YAML file",
action="store",
type=ExistingFile,
)
parser.add_argument(
"-f",
"--fonts",
help="What fonts to use when generating cards",
action="store",
default="free",
choices=["free", "accurate"],
dest="fonts",
)
parser.add_argument(
"-b",
"--bleed",
help="How many millimeters of print bleed radius to add around each card.",
action="store",
default=0,
type=lambda b: float(b) * mm,
)
parser.add_argument(
"-e",
"--export",
help="Export as single cards or as a grid",
action="store",
default="single",
choices=["single", "grid"],
dest="export",
)
parser.add_argument(
"-c",
"--canvas",
help="Size of the canvas to export to. Available sizes: A1, A2, A3, A4",
action="store",
default="A4",
choices=["A4", "A3", "A2", "A1"],
dest="canvas",
)
background_group = parser.add_mutually_exclusive_group()
background_group.add_argument(
"--no-bg",
help="Do not add the 'parchment' effect background.",
action="store_const",
const=None,
default=ASSET_DIR / "background.png",
dest="background",
)
background_group.add_argument(
"--bg",
help="Custom background image to use",
action="store",
dest="background",
type=ExistingFile,
)
args = parser.parse_args()
fonts = None
if args.fonts == "accurate":
try:
fonts = AccurateFonts()
except TTFError:
raise Exception(
"Failed to load accurate fonts, are you sure you used the correct file names?"
)
else:
fonts = FreeFonts()
canvas = canvas.Canvas(str(args.output_path), pagesize=A4)
with open(args.input, "r") as stream:
try:
entries = yaml.load(stream, Loader=yaml.SafeLoader)
except yaml.YAMLError as exc:
print(exc)
exit()
cards = []
for entry in entries:
image_path = None
if "image_path" in entry:
image_path = pathlib.Path(entry["image_path"])
if not image_path.is_absolute():
image_path = (args.input.parent / image_path).absolute()
if not image_path.exists():
raise ValueError(
"Invalid `image_path` in `{}`: {}".format(
entry["title"], entry["image_path"]
)
)
if entry.get("type") == None or entry.get("type") == "monster":
card = MonsterCard(
**entry,
background=args.background,
bleed=args.bleed,
)
elif entry.get("type") == "item":
card = ItemCard(
**entry,
background=args.background,
bleed=args.bleed,
)
cards += [card]
if len(cards) == 0:
print("No cards to generate")
exit()
canvas_size = A4
if args.canvas == "A1":
canvas_size = A1
if args.canvas == "A2":
canvas_size = A2
if args.canvas == "A3":
canvas_size = A3
export = ExportCards(cards, canvas, canvas_size=canvas_size)
if args.export == "grid":
export.export_grid()
else:
export.export_singles()
canvas.save()