Skip to content

Commit 7f6cc41

Browse files
committed
Switch game-thumbs to game-thumbs.swvn.io with type/style config
Hardcode base URL to https://game-thumbs.swvn.io — no user-configurable server URL needed. Settings now expose Image Type (Logo/Cover) and a Style dropdown whose options update dynamically based on type. Config saves image_type and style; build_thumb_url reads them to set logo=true/false and the style query param. preview_send uses the same _build_url helper. https://claude.ai/code/session_01XuhxcauQKNuKofhxqfHPmm
1 parent 282138f commit 7f6cc41

3 files changed

Lines changed: 65 additions & 29 deletions

File tree

game_thumbs.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
log = logging.getLogger(__name__)
1212

13+
GAME_THUMBS_BASE = "https://game-thumbs.swvn.io"
14+
1315
# Separators used in sports titles: "vs", "vs.", "v.", "@", "at" (away at home)
1416
_TEAM_SEP = re.compile(r'\s+(?:vs?\.?|@|at)\s+', re.IGNORECASE)
1517
_TRAILING = re.compile(r'\s*[-–(].*$') # strip trailing dash/paren noise
@@ -34,15 +36,19 @@ def _to_pascal(name: str) -> str:
3436
return "".join(w.capitalize() for w in re.split(r"\s+", name.strip()) if w)
3537

3638

