Files
zwischenablage-server/client-desktop/netclip/__main__.py
T
duffyduckandClaude Opus 5.5 af51ef5701 Release-Skript mit automatischer Versionierung und Docker-Builds
- scripts/release.py: Version (patch/minor/major) automatisch hochzaehlen, CHANGELOG
  abschliessen, committen, taggen; --build baut alle Pakete in Docker
- docker-build/: Build-Container fuer Windows (Wine + PyInstaller + Inno Setup),
  Linux und Android; Server-Image als docker-save-Archiv
- Versionsanzeige im Desktop-Client und in der Android-App
- Feste Android-Release-Signatur aus secrets/ (nicht im Git)
- Windows-Icon im Repo, damit der Wine-Build ohne Qt-Fenster auskommt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:45:17 +02:00

121 lines
3.9 KiB
Python

"""NetClip-Desktop-Client.
netclip starten (Tray-Icon)
netclip --minimized ohne Verlaufsfenster starten (Autostart)
netclip --show Verlauf der laufenden Instanz öffnen (fuer ein Tastenkuerzel)
netclip --import datei.netclip Verbindungsdaten importieren
netclip --server URL --token T [--server-key K] [--insecure] [--autostart]
Einstellungen setzen (fuer automatisches Ausrollen)
"""
import argparse
import sys
from PySide6.QtCore import QTimer
from PySide6.QtNetwork import QLocalServer, QLocalSocket
from PySide6.QtWidgets import QApplication, QMessageBox, QSystemTrayIcon
from . import __version__, autostart, config, connection
INSTANCE = "netclip-instance"
def parse_args():
p = argparse.ArgumentParser(prog="netclip", description="Netzwerk-Zwischenablage")
p.add_argument("--version", action="version", version=f"NetClip {__version__}")
p.add_argument("--minimized", action="store_true")
p.add_argument("--show", action="store_true")
p.add_argument("--import", dest="import_file")
p.add_argument("--server")
p.add_argument("--token")
p.add_argument("--server-key")
p.add_argument("--device-name")
p.add_argument("--insecure", action="store_true", help="TLS-Zertifikat nicht prüfen")
p.add_argument("--autostart", action="store_true")
p.add_argument("--configure-only", action="store_true", help="nur Einstellungen schreiben, nicht starten")
return p.parse_args()
def apply_args(args) -> bool:
cfg = config.load()
changed = False
if args.import_file:
with open(args.import_file, encoding="utf-8") as f:
for k, v in connection.parse(f.read()).items():
setattr(cfg, k, v)
changed = True
for attr in ("server", "token", "server_key", "device_name"):
value = getattr(args, attr)
if value is not None:
setattr(cfg, attr, value)
changed = True
if args.insecure:
cfg.verify_tls = False
changed = True
if args.autostart:
cfg.autostart = True
autostart.set_enabled(True)
changed = True
if changed:
config.save(cfg)
return changed
def main():
args = parse_args()
changed = apply_args(args)
if args.configure_only:
print(f"Konfiguration gespeichert: {config.config_file()}")
return
app = QApplication(sys.argv)
app.setApplicationName("NetClip")
app.setApplicationVersion(__version__)
app.setQuitOnLastWindowClosed(False)
# Einzelinstanz: laeuft schon eine, dort ggf. Verlauf öffnen bzw. neu laden und beenden
sock = QLocalSocket()
sock.connectToServer(INSTANCE)
if sock.waitForConnected(300):
sock.write(b"reload\n" if changed else b"show\n")
sock.waitForBytesWritten(300)
sock.disconnectFromServer()
return
if not QSystemTrayIcon.isSystemTrayAvailable():
QMessageBox.warning(None, "NetClip", "Kein System-Tray gefunden. Der Verlauf ist über das Fenster erreichbar.")
from .controller import Controller
from .ui import HistoryWindow, Tray, app_icon
app.setWindowIcon(app_icon())
ctl = Controller()
window = HistoryWindow(ctl)
tray = Tray(ctl, window)
server = QLocalServer()
QLocalServer.removeServer(INSTANCE)
server.listen(INSTANCE)
def on_connection():
conn = server.nextPendingConnection()
def read():
cmd = bytes(conn.readAll()).decode().strip()
if cmd == "reload":
ctl.apply_config(config.load())
window.show_raise()
conn.readyRead.connect(read)
server.newConnection.connect(on_connection)
if not ctl.cfg.configured:
QTimer.singleShot(200, tray.open_settings)
elif not args.minimized:
window.show_raise()
app.aboutToQuit.connect(ctl.shutdown)
sys.exit(app.exec())
if __name__ == "__main__":
main()