New features: - P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering - Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris - Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback - Dark Side / New Hope toast notifications on theme toggle - Kitty terminal detection with cat emoji on splash Robustness (from Apollo code review): - Circuit breaker in track loop after 10 consecutive errors - Input validation for frequency, symbol rate, step size across scan/spectrum/track - Consolidated sys.path manipulation into __init__.py - Radar scope pre-computes dist/angle LUT per pixel on resize Cleanup: - Removed unused imports across lband, monitor, scan, signal_gauge - Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI) - Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
100 lines
3.3 KiB
Python
100 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Download splash art from 16colo.rs for SkyWalker-1 TUI.
|
|
|
|
Fetches pixel/teletext art from Mistigris packs on 16colo.rs and saves
|
|
them as bundled assets for the splash screen.
|
|
|
|
Usage:
|
|
python scripts/fetch_art.py
|
|
"""
|
|
|
|
import urllib.request
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ASSETS_DIR = Path(__file__).resolve().parent.parent / "src" / "skywalker_tui" / "assets" / "splash"
|
|
|
|
ART_SOURCES = [
|
|
{
|
|
"url": "https://16colo.rs/pack/mist0717/raw/ILLARTERATE-SETI-100_02_SATELLITE.PNG",
|
|
"filename": "seti-satellite.png",
|
|
"artist": "Illarterate",
|
|
"title": "S.E.T.I. Satellite",
|
|
"pack": "mist0717",
|
|
},
|
|
{
|
|
"url": "https://16colo.rs/pack/mist1119/raw/192.168.10.13-DIALTONE.JPG",
|
|
"filename": "dialtone.jpg",
|
|
"artist": "192.168.10.13",
|
|
"title": "Dialtone",
|
|
"pack": "mist1119",
|
|
},
|
|
{
|
|
"url": "https://16colo.rs/pack/mist0523/raw/BLIPPYPIXEL-SO_FAR_AWAY.GIF",
|
|
"filename": "so-far-away.gif",
|
|
"artist": "Blippypixel",
|
|
"title": "So Far Away",
|
|
"pack": "mist0523",
|
|
},
|
|
{
|
|
"url": "https://16colo.rs/pack/mist0121/raw/JELLICA_JAKE-PRODIGY.JPG",
|
|
"filename": "prodigy-out-of-space.jpg",
|
|
"artist": "Jellica Jake",
|
|
"title": "Prodigy / Out of Space",
|
|
"pack": "mist0121",
|
|
},
|
|
{
|
|
"url": "https://16colo.rs/pack/mist1120/raw/BLIPPYPIXEL-SPACE_DOCKER.GIF",
|
|
"filename": "space-docker.gif",
|
|
"artist": "Blippypixel",
|
|
"title": "Space Docker",
|
|
"pack": "mist1120",
|
|
},
|
|
]
|
|
|
|
|
|
def fetch_all():
|
|
ASSETS_DIR.mkdir(parents=True, exist_ok=True)
|
|
downloaded = 0
|
|
|
|
for art in ART_SOURCES:
|
|
dest = ASSETS_DIR / art["filename"]
|
|
if dest.exists():
|
|
print(f" exists: {art['filename']}", file=sys.stderr)
|
|
downloaded += 1
|
|
continue
|
|
|
|
print(f" fetch: {art['filename']} from {art['url']}", file=sys.stderr)
|
|
try:
|
|
req = urllib.request.Request(art["url"], headers={"User-Agent": "SkyWalker-1-TUI/0.1"})
|
|
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
data = resp.read()
|
|
dest.write_bytes(data)
|
|
print(f" {len(data):,} bytes -> {dest.name}", file=sys.stderr)
|
|
downloaded += 1
|
|
except Exception as e:
|
|
print(f" FAIL: {art['filename']}: {e}", file=sys.stderr)
|
|
|
|
# Write CREDITS.md
|
|
credits = ASSETS_DIR / "CREDITS.md"
|
|
lines = ["# Splash Art Credits\n", ""]
|
|
lines.append("All artwork sourced from [16colo.rs](https://16colo.rs) /")
|
|
lines.append("[Mistigris](https://mistigris.com) art packs.\n")
|
|
lines.append("| File | Artist | Title | Pack |")
|
|
lines.append("|------|--------|-------|------|")
|
|
for art in ART_SOURCES:
|
|
pack_url = f"https://16colo.rs/pack/{art['pack']}"
|
|
lines.append(
|
|
f"| `{art['filename']}` | {art['artist']} "
|
|
f"| {art['title']} | [{art['pack']}]({pack_url}) |"
|
|
)
|
|
lines.append("")
|
|
credits.write_text("\n".join(lines))
|
|
|
|
print(f"\n {downloaded}/{len(ART_SOURCES)} images downloaded to {ASSETS_DIR}", file=sys.stderr)
|
|
return downloaded
|
|
|
|
|
|
if __name__ == "__main__":
|
|
fetch_all()
|