#!/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") 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(BASE_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": 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") 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()