SFTP sur cette connexion : ne plus perdre la cible ssh detectee
Signale par l'utilisateur avec une capture d'ecran : bouton "SFTP sur cette connexion" clique depuis un terminal local visiblement connecte en ssh (prompt root@debian:~#), formulaire de connexion vide a l'arrivee - "si je dois remplir le formulaire pour une session actuelle ca perd tout son sens". Cause reelle : detect_ssh_target() ne scrutait le texte du terminal qu'au moment du clic (buffer visible + historique pyte, 5000 lignes). Si la ligne `ssh user@hote` tapee par l'utilisateur n'y figure plus au moment du clic (beaucoup de sortie depuis, ecran efface...), plus rien n'est detectable - alors meme que la connexion ssh est toujours active. La capture montree correspond exactement a ce cas : un ecran efface apres la connexion. Corrige a la racine plutot qu'en agrandissant simplement l'historique scrute : app/ui/tabs.py (BaseTerminalTab) memorise desormais la cible des qu'une commande ssh apparait dans la sortie recue (_track_ssh_target, cablee comme terminal.feed sur data_received), et ne l'oublie plus jamais - detect_current_ssh_target() la renvoie en priorite, avec un dernier examen du buffer actuel seulement en repli. Le bouton "SFTP sur cette connexion" et le raccourci global Ctrl+Shift+F (ConnectionController._current_tab_ssh_target) utilisent tous les deux ce nouveau point d'entree unique. tests/test_ssh_target_tracking.py (4 verifications, nouveau fichier - ce bouton n'avait encore aucun test dedie) : memorisation a la frappe, cible toujours renvoyee meme quand le buffer live ne la contient plus, mise a jour vers une commande ssh plus recente, bouton emettant bien la cible memorisee. Suite complete revalidee (36/36), ruff propre. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,6 @@ from app.dialogs.session_dialog import SessionDialog
|
||||
from app.key_manager import KeyManager
|
||||
from app.local_terminal import DEFAULT_SHELL, SHELL_LABELS
|
||||
from app.openssh.config import OpenSSHHost, session_from_openssh_host
|
||||
from app.services.ssh_target import detect_ssh_target
|
||||
from app.session_manager import AUTH_PASSWORD, PASSWORD_STORAGE_SECURE, Session, SessionStore
|
||||
from app.ui.split_pane import LAYOUT_LABELS, PaneSlot, SplitContainer
|
||||
from app.ui.tabs import BaseTerminalTab, LocalTerminalTabWidget, SessionTabWidget, SFTPTabWidget
|
||||
@@ -181,7 +180,7 @@ class ConnectionController(QObject):
|
||||
"port": widget.session.port,
|
||||
}
|
||||
if isinstance(widget, BaseTerminalTab):
|
||||
return detect_ssh_target(widget.terminal.buffer_text())
|
||||
return widget.detect_current_ssh_target()
|
||||
return None
|
||||
|
||||
def _quick_connect(self, sftp: bool, target: dict | None = None) -> None:
|
||||
|
||||
@@ -151,6 +151,7 @@ class BaseTerminalTab(QWidget):
|
||||
self._log_file = None
|
||||
self._connection_generation = 0
|
||||
self._closing = False
|
||||
self._last_ssh_target: dict | None = None
|
||||
|
||||
# ---------- journalisation ----------
|
||||
def toggle_logging(self) -> None:
|
||||
@@ -193,6 +194,24 @@ class BaseTerminalTab(QWidget):
|
||||
except OSError:
|
||||
self.stop_logging()
|
||||
|
||||
# ---------- detection d'une commande ssh tapee a la main ----------
|
||||
def _track_ssh_target(self, _data: bytes) -> None:
|
||||
"""Reevalue a chaque sortie recue, et ne fait que memoriser un
|
||||
resultat trouve (jamais l'oublier) : la commande `ssh ...` typee par
|
||||
l'utilisateur peut ensuite defiler hors de l'ecran visible, voire hors
|
||||
de l'historique conserve (beaucoup de sortie, `clear`...), longtemps
|
||||
avant qu'on ait besoin de s'en souvenir (bouton SFTP sur cette
|
||||
connexion)."""
|
||||
target = detect_ssh_target(self.terminal.buffer_text())
|
||||
if target:
|
||||
self._last_ssh_target = target
|
||||
|
||||
def detect_current_ssh_target(self) -> dict | None:
|
||||
"""Cible ssh de ce terminal : la derniere commande ssh vue passer
|
||||
(memorisee au moment ou elle etait encore visible), sinon un dernier
|
||||
examen du texte actuellement disponible."""
|
||||
return self._last_ssh_target or detect_ssh_target(self.terminal.buffer_text())
|
||||
|
||||
def _wire_connection(self) -> None:
|
||||
# Un signal deconnexion/erreur/connexion emis par une connexion remplacee
|
||||
# entre-temps (ex. reconnexion en cours) ne doit pas ecraser l'etat de la
|
||||
@@ -201,6 +220,7 @@ class BaseTerminalTab(QWidget):
|
||||
generation = self._connection_generation
|
||||
self.connection.connected.connect(lambda: self._on_current_generation(generation, self._on_connected))
|
||||
self.connection.data_received.connect(self.terminal.feed)
|
||||
self.connection.data_received.connect(self._track_ssh_target)
|
||||
self.connection.data_received.connect(self._log_output)
|
||||
self.connection.disconnected.connect(
|
||||
lambda reason: self._on_current_generation(generation, self._on_disconnected, reason)
|
||||
@@ -790,7 +810,7 @@ class LocalTerminalTabWidget(BaseTerminalTab):
|
||||
"Ouvre un gestionnaire de fichiers SFTP sur l'hote de la commande ssh tapee ici"
|
||||
)
|
||||
self.sftp_btn.clicked.connect(
|
||||
lambda: self.sftp_requested.emit(detect_ssh_target(self.terminal.buffer_text()))
|
||||
lambda: self.sftp_requested.emit(self.detect_current_ssh_target())
|
||||
)
|
||||
self.bar.addWidget(self.sftp_btn)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user