39+
def _build_url(league_code: str, away: str, home: str, image_type: str, style: str) -> str:
40+
logo = "true" if image_type == "logo" else "false"
41+
return (
42+
f"{GAME_THUMBS_BASE}/{league_code}/{away}/{home}"
43+
f"/thumb.png?style={style}&logo={logo}&aspect=16-9"
44+
)
45+
46+
3747
def build_thumb_url(game: "GroupedMatch", cfg: dict) -> str:
3848
"""Return a Game-Thumbs URL, or '' if teams/league/config unavailable."""
3949
thumbs_cfg = cfg.get("game_thumbs", {})
4050
if not thumbs_cfg.get("enabled"):
4151
return ""
42-
base_url = thumbs_cfg.get("base_url", "").rstrip("/")
43-
if not base_url:
44-
log.warning("game_thumbs enabled but base_url not set in Settings")
45-
return ""
4652
league_code = getattr(game.subscription, "game_thumbs_league", None)
4753
if not league_code:
4854
log.debug("build_thumb_url: no game_thumbs_league on subscription '%s'",
@@ -57,6 +63,8 @@ def build_thumb_url(game: "GroupedMatch", cfg: dict) -> str:
5763
return ""
5864
away = _to_pascal(teams[0])
5965
home = _to_pascal(teams[1])
60-
url = f"{base_url}/{league_code}/{away}/{home}/thumb.png?style=1&logo=true&aspect=16-9"
66+
image_type = thumbs_cfg.get("image_type", "logo")
67+
style = str(thumbs_cfg.get("style", "1"))
68+
url = _build_url(league_code, away, home, image_type, style)
6169
log.info("build_thumb_url: %s", url)
6270
return url

server.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -683,14 +683,10 @@ async def save_settings(request: Request):
683683

684684
thumbs = cfg.setdefault("game_thumbs", {})
685685
thumbs["enabled"] = form.get("game_thumbs_enabled") == "on"
686-
raw_thumbs_url = form.get("game_thumbs_url", "").strip()
687-
if raw_thumbs_url:
688-
try:
689-
thumbs["base_url"] = _validate_url(raw_thumbs_url)
690-
except ValueError as exc:
691-
return Response(status_code=400, headers={"X-Toast": str(exc)})
692-
elif "base_url" not in thumbs:
693-
thumbs["base_url"] = ""
686+
thumbs["image_type"] = form.get("game_thumbs_type", "logo").strip() or "logo"
687+
raw_style = form.get("game_thumbs_style", "1").strip()
688+
thumbs["style"] = raw_style if raw_style.isdigit() else "1"
689+
thumbs.pop("base_url", None)
694690

695691
tpl = cfg.setdefault("notification_template", {})
696692
tpl_title = form.get("notif_title_tpl", "").strip()
@@ -818,16 +814,16 @@ async def preview_send(
818814

819815
thumb_url = ""
820816
if sub_game_thumbs_league:
821-
from game_thumbs import build_thumb_url, _extract_game_teams, _to_pascal
817+
from game_thumbs import _extract_game_teams, _to_pascal, _build_url
822818
thumbs_cfg = cfg.get("game_thumbs", {})
823819
if thumbs_cfg.get("enabled"):
824-
base_url = thumbs_cfg.get("base_url", "").rstrip("/")
825-
if base_url:
826-
teams = _extract_game_teams(notif_title)
827-
if teams:
828-
away = _to_pascal(teams[0])
829-
home = _to_pascal(teams[1])
830-
thumb_url = f"{base_url}/{sub_game_thumbs_league}/{away}/{home}/thumb.png?style=1&logo=true&aspect=16-9"
820+
teams = _extract_game_teams(notif_title)
821+
if teams:
822+
away = _to_pascal(teams[0])
823+
home = _to_pascal(teams[1])
824+
image_type = thumbs_cfg.get("image_type", "logo")
825+
style = str(thumbs_cfg.get("style", "1"))
826+
thumb_url = _build_url(sub_game_thumbs_league, away, home, image_type, style)
831827

832828
errors = _send_to_channels(notif_title, notif_body, sub_channels, cfg, thumb_url=thumb_url)
833829
if errors:

templates/settings.html

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,33 @@ <h2 class="text-sm font-semibold text-white">Notification Message</h2>
160160

161161
<!-- ── Game Thumbnails ───────────────────────────────────────────── -->
162162
{% set thumbs = cfg.get('game_thumbs', {}) %}
163-
<section class="card p-5 space-y-4">
163+
<section class="card p-5 space-y-4"
164+
x-data="{
165+
type: '{{ thumbs.get('image_type', 'logo') }}',
166+
logoStyles: [
167+
{v:'1', label:'Style 1 — Diagonal split with dividing line'},
168+
{v:'2', label:'Style 2 — Side by side arrangement'},
169+
{v:'3', label:'Style 3 — Circle badges with team colors (league logo overlay)'},
170+
{v:'4', label:'Style 4 — Square badges with team colors (league logo overlay)'},
171+
{v:'5', label:'Style 5 — Circle badges with league logo on left (white background)'},
172+
{v:'6', label:'Style 6 — Square badges with league logo on left (white background)'},
173+
],
174+
coverStyles: [
175+
{v:'1', label:'Style 1 — Diagonal/horizontal split with team colors'},
176+
{v:'2', label:'Style 2 — Gradient blend between team colors'},
177+
{v:'3', label:'Style 3 — Minimalist badge with team circles (light background)'},
178+
{v:'4', label:'Style 4 — Minimalist badge with team circles (dark background)'},
179+
{v:'5', label:'Style 5 — Grid background with grey diagonal lines and fade to black'},
180+
{v:'6', label:'Style 6 — Grid background with team color gradient lines and fade to black'},
181+
{v:'98', label:'Style 98 — 3D embossed with textures, reflections, metallic VS badge, and league logo'},
182+
{v:'99', label:'Style 99 — 3D embossed with textures, reflections, and metallic VS badge (no league logo)'},
183+
],
184+
get styles() { return this.type === 'cover' ? this.coverStyles : this.logoStyles; }
185+
}">
164186
<div class="flex items-center justify-between">
165187
<div>
166188
<h2 class="text-sm font-semibold text-white">Game Thumbnails</h2>
167-
<p class="text-xs text-muted mt-0.5">Attach a team matchup image via a self-hosted <a href="https://game-thumbs-docs.swvn.io/" target="_blank" class="text-indigo-400 hover:underline">Game-Thumbs</a> server. Set <code class="text-indigo-300">game_thumbs_league</code> per subscription.</p>
189+
<p class="text-xs text-muted mt-0.5">Attach a team matchup image from <a href="https://game-thumbs.swvn.io" target="_blank" class="text-indigo-400 hover:underline">game-thumbs.swvn.io</a>. Set <code class="text-indigo-300">game_thumbs_league</code> per subscription.</p>
168190
</div>
169191
<label class="relative inline-flex items-center cursor-pointer shrink-0 ml-4">
170192
<input type="checkbox" name="game_thumbs_enabled" value="on" class="sr-only peer"
@@ -175,12 +197,22 @@ <h2 class="text-sm font-semibold text-white">Game Thumbnails</h2>
175197
after:transition-all peer-checked:after:translate-x-4"></div>
176198
</label>
177199
</div>
178-
<div class="border-t border-border pt-4">
179-
<label class="form-label">Server URL</label>
180-
<input name="game_thumbs_url" class="field"
181-
value="{{ thumbs.get('base_url', '') }}"
182-
placeholder="e.g. http://192.168.1.40:3050" />
183-
<p class="form-hint">Base URL of your Game-Thumbs server — no trailing slash</p>
200+
<div class="border-t border-border pt-4 grid grid-cols-2 gap-4">
201+
<div>
202+
<label class="form-label">Image Type</label>
203+
<select name="game_thumbs_type" class="field" x-model="type">
204+
<option value="logo">Logo</option>
205+
<option value="cover">Cover</option>
206+
</select>
207+
</div>
208+
<div>
209+
<label class="form-label">Style</label>
210+
<select name="game_thumbs_style" class="field">
211+
<template x-for="s in styles" :key="s.v">
212+
<option :value="s.v" :selected="s.v === '{{ thumbs.get('style', '1')|string }}'" x-text="s.label"></option>
213+
</template>
214+
</select>
215+
</div>
184216
</div>
185217
</section>
186218

0 commit comments

Comments
 (0)