summaryrefslogtreecommitdiff
path: root/raveos-center/raveos_center/proton.py
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-center/raveos_center/proton.py')
-rw-r--r--raveos-center/raveos_center/proton.py125
1 files changed, 125 insertions, 0 deletions
diff --git a/raveos-center/raveos_center/proton.py b/raveos-center/raveos_center/proton.py
new file mode 100644
index 0000000..bff9649
--- /dev/null
+++ b/raveos-center/raveos_center/proton.py
@@ -0,0 +1,125 @@
+import hashlib
+import json
+import re
+import shutil
+import tarfile
+import tempfile
+import urllib.request
+from pathlib import Path
+
+from raveos_center import VERZIO
+
+KIADAS = "https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases/latest"
+STEAM_HELYEK = [
+ Path.home() / ".steam" / "root",
+ Path.home() / ".local" / "share" / "Steam",
+ Path.home() / ".var" / "app" / "com.valvesoftware.Steam" / "data" / "Steam",
+]
+NEV_MINTA = re.compile(r"^GE-Proton([0-9]+)-([0-9]+)(-x86_64)?$")
+FEJLEC = {"User-Agent": f"RaveOS-Center/{VERZIO}"}
+
+
+def celmappak():
+ lista = []
+ latott = set()
+ for hely in STEAM_HELYEK:
+ if not hely.is_dir():
+ continue
+ valodi = hely.resolve()
+ if valodi in latott:
+ continue
+ latott.add(valodi)
+ lista.append(valodi / "compatibilitytools.d")
+ return lista
+
+
+def _sorrend(nevek):
+ return sorted(nevek, key=lambda n: [int(x) for x in NEV_MINTA.match(n).groups()[:2]], reverse=True)
+
+
+def _mappaban(mappa):
+ if not mappa.is_dir():
+ return []
+ return _sorrend(p.name for p in mappa.iterdir() if p.is_dir() and not p.is_symlink() and NEV_MINTA.match(p.name))
+
+
+def telepitett():
+ nevek = set()
+ for mappa in celmappak():
+ nevek.update(_mappaban(mappa))
+ return _sorrend(nevek)
+
+
+def regiek():
+ return [(mappa, nev) for mappa in celmappak() for nev in _mappaban(mappa)[1:]]
+
+
+def _lekeres(url, ido=30):
+ return urllib.request.urlopen(urllib.request.Request(url, headers=FEJLEC), timeout=ido)
+
+
+def legujabb():
+ with _lekeres(KIADAS) as valasz:
+ adat = json.load(valasz)
+ nev = adat.get("tag_name", "")
+ if not NEV_MINTA.match(nev):
+ raise RuntimeError("ismeretlen kiadásnév")
+ eszkozok = {e["name"]: e for e in adat.get("assets", [])}
+ for mappa in (f"{nev}-x86_64", nev):
+ tar = eszkozok.get(f"{mappa}.tar.gz")
+ osszeg = eszkozok.get(f"{mappa}.sha512sum")
+ if tar and osszeg:
+ return {
+ "nev": mappa,
+ "url": tar["browser_download_url"],
+ "meret": tar.get("size", 0),
+ "osszeg_url": osszeg["browser_download_url"],
+ }
+ raise RuntimeError("a kiadásból hiányzik a csomag vagy az ellenőrzőösszeg")
+
+
+def telepit(kiadas, haladas):
+ mappak = celmappak()
+ if not mappak:
+ raise RuntimeError("nem található Steam, előbb indítsd el egyszer a Steamet")
+ with _lekeres(kiadas["osszeg_url"]) as valasz:
+ vart = valasz.read().decode().split()[0].lower()
+ if not re.fullmatch(r"[0-9a-f]{128}", vart):
+ raise RuntimeError("érvénytelen ellenőrzőösszeg")
+ mappak[0].mkdir(parents=True, exist_ok=True)
+ with tempfile.NamedTemporaryFile(dir=mappak[0], suffix=".tar.gz") as ideiglenes:
+ hasito = hashlib.sha512()
+ letoltve = 0
+ with _lekeres(kiadas["url"], 60) as valasz:
+ while darab := valasz.read(1 << 20):
+ ideiglenes.write(darab)
+ hasito.update(darab)
+ letoltve += len(darab)
+ if kiadas["meret"]:
+ haladas(min(90, int(letoltve * 90 / kiadas["meret"])))
+ ideiglenes.flush()
+ if hasito.hexdigest() != vart:
+ raise RuntimeError("a letöltött fájl ellenőrzőösszege nem egyezik")
+ for mappa in mappak:
+ mappa.mkdir(parents=True, exist_ok=True)
+ cel = mappa / kiadas["nev"]
+ if cel.is_symlink() or cel.is_file():
+ cel.unlink()
+ elif cel.exists():
+ shutil.rmtree(cel)
+ with tarfile.open(ideiglenes.name, "r:gz") as tar:
+ tagok = tar.getmembers()
+ if any(t.name != kiadas["nev"] and not t.name.startswith(kiadas["nev"] + "/") for t in tagok):
+ raise RuntimeError("váratlan tartalom a csomagban")
+ tar.extractall(mappa, members=tagok, filter="data")
+ haladas(100)
+ return kiadas["nev"]
+
+
+def torol(nev, mappak=None):
+ if not NEV_MINTA.match(nev):
+ raise ValueError("érvénytelen név")
+ for mappa in mappak or celmappak():
+ cel = mappa / nev
+ if cel.is_dir() and not cel.is_symlink():
+ shutil.rmtree(cel)