def __init__(self, jobs_ctx, claimer): super().__init__() self.setupUi(self) self.claimer = claimer self.jobs_ctx = jobs_ctx self.signify_trust_job = None self.wait_peer_trust_job = None self.get_greeter_sas_job = None self.get_claimer_sas_job = None self.widget_claimer_code.hide() font = self.line_edit_claimer_code.font() font.setBold(True) font.setLetterSpacing(QFont.PercentageSpacing, 180) self.line_edit_claimer_code.setFont(font) self.code_input_widget.good_code_clicked.connect(self._on_good_greeter_code_clicked) self.code_input_widget.wrong_code_clicked.connect(self._on_wrong_greeter_code_clicked) self.code_input_widget.none_clicked.connect(self._on_none_clicked) self.get_greeter_sas_success.connect(self._on_get_greeter_sas_success) self.get_greeter_sas_error.connect(self._on_get_greeter_sas_error) self.get_claimer_sas_success.connect(self._on_get_claimer_sas_success) self.get_claimer_sas_error.connect(self._on_get_claimer_sas_error) self.signify_trust_success.connect(self._on_signify_trust_success) self.signify_trust_error.connect(self._on_signify_trust_error) self.wait_peer_trust_success.connect(self._on_wait_peer_trust_success) self.wait_peer_trust_error.connect(self._on_wait_peer_trust_error) self.get_greeter_sas_job = self.jobs_ctx.submit_job( ThreadSafeQtSignal(self, "get_greeter_sas_success", QtToTrioJob), ThreadSafeQtSignal(self, "get_greeter_sas_error", QtToTrioJob), self.claimer.get_greeter_sas, )
def on_share_clicked(self): user_name = self.line_edit_share.text() if not user_name: return if user_name == self.core.device.user_id: show_info(self, _("TEXT_WORKSPACE_SHARING_CANNOT_SHARE_WITH_YOURSELF")) return for i in range(self.scroll_content.layout().count()): item = self.scroll_content.layout().itemAt(i) if item and item.widget() and item.widget().user == user_name: show_info( self, _("TEXT_WORKSPACE_SHARING_ALREADY_SHARED_user").format(user=user_name) ) return self.jobs_ctx.submit_job( ThreadSafeQtSignal(self, "share_success", QtToTrioJob), ThreadSafeQtSignal(self, "share_error", QtToTrioJob), _do_share_workspace, user_fs=self.user_fs, workspace_fs=self.workspace_fs, user=user_name, role=_index_to_role(self.combo_role.currentIndex()), )
def reencrypt_workspace(self, workspace_id, user_revoked, role_revoked, reencryption_already_in_progress): if workspace_id in self.reencrypting or ( not user_revoked and not role_revoked and not reencryption_already_in_progress): return question = "" if user_revoked: question += "{}\n".format( _("TEXT_WORKSPACE_NEED_REENCRYPTION_BECAUSE_USER_REVOKED")) if role_revoked: question += "{}\n".format( _("TEXT_WORKSPACE_NEED_REENCRYPTION_BECAUSE_USER_REMOVED")) question += _("TEXT_WORKSPACE_NEED_REENCRYPTION_INSTRUCTIONS") r = ask_question( self, _("TEXT_WORKSPACE_NEED_REENCRYPTION_TITLE"), question, [_("ACTION_WORKSPACE_REENCRYPTION_CONFIRM"), _("ACTION_CANCEL")], ) if r != _("ACTION_WORKSPACE_REENCRYPTION_CONFIRM"): return @contextmanager def _handle_fs_errors(): try: yield except FSBackendOfflineError as exc: raise JobResultError(ret=workspace_id, status="offline-backend", origin=exc) except FSWorkspaceNoAccess as exc: raise JobResultError(ret=workspace_id, status="access-error", origin=exc) except FSWorkspaceNotFoundError as exc: raise JobResultError(ret=workspace_id, status="not-found", origin=exc) except FSError as exc: raise JobResultError(ret=workspace_id, status="fs-error", origin=exc) async def _reencrypt(on_progress, workspace_id): with _handle_fs_errors(): if reencryption_already_in_progress: job = await self.core.user_fs.workspace_continue_reencryption( workspace_id) else: job = await self.core.user_fs.workspace_start_reencryption( workspace_id) while True: with _handle_fs_errors(): total, done = await job.do_one_batch() on_progress.emit(workspace_id, total, done) if total == done: break return workspace_id self.reencrypting.add(workspace_id) self.jobs_ctx.submit_job( ThreadSafeQtSignal(self, "workspace_reencryption_success", QtToTrioJob), ThreadSafeQtSignal(self, "workspace_reencryption_error", QtToTrioJob), _reencrypt, on_progress=ThreadSafeQtSignal(self, "workspace_reencryption_progress", EntryID, int, int), workspace_id=workspace_id, )
def on_list_success(self, job): # Hide the spinner in case it was visible self.spinner.hide() workspaces = job.ret # Use temporary dict to update the workspace mapping new_mapping = {} old_mapping = dict(self.workspace_button_mapping) # Loop over the resulting workspaces for workspace_fs, workspace_name, ws_entry, users_roles, files, timestamped in workspaces: # Pop button from existing mapping key = (workspace_fs.workspace_id, getattr(workspace_fs, "timestamp", None)) button = old_mapping.pop(key, None) # Create and bind button if it doesn't exist if button is None: button = WorkspaceButton(workspace_fs) button.clicked.connect(self.load_workspace) if self.core.device.is_outsider: button.button_share.hide() else: button.share_clicked.connect(self.share_workspace) button.reencrypt_clicked.connect(self.reencrypt_workspace) button.delete_clicked.connect(self.delete_workspace) button.rename_clicked.connect(self.rename_workspace) button.remount_ts_clicked.connect(self.remount_workspace_ts) button.open_clicked.connect(self.open_workspace) button.switch_clicked.connect(self._on_switch_clicked) # Apply new state button.apply_state( workspace_name=workspace_name, workspace_fs=workspace_fs, users_roles=users_roles, is_mounted=self.is_workspace_mounted(workspace_fs.workspace_id, None), files=files[:4], timestamped=timestamped, ) # Use this opportunity to trigger the `get_reencryption_needs` routine if button.is_owner: try: self.jobs_ctx.submit_job( ThreadSafeQtSignal(self, "reencryption_needs_success", QtToTrioJob), ThreadSafeQtSignal(self, "reencryption_needs_error", QtToTrioJob), _get_reencryption_needs, workspace_fs=workspace_fs, ) except JobSchedulerNotAvailable: pass # Add the button to the new mapping # Note that the order of insertion matters as it corresponds to the order in which # the workspaces are displayed. new_mapping[key] = button # Set the new mapping self.workspace_button_mapping = new_mapping # Refresh the layout, taking the filtering into account self.refresh_workspace_layout() # Dereference the old buttons for button in old_mapping.values(): button.setParent(None)