"""Verbindungsdaten (Server, Token, ...) als Datei oder QR-Code weitergeben. Format (Datei-Inhalt und QR-Code identisch, Android versteht dasselbe): netclip://connect?v=1&server=&token=[&key=][&insecure=1] Eine .netclip-Datei darf alternativ JSON {"server":..,"token":..,"server_key":..,"verify_tls":..} enthalten. """ import json from urllib.parse import parse_qs, urlencode, urlparse FIELDS = ("server", "token", "server_key", "verify_tls") def to_uri(server: str, token: str, server_key: str = "", verify_tls: bool = True) -> str: q = {"v": "1", "server": server, "token": token} if server_key: q["key"] = server_key if not verify_tls: q["insecure"] = "1" return "netclip://connect?" + urlencode(q) def parse(text: str) -> dict: """Gibt {"server", "token", "server_key", "verify_tls"} zurück, ValueError bei ungültigem Inhalt.""" text = text.strip() if text.startswith("{"): data = json.loads(text) result = {k: data[k] for k in FIELDS if k in data} else: u = urlparse(text) if u.scheme != "netclip": raise ValueError("keine NetClip-Verbindungsdaten") q = {k: v[0] for k, v in parse_qs(u.query).items()} result = {"server": q.get("server", ""), "token": q.get("token", ""), "server_key": q.get("key", ""), "verify_tls": q.get("insecure") != "1"} if not result.get("server") or not result.get("token"): raise ValueError("Server oder Token fehlt") return result def qr_image(data: str): """QR-Code als QImage (benoetigt das Paket 'qrcode').""" import qrcode from PySide6.QtGui import QColor, QImage, QPainter qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_M, border=4) qr.add_data(data) qr.make(fit=True) matrix = qr.get_matrix() scale = max(4, 360 // len(matrix)) size = len(matrix) * scale img = QImage(size, size, QImage.Format.Format_RGB32) img.fill(QColor("white")) p = QPainter(img) for y, row in enumerate(matrix): for x, on in enumerate(row): if on: p.fillRect(x * scale, y * scale, scale, scale, QColor("black")) p.end() return img