feat: /api/v2/analiza/* endpoints - sport analytics backend

This commit is contained in:
Damir Radulic
2026-05-16 00:28:12 +02:00
parent 7ca5d7d94e
commit aca5051418
1355 changed files with 321891 additions and 4128 deletions
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
"""Mine 18 godišnjaka 2006-2024: extract klub mentions, sportaš results, trophies."""
import os
import psycopg2, re, json
from collections import defaultdict
DB = dict(host='localhost', port=5432, dbname='rinet_v3',
user='rinet', password=os.environ["DB_PASSWORD"])
conn = psycopg2.connect(**DB); conn.autocommit = True
cu = conn.cursor()
# Get all godisnjak texts
cu.execute("""SELECT id, godina, length(sadrzaj) AS chars, sadrzaj
FROM pgz_sport.dokumenti
WHERE vrsta='godisnjak' AND godina IS NOT NULL
ORDER BY godina""")
godisnjaci = cu.fetchall()
print(f"Loaded {len(godisnjaci)} godišnjaka")
# Get all PGZ klubovi for matching
cu.execute("""SELECT id, naziv FROM pgz_sport.klubovi WHERE aktivan=true""")
klubovi = cu.fetchall()
print(f"Active klubova: {len(klubovi)}")
# Build matching index - extract base name from naziv
def base_name(naziv):
"""Extract searchable base from club naziv."""
n = re.sub(r'^(HNK|NK|RK|KK|VK|HK|AK|TK|BK|PK|HAOK|HŠK|ŽNK|ŠD|ŠRK|HRK|HŠŠ|KAK|KKM|KKP|HOO|VKK|HMNL|ŽRK|ŠKD|ŠK|ŠHRK)\s+', '', naziv, flags=re.IGNORECASE).strip()
n = re.sub(r'\s*\([^)]+\)\s*', ' ', n).strip()
n = re.sub(r'^(NOGOMETNI|RUKOMETNI|VATERPOLO|ATLETSKI|TENISKI|KOŠARKAŠKI|BOĆARSKI|JEDRILIČARSKI|KARATE)\s+(KLUB|KLUB\s+)', '', n, flags=re.IGNORECASE)
return n.strip()[:50]
# Index for fast lookup
klub_index = [] # (klub_id, naziv, base, base_lower)
for kid, naziv in klubovi:
if not naziv or len(naziv) < 3: continue
b = base_name(naziv)
if len(b) < 3: continue
klub_index.append((kid, naziv, b, b.lower()))
# Stats per klub: in which years did it appear?
klub_mentions = defaultdict(list) # klub_id → [godina,...]
# For each godišnjak, find clubs mentioned
for did, godina, chars, text in godisnjaci:
if not text or len(text) < 5000: continue
text_low = text.lower()
matched_in_doc = set()
for kid, naziv, base, base_low in klub_index:
if base_low in text_low:
matched_in_doc.add(kid)
print(f" godišnjak {godina}: {len(matched_in_doc)} klubova mentioned")
for kid in matched_in_doc:
klub_mentions[kid].append(godina)
# Update klubovi with godina_prvog_pojavljivanja and godina_zadnjeg
print(f"\n=== Klubovi sa mentions: {len(klub_mentions)} ===")
# Add new column
cu.execute("ALTER TABLE pgz_sport.klubovi ADD COLUMN IF NOT EXISTS godisnjak_godine INT[]")
cu.execute("ALTER TABLE pgz_sport.klubovi ADD COLUMN IF NOT EXISTS godisnjak_prvi INT")
cu.execute("ALTER TABLE pgz_sport.klubovi ADD COLUMN IF NOT EXISTS godisnjak_zadnji INT")
updated = 0
for kid, godine in klub_mentions.items():
godine_sorted = sorted(set(godine))
cu.execute("""UPDATE pgz_sport.klubovi
SET godisnjak_godine=%s, godisnjak_prvi=%s, godisnjak_zadnji=%s
WHERE id=%s""",
(godine_sorted, godine_sorted[0], godine_sorted[-1], kid))
updated += 1
print(f"Updated {updated} klubova sa godinama pojavljivanja")
# Top klubovi by mentions
top_klubovi = sorted(klub_mentions.items(), key=lambda x: len(x[1]), reverse=True)[:20]
print("\n=== TOP 20 klubova po godinama pojavljivanja ===")
for kid, godine in top_klubovi:
cu.execute("SELECT naziv FROM pgz_sport.klubovi WHERE id=%s", (kid,))
n = cu.fetchone()[0]
print(f" {len(godine):2}× {n[:60]}")
conn.close()