126 lines
6.7 KiB
Python
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()
|