Reunit en un seul outil les fonctions utiles de MobaXterm, Termius et Bitvise, sans compte ni service tiers, avec toutes les donnees en local. - Terminaux multi-onglets : sessions SSH et terminaux Windows locaux (PowerShell / cmd) via la pseudo-console native ConPTY - Gestionnaire de fichiers SFTP facon WinSCP : double panneau, colonnes triables, glisser-deposer, renommage, permissions, file de transferts. Ouvrable sur une connexion en cours sans creer de favori - Gestion des cles SSH : generation Ed25519/RSA, import, export - Gestion du fichier known_hosts, avec remplacement guide d'une cle d'hote modifiee (cas frequent des serveurs en DHCP) - Trois themes (clair, bleu nuit, noir), commutables a chaud - Authentification automatique reprenant le comportement de la commande ssh (agent SSH et cles ~/.ssh), mot de passe demande seulement en secours Aucun mot de passe n'est stocke sur le disque. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
"""Emplacements des donnees et des ressources, valables en mode script comme en .exe.
|
|
|
|
Point d'attention : une fois l'application figee par PyInstaller, `__file__` pointe vers
|
|
un dossier temporaire (`sys._MEIPASS`) que Windows supprime a la fermeture. Y ecrire les
|
|
sessions, les cles ou known_hosts reviendrait a les perdre a chaque sortie. Les donnees
|
|
utilisateur vont donc a cote de l'executable (mode portable), avec repli sur %APPDATA%
|
|
si cet emplacement n'est pas accessible en ecriture (installation dans Program Files,
|
|
lancement depuis un support en lecture seule...).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
FROZEN = getattr(sys, "frozen", False)
|
|
|
|
|
|
def _app_dir() -> Path:
|
|
"""Dossier de l'executable (mode figé) ou racine du projet (mode script)."""
|
|
if FROZEN:
|
|
return Path(sys.executable).resolve().parent
|
|
return Path(__file__).resolve().parent.parent
|
|
|
|
|
|
def _resolve_resources() -> Path:
|
|
if FROZEN:
|
|
bundled = getattr(sys, "_MEIPASS", None)
|
|
if bundled: # onefile : ressources extraites dans un dossier temporaire
|
|
return Path(bundled) / "resources"
|
|
return _app_dir() / "resources"
|
|
|
|
|
|
def _resolve_data() -> Path:
|
|
candidate = _app_dir() / "data"
|
|
try:
|
|
candidate.mkdir(parents=True, exist_ok=True)
|
|
probe = candidate / ".write_test"
|
|
probe.write_text("", encoding="utf-8")
|
|
probe.unlink()
|
|
return candidate
|
|
except OSError:
|
|
fallback = Path(os.environ.get("APPDATA") or Path.home()) / "PySSHClient"
|
|
fallback.mkdir(parents=True, exist_ok=True)
|
|
return fallback
|
|
|
|
|
|
RESOURCES_DIR = _resolve_resources()
|
|
DATA_DIR = _resolve_data()
|