def resetPushButtonPressed(self, button): # create an object for PersepolisDB persepolis_db = PersepolisDB() # Reset data base persepolis_db.resetDataBase() # close connections persepolis_db.closeConnections() # Reset persepolis_setting persepolis_setting = QSettings('persepolis_download_manager', 'persepolis') persepolis_setting.clear() persepolis_setting.sync()
class MainController(QObject): def __init__(self, app: QApplication, model: MainModel): # initialize settings self.env_settings = QSettings() self.app = app self.model = model self.view = None self.sync_controller = None self.file_controller = None self.remote_file_controller = None self.settings_controller = None self.notification_controller = None self.watcher = None self.algoritmo = None def start(self): # Create main window self.model.remote_file_model.set_network_model( self.model.network_model) self.view = MainWindow(self.model) self.view.show() # Creazione delle View principali self.sync_controller = SyncController( self.model.sync_model, self.view.main_widget.sync_widget) self.file_controller = FileController( self.model.file_model, self.view.main_widget.files_widget) self.remote_file_controller = RemoteFileController( self.model, self.view.main_widget.remote_widget) self.settings_controller = SettingsController( self.model, self.view.main_widget.settings_view) self.notification_controller = NotificationController( self.app, self.view) # ALGORITMO self.algoritmo = DecisionEngine(self.model, self.notification_controller) self.algoritmo.Sg_toggle_files_update.connect( self.file_controller.Sl_toggle_files_update) self.file_controller._view.force_sync_button.clicked.connect( self.algoritmo.Sl_model_changed) self.algoritmo.start() self.model.settings_model.Sg_model_changed.connect( self.algoritmo.Sl_model_changed) # Attivo il watchdog nella root definita dall'utente self.watcher = Watcher() self.watcher.run(True) # Controllo se l'algoritmo era acceso l'ultima volta self.Sl_sync_model_changed() self.model.sync_model.Sg_model_changed.connect( self.Sl_sync_model_changed) # Ripristino il riavvio di watchdog, quando cambio path self.model.settings_model.Sg_model_path_changed.connect( self.Sl_path_updated) # Connect segnali watchdog self.watcher.signal_event.connect( self.model.file_model.Sl_update_model) self.watcher.signal_event.connect( self.view.main_widget.settings_view.set_quota_disk_widget. Sl_model_changed) # Connect per cambiare le viste self.view.main_widget.Sg_switch_to_files.connect( self.Sl_switch_to_files) self.view.main_widget.Sg_switch_to_remote.connect( self.Sl_switch_to_remote) self.view.main_widget.Sg_switch_to_settings.connect( self.Sl_switch_to_settings) @Slot() def Sl_path_updated(self): self.env_settings.sync() self.watcher.reboot() @Slot() def Sl_sync_model_changed(self): state = self.model.sync_model.get_state() self.algoritmo.set_running(state) @Slot() def Sl_switch_to_files(self): self.view.main_widget.chage_current_view_to_files() @Slot() def Sl_switch_to_remote(self): self.view.main_widget.chage_current_view_to_remote() @Slot() def Sl_switch_to_settings(self): self.view.main_widget.chage_current_view_to_settings()
class SettingsModel(QObject): Sg_model_changed = Signal() Sg_model_path_changed = Signal() __model = None __create_key = object() @classmethod def get_instance(cls): if SettingsModel.__model is None: SettingsModel.__model = SettingsModel(cls.__create_key) return SettingsModel.__model def __init__(self, create_key): assert (create_key == SettingsModel.__create_key), \ "SettingsModel objects must be created using SettingsModel.get_instance()" super(SettingsModel, self).__init__(None) self.env_settings = QSettings() def get_policy(self) -> Policy: return Policy(settings.get_policy()) def set_policy(self, new_policy: Policy) -> None: settings.update_policy(new_policy.value) self.Sg_model_changed.emit() def get_path(self) -> Optional[str]: return self.env_settings.value("sync_path") def set_path(self, new_path: str) -> None: self.env_settings.setValue("sync_path", new_path) self.env_settings.sync() self.Sg_model_changed.emit() self.Sg_model_path_changed.emit() def set_sync_time(self, new_sync_time: int) -> None: settings.update_sync_time(new_sync_time) self.Sg_model_changed.emit() def get_sync_time(self) -> int: return settings.get_sync_time() def get_quota_disco_raw(self) -> float: """Ritorna il valore grezzo""" return settings.get_quota_disco() def get_quota_disco(self) -> str: """Ritorna il valore con la sua unità adatta""" return self.convert_size(settings.get_quota_disco()) def set_quota_disco(self, new_quota: bitmath.Byte) -> None: # TODO: Il controllo non dovremmo farlo nel controller? folder_size = bitmath.parse_string(self.convert_size(self.get_size())) free_disk = bitmath.parse_string( self.convert_size(self.get_free_disk())) # Controllo che la nuova quota sia minore dello spazio disponibile nell'hdd # e maggiore dello spazio utilizzato dalla cartella corrente if folder_size <= new_quota <= free_disk: settings.update_quota_disco(str(new_quota.value)) self.Sg_model_changed.emit() def get_free_disk(self) -> int: mem = psutil.disk_usage('/') return mem.free @staticmethod def convert_size(size_bytes: int) -> str: if size_bytes == 0: return "0 B" size_name = ("Byte", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB") i = int(math.floor(math.log(size_bytes, 1024))) p = math.pow(1024, i) s = round(size_bytes / p, 2) return "%s %s" % (s, size_name[i]) def get_quota_libera(self) -> float: return self.get_quota_disco_raw() - self.get_size() def get_size(self) -> int: total_size = 0 if not self.get_path(): return 0 for dirpath, dirnames, filenames in os.walk(self.get_path()): for f in filenames: fp = os.path.join(dirpath, f) # skip if it is symbolic link if not os.path.islink(fp): total_size += os.path.getsize(fp) return total_size def get_sync_list(self) -> list: return settings.get_sync_list() def is_id_in_sync_list(self, id: str) -> bool: return id in settings.get_sync_list() def add_id_to_sync_list(self, id: str) -> None: """Aggiungi id a whitelist""" id_list = settings.get_sync_list() if not self.is_id_in_sync_list(id): id_list.append(id) settings.update_sync_list(id_list) self.Sg_model_changed.emit() def remove_id_from_sync_list(self, id: str) -> None: """Rimuovi id da whitelist""" id_list = settings.get_sync_list() if self.is_id_in_sync_list(id): id_list.remove(id) settings.update_sync_list(id_list) self.Sg_model_changed.emit()
class NetworkModel(QObject, Api, metaclass=NetworkMeta): logger = logging.getLogger("NetworkModel") __model = None status: Status = Status.Ok Sg_model_changed = Signal() Sg_logout = Signal() # error signals Sg_login_failed = Signal() Sg_connection_failed = Signal() Sg_server_failed = Signal() __create_key = object() @classmethod def get_instance(cls): if NetworkModel.__model is None: NetworkModel.__model = NetworkModel(cls.__create_key) return NetworkModel.__model def __init__(self, create_key): assert (create_key == NetworkModel.__create_key), \ "NetworkModel objects must be created using NetworkModel.get_instance()" super(NetworkModel, self).__init__(None) super(Api, self).__init__() self.api_implementation = ApiImplementation() self.env_settings = QSettings() self.lock = Lock() def raise_for_status(self): if self.status == Status.Error: raise APIException() @APIExceptionsHandler def login(self, user: str = "", password: str = "") -> None: NetworkModel.logger.info("try to login...") user = user if user else self.env_settings.value("Credentials/user") password = password if password else self.env_settings.value( "Credentials/password") self.api_implementation.login(user, password) NetworkModel.logger.info("login successful") # save to Qsettings NetworkModel.logger.info("saving credentials") self.env_settings.setValue("Credentials/user", user) self.env_settings.setValue("Credentials/password", password) self.env_settings.sync() self.Sg_model_changed.emit() @APIExceptionsHandler @RetryLogin def get_info_from_email(self) -> dict[str, str]: self.lock.acquire() try: return self.api_implementation.get_info_from_email() finally: self.lock.release() @APIExceptionsHandler @RetryLogin def get_user_id(self) -> str: self.lock.acquire() try: return self.api_implementation.get_user_id() finally: self.lock.release() @APIExceptionsHandler @RetryLogin def is_logged(self) -> bool: return self.api_implementation.is_logged() def get_username(self) -> str: user = self.env_settings.value("Credentials/user") return user if user else "" def get_password(self) -> str: password = self.env_settings.value("Credentials/password") return password if password else "" @APIExceptionsHandler @RetryLogin def logout(self) -> bool: self.lock.acquire() try: if self.api_implementation.logout(): self.message = "" self.env_settings.setValue("Credentials/user", None) self.env_settings.setValue("Credentials/password", None) return True return False finally: self.lock.release() @RetryLogin def download_node(self, node: TreeNode, path_folder: str, quota_libera: float) -> dict: remote_node = self.api_implementation.get_content_from_node( node.get_payload().id) file_size = remote_node["getNode"]["size"] # Se ho spazio procedo al download if quota_libera > file_size: result = self.api_implementation.download_node(node, path_folder) return { "node_name": node.get_name(), "result": result, "type": "network_error" if not result else "" } return { "node_name": node.get_name(), "result": False, "type": "space_error" } @RetryLogin def upload_node(self, node: TreeNode, parent_folder_id: str) -> None: self.api_implementation.upload_node(node, parent_folder_id) @RetryLogin def delete_node(self, node_id: str) -> None: self.lock.acquire() try: self.api_implementation.delete_node(node_id) finally: self.lock.release() @RetryLogin def get_content_from_node(self, node_id: str = "LOCAL_ROOT") -> str: self.lock.acquire() try: return self.api_implementation.get_content_from_node(node_id) finally: self.lock.release() @RetryLogin def create_folder(self, folder_name: str, parent_folder_id: str = "LOCAL_ROOT") -> str: self.lock.acquire() try: return self.api_implementation.create_folder( folder_name, parent_folder_id) finally: self.lock.release()
env_settings = QSettings() # env_settings.setValue("sync_path", None) # env_settings.setValue("Credentials/user", None) # env_settings.setValue("Credentials/password", None) # Controlliamo se l'utente ha già settato il PATH della cartella check_path = env_settings.value("sync_path") if not check_path or not os.path.isdir(check_path): dialog = QFileDialog() dialog.setFileMode(QFileDialog.Directory) dialog.setViewMode(QFileDialog.Detail) # provare anche .List dialog.setOption(QFileDialog.ShowDirsOnly) dialog.setOption(QFileDialog.DontResolveSymlinks) # L'utente non ha selezionato la cartella if not dialog.exec(): env_settings.setValue("sync_path", None) app.quit() sync_path = dialog.selectedFiles() if len(sync_path) == 1: env_settings.setValue("sync_path", sync_path[0]) env_settings.sync() print("Nuova directory: " + env_settings.value("sync_path")) model = MainModel() controller = MainController(app, model) login_controller = LoginController(model, controller) sys.exit(app.exec())
# persepolis --clear >> remove config_folder if args.clear: from persepolis.scripts.data_base import PersepolisDB # create an object for PersepolisDB persepolis_db = PersepolisDB() # Reset data base persepolis_db.resetDataBase() # close connections persepolis_db.closeConnections() # Reset persepolis_setting persepolis_setting.clear() persepolis_setting.sync() sys.exit(0) # persepolis --default >> remove persepolis setting. if args.default: persepolis_setting.clear() persepolis_setting.sync() print('Persepolis restored default') sys.exit(0) if args.link: add_link_dictionary['link'] = "".join(args.link) # if plugins call persepolis, then just start persepolis in system tray args.tray = True