Files
two-stands-cg/generate_placeholders.py
2026-08-02 17:54:45 +03:00

195 lines
7.7 KiB
Python

#!/usr/bin/env python3
"""
Generate data/transfers.json from assets/transfers-list.csv.
CSV columns: Player, Club, Sum, Photo, Logo
- Photo: filename of the player photo at project root (e.g. tmp-player.png)
- Logo: filename of the club logo in clubs-logo/ (e.g. chelsea.png)
Team colours are looked up from the CLUBS dict below; unknown clubs
get auto-generated colours.
Run: python3 generate_placeholders.py
"""
import csv
import json
import os
import colorsys
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(BASE_DIR, "data")
CSV_PATH = os.path.join(BASE_DIR, "assets", "transfers-list.csv")
CLUBS_DIR = os.path.join(BASE_DIR, "clubs-logo")
PLAYER_DIR = os.path.join(BASE_DIR, "players")
os.makedirs(DATA_DIR, exist_ok=True)
# ---------------------------------------------------------------------------
# Russian club name -> colours
# ---------------------------------------------------------------------------
CLUBS = {
"Челси": {"color": "#034694", "accent": "#FFFFFF"},
"Барселона": {"color": "#A50044", "accent": "#004D98"},
"Реал": {"color": "#FEBE10", "accent": "#00529F"},
"Арсенал": {"color": "#EF0107", "accent": "#FFFFFF"},
"Бавария": {"color": "#DC052D", "accent": "#0066B2"},
"ПСЖ": {"color": "#004170", "accent": "#DA291C"},
"Ман Сити": {"color": "#6CABDD", "accent": "#1C2C5B"},
"Ливерпуль": {"color": "#C8102E", "accent": "#FFFFFF"},
"Ювентус": {"color": "#000000", "accent": "#FFFFFF"},
"Интер": {"color": "#0068A8", "accent": "#000000"},
"Милан": {"color": "#FB090B", "accent": "#000000"},
"Атлетико": {"color": "#CB3524", "accent": "#261E60"},
"Тоттенхэм": {"color": "#132257", "accent": "#FFFFFF"},
"Ньюкасл": {"color": "#241F20", "accent": "#FFFFFF"},
"Вест Хэм": {"color": "#7A263A", "accent": "#1BB1E7"},
"Брайтон": {"color": "#0057B8", "accent": "#FFCD00"},
"Байер": {"color": "#E32221", "accent": "#000000"},
"Айнтрахт": {"color": "#000000", "accent": "#E1000F"},
"Олимпиакос": {"color": "#E30613", "accent": "#FFFFFF"},
"Галатасарай":{"color": "#A90432", "accent": "#FCB330"},
"Аталанта": {"color": "#1E71B8", "accent": "#000000"},
"Наполи": {"color": "#12A0E0", "accent": "#FFFFFF"},
"Брюгге": {"color": "#0066B2", "accent": "#000000"},
"Боде/Глимт": {"color": "#FCD116", "accent": "#000000"},
"Унион": {"color": "#EA2127", "accent": "#FFFFFF"},
"Копенгаген": {"color": "#000000", "accent": "#FFFFFF"},
"Пафос": {"color": "#0033A0", "accent": "#FFFFFF"},
"Славия": {"color": "#C8102E", "accent": "#FFFFFF"},
"Карабах": {"color": "#000000", "accent": "#FFFFFF"},
"Кайрат": {"color": "#000000", "accent": "#FFD700"},
"Бенфика": {"color": "#E30613", "accent": "#FFFFFF"},
"Вильярреал": {"color": "#FFE667", "accent": "#00529F"},
"Аякс": {"color": "#D2122E", "accent": "#FFFFFF"},
"Монако": {"color": "#E20E32", "accent": "#FFFFFF"},
"ПСВ": {"color": "#ED1C24", "accent": "#FFFFFF"},
"Спортинг": {"color": "#008053", "accent": "#FFFFFF"},
"Марсель": {"color": "#009DDC", "accent": "#FFFFFF"},
"Боруссия": {"color": "#FDE100", "accent": "#000000"},
"Атлетик": {"color": "#EE2523", "accent": "#FFFFFF"},
"Манчестер Сити": {"color": "#6CABDD", "accent": "#1C2C5B"},
"Манчестер Юнайтед": {"color": "#DA291C", "accent": "#FFE500"},
"Астон Вилла": {"color": "#95BFE5", "accent": "#670E36"},
"Аль-Хилаль": {"color": "#1B458F", "accent": "#FFFFFF"},
"Кристал Пэлас": {"color": "#1B458F", "accent": "#C4122E"},
"Комо": {"color": "#0033A0", "accent": "#FFFFFF"},
}
FREE_AGENT_KEYWORDS = ("свободн", "free")
LOAN_KEYWORDS = ("аренд", "loan")
# ---------------------------------------------------------------------------
# Colour helpers
# ---------------------------------------------------------------------------
def _hex_to_rgb(h):
h = h.lstrip("#")
return tuple(int(h[i:i+2], 16) for i in (0, 2, 4))
def _rgb_to_hex(rgb):
return "#{:02X}{:02X}{:02X}".format(*rgb)
def auto_colors(name):
h = hash(name) % 360
r, g, b = colorsys.hsv_to_rgb(h / 360, 0.65, 0.75)
return _rgb_to_hex((int(r * 255), int(g * 255), int(b * 255))), "#FFFFFF"
# ---------------------------------------------------------------------------
# Parse CSV and build JSON
# ---------------------------------------------------------------------------
def parse_csv():
rows = []
with open(CSV_PATH, encoding="utf-8-sig") as f:
reader = csv.DictReader(f, skipinitialspace=True)
for row in reader:
player = (row.get("Player") or "").strip()
if not player:
continue
rows.append({
"player": player,
"club": (row.get("Club") or "").strip(),
"fee": (row.get("Sum") or "").strip(),
"photo": (row.get("Photo") or "").strip(),
"logo": (row.get("Logo") or "").strip(),
})
return rows
def main():
rows = parse_csv()
if not rows:
print("ERROR: no data found in", CSV_PATH)
return
transfers_json = []
warnings = []
for i, r in enumerate(rows):
club_name = r["club"]
if not club_name:
warnings.append(f"Row {i+1}: empty club for player '{r['player']}'")
continue
meta = CLUBS.get(club_name)
if meta:
color = meta["color"]
accent = meta["accent"]
else:
color, accent = auto_colors(club_name)
warnings.append(f"Row {i+1}: unknown club '{club_name}' -> auto colours {color}")
photo = r["photo"] if r["photo"] else "tmp-player.png"
photo_path = os.path.join(PLAYER_DIR, photo)
if not os.path.exists(photo_path):
warnings.append(f"Row {i+1}: photo '{photo}' not found at project root")
logo = r["logo"] if r["logo"] else ""
logo_path = os.path.join(CLUBS_DIR, logo) if logo else ""
if logo and not os.path.exists(logo_path):
warnings.append(f"Row {i+1}: logo '{logo}' not found in clubs-logo/")
is_free = any(kw in r["fee"].lower() for kw in FREE_AGENT_KEYWORDS)
is_loan = any(kw in r["fee"].lower() for kw in LOAN_KEYWORDS)
price = r["fee"] if r["fee"] else ""
if is_free:
status = "free-agent"
elif is_loan:
status = "loan"
else:
status = "fee"
transfers_json.append({
"id": i + 1,
"playerName": r["player"],
"photo": f"players/{photo}",
"team": {
"name": club_name,
"logo": f"clubs-logo/{logo}" if logo else "",
"color": color,
"accent": accent,
},
"price": price,
"status": status,
})
json_path = os.path.join(DATA_DIR, "transfers.json")
with open(json_path, "w", encoding="utf-8") as f:
json.dump({"transfers": transfers_json}, f, indent=2, ensure_ascii=False)
f.write("\n")
print(f" Data -> {os.path.relpath(json_path, BASE_DIR)}")
if warnings:
print("\n WARNINGS:")
for w in warnings:
print(f" ! {w}")
print(f"\nDone! {len(transfers_json)} transfers written to transfers.json")
if __name__ == "__main__":
main()