diff options
Diffstat (limited to 'raveos-center/raveos_center/jegyek_api.py')
| -rw-r--r-- | raveos-center/raveos_center/jegyek_api.py | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/raveos-center/raveos_center/jegyek_api.py b/raveos-center/raveos_center/jegyek_api.py new file mode 100644 index 0000000..c8c7268 --- /dev/null +++ b/raveos-center/raveos_center/jegyek_api.py @@ -0,0 +1,135 @@ +import json +import os +import threading +import urllib.error +import urllib.request +from pathlib import Path + +ALAP = os.environ.get("RAVEOS_JEGYEK_URL", "https://jegyek.rp1.hu/api/v1") +KONFIG = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config")) / "raveos-center" +KULCSFAJL = KONFIG / "kliens.json" + + +class ApiHiba(Exception): + def __init__(self, kod, uzenet): + super().__init__(uzenet) + self.kod = kod + + +def _keres(modszer, ut, adat=None, nyers=None, tipus="application/json", kulcs=None, ido=30): + fejlec = {"User-Agent": "raveos-center"} + torzs = None + if adat is not None: + torzs = json.dumps(adat).encode() + fejlec["Content-Type"] = "application/json" + elif nyers is not None: + torzs = nyers + fejlec["Content-Type"] = tipus + if kulcs: + fejlec["Authorization"] = f"Bearer {kulcs}" + keres = urllib.request.Request(ALAP + ut, data=torzs, headers=fejlec, method=modszer) + try: + with urllib.request.urlopen(keres, timeout=ido) as valasz: + return json.loads(valasz.read() or b"{}") + except urllib.error.HTTPError as e: + try: + uzenet = json.loads(e.read()).get("hiba", str(e)) + except ValueError: + uzenet = str(e) + raise ApiHiba(e.code, uzenet) from None + except (urllib.error.URLError, OSError) as e: + raise ApiHiba(0, "nincs_kapcsolat") from e + + +_kulcs_zar = threading.Lock() + + +def kulcs(): + with _kulcs_zar: + try: + return json.loads(KULCSFAJL.read_text())["kulcs"] + except (OSError, ValueError, KeyError): + pass + uj = _keres("POST", "/kliens")["kulcs"] + KONFIG.mkdir(parents=True, exist_ok=True) + os.chmod(KONFIG, 0o700) + ideiglenes = KULCSFAJL.with_suffix(".uj") + fd = os.open(ideiglenes, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600) + with os.fdopen(fd, "w") as f: + json.dump({"kulcs": uj}, f) + os.replace(ideiglenes, KULCSFAJL) + return uj + + +def _hitelesitett(modszer, ut, **kw): + try: + return _keres(modszer, ut, kulcs=kulcs(), **kw) + except ApiHiba as e: + if e.kod != 401: + raise + with _kulcs_zar: + KULCSFAJL.unlink(missing_ok=True) + return _keres(modszer, ut, kulcs=kulcs(), **kw) + + +def jegyeim(): + return _hitelesitett("GET", "/jegyek")["jegyek"] + + +def jegy(jegy_id): + return _hitelesitett("GET", f"/jegyek/{jegy_id}") + + +def uj_jegy(tipus, cim, szoveg, rendszer=None, naplo=None): + adat = {"tipus": tipus, "cim": cim, "szoveg": szoveg} + if rendszer: + adat["rendszer"] = rendszer + if naplo: + adat["naplo"] = naplo + return _hitelesitett("POST", "/jegyek", adat=adat) + + +def valasz(jegy_id, szoveg): + return _hitelesitett("POST", f"/jegyek/{jegy_id}/uzenetek", adat={"szoveg": szoveg}) + + +def otletek(): + return _hitelesitett("GET", "/otletek")["otletek"] + + +def szavaz(jegy_id, tamogat): + return _hitelesitett("PUT" if tamogat else "DELETE", f"/otletek/{jegy_id}/szavazat") + + +def ertekeles(): + return _hitelesitett("GET", "/ertekeles") + + +def ertekel(csillag, szoveg): + return _hitelesitett("PUT", "/ertekeles", adat={"csillag": csillag, "szoveg": szoveg}) + + +def allapot(): + return _hitelesitett("GET", "/allapot") + + +def naplo_feltolt(szoveg): + return _hitelesitett( + "POST", "/naplok?forras=center", nyers=szoveg.encode(), tipus="text/plain; charset=utf-8", ido=60 + )["azonosito"] + + +HIBAUZENETEK = { + "nincs_kapcsolat": "Nem sikerült elérni a szervert. Ellenőrizd az internetkapcsolatot.", + "tul_sok_keres": "Túl sok kérés rövid idő alatt. Próbáld újra kicsit később.", + "lezart_jegy": "Ez a jegy le van zárva, már nem lehet rá válaszolni.", + "nincs_jegy": "Ez a jegy már nem létezik.", + "nincs_ilyen_naplo": "A megadott naplóazonosító nem létezik.", + "kitiltva": "Ez a gép ki van tiltva a Visszajelzés használatából.", +} + + +def emberi(hiba): + if isinstance(hiba, ApiHiba): + return HIBAUZENETEK.get(str(hiba), f"A szerver hibát jelzett ({hiba}).") + return str(hiba) |