first commit

This commit is contained in:
duffyduck
2026-10-16 15:55:14 +02:00
commit 65e8b9440d
62 changed files with 4799 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
"""Verbindungsdaten (Server, Token, ...) als Datei oder QR-Code weitergeben.
Format (Datei-Inhalt und QR-Code identisch, Android versteht dasselbe):
netclip://connect?v=1&server=<url>&token=<token>[&key=<server_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