def storeEntry(self, e, key): if not self._checkKey(key, export=False): raise errors.Forbidden() entry = pickle.loads(e) for k in list(entry.keys())[:]: if isinstance(entry[k], str): entry[k] = entry[k].decode("UTF-8") if "key" in entry.keys(): key = db.Key(encoded=entry["key"]) elif "id" in entry.keys(): key = db.Key(encoded=entry["id"]) else: raise AttributeError() logging.error(key.kind()) logging.error(key.id()) logging.error(key.name()) dbEntry = db.Entity(kind=key.kind(), parent=key.parent(), id=key.id(), _app=key.app(), name=key.name()) #maybe some more fixes here ? for k in entry.keys(): if k != "key": val = entry[k] #if isinstance(val, dict) or isinstance(val, list): # val = pickle.dumps( val ) dbEntry[k] = val if dbEntry.key().id(): # Ensure the Datastore knows that it's id is in use datastore._GetConnection()._reserve_keys([dbEntry.key()]) db.Put(dbEntry)
def setKeyTxn(orderKey, idx): """Assigns the new order to the given order""" dbObj = db.Get(db.Key(orderKey)) if not dbObj: return dbObj["idx"] = idx db.Put(dbObj)
def sofortStatus(self, *args, **kwargs): sortOrder = [ "transaction", "user_id", "project_id", "sender_holder", "sender_account_number", "sender_bank_code", "sender_bank_name", "sender_bank_bic", "sender_iban", "sender_country_id", "recipient_holder", "recipient_account_number", "recipient_bank_code", "recipient_bank_name", "recipient_bank_bic", "recipient_iban", "recipient_country_id", "international_transaction", "amount", "currency_id", "reason_1", "reason_2", "security_criteria", "user_variable_0", "user_variable_1", "user_variable_2", "user_variable_3", "user_variable_4", "user_variable_5", "created" ] hashstr = "|".join([kwargs[key] for key in sortOrder] + [conf["sofort"]["notificationpassword"]]) if hashlib.sha512( hashstr.encode("utf-8")).hexdigest() != kwargs["hash"]: logging.error( "RECIVED INVALID HASH FOR sofort (%s!=%s)" % (hashlib.sha512( hashstr.encode("utf-8")).hexdigest(), kwargs["hash"])) return ("INVALID HASH") order = db.Get(db.Key(kwargs["user_variable_0"])) if not order: logging.error("RECIVED UNKNOWN ORDER by sofort (%s)" % (kwargs["user_variable_0"])) return ("UNKNOWN ORDER") if ("%.2f" % order["price"]) != kwargs["amount"]: logging.error("RECIVED INVALID AMOUNT PAYED sofort (%s!=%s)" % (order["price"], kwargs["amount"])) return ("INVALID AMOUNT") self.orderHandler.setPayed(kwargs["user_variable_0"]) return ("OKAY")
def storeEntry2(self, e, key): if not self._checkKey(key, export=False): raise errors.Forbidden() entry = pickle.loads(e.decode("HEX")) for k in list(entry.keys())[:]: if isinstance(entry[k], str): entry[k] = entry[k].decode("UTF-8") key = db.Key(encoded=utils.normalizeKey(entry["key"])) logging.info(key.kind()) logging.info(key.id()) logging.info(key.name()) dbEntry = db.Entity(kind=key.kind(), parent=key.parent(), id=key.id(), name=key.name()) #maybe some more fixes here ? for k in entry.keys(): if k != "key": val = entry[k] dbEntry[k] = val db.Put(dbEntry) try: skel = skeletonByKind(key.kind())() except: logging.error("Unknown Skeleton - skipping") skel.fromDB(str(dbEntry.key())) skel.refresh() skel.toDB(clearUpdateTag=True)
def assignBillSequence(self, orderKey): """ Assigns an unique order-order to the given order. """ def getKeyTxn(kindName, orderKey): """Generates and returns a new, unique Key""" seqObj = db.GetOrInsert(kindName, "viur_bill_sequences", count=1000) idx = seqObj["count"] seqObj["count"] += 1 db.Put(seqObj) return str(idx) def setKeyTxn(orderKey, idx): """Assigns the new order to the given order""" dbObj = db.Get(db.Key(orderKey)) if not dbObj: return dbObj["idx"] = idx db.Put(dbObj) dbObj = db.Get(db.Key(orderKey)) if not dbObj: return idx = db.RunInTransaction(getKeyTxn, self.viewSkel().kindName, orderKey) db.RunInTransaction(setKeyTxn, orderKey, idx) self.billSequenceAvailable(orderKey)
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)
def txnDelete(key, skel): dbObj = db.Get(db.Key( key)) # Fetch the raw object as we might have to clear locks for boneName, bone in skel.items(): # Ensure that we delete any value-lock objects remaining for this entry if bone.unique: try: logging.error("x1") logging.error(dbObj.keys()) if "%s.uniqueIndexValue" % boneName in dbObj.keys(): logging.error("x2") db.Delete( db.Key.from_path( "%s_%s_uniquePropertyIndex" % (skel.kindName, boneName), dbObj["%s.uniqueIndexValue" % boneName])) except db.EntityNotFoundError: raise pass # Delete the blob-key lock object try: lockObj = db.Get(db.Key.from_path("viur-blob-locks", str(key))) except: lockObj = None if lockObj is not None: if lockObj["old_blob_references"] is None and lockObj[ "active_blob_references"] is None: db.Delete(lockObj) # Nothing to do here else: if lockObj["old_blob_references"] is None: # No old stale entries, move active_blob_references -> old_blob_references lockObj["old_blob_references"] = lockObj[ "active_blob_references"] elif lockObj["active_blob_references"] is not None: # Append the current references to the list of old & stale references lockObj["old_blob_references"] += lockObj[ "active_blob_references"] lockObj["active_blob_references"] = [ ] # There are no active ones left lockObj["is_stale"] = True lockObj["has_old_blob_references"] = True db.Put(lockObj) db.Delete(db.Key(key))
def normalizeKey(key): """ Normalizes a datastore key (replacing _application with the current one) :param key: Key to be normalized. :return: Normalized key in string representation. """ if key is None: return None key = db.Key(encoded=str(key)) if key.parent(): parent = db.Key(encoded=normalizeKey(key.parent())) else: parent = None return str(db.Key.from_path(key.kind(), key.id_or_name(), parent=parent))
def fromShortKey(key): if isinstance(key, basestring): try: key = db.Key(encoded=key) except: key = unicode(key) if key.isdigit(): key = long(key) key = db.Key.from_path(skel.kindName, key) assert isinstance(key, db.Key) return (key)
def getSofortURL(self, orderID): order = db.Get(db.Key(orderID)) hashstr = "%s|%s|||||%.2f|EUR|%s||%s||||||%s" % ( conf["sofort"]["userid"], conf["sofort"]["projectid"], float(order["price"]), str(order.key()), str( order.key()), conf["sofort"]["projectpassword"]) hash = hashlib.sha512(hashstr.encode("UTF-8")).hexdigest() returnURL = "https://www.sofortueberweisung.de/payment/start?user_id=%s&project_id=%s&amount=%.2f¤cy_id=EUR&reason_1=%s&user_variable_0=%s&hash=%s" % ( conf["sofort"]["userid"], conf["sofort"]["projectid"], float(order["price"]), str(order.key()), str(order.key()), hash) return (returnURL)
def _rewriteQuery(self, name, skel, dbFilter, rawFilter): """ Rewrites a datastore query to operate on "viur-relations" instead of the original kind. This is needed to perform relational queries on n:m relations. """ origFilter = dbFilter.datastoreQuery origSortOrders = dbFilter.getOrders() if isinstance(origFilter, db.MultiQuery): raise NotImplementedError( "Doing a relational Query with multiple=True and \"IN or !=\"-filters is currently unsupported!" ) dbFilter.datastoreQuery = type(dbFilter.datastoreQuery)( "viur-relations") #skel.kindName+"_"+self.kind+"_"+name dbFilter.filter("viur_src_kind =", skel.kindName) dbFilter.filter("viur_dest_kind =", self.kind) dbFilter.filter("viur_src_property", name) if dbFilter._origCursor: #Merge the cursor in again (if any) dbFilter.cursor(dbFilter._origCursor) if origFilter: for k, v in origFilter.items(): #Merge old filters in #Ensure that all non-relational-filters are in parentKeys if k == "__key__": # We must process the key-property separately as its meaning changes as we change the datastore kind were querying if isinstance(v, list) or isinstance(v, tuple): logging.warning( "Invalid filtering! Doing an relational Query on %s with multiple key= filters is unsupported!" % (name)) raise RuntimeError() if not isinstance(v, db.Key): v = db.Key(v) dbFilter.ancestor(v) continue if not (k if "." not in k else k.split(".")[0]) in self.parentKeys: logging.warning( "Invalid filtering! %s is not in parentKeys of RelationalBone %s!" % (k, name)) raise RuntimeError() dbFilter.filter("src.%s" % k, v) orderList = [] for k, d in origSortOrders: #Merge old sort orders in if not k in self.parentKeys: logging.warning( "Invalid filtering! %s is not in parentKeys of RelationalBone %s!" % (k, name)) raise RuntimeError() orderList.append(("src.%s" % k, d)) if orderList: dbFilter.order(*orderList) return (name, skel, dbFilter, rawFilter)
def filterHook(self, name, query, param, value): #FIXME """ Hook installed by buildDbFilter. This rewrites all filters added to the query after buildDbFilter has been run to match the layout of our viur-relations index. Also performs sanity checks wherever this query is possible at all. """ if param.startswith("src.") or param.startswith( "dest.") or param.startswith("viur_"): #This filter is already valid in our relation return (param, value) if param.startswith("%s." % name): #We add a constrain filtering by properties of the referenced entity refKey = param.replace("%s." % name, "") if " " in refKey: #Strip >, < or = params refKey = refKey[:refKey.find(" ")] if refKey not in self.refKeys: logging.warning( "Invalid filtering! %s is not in refKeys of RelationalBone %s!" % (refKey, name)) raise RuntimeError() if self.multiple: return (param.replace("%s." % name, "dest."), value) else: return (param, value) else: #We filter by a property of this entity if not self.multiple: #Not relational, not multiple - nothing to do here return (param, value) #Prepend "src." srcKey = param if " " in srcKey: srcKey = srcKey[:srcKey.find(" ")] #Cut <, >, and = if srcKey == "__key__": #Rewrite key= filter as its meaning has changed if isinstance(value, list) or isinstance(value, tuple): logging.warning( "Invalid filtering! Doing an relational Query on %s with multiple key= filters is unsupported!" % (name)) raise RuntimeError() if not isinstance(value, db.Key): value = db.Key(value) query.ancestor(value) return (None) if srcKey not in self.parentKeys: logging.warning( "Invalid filtering! %s is not in parentKeys of RelationalBone %s!" % (srcKey, name)) raise RuntimeError() return ("src.%s" % param, value)
def calculateOrderSum(self, step, orderKey, *args, **kwargs): """ Calculates the final price for this order. This function *must* be called before any attempt is made to start a payment process. :param step: Current step within the ordering process :type step: int :param orderKey: order to calculate the price for :type orderKey: str """ price = sum([x[3] for x in self.getBillItems(orderKey)]) orderObj = db.Get(db.Key(str(orderKey))) orderObj["price"] = price db.Put(orderObj)
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 relSkelFromKey(key): if not isinstance(key, db.Key): key = db.Key(encoded=key) if not key.kind() == self.kind: logging.error( "I got a key, which kind doesn't match my type! (Got: %s, my type %s)" % (key.kind(), self.kind)) return None entity = db.Get(key) if not entity: logging.error("Key %s not found" % str(key)) return None relSkel = RefSkel.fromSkel(skeletonByKind(self.kind), *self.refKeys) relSkel.unserialize(entity) return relSkel
def fromDB(self, key): """ Load entity with *key* from the data store into the Skeleton. Reads all available data of entity kind *kindName* and the key *key* from the data store into the Skeleton structure's bones. Any previous data of the bones will discard. To store a Skeleton object to the data store, see :func:`~server.skeleton.Skeleton.toDB`. :param key: A :class:`server.DB.Key`, :class:`server.DB.Query`, or string,\ from which the data shall be fetched. :type key: server.DB.Key | DB.Query | str :returns: True on success; False if the given key could not be found. :rtype: bool """ if isinstance(key, basestring): try: key = db.Key(key) except db.BadKeyError: key = unicode(key) if key.isdigit(): key = long(key) elif not len(key): raise ValueError("fromDB called with empty key!") key = db.Key.from_path(self.kindName, key) if not isinstance(key, db.Key): raise ValueError( "fromDB expects an db.Key instance, an string-encoded key or a long as argument, got \"%s\" instead" % key) if key.kind() != self.kindName: # Wrong Kind return (False) try: dbRes = db.Get(key) except db.EntityNotFoundError: return (False) if dbRes is None: return (False) self.setValues(dbRes) key = str(dbRes.key()) self["key"] = key return (True)
def getStates(self, orderKey): """ Returns the states currently set for the given order. :param orderKey: Key of the order :type orderKey: str :returns: States of the given order. :rtype: list of str """ dbObj = db.Get(db.Key(orderKey)) res = [] if not dbObj: return res for state in self.states: stateName = "state_%s" % state if stateName in dbObj and str(dbObj[stateName]) == "1": res.append(state) return res
def shortKey(key): try: return str(db.Key(encoded=key).id_or_name()) except: return key
def txnUpdate(key, mergeFrom, clearUpdateTag): blobList = set() skel = type(mergeFrom)() # Load the current values from Datastore or create a new, empty db.Entity if not key: dbObj = db.Entity(skel.kindName) oldBlobLockObj = None else: k = db.Key(key) assert k.kind() == skel.kindName, "Cannot write to invalid kind!" try: dbObj = db.Get(k) except db.EntityNotFoundError: dbObj = db.Entity(k.kind(), id=k.id(), name=k.name(), parent=k.parent()) else: skel.setValues(dbObj) try: oldBlobLockObj = db.Get(db.Key.from_path("viur-blob-locks", str(k))) except: oldBlobLockObj = None # Remember old hashes for bones that must have an unique value oldUniqeValues = {} for boneName, boneInstance in skel.items(): if boneInstance.unique: if "%s.uniqueIndexValue" % boneName in dbObj: oldUniqeValues[boneName] = dbObj["%s.uniqueIndexValue" % boneName] ## Merge the values from mergeFrom in for key, bone in skel.items(): if key in mergeFrom: bone.mergeFrom(skel.valuesCache, key, mergeFrom) for key, _bone in skel.items(): dbObj = _bone.serialize(skel.valuesCache, key, dbObj) blobList.update(_bone.getReferencedBlobs(self.valuesCache, key)) if clearUpdateTag: dbObj["viur_delayed_update_tag"] = 0 # Mark this entity as Up-to-date. else: dbObj[ "viur_delayed_update_tag"] = time() # Mark this entity as dirty, so the background-task will catch it up and update its references. dbObj = skel.preProcessSerializedData(dbObj) try: ourKey = str(dbObj.key()) except: # Its not an update but an insert, no key yet ourKey = None # Lock hashes from bones that must have unique values newUniqeValues = {} for boneName, boneInstance in skel.items(): if boneInstance.unique: # Check if the property is really unique newUniqeValues[boneName] = boneInstance.getUniquePropertyIndexValue( self.valuesCache, boneName) if newUniqeValues[boneName] is not None: try: lockObj = db.Get(db.Key.from_path( "%s_%s_uniquePropertyIndex" % (skel.kindName, boneName), newUniqeValues[boneName])) if lockObj["references"] != ourKey: # This value has been claimed, and that not by us raise ValueError( "The unique value '%s' of bone '%s' has been recently claimed!" % (self.valuesCache[boneName], boneName)) except db.EntityNotFoundError: # No lockObj found for that value, we can use that pass dbObj["%s.uniqueIndexValue" % boneName] = newUniqeValues[boneName] else: if "%s.uniqueIndexValue" % boneName in dbObj: del dbObj["%s.uniqueIndexValue" % boneName] if not skel.searchIndex: # We generate the searchindex using the full skel, not this (maybe incomplete one) tags = [] for key, _bone in skel.items(): if _bone.searchable: tags += [tag for tag in _bone.getSearchTags(self.valuesCache, key) if (tag not in tags and len(tag) < 400)] dbObj["viur_tags"] = tags db.Put(dbObj) # Write the core entry back # Now write the blob-lock object blobList = skel.preProcessBlobLocks(blobList) if blobList is None: raise ValueError( "Did you forget to return the bloblist somewhere inside getReferencedBlobs()?") if None in blobList: raise ValueError("None is not a valid blobKey.") if oldBlobLockObj is not None: oldBlobs = set(oldBlobLockObj["active_blob_references"] if oldBlobLockObj[ "active_blob_references"] is not None else []) removedBlobs = oldBlobs - blobList oldBlobLockObj["active_blob_references"] = list(blobList) if oldBlobLockObj["old_blob_references"] is None: oldBlobLockObj["old_blob_references"] = [x for x in removedBlobs] else: tmp = set(oldBlobLockObj["old_blob_references"] + [x for x in removedBlobs]) oldBlobLockObj["old_blob_references"] = [x for x in (tmp - blobList)] oldBlobLockObj["has_old_blob_references"] = oldBlobLockObj[ "old_blob_references"] is not None and len( oldBlobLockObj["old_blob_references"]) > 0 oldBlobLockObj["is_stale"] = False db.Put(oldBlobLockObj) else: # We need to create a new blob-lock-object blobLockObj = db.Entity("viur-blob-locks", name=str(dbObj.key())) blobLockObj["active_blob_references"] = list(blobList) blobLockObj["old_blob_references"] = [] blobLockObj["has_old_blob_references"] = False blobLockObj["is_stale"] = False db.Put(blobLockObj) for boneName, boneInstance in skel.items(): if boneInstance.unique: # Update/create/delete missing lock-objects if boneName in oldUniqeValues and oldUniqeValues[boneName] != \ newUniqeValues[boneName]: # We had an old lock and its value changed try: # Try to delete the old lock oldLockObj = db.Get(db.Key.from_path( "%s_%s_uniquePropertyIndex" % (skel.kindName, boneName), oldUniqeValues[boneName])) if oldLockObj["references"] != ourKey: # We've been supposed to have that lock - but we don't. # Don't remove that lock as it now belongs to a different entry logging.critical( "Detected Database corruption! A Value-Lock had been reassigned!") else: # It's our lock which we don't need anymore db.Delete(db.Key.from_path( "%s_%s_uniquePropertyIndex" % ( skel.kindName, boneName), oldUniqeValues[boneName])) except db.EntityNotFoundError as e: logging.critical( "Detected Database corruption! Could not delete stale lock-object!") if newUniqeValues[boneName] is not None: # Lock the new value newLockObj = db.Entity( "%s_%s_uniquePropertyIndex" % (skel.kindName, boneName), name=newUniqeValues[boneName]) newLockObj["references"] = str(dbObj.key()) db.Put(newLockObj) return (str(dbObj.key()), dbObj, skel)
def fromClient(self, valuesCache, name, data): """ Reads a value from the client. If this value is valid for this bone, store this value and return None. Otherwise our previous value is left unchanged and an error-message is returned. :param name: Our name in the skeleton :type name: String :param data: *User-supplied* request-data :type data: Dict :returns: None or String """ #from server.skeleton import RefSkel, skeletonByKind oldValues = valuesCache.get(name, None) valuesCache[name] = [] tmpRes = {} clientPrefix = "%s." % name for k, v in data.items(): if k.startswith(clientPrefix) or k == name: if k == name: k = k.replace(name, "", 1) else: k = k.replace(clientPrefix, "", 1) if "." in k: try: idx, bname = k.split(".", 1) idx = int(idx) except ValueError: # We got some garbarge as input; don't try to parse it continue elif k.isdigit() and self.using is None: idx = int(k) bname = "key" elif self.using is None and not self.multiple: idx = 0 bname = "key" else: continue if not idx in tmpRes: tmpRes[idx] = {} if bname in tmpRes[idx]: if isinstance(tmpRes[idx][bname], list): tmpRes[idx][bname].append(v) else: tmpRes[idx][bname] = [tmpRes[idx][bname], v] else: tmpRes[idx][bname] = v tmpList = [(k, v) for k, v in tmpRes.items() if "key" in v] tmpList.sort(key=lambda k: k[0]) tmpList = [{ "reltmp": v, "dest": { "key": v["key"] } } for k, v in tmpList] errorDict = {} forceFail = False if not tmpList and self.required: return "No value selected!" for r in tmpList[:]: # Rebuild the referenced entity data isEntryFromBackup = False #If the referenced entry has been deleted, restore information from entry = None try: entry = db.Get(db.Key(r["dest"]["key"])) except: #Invalid key or something like thatmnn logging.info( "Invalid reference key >%s< detected on bone '%s'", r["dest"]["key"], name) if isinstance(oldValues, dict): if oldValues["dest"]["key"] == str(r["dest"]["key"]): refSkel = self._refSkelCache refSkel.setValuesCache(oldValues["dest"]) entry = refSkel.serialize() isEntryFromBackup = True elif isinstance(oldValues, list): for dbVal in oldValues: if dbVal["dest"]["key"] == str(r["dest"]["key"]): refSkel = self._refSkelCache refSkel.setValuesCache(dbVal["dest"]) entry = refSkel.serialize() isEntryFromBackup = True if not isEntryFromBackup: if not self.multiple: #We can stop here :/ return ("Invalid entry selected") else: tmpList.remove(r) continue if not entry or ( not isEntryFromBackup and not entry.key().kind() == self.kind ): #Entry does not exist or has wrong type (is from another module) if entry: logging.error( "I got a key, which kind doesn't match my type! (Got: %s, my type %s)" % (entry.key().kind(), self.kind)) tmpList.remove(r) continue tmp = { k: entry[k] for k in entry.keys() if (k in self.refKeys or any([k.startswith("%s." % x) for x in self.refKeys])) } tmp["key"] = r["dest"]["key"] relSkel = self._refSkelCache relSkel.setValuesCache({}) relSkel.unserialize(tmp) r["dest"] = relSkel.getValuesCache() # Rebuild the refSkel data if self.using is not None: refSkel = self._usingSkelCache refSkel.setValuesCache({}) if not refSkel.fromClient(r["reltmp"]): for k, v in refSkel.errors.items(): errorDict["%s.%s.%s" % (name, tmpList.index(r), k)] = v forceFail = True r["rel"] = refSkel.getValuesCache() else: r["rel"] = None del r["reltmp"] if self.multiple: cleanList = [] for item in tmpList: err = self.isInvalid(item) if err: errorDict["%s.%s" % (name, tmpList.index(item))] = err else: cleanList.append(item) if not cleanList: errorDict[name] = "No value selected" valuesCache[name] = tmpList else: if tmpList: val = tmpList[0] else: val = None err = self.isInvalid(val) if not err: valuesCache[name] = val if val is None: errorDict[name] = "No value selected" if len(errorDict.keys()): return ReadFromClientError(errorDict, forceFail)
def postDeletedHandler(self, skel, key, id): db.Delete([ x for x in db.Query("viur-relations").ancestor(db.Key(id)).run( keysOnly=True) ])
def postSavedHandler(self, valuesCache, boneName, skel, key, dbfields): if not valuesCache[boneName]: values = [] elif isinstance(valuesCache[boneName], dict): values = [dict((k, v) for k, v in valuesCache[boneName].items())] else: values = [ dict((k, v) for k, v in x.items()) for x in valuesCache[boneName] ] parentValues = {} for parentKey in dbfields.keys(): if parentKey in self.parentKeys or any( [parentKey.startswith(x + ".") for x in self.parentKeys]): parentValues[parentKey] = dbfields[parentKey] dbVals = db.Query("viur-relations").ancestor( db.Key(key)) #skel.kindName+"_"+self.kind+"_"+key dbVals.filter("viur_src_kind =", skel.kindName) dbVals.filter("viur_dest_kind =", self.kind) dbVals.filter("viur_src_property =", boneName) for dbObj in dbVals.iter(): try: if not dbObj["dest.key"] in [x["dest"]["key"] for x in values ]: #Relation has been removed db.Delete(dbObj.key()) continue except: #This entry is corrupt db.Delete(dbObj.key()) else: # Relation: Updated data = [ x for x in values if x["dest"]["key"] == dbObj["dest.key"] ][0] if self.indexed: #We dont store more than key and kinds, and these dont change #Write our (updated) values in refSkel = self._refSkelCache refSkel.setValuesCache(data["dest"]) for k, v in refSkel.serialize().items(): dbObj["dest." + k] = v for k, v in parentValues.items(): dbObj["src." + k] = v if self.using is not None: usingSkel = self._usingSkelCache usingSkel.setValuesCache(data["rel"]) for k, v in usingSkel.serialize().items(): dbObj["rel." + k] = v dbObj["viur_delayed_update_tag"] = time() db.Put(dbObj) values.remove(data) # Add any new Relation for val in values: dbObj = db.Entity( "viur-relations", parent=db.Key(key)) #skel.kindName+"_"+self.kind+"_"+key if not self.indexed: #Dont store more than key and kinds, as they aren't used anyway dbObj["dest.key"] = val["dest"]["key"] dbObj["src.key"] = key else: refSkel = self._refSkelCache refSkel.setValuesCache(val["dest"]) for k, v in refSkel.serialize().items(): dbObj["dest." + k] = v for k, v in parentValues.items(): dbObj["src." + k] = v if self.using is not None: usingSkel = self._usingSkelCache usingSkel.setValuesCache(val["rel"]) for k, v in usingSkel.serialize().items(): dbObj["rel." + k] = v dbObj["viur_delayed_update_tag"] = time() dbObj[ "viur_src_kind"] = skel.kindName #The kind of the entry referencing #dbObj[ "viur_src_key" ] = str( key ) #The key of the entry referencing dbObj[ "viur_src_property"] = boneName #The key of the bone referencing #dbObj[ "viur_dest_key" ] = val["key"] dbObj["viur_dest_kind"] = self.kind db.Put(dbObj)
def iterImport(module, target, exportKey, cursor=None, amount=0): """ Processes 100 Entries and calls the next batch """ urlfetch.set_default_fetch_deadline(20) payload = {"module": module, "key": exportKey} if cursor: payload.update({"cursor": cursor}) result = urlfetch.fetch( url=target, payload=urllib.urlencode(payload), method=urlfetch.POST, headers={'Content-Type': 'application/x-www-form-urlencoded'}) if result.status_code == 200: res = pickle.loads(result.content.decode("HEX")) skel = skeletonByKind(module)() logging.info("%s: %d new entries fetched, total %d entries fetched" % (module, len(res["values"]), amount)) if len(res["values"]) == 0: try: utils.sendEMailToAdmins( "Import of kind %s finished with %d entities" % (module, amount), "ViUR finished to import %d entities of " "kind %s from %s.\n" % (amount, module, target)) except: #OverQuota, whatever logging.error("Unable to send Email") return for entry in res["values"]: for k in list(entry.keys())[:]: if isinstance(entry[k], str): entry[k] = entry[k].decode("UTF-8") if not "key" in entry.keys(): entry["key"] = entry["id"] key = db.Key(encoded=utils.normalizeKey(entry["key"])) # Special case: Convert old module root nodes!!! if module.endswith( "_rootNode") and key.name() and "_modul_" in key.name(): name = key.name().replace("_modul_", "_module_") else: name = key.name() dbEntry = db.Entity(kind=key.kind(), parent=key.parent(), id=key.id(), name=name) for k in entry.keys(): if k == "key": continue dbEntry[k] = entry[k] # Special case: Convert old module root nodes!!! if (isinstance(skel, (HierarchySkel, TreeLeafSkel)) and k in ["parentdir", "parententry", "parentrepo"] and entry[k]): key = db.Key(encoded=str(entry[k])) if key.parent(): parent = db.Key( encoded=utils.normalizeKey(key.parent())) else: parent = None if key.id_or_name() and "_modul_" in str(key.id_or_name()): name = key.id_or_name().replace("_modul_", "_module_") else: name = key.id_or_name() dbEntry[k] = str( db.Key.from_path(key.kind(), name, parent=parent)) db.Put(dbEntry) skel.fromDB(str(dbEntry.key())) skel.refresh() skel.toDB(clearUpdateTag=True) amount += 1 iterImport(module, target, exportKey, res["cursor"], amount)
def checkout(self, step=None, key=None, skey=None, *args, **kwargs): """ Performs the checkout process trough the state machine provided by self.steps. :param step: The current step index, None for beginning a new checkout :param key: Key of the current checkout :param skey: Server security key :return: Returns the rendered template or throws redirection exceptions. """ myKindName = self.viewSkel().kindName if step is None: logging.info("Starting new checkout process") billObj = db.Entity(myKindName) billObj["idx"] = "0000000" for state in self.states: billObj["state_%s" % state] = "0" db.Put(billObj) key = str(billObj.key()) #Copy the Cart if "amountSkel" in dir(self): cart = session.current.get("cart_products") or {} s = self.amountSkel() products = [] for prod, atts in cart.items(): for i in range(0, atts["amount"]): products.append(str(prod)) s.fromClient({"product": products}) s.toDB() session.current["order_" + myKindName] = { "key": str(key), "completedSteps": [] } session.current.markChanged() raise errors.Redirect("?step=0&key=%s" % str(key)) elif key: try: orderKey = db.Key(key) step = int(step) assert (step >= 0) assert (step < len(self.steps)) except: raise errors.NotAcceptable() sessionInfo = session.current.get("order_" + myKindName) if not sessionInfo or not sessionInfo.get("key") == str(orderKey): raise errors.Unauthorized() if step in sessionInfo["completedSteps"]: session.current["order_" + myKindName]["completedSteps"] = [ x for x in sessionInfo["completedSteps"] if x < step ] session.current.markChanged() #Make sure that no steps can be skipped if step != 0 and not step - 1 in sessionInfo["completedSteps"]: raise errors.Redirect("?step=0&key=%s" % str(str(orderKey))) currentStep = self.steps[step] if "preHandler" in currentStep.keys(): try: if isinstance(currentStep["preHandler"], list): for handler in currentStep["preHandler"]: handler(self, step, str(orderKey), *args, **kwargs) else: currentStep["preHandler"](self, step, str(orderKey), refkwargs=kwargs, *args, **kwargs) except SkipStepException: session.current["order_" + myKindName]["completedSteps"].append(step) session.current.markChanged() raise errors.Redirect("?step=%s&key=%s" % (str(step + 1), str(orderKey))) except ReturnHtmlException as e: return (e.html) if "requiresSecurityKey" in currentStep and currentStep[ "requiresSecurityKey"]: if not securitykey.validate(skey): raise errors.PreconditionFailed() pass if "mainHandler" in currentStep: if currentStep["mainHandler"]["action"] == "edit": skel = self.getSkelByName( currentStep["mainHandler"]["skeleton"], str(orderKey)) skel.fromDB(str(orderKey)) if not len(kwargs.keys()) or not skel.fromClient(kwargs): return (self.render.edit( skel, tpl=currentStep["mainHandler"]["template"], step=step)) skel.toDB() if currentStep["mainHandler"]["action"] == "view": if not "complete" in kwargs or not kwargs[ "complete"] == u"1": skel = self.getSkelByName( currentStep["mainHandler"]["skeleton"], str(orderKey)) skel.fromDB(str(orderKey)) return (self.render.view( skel, tpl=currentStep["mainHandler"]["template"], step=step)) elif currentStep["mainHandler"]["action"] == "function": res = currentStep["mainHandler"]["function"](self, step, str(orderKey), *args, **kwargs) if res: return res if "postHandler" in currentStep: currentStep["postHandler"](self, step, str(orderKey), *args, **kwargs) session.current["order_" + myKindName]["completedSteps"].append(step) session.current.markChanged() logging.info("next ?step=%s&key=%s" % (str(step + 1), str(orderKey))) raise errors.Redirect("?step=%s&key=%s" % (str(step + 1), str(orderKey)))