def key_for_namespace(cls, namespace):
        """Return the Key for a namespace.

    Args:
      namespace: A string giving the namespace whose key is requested.

    Returns:
      The Key for the namespace.
    """
        if namespace:
            return model.Key(cls.KIND_NAME, namespace)
        else:
            return model.Key(cls.KIND_NAME, cls.EMPTY_NAMESPACE_ID)
示例#2
0
    def get(self, name):
        NOT_SET_VALUE = u'!!!__ NOT SET __!!!'

        entity = self(key=model.Key(self, name))
        entity.populate(value=NOT_SET_VALUE)
        txn = lambda: entity.put() if not entity.key.get() else entity.key
        retval = model.transaction(txn).get()

        # Fall back to environment vars
        if retval.value == NOT_SET_VALUE:
            fallback_value = environ.get(name)
            if fallback_value is not None:
                retval.value = fallback_value
                retval.put()
                return fallback_value

        if retval.value == NOT_SET_VALUE:
            logging.error(
                ('%s %s not found in the database. A placeholder ' +
                 'record has been created. Go to the Developers Console '
                 'for your app in App Engine, look up the Settings record '
                 'with name=%s and enter its value in that record\'s value '
                 'field.') % (self.__name__, name, name))

        return retval.value
示例#3
0
    def delete_multi(cls, values):
        """Deletes multiple unique values at once.

        :param values:
            A sequence of values to be deleted.
        """
        return model.delete_multi(model.Key(cls, v) for v in values)
示例#4
0
    def create_multi(cls, values):
        """Creates multiple unique values at once.

        :param values:
            A sequence of values to be unique. See :meth:`create`.
        :returns:
            A tuple (bool, list_of_keys). If all values were created, bool is
            True and list_of_keys is empty. If one or more values weren't
            created, bool is False and the list contains all the values that
            already existed in datastore during the creation attempt.
        """
        # Maybe do a preliminary check, before going for transactions?
        # entities = model.get_multi(keys)
        # existing = [entity.key.id() for entity in entities if entity]
        # if existing:
        #    return False, existing

        # Create all records transactionally.
        keys = [model.Key(cls, value) for value in values]
        entities = [cls(key=key) for key in keys]
        func = lambda e: e.put() if not e.key.get() else None
        created = [model.transaction(lambda: func(e)) for e in entities]

        if created != keys:
            # A poor man's "rollback": delete all recently created records.
            model.delete_multi(k for k in created if k)
            return False, [k.id() for k in keys if k not in created]

        return True, []
示例#5
0
    def remove_unique(cls, auth_id, unique_properties, **user_values):
        uniques = [('%s.auth_id:%s' % (cls.__name__, auth_id), 'auth_id')]
        print uniques
        if unique_properties:
            for name in unique_properties:
                key = '%s.%s:%s' % (cls.__name__, name, user_values[name])
                uniques.append((key, name))

        # Delete the uniques
        ndb.delete_multi(model.Key(cls.unique_model, k) for k, v in uniques)
 def get_multi_async(cls, blob_keys, **ctx_options):
     """Async version of get_multi()."""
     for blob_key in blob_keys:
         if not isinstance(blob_key, (BlobKey, six.string_types)):
             raise TypeError('Expected blob key, got %r' % (blob_key, ))
     if 'parent' in ctx_options:
         raise TypeError('Parent is not supported')
     blob_key_strs = list(map(str, blob_keys))
     keys = [model.Key(BLOB_INFO_KIND, id) for id in blob_key_strs]
     return model.get_multi_async(keys, **ctx_options)
    def key_for_entity_group(cls, key):
        """Return the key for the entity group containing key.

    Args:
      key: a key for an entity group whose __entity_group__ key you want.

    Returns:
      The __entity_group__ key for the entity group containing key.
    """
        return model.Key(cls.KIND_NAME, cls.ID, parent=key.root())
    def key_for_kind(cls, kind):
        """Return the __property__ key for kind.

    Args:
      kind: kind whose key is requested.

    Returns:
      The parent key for __property__ keys of kind.
    """
        return model.Key(Kind.KIND_NAME, kind)
    def key_for_kind(cls, kind):
        """Return the __kind__ key for kind.

    Args:
      kind: kind whose key is requested.

    Returns:
      The key for kind.
    """
        return model.Key(cls.KIND_NAME, kind)
    def key_for_property(cls, kind, property):
        """Return the __property__ key for property of kind.

    Args:
      kind: kind whose key is requested.
      property: property whose key is requested.

    Returns:
      The key for property of kind.
    """
        return model.Key(Kind.KIND_NAME, kind, Property.KIND_NAME, property)
示例#11
0
def send_live_message(key):
    """Deferred task for sending messages to the open channels."""
    
    message_key = model.Key(urlsafe=key)
    message = message_key.get()
    
    if message is None:
        return
    
    # Only notify rescent connections
    timestamp = datetime.datetime.now()
    oldest = timestamp - datetime.timedelta(hours=2)
    
    connections = Connection.query().filter(Connection.timestamp >= oldest).fetch(200, keys_only=True)
    
    for connection in connections:
        channel.send_message(connection.id(), message.to_json())
示例#12
0
    def get_key(cls, user, subject, token):
        """Returns a token key.

        :param user:
            User unique ID.
        :param subject:
            The subject of the key. Examples:

            - 'auth'
            - 'signup'
        :param token:
            Randomly generated token.
        :returns:
            ``model.Key`` containing a string id in the following format:
            ``{user_id}.{subject}.{token}.``
        """
        return model.Key(cls, '%s.%s.%s' % (str(user), subject, token))
