Пример #1
0
    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()
Пример #2
0
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()
Пример #3
0
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()
Пример #4
0
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()
Пример #5
0
    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())
Пример #6
0
# 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