class_name MapPush extends RefCounted ## „Map auf Server pushen“: aktuelle Map lokal prüfen und signieren ## (SvmapIO.to_signed_text), dann per Admin-API hochladen. UI-frei und testbar. ## opts: {name: String ("" = aus Map-Name), overwrite: bool, add_to_rotation: bool} ## Rückgabe: {ok, stage ("lokal"|"upload"), text (verständliche Meldung), ## id (Server-Map-ID), exists (bool: 409 – Nachfrage nötig), status} static func push(client: AdminClient, doc: Dictionary, opts: Dictionary = {}) -> Dictionary: var signed := SvmapIO.to_signed_text(doc) if not bool(signed["ok"]): var lines := "Die Map ist noch nicht gültig und wurde nicht hochgeladen:\n" for e in signed["errors"]: lines += "• %s\n" % str(e) return {"ok": false, "stage": "lokal", "text": lines.strip_edges(), "id": "", "exists": false, "status": 0} var info: Dictionary = doc.get("info", {}) var slug := str(opts.get("name", "")).strip_edges() if slug == "": slug = AdminTexte.slugify(str(info.get("name", ""))) if slug == "": return {"ok": false, "stage": "lokal", "text": "Die Map braucht einen Namen (Tab „Map“), bevor sie hochgeladen werden kann.", "id": "", "exists": false, "status": 0} var bytes: PackedByteArray = str(signed["text"]).to_utf8_buffer() var query := {"name": slug} if bool(opts.get("overwrite", false)): query["overwrite"] = "1" if bool(opts.get("add_to_rotation", false)): query["add_to_rotation"] = "1" var res: Dictionary = await client.call_api("POST", "/maps", null, query, bytes) var body: Dictionary = res.get("body", {}) if bool(res.get("ok", false)): var msg := "Hochgeladen als „%s“ (%s, %d Objekte)." % [str(body.get("name", slug)), _groesse(bytes.size()), int(body.get("objects", 0))] if bool(body.get("replaced", false)): msg += " Die vorherige Version wurde ersetzt." return {"ok": true, "stage": "upload", "text": msg, "id": str(body.get("id", "")), "exists": false, "status": 200} var exists := int(res.get("status", 0)) == 409 and str(body.get("code", "")) == "exists" return {"ok": false, "stage": "upload", "text": AdminTexte.erklaere(res), "id": "", "exists": exists, "status": int(res.get("status", 0))} static func _groesse(n: int) -> String: return "%.1f MB" % (n / 1048576.0) if n >= 1048576 else "%d KB" % maxi(1, n / 1024)