def updateParentRepo(self, parentNode, newRepoKey, depth=0): """ Recursively fixes the parentrepo key after a move operation. This will delete all entries which are children of *nodeKey*, except *key* nodeKey. :param parentNode: URL-safe key of the node which children should be fixed. :type parentNode: str :param newNode: URL-safe key of the new repository. :type newNode: strg :param depth: Safety level depth preventing infinitive loops. :type depth: int """ if depth > 99: logging.critical( "Maximum recursion depth reached in server.applications.tree/fixParentRepo" ) logging.critical("Your data is corrupt!") logging.critical("Params: parentNode: %s, newRepoKey: %s" % (parentNode, newRepoKey)) return def fixTxn(nodeKey, newRepoKey): node = db.Get(nodeKey) node["parentrepo"] = newRepoKey db.Put(node) # Fix all nodes for repo in db.Query(self.viewNodeSkel().kindName).filter( "parentdir =", parentNode).iter(keysOnly=True): self.updateParentRepo(str(repo), newRepoKey, depth=depth + 1) db.RunInTransaction(fixTxn, str(repo), newRepoKey) # Fix the leafs on this level for repo in db.Query(self.viewLeafSkel().kindName).filter( "parentdir =", parentNode).iter(keysOnly=True): db.RunInTransaction(fixTxn, str(repo), newRepoKey)
def startProcessing(self, step, orderID): def setTokenTxn(key, token): order = db.Get(key) if not order: return order["paypal_token"] = urllib.unquote(token) db.Put(order) paypal = PayPal.PayPalHandler() key = db.Key(orderID) order = db.Get(key) if not order: return token = paypal.SetExpressCheckout("%.2f" % order["price"]) db.RunInTransaction(setTokenTxn, key, token) raise (errors.Redirect(paypal.getPayURL(token)))
def updateTimeDrift(self, userKey, idx): """ Updates the clock-drift value. The value is only changed in 1/10 steps, so that a late submit by an user doesn't skew it out of bounds. Maximum change per call is 0.3 minutes. :param userKey: For which user should the update occour :param idx: How many steps before/behind was that token :return: """ def updateTransaction(userKey, idx): user = db.Get(userKey) if not "otptimedrift" in user or not isinstance(user["otptimedrift"],float): user["otptimedrift"] = 0.0 user["otptimedrift"] += min(max(0.1*idx,-0.3),0.3) db.Put(user) db.RunInTransaction(updateTransaction, userKey, idx)
def doCheckForUnreferencedBlobs(cursor=None): def getOldBlobKeysTxn(dbKey): obj = db.Get(dbKey) res = obj["old_blob_references"] or [] if obj["is_stale"]: db.Delete(dbKey) else: obj["has_old_blob_references"] = False obj["old_blob_references"] = [] db.Put(obj) return res gotAtLeastOne = False query = db.Query("viur-blob-locks").filter("has_old_blob_references", True).cursor(cursor) for lockKey in query.run(100, keysOnly=True): gotAtLeastOne = True oldBlobKeys = db.RunInTransaction(getOldBlobKeysTxn, lockKey) for blobKey in oldBlobKeys: if db.Query("viur-blob-locks").filter("active_blob_references =", blobKey).get(): #This blob is referenced elsewhere logging.info("Stale blob is still referenced, %s" % blobKey) continue # Add a marker and schedule it for deletion fileObj = db.Query("viur-deleted-files").filter("dlkey", blobKey).get() if fileObj: #Its already marked logging.info("Stale blob already marked for deletion, %s" % blobKey) return fileObj = db.Entity("viur-deleted-files") fileObj["itercount"] = 0 fileObj["dlkey"] = str(blobKey) logging.info("Stale blob marked dirty, %s" % blobKey) db.Put(fileObj) newCursor = query.getCursor() if gotAtLeastOne and newCursor and newCursor.urlsafe() != cursor: doCheckForUnreferencedBlobs(newCursor.urlsafe())
def setState(self, orderKey, state, removeState=False): """ Set a status on the given order. :param orderKey: Key of the order :type orderKey: str :param state: An state out of self.states :type state: str :param removeState: Should the state be removed instead of set :type removeState: bool """ def txn(orderKey, state, removeState): dbObj = db.Get(db.Key(orderKey)) if not dbObj: return dbObj["state_%s" % state] = "1" if not removeState else "0" dbObj["changedate"] = datetime.now() db.Put(dbObj) db.RunInTransaction(txn, orderKey, state, removeState)
def setStatus(key, values=None, check=None, func=None): """ Universal function to set a status within a transaction. :param key: Entity key to change :param values: A dict of key-values to update on the entry :param check: An optional dict of key-values to check on the entry before :param func: A function that is called inside the transaction If the function does not raise, all went well. """ assert isinstance(values, dict), "'values' has to be a dict, you diggi!" def transaction(): obj = db.Get(key) if check: assert isinstance(check, dict), "'check' has to be a dict, you diggi!" assert all([obj[bone] == value for bone, value in check.items()]) if values: for bone, value in values.items(): if bone[0] == "+": obj[bone[1:]] += value elif bone[0] == "-": obj[bone[1:]] -= value else: obj[bone] = value if func and callable(func): func(obj) db.Put(obj) db.RunInTransaction(transaction)