示例#13
0
 def add_commit(cls, key):
     commit_key = model.Key(urlsafe=key)
     commit = commit_key.get()
     parent_key = commit_key.parent()
     if parent_key is None:
         return
     
     parent = parent_key.get()
     
     picture_url = getattr(parent, 'picture_url', '/static/images/spread_the_word_button.png')
     
     message = cls(username=parent.username, 
         picture_url=picture_url, message=commit.message[:200], url=commit.url,
         project=commit.project, commit_hash=commit.hash)
     message.put()
     
     deferred.defer(send_live_message, message.key.urlsafe(), _queue="live")
     return message
示例#14
0
    def create(cls, value):
        """Creates a new unique value.

        :param value:
            The value to be unique, as a string.

            The value should include the scope in which the value must be
            unique (ancestor, namespace, kind and/or property name).

            For example, for a unique property `email` from kind `User`, the
            value can be `User.email:[email protected]`. In this case `User.email`
            is the scope, and `[email protected]` is the value to be unique.
        :returns:
            True if the unique value was created, False otherwise.
        """
        entity = cls(key=model.Key(cls, value))
        txn = lambda: entity.put() if not entity.key.get() else None
        return model.transaction(txn) is not None
示例#15
0
    def get_by_auth_token(cls, user_id, token):
        """Returns a user object based on a user ID and token.

        :param user_id:
            The user_id of the requesting user.
        :param token:
            The token string to be verified.
        :returns:
            A tuple ``(User, timestamp)``, with a user object and
            the token timestamp, or ``(None, None)`` if both were not found.
        """
        token_key = cls.token_model.get_key(user_id, 'auth', token)
        user_key = model.Key(cls, user_id)
        # Use get_multi() to save a RPC call.
        valid_token, user = model.get_multi([token_key, user_key])
        if valid_token and user:
            timestamp = int(time.mktime(valid_token.created.timetuple()))
            return user, timestamp

        return None, None
示例#16
0
    def create_user(cls, auth_id, unique_properties=None, **user_values):
        """Creates a new user (calls the original webapp2.auth.User.create_user. However, when the user
            creation fails due to an exception (e.g. when a required property isn't provided), we'll clean up
            and delete any unique properties created alongside the user model."""
        try:
            # Call original create_user method
            return super(User, cls).create_user(auth_id, unique_properties, **user_values)

        except Exception, exc:
            # Since the original create_user method calls user.put() (where the exception occurs), only *after*
            # calling cls.unique_model.create_multi(k for k, v in uniques), this means we'll have to delete
            # those created uniques (other they'll just stay as garbage data in the DB, while not allowing
            # the user to re-register with the same username/email/etc.
            uniques = [('%s.auth_id:%s' % (cls.__name__, auth_id), 'auth_id')]
            if unique_properties:
                for name in unique_properties:
                    key = '%s.%s:%s' % (cls.__name__, name, user_values[name])
                    uniques.append((key, name))

            # Delete the uniques
            ndb.delete_multi(model.Key(cls.unique_model, k) for k,v in uniques)

            # Continue throwing the original exception
            raise exc
示例#17
0
 def set(self, name, inputValue):
     entity = self(key=model.Key(self, name))
     entity.populate(value=inputValue)
     entity.put()
示例#18
0
    def put(self, entity, **ctx_options):
        options = _make_ctx_options(ctx_options)

        key = entity._key
        if key is None:

            key = model.Key(entity.__class__, None)
        use_datastore = self._use_datastore(key, options)
        use_memcache = None
        memcache_deadline = None

        if entity._has_complete_key():
            use_memcache = self._use_memcache(key, options)
            if use_memcache:

                memcache_deadline = self._get_memcache_deadline(options)
                mkey = self._memcache_prefix + key.urlsafe()
                ns = key.namespace()
                if use_datastore:
                    yield self.memcache_set(mkey,
                                            _LOCKED,
                                            time=_LOCK_TIME,
                                            namespace=ns,
                                            use_cache=True,
                                            deadline=memcache_deadline)
                else:
                    pbs = entity._to_pb(
                        set_key=False).SerializePartialToString()

                    if len(pbs) > memcache.MAX_VALUE_SIZE:
                        raise ValueError(
                            'Values may not be more than %d bytes in length; '
                            'received %d bytes' %
                            (memcache.MAX_VALUE_SIZE, len(pbs)))
                    timeout = self._get_memcache_timeout(key, options)
                    yield self.memcache_set(mkey,
                                            pbs,
                                            time=timeout,
                                            namespace=ns,
                                            deadline=memcache_deadline)

        if use_datastore:
            key = yield self._put_batcher.add(entity, options)
            if not isinstance(self._conn,
                              datastore_rpc.TransactionalConnection):
                if use_memcache is None:
                    use_memcache = self._use_memcache(key, options)
                if use_memcache:
                    mkey = self._memcache_prefix + key.urlsafe()
                    ns = key.namespace()

                    yield self.memcache_delete(mkey,
                                               namespace=ns,
                                               deadline=memcache_deadline)

        if key is not None:
            if entity._key != key:
                logging.info('replacing key %s with %s', entity._key, key)
                entity._key = key

            if self._use_cache(key, options):

                self._cache[key] = entity

        raise tasklets.Return(key)