#!/usr/bin/env python3 """Merge GF + KS data, compute rankings, generate HTML article.""" import json, os, sys from datetime import datetime, timezone # Load data with open("/home/hermes/workspace/gf_filtered.json") as f: gf_data = json.load(f) with open("/home/hermes/workspace/ks_filtered.json") as f: ks_data = json.load(f) print(f"GF: {len(gf_data)}, KS: {len(ks_data)}") # Convert both to common format merged = [] now = datetime.now(timezone.utc) # Process Gamefound for p in gf_data: name = p.get("projectName", "") funds = float(p.get("fundsGathered", 0) or 0) goal = float(p.get("campaignGoal", 0) or 0) backers = int(p.get("backerCount", 0) or 0) end_str = p.get("campaignEndDate", "") if end_str: try: end_dt = datetime.fromisoformat(end_str.replace('Z', '+00:00')) except: end_dt = None else: end_dt = None days_left = (end_dt - now).days + 1 if end_dt else 999 if days_left < 0: days_left = 0 pct = round(funds / goal * 100, 1) if goal > 0 else 0 # EUR to USD for ranking consistency (1 EUR ≈ 1.08 USD) usd_equiv = funds * 1.08 merged.append({ "name": name, "url": p.get("projectHomeUrl", ""), "platform": "Gamefound", "funds": funds, "goal": goal, "funding_usd": usd_equiv, "backers": backers, "days_left": days_left, "pct": pct, "end_date": end_str, "image": p.get("projectImageUrl", ""), "blurb": p.get("shortDescription", ""), "creator": p.get("creatorName", ""), "currency": p.get("currencyShortName", "EUR"), "state": "live", }) # Process Kickstarter for p in ks_data: funds = float(p.get("pledged", 0) or 0) goal = float(p.get("goal", 0) or 0) currency = p.get("currency", "USD") backers = int(p.get("backers_count", 0) or 0) # KS is in USD by default if currency == "USD": usd_equiv = funds elif currency == "EUR": usd_equiv = funds * 1.08 else: usd_equiv = funds * 1.0 # approximate # Days left deadline_str = p.get("deadline") if deadline_str: try: end_dt = datetime.fromisoformat(deadline_str.replace('Z', '+00:00')) except: end_dt = None else: # Try timestamp ts = p.get("deadline_ts") if isinstance(ts, int): end_dt = datetime.fromtimestamp(ts, tz=timezone.utc) else: end_dt = None days_left = (end_dt - now).days + 1 if end_dt else 999 if days_left < 0: days_left = 0 pct = round(funds / goal * 100, 1) if goal > 0 else 0 merged.append({ "name": p.get("name", ""), "url": p.get("url", ""), "platform": "Kickstarter", "funds": funds, "goal": goal, "funding_usd": usd_equiv, "backers": backers, "days_left": days_left, "pct": pct, "end_date": deadline_str, "image": p.get("photo", ""), "blurb": p.get("blurb", ""), "creator": p.get("creator", ""), "currency": currency, "state": p.get("state", "live"), }) # Sort by funding (USD equivalent) merged.sort(key=lambda x: x["funding_usd"], reverse=True) # Save merged data with open("/home/hermes/workspace/merged_data.json", "w") as f: json.dump(merged, f, indent=2, ensure_ascii=False) print(f"\nTotal merged: {len(merged)}") print(f"\nTop 10 by funding:") for i, p in enumerate(merged[:10]): plat = p['platform'][:2] funds_str = f"${p['funding_usd']:,.0f}" if p['currency'] == 'USD' else f"€{p['funds']:,.0f}" print(f" {i+1}. [{plat}] {p['name']}: {funds_str} ({p['pct']}%) · {p['backers']} backers · {p['days_left']}d left") # Save top 10, endspurts (≤3d), etc. print(f"\nEndspurte (≤3d): {sum(1 for p in merged if p['days_left'] <= 3)}") print(f"Geheimtipps (<$10k, >100% funded, >50 backers): {sum(1 for p in merged if p['funding_usd'] < 10000 and p['pct'] > 100 and p['backers'] > 50)}") # Get KW number kw = now.isocalendar()[1] print(f"\nKW: {kw}") print(f"\nDONE")