From 081baa52467a2b8eaac6ae44feedad5f31d41fe2 Mon Sep 17 00:00:00 2001 From: "N0\\A" Date: Fri, 24 Oct 2025 19:39:19 +0200 Subject: [PATCH] RECEIVING FILES WORKS --- core/dukto.py | 38 +++++++++++++++++++--------- main.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 16 deletions(-) diff --git a/core/dukto.py b/core/dukto.py index 1f11d65..35b1d77 100644 --- a/core/dukto.py +++ b/core/dukto.py @@ -234,6 +234,10 @@ class DuktoProtocol: def _receive_files(self, conn: socket.socket, sender_ip: str): self.is_receiving = True + # Define the receive directory + receive_dir = Path.home() / "Received" + receive_dir.mkdir(parents=True, exist_ok=True) + if self.on_receive_start: self.on_receive_start(sender_ip) @@ -279,16 +283,24 @@ class DuktoProtocol: # Find unique name i = 2 original_name = name - while os.path.exists(name): - name = f"{original_name} ({i})" + dest_path = receive_dir / name + while dest_path.exists(): + dest_path = receive_dir / f"{original_name} ({i})" i += 1 + root_folder_name = original_name - root_folder_renamed = name - received_files.append(name) + root_folder_renamed = dest_path.name + + final_path = dest_path + received_files.append(str(final_path)) + elif root_folder_name != root_folder_renamed: name = name.replace(root_folder_name, root_folder_renamed, 1) + final_path = receive_dir / name + else: + final_path = receive_dir / name - os.makedirs(name, exist_ok=True) + final_path.mkdir(parents=True, exist_ok=True) elif name == "___DUKTO___TEXT___": # Text transfer receiving_text = True @@ -308,21 +320,23 @@ class DuktoProtocol: self.on_transfer_progress(total_size, total_received) else: # Regular file + dest_name = name if '/' in name and name.split('/')[0] == root_folder_name: - name = name.replace(root_folder_name, root_folder_renamed, 1) + dest_name = dest_name.replace(root_folder_name, root_folder_renamed, 1) # Find unique filename i = 2 - original_name = name - base_path = Path(name) - while os.path.exists(name): - name = f"{base_path.stem} ({i}){base_path.suffix}" + original_path = receive_dir / dest_name + dest_path = original_path + while dest_path.exists(): + dest_path = original_path.with_name(f"{original_path.stem} ({i}){original_path.suffix}") i += 1 - received_files.append(name) + received_files.append(str(dest_path)) + dest_path.parent.mkdir(parents=True, exist_ok=True) # Receive file data - with open(name, 'wb') as f: + with open(dest_path, 'wb') as f: received = 0 while received < element_size: chunk = conn.recv(min(8192, element_size - received)) diff --git a/main.py b/main.py index ae31d44..ba7999c 100644 --- a/main.py +++ b/main.py @@ -319,7 +319,15 @@ class WebSearchResults(QtWidgets.QDialog): class MainWindow(QtWidgets.QMainWindow): show_menu_signal = QtCore.Signal() + + # Dukto signals receive_request_signal = QtCore.Signal(str) + progress_update_signal = QtCore.Signal(int, int) + receive_start_signal = QtCore.Signal(str) + receive_complete_signal = QtCore.Signal(list, int) + receive_text_signal = QtCore.Signal(str, int) + dukto_error_signal = QtCore.Signal(str) + def __init__(self, dukto_handler, restart=False, no_quit=False, super_menu=True): super().__init__() @@ -347,8 +355,23 @@ class MainWindow(QtWidgets.QMainWindow): self.super_menu = super_menu self.dukto_handler = dukto_handler - self.dukto_handler.on_receive_request = self.on_dukto_receive_request + self.progress_dialog = None + + # Connect Dukto callbacks to emit signals + self.dukto_handler.on_receive_request = lambda ip: self.receive_request_signal.emit(ip) + self.dukto_handler.on_transfer_progress = lambda total, rec: self.progress_update_signal.emit(total, rec) + self.dukto_handler.on_receive_start = lambda ip: self.receive_start_signal.emit(ip) + self.dukto_handler.on_receive_complete = lambda files, size: self.receive_complete_signal.emit(files, size) + self.dukto_handler.on_receive_text = lambda text, size: self.receive_text_signal.emit(text, size) + self.dukto_handler.on_error = lambda msg: self.dukto_error_signal.emit(msg) + + # Connect signals to GUI slots self.receive_request_signal.connect(self.show_receive_confirmation) + self.progress_update_signal.connect(self.update_progress_dialog) + self.receive_start_signal.connect(self.handle_receive_start) + self.receive_complete_signal.connect(self.handle_receive_complete) + self.receive_text_signal.connect(self.handle_receive_text) + self.dukto_error_signal.connect(self.handle_dukto_error) self.tray = QtWidgets.QSystemTrayIcon(self) self.tray.setIcon(QtGui.QIcon(str(ASSET))) @@ -423,9 +446,6 @@ class MainWindow(QtWidgets.QMainWindow): def toggle_visible(self): self.setVisible(not self.isVisible()) - def on_dukto_receive_request(self, sender_ip: str): - self.receive_request_signal.emit(sender_ip) - def show_receive_confirmation(self, sender_ip: str): reply = QtWidgets.QMessageBox.question( self, @@ -439,6 +459,47 @@ class MainWindow(QtWidgets.QMainWindow): else: self.dukto_handler.reject_transfer() + @QtCore.Slot(str) + def handle_receive_start(self, sender_ip: str): + self.progress_dialog = QtWidgets.QProgressDialog("Receiving file...", "Cancel", 0, 100, self) + self.progress_dialog.setWindowTitle(f"Receiving from {sender_ip}") + self.progress_dialog.setWindowModality(QtCore.Qt.WindowModal) # type: ignore + self.progress_dialog.show() + + @QtCore.Slot(int, int) + def update_progress_dialog(self, total_size: int, received: int): + if self.progress_dialog: + self.progress_dialog.setMaximum(total_size) + self.progress_dialog.setValue(received) + + @QtCore.Slot(list, int) + def handle_receive_complete(self, received_files: list, total_size: int): + if self.progress_dialog: + self.progress_dialog.setValue(total_size) + self.progress_dialog.close() + self.progress_dialog = None + + QtWidgets.QMessageBox.information(self, "Transfer Complete", f"Successfully received {len(received_files)} items to ~/Received.") + + # Open the directory + receive_dir = str(Path.home() / "Received") + url = QtCore.QUrl.fromLocalFile(receive_dir) + QtGui.QDesktopServices.openUrl(url) + + @QtCore.Slot(str, int) + def handle_receive_text(self, text: str, total_size: int): + if self.progress_dialog: + self.progress_dialog.close() + self.progress_dialog = None + QtWidgets.QMessageBox.information(self, "Text Received", text) + + @QtCore.Slot(str) + def handle_dukto_error(self, error_msg: str): + if self.progress_dialog: + self.progress_dialog.close() + self.progress_dialog = None + QtWidgets.QMessageBox.critical(self, "Transfer Error", error_msg) + def start_app_launcher(self): self.app_launcher_dialog = AppLauncherDialog(self) self.app_launcher_dialog.move(QtGui.QCursor.pos())