Files
pgz-sport/scrapers/qa_from_sport_facts.py
T

126 lines
6.7 KiB
Python

#!/usr/bin/env python3
from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh
import os
# qa_from_sport_facts.py — Generate Q&A pairs from PGZ sport facts za DABI trening
import psycopg2, hashlib, logging, json, re
logging.basicConfig(level=logging.INFO, format='%(asctime)s [qa_gen] %(message)s')
log = logging.getLogger("qa_gen")
DSN = f"host=10.10.0.2 port=6432 dbname=rinet_v3 user=rinet password={os.environ['DB_PASSWORD']}"
def main():
conn = psycopg2.connect(DSN); conn.autocommit = True
cur = conn.cursor()
# Klubovi facts → Q&A
cur.execute("""
SELECT id, naziv, oib, sport, grad, predsjednik, tajnik, godina_osnutka, broj_clanova
FROM pgz_sport.klubovi WHERE aktivan = true AND naziv IS NOT NULL
LIMIT 1000
""")
qa_rows = []
for r in cur.fetchall():
kid, naziv, oib, sport, grad, preds, tajn, god, n_cl = r
# Generate diverse Q-A pairs
pairs = []
if oib: pairs.append((f"Koji je OIB kluba {naziv}?", f"OIB kluba {naziv} je {oib}."))
if sport: pairs.append((f"Kojim sportom se bavi klub {naziv}?", f"Klub {naziv} bavi se sportom: {sport}."))
if grad: pairs.append((f"U kojem gradu je klub {naziv}?", f"Klub {naziv} djeluje u gradu {grad}."))
if preds: pairs.append((f"Tko je predsjednik kluba {naziv}?", f"Predsjednik kluba {naziv} je {preds}."))
if tajn: pairs.append((f"Tko je tajnik kluba {naziv}?", f"Tajnik kluba {naziv} je {tajn}."))
if god: pairs.append((f"Kada je osnovan klub {naziv}?", f"Klub {naziv} osnovan je {god}. godine."))
if n_cl: pairs.append((f"Koliko članova ima klub {naziv}?", f"Klub {naziv} ima {n_cl} članova."))
for q, a in pairs:
qa_hash = hashlib.sha256(f"{q}".encode()).hexdigest()[:32]
qa_rows.append((q, a, 'pgz_sport_klub_qa', 'auto_generated', 0.92, qa_hash))
# Savezi facts
cur.execute("""
SELECT id, naziv, oib, sport, predsjednik, tajnik FROM pgz_sport.savezi
WHERE naziv IS NOT NULL
""")
for r in cur.fetchall():
sid, naziv, oib, sport, preds, tajn = r
if oib: qa_rows.append((f"Koji je OIB saveza {naziv}?", f"OIB saveza {naziv} je {oib}.",
'pgz_sport_savez_qa', 'auto_generated', 0.92,
hashlib.sha256(f"savez_oib:{sid}".encode()).hexdigest()[:32]))
if preds: qa_rows.append((f"Tko je predsjednik {naziv}?", f"Predsjednik {naziv} je {preds}.",
'pgz_sport_savez_qa', 'auto_generated', 0.92,
hashlib.sha256(f"savez_preds:{sid}".encode()).hexdigest()[:32]))
# Multi-chair pitanja
cur.execute("""
WITH all_links AS (
SELECT lower(trim(predsjednik)) AS pk, predsjednik AS pname,
'klub:'||k.id AS oid, k.naziv AS oname, 'predsjednik' AS role
FROM pgz_sport.klubovi k WHERE predsjednik IS NOT NULL AND length(trim(predsjednik)) > 5
UNION ALL
SELECT lower(trim(tajnik)), tajnik, 'klub:'||k.id, k.naziv, 'tajnik'
FROM pgz_sport.klubovi k WHERE tajnik IS NOT NULL AND length(trim(tajnik)) > 5
)
SELECT pname, count(DISTINCT oid) AS n,
string_agg(DISTINCT oname, ', ') AS klubovi
FROM all_links GROUP BY pname HAVING count(DISTINCT oid) >= 3
ORDER BY 2 DESC LIMIT 50
""")
for r in cur.fetchall():
pname, n, klubovi = r
q = f"U koliko klubova/saveza je {pname} u funkciji?"
a = f"{pname} sjedi na {n} stolica u PGŽ Sport. Klubovi: {klubovi[:300]}. Ovo je multi-chair pozicija — moguć sukob interesa."
qh = hashlib.sha256(f"mc_qa:{pname}".encode()).hexdigest()[:32]
qa_rows.append((q, a, 'pgz_sport_multichair_qa', 'auto_generated', 0.90, qh))
# Manifestacije Q&A
cur.execute("SELECT id, naziv, mjesto, godina_od, organizator FROM pgz_sport.manifestacije WHERE naziv IS NOT NULL")
for r in cur.fetchall():
mid, naziv, mjesto, god, org = r
if mjesto: qa_rows.append((f"Gdje se održava manifestacija {naziv}?", f"Manifestacija {naziv} održava se u {mjesto}.",
'pgz_sport_manifestacija_qa', 'auto_generated', 0.85,
hashlib.sha256(f"man_mjesto:{mid}".encode()).hexdigest()[:32]))
if org: qa_rows.append((f"Tko organizira manifestaciju {naziv}?", f"Manifestaciju {naziv} organizira {org}.",
'pgz_sport_manifestacija_qa', 'auto_generated', 0.85,
hashlib.sha256(f"man_org:{mid}".encode()).hexdigest()[:32]))
if god: qa_rows.append((f"Otkad se održava manifestacija {naziv}?", f"Manifestacija {naziv} održava se od {god}. godine.",
'pgz_sport_manifestacija_qa', 'auto_generated', 0.85,
hashlib.sha256(f"man_god:{mid}".encode()).hexdigest()[:32]))
# Natjecanja Q&A
cur.execute("SELECT id, naziv, sport, sezona, razina, tip FROM pgz_sport.natjecanja WHERE naziv IS NOT NULL LIMIT 500")
for r in cur.fetchall():
nid, naziv, sport, sez, raz, tip = r
if sport: qa_rows.append((f"Kojim sportom se bavi natjecanje {naziv}?", f"Natjecanje {naziv} je u sportu {sport}.",
'pgz_sport_natjecanje_qa', 'auto_generated', 0.85,
hashlib.sha256(f"nat_sport:{nid}".encode()).hexdigest()[:32]))
if raz: qa_rows.append((f"Koja je razina natjecanja {naziv}?", f"Natjecanje {naziv} je razine {raz}.",
'pgz_sport_natjecanje_qa', 'auto_generated', 0.85,
hashlib.sha256(f"nat_raz:{nid}".encode()).hexdigest()[:32]))
if sez: qa_rows.append((f"U kojoj sezoni je natjecanje {naziv}?", f"Natjecanje {naziv} je sezona {sez}.",
'pgz_sport_natjecanje_qa', 'auto_generated', 0.85,
hashlib.sha256(f"nat_sez:{nid}".encode()).hexdigest()[:32]))
# Save to dabi.training_qa
inserted = 0
for qa in qa_rows:
try:
cur.execute("""
INSERT INTO dabi.training_qa
(question, answer, category, source_type, created_at)
VALUES (%s, %s, %s, %s, now())
ON CONFLICT DO NOTHING
""", (qa[0], qa[1], qa[2], 'pgz_sport_auto'))
inserted += cur.rowcount
except Exception as e:
if inserted < 3:
log.warning(f"insert fail: {e}")
log.info(f"Q&A pairs generated: {len(qa_rows)}, inserted: {inserted}")
cur.close(); conn.close()
if __name__ == "__main__":
main()