382 lines
20 KiB
Python
382 lines
20 KiB
Python
#!/usr/bin/env python3
|
|
"""Build a review board that makes a page's proposed layer ownership visible."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
|
|
|
|
COLORS = {
|
|
"world": (34, 139, 170),
|
|
"actors": (209, 78, 82),
|
|
"board": (213, 151, 35),
|
|
"top": (125, 82, 180),
|
|
"bottom": (39, 132, 94),
|
|
"text": (24, 33, 39),
|
|
"panel": (246, 247, 242),
|
|
}
|
|
|
|
|
|
def font(size: int, bold: bool = False) -> ImageFont.FreeTypeFont | ImageFont.ImageFont:
|
|
candidates = [
|
|
"/System/Library/Fonts/Supplemental/Arial Bold.ttf" if bold else "/System/Library/Fonts/Supplemental/Arial.ttf",
|
|
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" if bold else "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
|
|
]
|
|
for candidate in candidates:
|
|
path = Path(candidate)
|
|
if path.is_file():
|
|
return ImageFont.truetype(str(path), size)
|
|
return ImageFont.load_default()
|
|
|
|
|
|
def build(source: Path, output: Path) -> None:
|
|
original = Image.open(source).convert("RGB")
|
|
source_w, source_h = original.size
|
|
image_w = 1120
|
|
image_h = round(source_h * image_w / source_w)
|
|
image = original.resize((image_w, image_h), Image.Resampling.LANCZOS)
|
|
panel_w = 430
|
|
margin = 28
|
|
board = Image.new("RGB", (image_w + panel_w + margin * 3, image_h + margin * 2), COLORS["panel"])
|
|
board.paste(image, (margin, margin))
|
|
draw = ImageDraw.Draw(board)
|
|
draw.rectangle((margin, margin, margin + image_w, margin + image_h), outline=(24, 33, 39), width=3)
|
|
|
|
def box(x0: float, y0: float, x1: float, y1: float, number: str, color: tuple[int, int, int]) -> None:
|
|
scaled = (margin + round(x0 * image_w), margin + round(y0 * image_h), margin + round(x1 * image_w), margin + round(y1 * image_h))
|
|
overlay = Image.new("RGBA", board.size, (0, 0, 0, 0))
|
|
odraw = ImageDraw.Draw(overlay)
|
|
odraw.rectangle(scaled, outline=color + (235,), width=5)
|
|
odraw.rectangle((scaled[0], scaled[1], scaled[0] + 38, scaled[1] + 34), fill=color + (235,))
|
|
board.paste(overlay, (0, 0), overlay)
|
|
draw.text((scaled[0] + 10, scaled[1] + 5), number, fill=(255, 255, 255), font=font(20, True))
|
|
|
|
box(0.00, 0.00, 1.00, 1.00, "01", COLORS["world"])
|
|
box(0.00, 0.00, 1.00, 0.105, "02", COLORS["top"])
|
|
box(0.255, 0.405, 0.395, 0.875, "03", COLORS["actors"])
|
|
box(0.395, 0.385, 0.565, 0.865, "04", COLORS["actors"])
|
|
box(0.625, 0.285, 0.985, 0.875, "05", COLORS["board"])
|
|
box(0.00, 0.90, 1.00, 1.00, "06", COLORS["bottom"])
|
|
|
|
panel_x = margin * 2 + image_w
|
|
draw.text((panel_x, margin), "HUB-001 / DECONSTRUCTION PROPOSAL", fill=COLORS["text"], font=font(21, True))
|
|
draw.text((panel_x, margin + 38), "The image is a composition reference; dynamic copy stays in Godot.", fill=(102, 118, 123), font=font(14))
|
|
rows = [
|
|
("01", "PAINTED WORLD", "Static environment and depth. No gameplay state."),
|
|
("02", "TOP STATUS RAIL", "Guild identity, pressure, Coin and Company slots."),
|
|
("03", "RECRUIT A", "Persistent person-bearing unit; name, profession, condition."),
|
|
("04", "RECRUIT B", "Persistent person-bearing unit; same engine-owned bindings."),
|
|
("05", "CONTRACT BOARD", "Physical primary destination; title, brief, state and action."),
|
|
("06", "BOTTOM DESTINATION RAIL", "Roster, Equipment, Party, Risk, locked Market."),
|
|
]
|
|
y = margin + 84
|
|
for number, title, detail in rows:
|
|
color = COLORS[{"01": "world", "02": "top", "03": "actors", "04": "actors", "05": "board", "06": "bottom"}[number]]
|
|
draw.rectangle((panel_x, y + 2, panel_x + 30, y + 32), fill=color)
|
|
draw.text((panel_x + 8, y + 6), number, fill=(255, 255, 255), font=font(15, True))
|
|
draw.text((panel_x + 44, y), title, fill=COLORS["text"], font=font(15, True))
|
|
draw.text((panel_x + 44, y + 21), detail, fill=(102, 118, 123), font=font(12))
|
|
y += 62
|
|
y += 12
|
|
draw.text((panel_x, y), "REVIEW QUESTIONS", fill=COLORS["text"], font=font(15, True))
|
|
questions = [
|
|
"Are the two actors the right persistent Company subject?",
|
|
"Does the board own the next action without becoming a side card?",
|
|
"Are the top and bottom rails compact enough at 760x360?",
|
|
"Are all blank regions large enough for zh/en engine text at 130%?",
|
|
]
|
|
y += 28
|
|
for question in questions:
|
|
draw.text((panel_x, y), "- " + question, fill=(102, 118, 123), font=font(12))
|
|
y += 27
|
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
board.save(output, format="PNG", optimize=True)
|
|
|
|
|
|
def build_party_line(source: Path, output: Path) -> None:
|
|
"""Build the PTY-001 review board with Party-specific layer ownership."""
|
|
original = Image.open(source).convert("RGB")
|
|
source_w, source_h = original.size
|
|
image_w = 1120
|
|
image_h = round(source_h * image_w / source_w)
|
|
image = original.resize((image_w, image_h), Image.Resampling.LANCZOS)
|
|
panel_w = 470
|
|
margin = 28
|
|
board = Image.new("RGB", (image_w + panel_w + margin * 3, image_h + margin * 2), COLORS["panel"])
|
|
board.paste(image, (margin, margin))
|
|
draw = ImageDraw.Draw(board)
|
|
draw.rectangle((margin, margin, margin + image_w, margin + image_h), outline=COLORS["text"], width=3)
|
|
|
|
def box(x0: float, y0: float, x1: float, y1: float, number: str, color: tuple[int, int, int]) -> None:
|
|
scaled = (
|
|
margin + round(x0 * image_w),
|
|
margin + round(y0 * image_h),
|
|
margin + round(x1 * image_w),
|
|
margin + round(y1 * image_h),
|
|
)
|
|
overlay = Image.new("RGBA", board.size, (0, 0, 0, 0))
|
|
odraw = ImageDraw.Draw(overlay)
|
|
odraw.rectangle(scaled, outline=color + (235,), width=5)
|
|
odraw.rectangle((scaled[0], scaled[1], scaled[0] + 38, scaled[1] + 34), fill=color + (235,))
|
|
board.paste(overlay, (0, 0), overlay)
|
|
draw.text((scaled[0] + 10, scaled[1] + 5), number, fill=(255, 255, 255), font=font(20, True))
|
|
|
|
box(0.00, 0.10, 1.00, 0.87, "01", COLORS["world"])
|
|
box(0.00, 0.00, 1.00, 0.12, "02", COLORS["top"])
|
|
box(0.08, 0.47, 0.88, 0.64, "03", COLORS["board"])
|
|
box(0.19, 0.28, 0.72, 0.69, "04", COLORS["actors"])
|
|
box(0.36, 0.65, 0.68, 0.83, "05", (34, 139, 170))
|
|
box(0.00, 0.87, 1.00, 1.00, "06", COLORS["bottom"])
|
|
box(0.60, 0.45, 0.84, 0.76, "07", (213, 151, 35))
|
|
|
|
panel_x = margin * 2 + image_w
|
|
draw.text((panel_x, margin), "PTY-001 / DECONSTRUCTION PROPOSAL", fill=COLORS["text"], font=font(21, True))
|
|
draw.text((panel_x, margin + 38), "The approved draft is a composition reference; runtime state stays separate.", fill=(102, 118, 123), font=font(13))
|
|
rows = [
|
|
("01", "PAINTED TRAINING YARD", "Static depth world reused from accepted Guild provenance.", COLORS["world"]),
|
|
("02", "TOP STATUS RAIL", "Party identity, Pressure and Company engine slots.", COLORS["top"]),
|
|
("03", "FORMATION CORD", "Rear-left to front-right line; static art without numbers.", COLORS["board"]),
|
|
("04", "FOUR RUNTIME RECRUITS", "Company-bound actors, foot markers and engine position values.", COLORS["actors"]),
|
|
("05", "RELATION PREVIEW", "Protection, reach, threat and target deltas rendered by Godot.", (34, 139, 170)),
|
|
("06", "COMMAND RAIL", "Undo, Reset, Save Order and Back; icon art plus hit areas.", COLORS["bottom"]),
|
|
("07", "SELECTION PATH", "Selected actor ring, legal destination and preview path.", (213, 151, 35)),
|
|
]
|
|
y = margin + 82
|
|
for number, title, detail, color in rows:
|
|
draw.rectangle((panel_x, y + 2, panel_x + 30, y + 32), fill=color)
|
|
draw.text((panel_x + 8, y + 6), number, fill=(255, 255, 255), font=font(15, True))
|
|
draw.text((panel_x + 44, y), title, fill=COLORS["text"], font=font(14, True))
|
|
draw.text((panel_x + 44, y + 20), detail, fill=(102, 118, 123), font=font(11))
|
|
y += 55
|
|
y += 8
|
|
draw.text((panel_x, y), "REVIEW QUESTIONS", fill=COLORS["text"], font=font(15, True))
|
|
questions = [
|
|
"Do all four actors read together at 760x360?",
|
|
"Is position 0 unmistakably exposed at front-right?",
|
|
"Does the relation preview explain change without becoming a card wall?",
|
|
"Are the four command icons distinct and attached to the bottom rail?",
|
|
]
|
|
y += 26
|
|
for question in questions:
|
|
draw.text((panel_x, y), "- " + question, fill=(102, 118, 123), font=font(11))
|
|
y += 24
|
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
board.save(output, format="PNG", optimize=True)
|
|
|
|
|
|
def build_readiness(source: Path, output: Path) -> None:
|
|
"""Build the PTY-002 frozen-snapshot layer ownership board."""
|
|
original = Image.open(source).convert("RGB")
|
|
source_w, source_h = original.size
|
|
image_w = 1120
|
|
image_h = round(source_h * image_w / source_w)
|
|
image = original.resize((image_w, image_h), Image.Resampling.LANCZOS)
|
|
panel_w = 510
|
|
margin = 28
|
|
board = Image.new("RGB", (image_w + panel_w + margin * 3, image_h + margin * 2), COLORS["panel"])
|
|
board.paste(image, (margin, margin))
|
|
draw = ImageDraw.Draw(board)
|
|
draw.rectangle((margin, margin, margin + image_w, margin + image_h), outline=COLORS["text"], width=3)
|
|
|
|
def box(x0: float, y0: float, x1: float, y1: float, number: str, color: tuple[int, int, int]) -> None:
|
|
scaled = (margin + round(x0 * image_w), margin + round(y0 * image_h), margin + round(x1 * image_w), margin + round(y1 * image_h))
|
|
overlay = Image.new("RGBA", board.size, (0, 0, 0, 0))
|
|
odraw = ImageDraw.Draw(overlay)
|
|
odraw.rectangle(scaled, outline=color + (235,), width=5)
|
|
odraw.rectangle((scaled[0], scaled[1], scaled[0] + 42, scaled[1] + 34), fill=color + (235,))
|
|
board.paste(overlay, (0, 0), overlay)
|
|
draw.text((scaled[0] + 11, scaled[1] + 5), number, fill=(255, 255, 255), font=font(19, True))
|
|
|
|
box(0.00, 0.12, 1.00, 0.86, "01", COLORS["world"])
|
|
box(0.00, 0.00, 1.00, 0.13, "02", COLORS["top"])
|
|
box(0.08, 0.47, 0.82, 0.60, "03", COLORS["board"])
|
|
box(0.18, 0.28, 0.73, 0.62, "04", COLORS["actors"])
|
|
box(0.04, 0.63, 0.76, 0.82, "05", (34, 139, 170))
|
|
box(0.78, 0.56, 0.99, 0.78, "06", (209, 78, 82))
|
|
box(0.00, 0.84, 1.00, 1.00, "07", COLORS["bottom"])
|
|
box(0.76, 0.27, 0.99, 0.50, "08", (102, 118, 123))
|
|
|
|
panel_x = margin * 2 + image_w
|
|
draw.text((panel_x, margin), "PTY-002 / DECONSTRUCTION", fill=COLORS["text"], font=font(21, True))
|
|
draw.text((panel_x, margin + 38), "Frozen review only; all values and copy stay in Godot.", fill=(102, 118, 123), font=font(13))
|
|
rows = [
|
|
("01", "PAINTED COURTYARD", "Static world and depth; no party state.", COLORS["world"]),
|
|
("02", "TOP STATUS RAIL", "Readiness identity, snapshot version and Company slot.", COLORS["top"]),
|
|
("03", "FORMATION RELATION LINE", "Static directional relation; no baked positions or values.", COLORS["board"]),
|
|
("04", "FROZEN COMPANY ACTORS", "Same four Company IDs and order from PTY-001; no reorder here.", COLORS["actors"]),
|
|
("05", "READINESS SUMMARY", "Protection, reach, pressure coverage and Reserve engine slots.", (34, 139, 170)),
|
|
("06", "WARNING STACK", "Severity/owner facts; actionable rows route to the owning page.", (209, 78, 82)),
|
|
("07", "COMMAND RAIL", "Revise, Back, primary Accept Preparation and post-accept route.", COLORS["bottom"]),
|
|
("08", "RISK NEXT STATE", "Unavailable until Accept; never a battle command on this page.", (102, 118, 123)),
|
|
]
|
|
y = margin + 82
|
|
for number, title, detail, color in rows:
|
|
draw.rectangle((panel_x, y + 2, panel_x + 32, y + 32), fill=color)
|
|
draw.text((panel_x + 8, y + 6), number, fill=(255, 255, 255), font=font(14, True))
|
|
draw.text((panel_x + 46, y), title, fill=COLORS["text"], font=font(13, True))
|
|
draw.text((panel_x + 46, y + 20), detail, fill=(102, 118, 123), font=font(10))
|
|
y += 52
|
|
y += 8
|
|
draw.text((panel_x, y), "REVIEW QUESTIONS", fill=COLORS["text"], font=font(15, True))
|
|
questions = [
|
|
"Does the page read as frozen review, not editable formation?",
|
|
"Do actors, front exposure and relation line remain first read?",
|
|
"Are warnings grouped without covering the world or actors?",
|
|
"Is Accept clearly primary and Risk visibly a later boundary?",
|
|
]
|
|
y += 26
|
|
for question in questions:
|
|
draw.text((panel_x, y), "- " + question, fill=(102, 118, 123), font=font(10))
|
|
y += 23
|
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
board.save(output, format="PNG", optimize=True)
|
|
|
|
|
|
def build_top_rail(source: Path, output: Path) -> None:
|
|
"""Build a close review board for the nested top status rail."""
|
|
original = Image.open(source).convert("RGB")
|
|
crop = original.crop((0, 0, original.width, round(original.height * 0.155)))
|
|
crop = crop.resize((2048, 260), Image.Resampling.LANCZOS)
|
|
panel_w = 560
|
|
margin = 24
|
|
board_height = max(crop.height + margin * 2, 540)
|
|
board = Image.new("RGB", (crop.width + panel_w + margin * 3, board_height), COLORS["panel"])
|
|
board.paste(crop, (margin, margin))
|
|
draw = ImageDraw.Draw(board)
|
|
draw.rectangle((margin, margin, margin + crop.width, margin + crop.height), outline=COLORS["text"], width=3)
|
|
|
|
def box(x0: int, x1: int, number: str, color: tuple[int, int, int]) -> None:
|
|
left = margin + x0
|
|
right = margin + x1
|
|
overlay = Image.new("RGBA", board.size, (0, 0, 0, 0))
|
|
odraw = ImageDraw.Draw(overlay)
|
|
odraw.rectangle((left, margin, right, margin + crop.height), outline=color + (235,), width=5)
|
|
odraw.rectangle((left, margin, left + 42, margin + 34), fill=color + (235,))
|
|
board.paste(overlay, (0, 0), overlay)
|
|
draw.text((left + 10, margin + 5), number, fill=(255, 255, 255), font=font(20, True))
|
|
|
|
box(0, 820, "02A", (34, 139, 170))
|
|
box(55, 175, "02B", (125, 82, 180))
|
|
box(190, 710, "02C", (39, 132, 94))
|
|
box(1210, 1455, "02D", (209, 78, 82))
|
|
box(1460, 1710, "02E", (213, 151, 35))
|
|
box(1715, 1900, "02F", (39, 132, 94))
|
|
box(1905, 2048, "02G", (102, 118, 123))
|
|
|
|
panel_x = margin * 2 + crop.width
|
|
draw.text((panel_x, margin), "02 / TOP RAIL SUB-DECOMPOSITION", fill=COLORS["text"], font=font(20, True))
|
|
draw.text((panel_x, margin + 38), "Frame, icons and engine slots have different ownership.", fill=(102, 118, 123), font=font(13))
|
|
rows = [
|
|
("02A", "RAIL SHELL", "Static segmented/NinePatch frame; stretches only in the center."),
|
|
("02B", "GUILD CREST", "Fixed square static emblem; no state text."),
|
|
("02C", "IDENTITY SLOT", "Engine-rendered Guild name; bounded and localized."),
|
|
("02D", "PRESSURE CELL", "Static icon plus engine value and state styling."),
|
|
("02E", "COIN CELL", "Static icon plus engine integer value."),
|
|
("02F", "COMPANY CELL", "Static people icon plus engine count."),
|
|
("02G", "SETTINGS", "Static icon plus transparent action hit area."),
|
|
]
|
|
y = margin + 82
|
|
for number, title, detail in rows:
|
|
color = (34, 139, 170) if number == "02A" else (125, 82, 180) if number == "02B" else (39, 132, 94) if number in {"02C", "02F"} else (209, 78, 82) if number == "02D" else (213, 151, 35) if number == "02E" else (102, 118, 123)
|
|
draw.rectangle((panel_x, y + 2, panel_x + 38, y + 32), fill=color)
|
|
draw.text((panel_x + 4, y + 6), number, fill=(255, 255, 255), font=font(13, True))
|
|
draw.text((panel_x + 50, y), title, fill=COLORS["text"], font=font(14, True))
|
|
draw.text((panel_x + 50, y + 20), detail, fill=(102, 118, 123), font=font(11))
|
|
y += 56
|
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
board.save(output, format="PNG", optimize=True)
|
|
|
|
|
|
def build_market(source: Path, output: Path) -> None:
|
|
"""Build the SHP-001 Market layer-ownership review board."""
|
|
original = Image.open(source).convert("RGB")
|
|
source_w, source_h = original.size
|
|
image_w = 1120
|
|
image_h = round(source_h * image_w / source_w)
|
|
image = original.resize((image_w, image_h), Image.Resampling.LANCZOS)
|
|
panel_w = 540
|
|
margin = 28
|
|
board = Image.new("RGB", (image_w + panel_w + margin * 3, image_h + margin * 2), COLORS["panel"])
|
|
board.paste(image, (margin, margin))
|
|
draw = ImageDraw.Draw(board)
|
|
draw.rectangle((margin, margin, margin + image_w, margin + image_h), outline=COLORS["text"], width=3)
|
|
|
|
def box(x0: float, y0: float, x1: float, y1: float, number: str, color: tuple[int, int, int]) -> None:
|
|
scaled = (margin + round(x0 * image_w), margin + round(y0 * image_h), margin + round(x1 * image_w), margin + round(y1 * image_h))
|
|
overlay = Image.new("RGBA", board.size, (0, 0, 0, 0))
|
|
odraw = ImageDraw.Draw(overlay)
|
|
odraw.rectangle(scaled, outline=color + (235,), width=5)
|
|
odraw.rectangle((scaled[0], scaled[1], scaled[0] + 42, scaled[1] + 34), fill=color + (235,))
|
|
board.paste(overlay, (0, 0), overlay)
|
|
draw.text((scaled[0] + 11, scaled[1] + 5), number, fill=(255, 255, 255), font=font(19, True))
|
|
|
|
box(0.00, 0.12, 0.78, 0.84, "01", COLORS["world"])
|
|
box(0.02, 0.02, 0.40, 0.18, "02", COLORS["top"])
|
|
box(0.15, 0.30, 0.31, 0.79, "03", COLORS["actors"])
|
|
box(0.31, 0.30, 0.53, 0.79, "04", COLORS["actors"])
|
|
box(0.53, 0.30, 0.77, 0.79, "05", COLORS["actors"])
|
|
box(0.78, 0.02, 0.995, 0.84, "06", COLORS["board"])
|
|
box(0.00, 0.84, 0.78, 1.00, "07", COLORS["bottom"])
|
|
box(0.78, 0.78, 0.995, 1.00, "08", (39, 132, 94))
|
|
|
|
panel_x = margin * 2 + image_w
|
|
draw.text((panel_x, margin), "SHP-001 / DECONSTRUCTION", fill=COLORS["text"], font=font(21, True))
|
|
draw.text((panel_x, margin + 38), "Composition is frozen; values and copy stay in Godot.", fill=(102, 118, 123), font=font(13))
|
|
rows = [
|
|
("01", "PAINTED REQUISITION WORLD", "Static world and counter depth; no Market state.", COLORS["world"]),
|
|
("02", "COMPANY / CAPACITY RAIL", "Owned count and Line capacity are separate engine slots.", COLORS["top"]),
|
|
("03", "RECRUIT OFFER A", "Equal person-bearing offer; stable ID, Profession, Trait and price.", COLORS["actors"]),
|
|
("04", "RECRUIT OFFER B", "Equal person-bearing offer; focus is local and never recommendation.", COLORS["actors"]),
|
|
("05", "RECRUIT OFFER C", "Equal person-bearing offer; no baked identity or purchase.", COLORS["actors"]),
|
|
("06", "EDGE LEDGER", "Coin, mode, refresh and lock facts; inspect-only at SHP-001.", COLORS["board"]),
|
|
("07", "EQUIPMENT TRAY", "Twelve sockets; four item objects and empty engine-owned slots.", COLORS["bottom"]),
|
|
("08", "REVIEW BOUNDARY", "One attached Review action opens SHP-002 or equipment review.", (39, 132, 94)),
|
|
]
|
|
y = margin + 82
|
|
for number, title, detail, color in rows:
|
|
draw.rectangle((panel_x, y + 2, panel_x + 34, y + 32), fill=color)
|
|
draw.text((panel_x + 8, y + 6), number, fill=(255, 255, 255), font=font(14, True))
|
|
draw.text((panel_x + 46, y), title, fill=COLORS["text"], font=font(13, True))
|
|
draw.text((panel_x + 46, y + 20), detail, fill=(102, 118, 123), font=font(10))
|
|
y += 50
|
|
y += 8
|
|
draw.text((panel_x, y), "REVIEW QUESTIONS", fill=COLORS["text"], font=font(15, True))
|
|
questions = [
|
|
"Do the three offers read as equal ordinary people at 760x360?",
|
|
"Can Company count and Line capacity be read independently?",
|
|
"Does the counter/tray/ledger stay physical instead of becoming cards?",
|
|
"Is Review the only strong boundary while list taps stay inspect-only?",
|
|
]
|
|
y += 26
|
|
for question in questions:
|
|
draw.text((panel_x, y), "- " + question, fill=(102, 118, 123), font=font(10))
|
|
y += 23
|
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
board.save(output, format="PNG", optimize=True)
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("source", type=Path)
|
|
parser.add_argument("output", type=Path)
|
|
parser.add_argument("--top-rail-output", type=Path)
|
|
parser.add_argument("--page-type", choices=("hub", "party", "readiness", "market"), default="hub")
|
|
args = parser.parse_args()
|
|
if args.page_type == "market":
|
|
build_market(args.source, args.output)
|
|
elif args.page_type == "party":
|
|
build_party_line(args.source, args.output)
|
|
elif args.page_type == "readiness":
|
|
build_readiness(args.source, args.output)
|
|
else:
|
|
build(args.source, args.output)
|
|
if args.top_rail_output:
|
|
build_top_rail(args.source, args.top_rail_output)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|