def move(self, nodes: Sequence[str], leafs: Sequence[str], destNode: str) -> str: """Moves elements to the given rootNode/path. :param nodes: Nodes to be removed :type nodes: list :param leafs: leafs to be removed :type leafs: list :param destNode: destination node id :type destNode: str """ request = RequestGroup(finishedHandler=self.delayEmitEntriesChanged) self._requestGroups.append(request) for node in nodes: request.addQuery( NetworkService.request("/%s/move" % self.module, { "key": node, "skelType": "node", "parentNode": destNode }, parent=self, secure=True)) for leaf in leafs: request.addQuery( NetworkService.request("/%s/move" % self.module, { "key": leaf, "skelType": "leaf", "parentNode": destNode }, parent=self, secure=True)) request.queryType = "move" self.checkBusyStatus() return str(id(request))
def deleteEntities(self, keys: Sequence[str]) -> None: def internalDeleteEntity(key): self.pendingDeletes.add(key) if key in self.entryCache: del self.entryCache[key] for k, v in self.queryCache.items(): if key in v["skelkeys"]: v["skelkeys"].remove(key) self.entityDeleted.emit(key) if isinstance(keys, list) and len(keys) > 1: req = RequestGroup(failureHandler=self.delayEmitEntriesChanged) req.addToStatusBar( "Deleting {{total}} Entries from %s" % (self.module), "Finished deleteing {{total}} Entries from %s" % self.module) for key in keys: internalDeleteEntity(key) r = NetworkService.request("/%s/delete" % self.module, {"key": key}, secure=True, parent=req) req.addQuery(r) else: # We just delete one if isinstance(keys, list): keys = keys[0] internalDeleteEntity(keys) NetworkService.request( "/%s/delete/%s" % (self.module, keys), secure=True, successHandler=self.logEntryDeleted, failureHandler=self.delayEmitEntriesChanged).deletedKey = keys self.checkBusyStatus()
def onBtnLoginReleased(self) -> None: self.setDisabled(True) QtGui.QGuiApplication.processEvents() if self.loginTask: self.loginTask.deleteLater() cb = self.ui.cbPortal currentPortalCfg = config.conf.accounts[cb.currentIndex().row()] NetworkService.setup(currentPortalCfg["server"] + "admin") if cb.currentIndex().row() != 0: # Move this account to the beginning, so it will be selected on the next start # of admin account = config.conf.accounts[cb.currentIndex().row()] config.conf.accounts.remove(account) config.conf.accounts.insert(0, account) self.loginTask = LoginTask(currentPortalCfg, parent=self) self.loginTask.loginSucceeded.connect(self.onLoginSucceeded) self.loginTask.loginFailed.connect(self.onLoginFailed) self.overlay.inform( self.overlay.BUSY, QtCore.QCoreApplication.translate("Login", "Login in progress")) if self.helpBrowser: self.helpBrowser.deleteLater() self.helpBrowser = None config.conf.loadPortalConfig(NetworkService.url) # now we're going to test if we're still logged in via restored and valid cookies # or have to start the login task NetworkService.request( "/user/view/self", secure=True, failSilent=True, successHandler=self.onNotLoggedInYet, #self.onSkipAuth, FIXME! failureHandler=self.onNotLoggedInYet)
def reqLogoutCallback(self, clickedBtn): if clickedBtn == self.requestLogoutBox.button( self.requestLogoutBox.Yes): self.setDisabled(True) NetworkService.request("/user/logout", secure=True, successHandler=self.reqLogoutSucceeded) self.requestLogoutBox = None
def loadPreview(self, url: str) -> None: """ Tries to fetch the entry specified by url and shows it on success Take a look in self.setHTML for the view part :param url: the url of the item to preview in our webview """ NetworkService.request(url, successHandler=self.setHTML)
def reparent(self, itemKey: str, destParent: str, sortIndex: int = None) -> None: data = {"key": itemKey, "parentNode": destParent, "skelType": "node"} if sortIndex is not None: data["sortindex"] = sortIndex NetworkService.request( "/%s/move" % self.module, data, True, finishedHandler=self.delayEmitEntriesChanged, parent=self) self.checkBusyStatus()
def startAuthenticating(self) -> None: print("LoginTask using method x-google") logger.debug("LoginTask using method x-google") if self.authThread: self.authThread.abort() # Fetch the HTML-File and extract the ClientID from it NetworkService.request("/user/auth_googleaccount/login", successHandler=self.onClientIDAvailable, failureHandler=self.onError)
def onHtmlBucketUploadFinished(self, *args, **kwargs): # The upload has been written to cloudstore self.stats["filesDone"] += 1 self.stats["bytesDone"] += self.currentHtmlUpload["fileSize"] self.uploadProgress.emit(self.stats["filesDone"], self.stats["filesTotal"]) NetworkService.request( "/file/add", self.currentHtmlUpload, successHandler=self.onHtmlFileModuleUploadFinished, secure=True)
def addCacheData(self, req: RequestWrapper) -> None: data = NetworkService.decode(req) logger.debug("TreeWrapper.addCacheData: %r, %r", req.skelType, req.queryArgs) if req.queryArgs: # This was a custom request key = self.cacheKeyFromFilter(req.node, req.queryArgs) if key not in self.dataCache or not self.dataCache[key]: self.dataCache[key] = [] assert data["action"] == "list" for skel in data["skellist"]: if not skel["key"] in [x["key"] for x in self.dataCache[key]]: skel["_type"] = req.skelType self.dataCache[key].append(skel) self.customQueryFinished.emit(key) cursor = None if "cursor" in data: cursor = data["cursor"] hasChanged = False addedData = list() if data["action"] == "list": if len(data["skellist"]): hasChanged = True for skel in data["skellist"]: skel["_type"] = req.skelType self.dataCache[skel["key"]] = skel addedData.append(skel) # logger.debug("TreeWrapper.addCacheData: %r, %r", skel["name"], req.skelType) if len(data["skellist"] ) == self.batchSize: # There might be more results if "cursor" in data and cursor: # We have a cursor (we can continue this query) # Fetch the next batch tmp = {k: v for k, v in req.queryArgs.items()} tmp["parententry"] = req.node tmp["cursor"] = cursor tmp["skelType"] = req.skelType tmp["amount"] = self.batchSize r = NetworkService.request( "/%s/list" % self.module, tmp, successHandler=self.addCacheData) r.wrapperCacheKey = req.wrapperCacheKey r.skelType = req.skelType r.node = req.node r.queryArgs = req.queryArgs elif data["action"] == "view": skel = data["values"] skel["_type"] = req.skelType self.dataCache[skel["key"]] = skel self.entityAvailable.emit(skel) if self.dataCache.get(req.wrapperCacheKey, False) is None: del self.dataCache[req.wrapperCacheKey] if hasChanged: self.entitiesAppended.emit(req.node, addedData) self.checkBusyStatus()
def startRun(self) -> None: token, isOkay = QtWidgets.QInputDialog.getText(self, "Insert Token", "Token") if not isOkay: self.loginFailed.emit("Aborted") return NetworkService.request("/user/f2_timebasedotp/otp", {"otptoken": token}, secure=True, successHandler=self.onViurAuth, failureHandler=self.onError)
def reqLogoutCallback(self, clickedBtn): if clickedBtn == self.requestLogoutBox.button( self.requestLogoutBox.Yes): NetworkService.request("/user/logout", secure=True, successHandler=self.onNoSession) else: self.ui.statusLbl.setText( "The current user has no access to ViUR Admin - please reload page" ) self.requestLogoutBox = None
def __init__(self, *args: Any, **kwargs: Any): super(TaskViewer, self).__init__(*args, **kwargs) self.ui = Ui_Task() self.ui.setupUi(self) self.overlay = Overlay(self) self.overlay.inform(self.overlay.BUSY) self.tasks = None NetworkService.request("/_tasks/list", secure=True, successHandler=self.onTaskList) self.show()
def delete(self, keys: Union[Sequence[str], str]) -> None: if isinstance(keys, list): req = RequestGroup(finishedHandler=self.delayEmitEntriesChanged) for key in keys: r = NetworkService.request("/%s/delete?skelType=node&key=%s" % (self.module, key), secure=True) req.addQuery(r) else: # We just delete one NetworkService.request( "/%s/delete?skelType=node&key=%s" % (self.module, keys), secure=True, finishedHandler=self.delayEmitEntriesChanged) self.checkBusyStatus()
def tokenReceived(self, token: str): """ Callback from the GoogleAuthenticationHandler. We received a token and now going to exchange it with the server for a session """ if self.authThread: self.authThread.abort() self.authThread = None NetworkService.request("/user/auth_googleaccount/login", {"token": token}, secure=True, successHandler=self.authStatusCallback, failureHandler=self.onError)
def loadConfig(self, request: RequestWrapper = None) -> None: # self.show() self.preloader = Preloader() self.preloader.show() self.preloader.finished.connect(self.onPreloaderFinished) # logger.debug("Checkpoint: loadConfig") NetworkService.request("/user/view/self", successHandler=self.onLoadUser, failureHandler=self.onError) NetworkService.request("/config", successHandler=self.onLoadConfig, failureHandler=self.onError) if self.dockWidget.isFloating(): self.dockWidget.show()
def __init__(self, module: str, *args: Any, **kwargs: Any): super(WidgetHandler, self).__init__(*args, **kwargs) self.module = module config = conf.serverConfig["modules"][module] if config["icon"]: if config["icon"].lower().startswith("http://") or config[ "icon"].lower().startswith("https://"): icon = config["icon"] else: icon = loadIcon(config["icon"]) else: icon = loadIcon("hierarchy") super(HierarchyCoreHandler, self).__init__(lambda: HierarchyWidget(module), sortIndex=config.get("sortIndex", 0), descr=config["name"], icon=icon, vanishOnClose=False, *args, **kwargs) self.repos: List[Dict[str, Any]] = list() self.tmp_obj = QtCore.QObject() fetchTask = NetworkService.request("/%s/listRootNodes" % module, parent=self.tmp_obj) fetchTask.requestSucceeded.connect(self.setRepos)
def parseHelpText(self, txt: str) -> str: """Parses the HTML-Text txt and returns it with remote Images replaced with their local copies @type txt: String @param txt: HTML-Text @return: String """ return txt # FIXME res = "" while txt: idx = txt.find("<img src=") if idx == -1: res += txt return (res) startpos = txt.find("\"", idx + 8) + 1 endpos = txt.find("\"", idx + 13) url = txt[startpos:endpos] res += txt[: startpos] res += getFileNameForUrl(url) # FIXME: BROKEN txt = txt[endpos:] fileName = os.path.join(conf.currentPortalConfigDirectory, sha1(url.encode("UTF-8")).hexdigest()) logger.debug("parseHelpText - url: %r", url) if not os.path.isfile(fileName): try: data = NetworkService.request(url) except: return None open(fileName, "w+b").write(data) return txt
def onTriggered(self) -> None: if self.appType == ApplicationType.LIST: selection = self.parent().getSelection() else: selection = [] if self.config.get("action") == "fetch": req = RequestGroup(parent=self.parent(), finishedHandler=self.reloadParent ) # failureHandler=self.delayEmitEntriesChanged req.addToStatusBar( "%s: {{finished}}/{{total}}" % self.config.get("name"), "Done") for item in selection: url = str(self.config.get("url")).replace( "{{key}}", item["key"]) r = NetworkService.request(url, secure=True, parent=req) req.addQuery(r) elif self.config.get("action") == "open": if not isPyodide: import webbrowser for item in selection: url = str(self.config.get("url")).replace( "{{key}}", item["key"]) webbrowser.open(url) else: import js for item in selection: url = str(self.config.get("url")).replace( "{{key}}", item["key"]) js.window.open(url)
def queryData(self, **kwargs: Any) -> str: key = self.cacheKeyFromFilter(kwargs) if key in self.queryCache: if self.queryCache[key] is None: # We already started querying that key return key #ctime, data, cursor = self.dataCache[key] cacheDict = self.queryCache[key] if cacheDict["ctime"] + self.maxCacheTime > time( ): # This cache-entry is still valid self.deferredTaskQueue.append(("queryResultAvailable", key)) QtCore.QTimer.singleShot(25, self.execDefered) # callback( None, data, cursor ) return key # Its a cache-miss or cache too old self.queryCache[key] = None r = NetworkService.request("/%s/list" % self.module, kwargs, successHandler=self.addCacheData, failureHandler=self.fetchFailed) r.wrapperCbCacheKey = key # THIS IS BROKEN... Remove Busystatus and Loading-Overlay.. #QtCore.QTimer.singleShot(1, lambda: self.checkBusyStatus()) # Prevent #self.checkBusyStatus() return key
def addCacheData(self, req: RequestWrapper) -> None: data = NetworkService.decode(req) cursor = None if "cursor" in data: cursor = data["cursor"] if data["action"] == "list": self.queryCache[req.wrapperCbCacheKey] = { "ctime": time(), "skelkeys": [ x["key"] for x in data["skellist"] if x["key"] not in self.pendingDeletes ], "cursor": cursor } for skel in data["skellist"]: if skel["key"] in self.pendingDeletes: continue self.entryCache[skel["key"]] = skel elif data["action"] == "view": self.entryCache[data["values"]["key"]] = data["values"] self.entityAvailable.emit(data["values"]) if hasattr(req, "wrapperCbCacheKey"): self.queryResultAvailable.emit(req.wrapperCbCacheKey) self.checkBusyStatus()
def addCompletionData(self, req: RequestWrapper) -> None: try: data = NetworkService.decode(req) except ValueError: # Query was canceled return #self.beginResetModel() self.layoutAboutToBeChanged.emit() #self.dataCache = [] initial = not self.dataCache for skel in data["skellist"]: skel["__descr__"] = self.safeEval.execute(self.ast, { "value": {"dest": skel, "rel": None}, "structure": self.structure, "language": config.conf.adminConfig.get("language", "en") }) if self.dataCache: for s in self.dataCache: if s["key"] == skel["key"]: break else: self.dataCache.append(skel) changed = True else: self.dataCache.append(skel) changed = True #self.endResetModel() self.layoutChanged.emit() if initial: self.parent().complete()
def onViurAuth( self, request: RequestWrapper ) -> None: # We received an response to our auth request logger.debug("Checkpoint: onViurAuth") staticSkey = None for headerNameByteArray, headerValueByteArray in request.request.rawHeaderPairs( ): headerName = headerNameByteArray.data().decode("LATIN-1").lower() if headerName == "sec-x-viur-staticskey": staticSkey = headerValueByteArray.data().decode("LATIN-1") break try: res = NetworkService.decode(request) except Exception as err: # Something went wrong logger.error("onViurAuth: Except") self.onError(msg="Unable to decode response!") return logger.debug("onViurAuth: %r", res) if str(res).lower() == "okay": print("onViurAuth: okay") if staticSkey: # Pass the static skey to the securityTokenProvider so it can skip fetching new skeys securityTokenProvider.staticSecurityKey = staticSkey self.loginSucceeded.emit() elif str(res).startswith("X-VIUR-2FACTOR-"): secondFactor = str(res).replace("X-VIUR-2FACTOR-", "") self.secondFactorRequired.emit(secondFactor) else: logger.debug("onViurAuth: else: %r", res) self.onError(msg='Received response != "okay"!')
def onListDir(self, req: RequestWrapper) -> None: if self._cancel: return data = NetworkService.decode(req) if len(data["skellist"]) == 0: # Nothing to do here return if req.ntype == "node": self.remainingRequests += 1 r = RecursiveDownloader(os.path.join(self.localTargetDir, req.dname), [], data["skellist"], self.module, parent=self) r.downloadProgress.connect(self.downloadProgress) r.finished.connect(self.onRequestFinished) self.canceled.connect(r.cancel) else: self.remainingRequests += 1 self.stats["dirsDone"] += 1 self.stats["bytesDone"] += self.directorySize r = RecursiveDownloader(os.path.join(self.localTargetDir, req.dname), data["skellist"], [], self.module, parent=self) r.downloadProgress.connect(self.downloadProgress) r.finished.connect(self.onRequestFinished)
def delayEmitEntriesChanged(self, req: RequestWrapper = None, *args: Any, **kwargs: Any) -> None: """Give GAE a chance to apply recent changes and then force all open views of that module to reload its data :param req: :param args: :param kwargs: :return: """ logger.debug("TreeWrapper.deferredTaskQueue: %r", req) if req is not None: try: logger.debug(NetworkService.decode(req)) except: pass try: self._requestGroups.remove(req) logger.debug("request group removed") except Exception as err: logger.exception(err) logger.error("request group could not be removed") pass QtCore.QTimer.singleShot(self.updateDelay, self.emitEntriesChanged)
def onStructureAvailable(self, req: RequestWrapper) -> None: tmp = NetworkService.decode(req) if tmp is None: self.checkBusyStatus() return for stype, structlist in tmp.items(): structure: OrderedDict = OrderedDict() for k, v in structlist: structure[k] = v if stype == "viewNodeSkel": self.viewNodeStructure = structure elif stype == "viewLeafSkel": self.viewLeafStructure = structure elif stype == "editNodeSkel": self.editNodeStructure = structure elif stype == "editLeafSkel": self.editLeafStructure = structure elif stype == "addNodeSkel": self.addNodeStructure = structure elif stype == "addLeafSkel": self.addLeafStructure = structure else: raise ValueError( "onStructureAvailable: unknown node type: {0}".format( stype)) self.onModulStructureAvailable.emit() self.checkBusyStatus()
def __init__(self, *args: Any, **kwargs: Any): QtWidgets.QMainWindow.__init__(self, *args, **kwargs) self.ui = Ui_simpleLogin() self.ui.setupUi(self) self.ui.loginBtn.clicked.connect(self.onBtnLoginReleased) self.ui.googleLoginBtn.clicked.connect(self.onBtnGoogleLoginReleased) self.setDisabled(True) self.ui.statusLbl.setText("Please login") self.loginTask = None self.ui.label_4.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.pixMap = QtGui.QPixmap(":icons/login.png") self.resizeEvent() NetworkService.request("/user/view/self", successHandler=self.onHasSession, failureHandler=self.onNoSession, failSilent=True)
def onRootNodesAvailable(self, req: RequestWrapper) -> None: tmp = NetworkService.decode(req) if isinstance(tmp, list): self.rootNodes = tmp self.clearCache() self.rootNodesAvailable.emit() self.checkBusyStatus() logger.debug("TreeWrapper.onRootNodesAvailable: %r", tmp)
def editPreflight(self, key: str, node: str, skelType: str, data, callback) -> None: data["bounce"] = "1" data["skey"] = "-" url = "/%s/edit/%s/%s" % (self.module, skelType, key) if key else "/%s/add/%s/%s" % ( self.module, skelType, node) req = NetworkService.request(url, data, finishedHandler=callback)
def onRootNodesAvailable(self, req: RequestWrapper) -> None: tmp = NetworkService.decode(req) if isinstance(tmp, list): self.rootNodes = tmp else: self.rootNodes = [] self.rootNodesAvailable.emit() self.checkBusyStatus()
def validateCurrentPage(self) -> bool: from viur_admin.login import LoginTask, AuthProviderBase if self.forcePageFlip: self.forcePageFlip = False return True currentId = self.currentId() if currentId == 2 and isinstance( self.authProvider, AuthProviderBase) and self.authProvider.advancesAutomatically: return False if currentId == 0: if not self.ui.editTitle.text(): logger.error("AddPortalWizard.validateCurrentPage: no title") return False server = self.ui.editServer.text() if not server or not (server.startswith("http://") or server.startswith("https://")): logger.error( "AddPortalWizard.validateCurrentPage: invalid url") return False if not server.endswith("/"): server += "/" self.currentPortalConfig["server"] = server self.currentPortalConfig["name"] = self.ui.editTitle.text() NetworkService.url = server + "admin" NetworkService.request("/user/getAuthMethods", successHandler=self.onAuthMethodsKnown, failureHandler=self.onError) self.setDisabled(True) return False elif currentId == 1: self.currentPortalConfig["authMethod"] = self.validAuthMethods[ self.ui.cbAuthSelector.currentText()] logger.debug("AddPortalWizard.validateCurrentPage: %r, %r", currentId, self.currentPortalConfig) elif currentId == 2: if isinstance(self.loginTask, LoginTask): self.currentPortalConfig.update( self.loginTask.getUpdatedPortalConfig()) logger.debug("AddPortalWizard.validateCurrentPage: %r, %r", currentId, self.currentPortalConfig) self.loginTask.startAuthenticationFlow() return False return True