Exemplo n.º 1
0
 def _array_op(self, op, arrName, vals):
     """ array operations 
     If the array corresponding to arrName is an array of pointers,
     vals must be an array of ParseObjects. WARNING! This will
     set the current array to the 1 returned, which only has objectId.
     """
     # format vals to pointers if it is an array of objects
     arr_ptrs = "_" + arrName.upper() 
     
     array_not_none = getattr(self, arrName) is not None
     
     if self.__dict__[arrName] is None:
         self.__dict__[arrName] = []
     
     if arr_ptrs in self.__dict__:
         vals = [ format_pointer(val.__class__.__name__, val.objectId) for\
             val in vals ]
        
     if array_not_none: # array is not null/None
         res = parse("PUT", self.path() + '/' + self.objectId, 
             {arrName: {'__op':op, 'objects':vals} })
             
     else: # array does not exist. initialize it here.
         res = parse("PUT", self.path() + '/' + self.objectId, 
             {arrName:vals })
             
     if res and 'error' not in res:
         self.update_locally(res, False)
         return True
         
     return False 
Exemplo n.º 2
0
    def _array_op(self, op, arrName, vals):
        """ array operations 
        If the array corresponding to arrName is an array of pointers,
        vals must be an array of ParseObjects. WARNING! This will
        set the current array to the 1 returned, which only has objectId.
        """
        # format vals to pointers if it is an array of objects
        arr_ptrs = "_" + arrName.upper()

        array_not_none = getattr(self, arrName) is not None

        if self.__dict__[arrName] is None:
            self.__dict__[arrName] = []

        if arr_ptrs in self.__dict__:
            vals = [ format_pointer(val.__class__.__name__, val.objectId) for\
                val in vals ]

        if array_not_none:  # array is not null/None
            res = parse("PUT",
                        self.path() + '/' + self.objectId,
                        {arrName: {
                            '__op': op,
                            'objects': vals
                        }})

        else:  # array does not exist. initialize it here.
            res = parse("PUT",
                        self.path() + '/' + self.objectId, {arrName: vals})

        if res and 'error' not in res:
            self.update_locally(res, False)
            return True

        return False
Exemplo n.º 3
0
def pointer_query(dst_class,
                  dst_class_where,
                  dst_class_key,
                  dst_class_key_class,
                  dst_class_key_where,
                  dst_class_key_where_exclude=False,
                  count=False,
                  order="createdAt",
                  limit=900,
                  skip=0):
    if dst_class_key_where_exclude:
        x = "$notInQuery"
    else:
        x = "$inQuery"
    where = {
        # this is how queries are done to Pointer types
        dst_class_key: {
            x: {
                "where": query(dst_class_key_where, where_only=True),
                "className": dst_class_key_class,
                # inner limit applies!
                "limit": 990,
            }
        }
    }

    if dst_class_where:
        where.update(query(dst_class_where, where_only=True))
    if count:
        res = parse("GET",
                    "classes" + "/" + dst_class,
                    query={
                        "where": json.dumps(where),
                        "count": 1,
                        "limit": 0,
                    })
        if 'error' not in res:
            return res['count']
        # May occur if the class or the relation column does not yet exist
        return 0

    res = parse("GET",
                "classes" + "/" + dst_class,
                query={
                    "where": json.dumps(where),
                    "limit": limit,
                    "order": order,
                    "skip": skip,
                })

    if 'error' not in res:
        return res

    # May occur if the class or the relation column does not yet exist
    return None
Exemplo n.º 4
0
 def _relation_op(self, op, relAttrName, objectIds):
     """
     Helper function for add and remove relations.
     """
     if relAttrName not in self.__dict__:
         return False
     className = getattr(self, relAttrName)
     if className == USER_CLASS:
         className = "_User"
     objs = []
     for oid in objectIds:
         objs.append( { "__type": "Pointer",
                        "className": className,
                        "objectId": oid } )
     res = parse("PUT", self.path() + "/" + self.objectId, {
                 relAttrName[:-1]: {
                     "__op": op,
                     "objects": objs, 
                 }
              } )
     if res and 'error' not in res:
         cacheAttrName = relAttrName[0].lower() + relAttrName[1:-1]
         self.__dict__[cacheAttrName] = None
         return True
     else:
         return False
Exemplo n.º 5
0
 def _relation_op(self, op, relAttrName, objectIds):
     """
     Helper function for add and remove relations.
     """
     if relAttrName not in self.__dict__:
         return False
     className = getattr(self, relAttrName)
     if className == USER_CLASS:
         className = "_User"
     objs = []
     for oid in objectIds:
         objs.append({
             "__type": "Pointer",
             "className": className,
             "objectId": oid
         })
     res = parse("PUT",
                 self.path() + "/" + self.objectId,
                 {relAttrName[:-1]: {
                      "__op": op,
                      "objects": objs,
                  }})
     if res and 'error' not in res:
         cacheAttrName = relAttrName[0].lower() + relAttrName[1:-1]
         self.__dict__[cacheAttrName] = None
         return True
     else:
         return False
Exemplo n.º 6
0
def pointer_query(dst_class, dst_class_where, dst_class_key,
        dst_class_key_class, dst_class_key_where,
        dst_class_key_where_exclude=False, count=False,
        order="createdAt", limit=900, skip=0):
    if dst_class_key_where_exclude:
        x = "$notInQuery"
    else:
        x = "$inQuery"
    where = {
                # this is how queries are done to Pointer types
                dst_class_key:{
                    x:{
                        "where":query(dst_class_key_where,
                                    where_only=True),
                        "className": dst_class_key_class,
                        # inner limit applies!
                        "limit":990, 
                    }
                }      
            }
            
    if dst_class_where:
        where.update(query(dst_class_where, where_only=True))
    if count:
        res = parse("GET", "classes" + "/" + dst_class, query={
            "where":json.dumps(where), "count":1, "limit":0,
        })
        if 'error' not in res:
            return res['count']
        # May occur if the class or the relation column does not yet exist
        return 0
        
    res = parse("GET", "classes" + "/" + dst_class, query={
        "where":json.dumps(where), 
        "limit":limit, "order":order, "skip":skip,
    })
    
    if 'error' not in res:
        return res
        
    # May occur if the class or the relation column does not yet exist
    return None
Exemplo n.º 7
0
    def count(self, **constraints):
        """ 
        returns the number of objects that matches the constraints
        """
        constraints["count"] = 1
        constraints["limit"] = 0
        res = parse("GET", self.path, query=query(constraints))

        if res and 'count' in res:
            return res['count']

        return 0
Exemplo n.º 8
0
    def count(self, **constraints):
        """ 
        returns the number of objects that matches the constraints
        """
        constraints["count"] = 1
        constraints["limit"] = 0
        res = parse("GET", self.path, query=query(constraints) )

        if res and 'count' in res:
            return res['count']

        return 0
Exemplo n.º 9
0
    def create(self):
        """ 
        Override to trim the cc_number before storing
        """
        data = self._get_formatted_data()
        self._trim_cc_number()
        res = parse('POST', self.path(), data)
        if res and "error" not in res:
            self.update_locally(res, True)
            return True

        return False
Exemplo n.º 10
0
    def fetch_all(self, clear_first=False, with_cache=True):
        """
        Gets all of this object's data from parse and update all
        of its value locally. This includes pulling each pointer for
        caching.
        
        If clear_first, sets all non-BUILTINS in __dict__ to None.
            - note that cache attrs are also set to None
        If with_cache, retrieves all the cache attributes.
        """
        if clear_first:
            keys = self.__dict__.keys()
            for key in keys:
                if key not in ParseObject.BUILTINS:
                    self.__dict__[key] = None

        if with_cache:
            cache_attrs = ""
            # fill up the Pointer cache attributes and array of pointers
            for key in self.__dict__.iterkeys():
                if key[0].isupper() and not key.endswith("_") and\
                    not key == "ACL":
                    cache_attrs = cache_attrs + key + ","

            if len(cache_attrs) > 0:
                res = parse("GET",
                            self.path() + "/" + self.objectId,
                            query={"include": cache_attrs})
            else:
                res = parse("GET", self.path() + "/" + self.objectId)

        else:
            res = parse("GET", self.path() + "/" + self.objectId)

        if res and "error" not in res:
            self.update_locally(res, False)
            return True

        return False
Exemplo n.º 11
0
 def increment(self, attr, amount):
     """
     increments this object's attribute by amount.
     Attribute must be an integer!
     """
     res = parse("PUT", self.path() + "/" + self.objectId, {
             attr: {
              "__op": "Increment",
              "amount": amount } })
     if res and "error" not in res:
         self.set(attr, self.__dict__.get(attr) + amount)
         return True
     return False
Exemplo n.º 12
0
 def fetch_all(self, clear_first=False, with_cache=True):
     """
     Gets all of this object's data from parse and update all
     of its value locally. This includes pulling each pointer for
     caching.
     
     If clear_first, sets all non-BUILTINS in __dict__ to None.
         - note that cache attrs are also set to None
     If with_cache, retrieves all the cache attributes.
     """
     if clear_first:
         keys = self.__dict__.keys()
         for key in keys:
             if key not in ParseObject.BUILTINS:
                 self.__dict__[key] = None
                 
     if with_cache:
         cache_attrs = ""
         # fill up the Pointer cache attributes and array of pointers
         for key in self.__dict__.iterkeys():
             if key[0].isupper() and not key.endswith("_") and\
                 not key == "ACL":
                 cache_attrs = cache_attrs + key + ","
         
         if len(cache_attrs) > 0:
             res = parse("GET", self.path() + "/" + self.objectId,
                 query={ "include": cache_attrs })
         else:
             res = parse("GET", self.path() + "/" + self.objectId)
     
     else:
         res = parse("GET", self.path() + "/" + self.objectId)
         
     if res and "error" not in res:
         self.update_locally(res, False)
         return True
         
     return False
Exemplo n.º 13
0
    def update(self):
        """ 
        Override to trim the cc_number before storing
        """
        # get the formated data to be put in the request
        self._trim_cc_number()
        data = self._get_formatted_data()

        res = parse("PUT", self.path() + "/" + self.objectId, data)
        if res and "error" not in res:
            self.update_locally(res, True)
            return True

        return False
Exemplo n.º 14
0
 def increment(self, attr, amount):
     """
     increments this object's attribute by amount.
     Attribute must be an integer!
     """
     res = parse("PUT",
                 self.path() + "/" + self.objectId,
                 {attr: {
                     "__op": "Increment",
                     "amount": amount
                 }})
     if res and "error" not in res:
         self.set(attr, self.__dict__.get(attr) + amount)
         return True
     return False
Exemplo n.º 15
0
    def filter(self, **constraints):
        """ 
        Returns the list of objects that matches the constraints.
        
        See WHERE_OPTIONS for all currently supported options.
        Double underscores allow for usage of WHERE_OPTIONS like 
        gte (greater than or equal to). 
        """
        res = parse("GET", self.path, query=query(constraints))

        if res and "results" in res:
            objs = []
            for data in res['results']:
                objs.append(self.cls(**data))
            return objs

        return []
Exemplo n.º 16
0
    def filter(self, **constraints):
        """ 
        Returns the list of objects that matches the constraints.
        
        See WHERE_OPTIONS for all currently supported options.
        Double underscores allow for usage of WHERE_OPTIONS like 
        gte (greater than or equal to). 
        """
        res = parse("GET", self.path, query=query(constraints))

        if res and "results" in res:
            objs = []
            for data in res['results']:
                objs.append(self.cls(**data))     
            return objs
        
        return [] 
Exemplo n.º 17
0
    def update(self):
        """ Save changes to this object to the Parse DB.
        Returns True if update is successful. 
        
        Handles Pointers to other objects. If the pointer changed,
        then the cache corresponding to the attr is set to None.
        Relations are not handled by update. Use add_relation
        for Relations.
        """
        # get the formated data to be put in the request
        data = self._get_formatted_data()
        res = parse("PUT", self.path() + "/" + self.objectId, data)
        if res and "error" not in res:
            self.update_locally(res, False)
            return True

        return False
Exemplo n.º 18
0
    def update(self):
        """ Save changes to this object to the Parse DB.
        Returns True if update is successful. 
        
        Handles Pointers to other objects. If the pointer changed,
        then the cache corresponding to the attr is set to None.
        Relations are not handled by update. Use add_relation
        for Relations.
        """
        # get the formated data to be put in the request
        data = self._get_formatted_data()
        res = parse("PUT", self.path() + "/" + self.objectId, data)
        if res and "error" not in res:
            self.update_locally(res, False)
            return True

        return False
Exemplo n.º 19
0
    def update(self):
        """
        Capitalize certain strings before saving to parse.
        """
        self.street = title(self.street).strip()
        self.city = title(self.city).strip()
        if self.state:
            self.state = self.state.upper().strip()
        if self.zip:
            self.zip = self.zip.strip()

        data = self._get_formatted_data()
        res = parse("PUT", self.path() + "/" + self.objectId, data)
        if res and "error" not in res:
            self.update_locally(res, False)
            return True

        return False
Exemplo n.º 20
0
    def update(self, save_password=False):
        # get the formated data to be put in the request
        data = self._get_formatted_data()
        
        # this is actually unnecessary since parse will not save 
        # the given password if it is None.
        if not save_password:
            del data['password']
            
        res = parse("PUT", self.path() + "/" + self.objectId, data)
        
        # always set the password to None to prevent passing it around in comet receive
        if self.__dict__.get("password") is not None:
            self.password = None
        
        if res and "error" not in res:
            self.update_locally(res, False)
            return True

        return False
Exemplo n.º 21
0
    def update(self, save_password=False):
        # get the formated data to be put in the request
        data = self._get_formatted_data()

        # this is actually unnecessary since parse will not save
        # the given password if it is None.
        if not save_password:
            del data['password']

        res = parse("PUT", self.path() + "/" + self.objectId, data)

        # always set the password to None to prevent passing it around in comet receive
        if self.__dict__.get("password") is not None:
            self.password = None

        if res and "error" not in res:
            self.update_locally(res, False)
            return True

        return False
Exemplo n.º 22
0
    def create(self):
        """ 
        creates this object to the DB. This does not check 
        uniqueness of any field. 
        Use update to save an existing object.

        After a successful request, this object will now have the
        objectId available but not the rest of its attributes. 

        Note that self.__dict__ contains objectId which will result
        to the parse request returning an error only if it is not None

        If there exist a Pointer to other objects,
        this method makes sure that it is saved as a Pointer.
        """
        data = self._get_formatted_data()
        res = parse('POST', self.path(), data)
        if res and "error" not in res:
            self.update_locally(res, False)
            return True
        
        return False
Exemplo n.º 23
0
    def create(self):
        """ 
        creates this object to the DB. This does not check 
        uniqueness of any field. 
        Use update to save an existing object.

        After a successful request, this object will now have the
        objectId available but not the rest of its attributes. 

        Note that self.__dict__ contains objectId which will result
        to the parse request returning an error only if it is not None

        If there exist a Pointer to other objects,
        this method makes sure that it is saved as a Pointer.
        """
        data = self._get_formatted_data()
        res = parse('POST', self.path(), data)
        if res and "error" not in res:
            self.update_locally(res, False)
            return True

        return False
Exemplo n.º 24
0
 def delete(self):
     """ delete the row corresponding to this object in Parse """
     res = parse("DELETE", self.path() + '/' + self.objectId)
     if 'error' not in res:
         return True
     return False
Exemplo n.º 25
0
def relational_query(src_id,
                     src_class,
                     src_key,
                     dst_class,
                     dst_class_key,
                     dst_class_key_class,
                     dst_class_key_where,
                     dst_class_where=None,
                     dst_class_key_where_exclude=False,
                     count=False,
                     order="createdAt",
                     limit=900,
                     skip=0):
    """ 
    Make a query in an object's relation where the query involves
    a pointer to another class.
    
    src_id : the objectId of the of the object in the class in which 
            the relation column exists.
    src_class : the name of the class of the object with the src_id
    src_key : the name of the relation column of the src_class

    dst_class : the output object's class - the class we are querying.
    dst_class_where : append more constraints to the where clause.
    dst_class_key : the name of the column in the dst_class in which
                    the inQuery applies.
    dst_class_key_class : the class name of the dst_class_key
    dst_class_key_where : where parameter of the dst_class_key_class
    dst_class_key_where_exclude : inQuery if false

    count : if True, will only return the count of the results
    """
    if dst_class_key_where_exclude:
        x = "$notInQuery"
    else:
        x = "$inQuery"
    where = {
        # specify the relation (which class contains
        # it and which column is it
        "$relatedTo": {
            "object": {
                "__type": "Pointer",
                "className": src_class,
                "objectId": src_id
            },
            "key": src_key
        },
        # this is how queries are done to Pointer types
        dst_class_key: {
            x: {
                "where": query(dst_class_key_where, where_only=True),
                "className": dst_class_key_class,
                # inner limit applies!
                "limit": 990,
            }
        }
    }
    if dst_class_where:
        where.update(query(dst_class_where, where_only=True))
    if count:
        res = parse("GET",
                    "classes" + "/" + dst_class,
                    query={
                        "where": json.dumps(where),
                        "count": 1,
                        "limit": 0,
                    })
        if 'error' not in res:
            return res['count']
        # May occur if the class or the relation column does not yet exist
        return 0

    res = parse("GET",
                "classes" + "/" + dst_class,
                query={
                    "where": json.dumps(where),
                    "limit": limit,
                    "order": order,
                    "skip": skip,
                })

    if 'error' not in res:
        return res

    # May occur if the class or the relation column does not yet exist
    return None
Exemplo n.º 26
0
def request_password_reset(email):
    res = parse("POST", "requestPasswordReset", {"email": email})
    # success if res is {}
    return len(res) == 0
Exemplo n.º 27
0
    def get(self, attr, **constraints):
        """ 
        returns attr if it is not None, otherwise fetches the 
        attr from the Parse DB and returns that. 

        If the attr is a #2, then it is treated
        as a cache for a ParseObject. Note that all of this 
        attribute's data is retrieved.
        
        Getting an array of pointers using this method will return
        a list of ParseObjects with only the objectId set even if
        an include is provided.

        Constraints may also be provided to filter objects
        in a relation. If limit of 0 is given or result is empty, 
        then the cache will be set to None. If count is given,
        then this method will return the count and not the list.
        """
        # all objects have these by default. These should not be  
        # manually set to None!
        if attr in ParseObject.BUILTINS:
            return self.__dict__.get(attr)
            
        if self.__dict__.get(attr) is not None:
            # make sure that if count constraints are
            # present the cache does not block 
            if not (attr[0].islower() and attr[0].upper() +\
                attr[1:] + "_" in self.__dict__ and\
                'count' in constraints):
                return self.__dict__.get(attr)
                
        # Pointer cache 
        if attr[0].islower() and\
            self.__dict__.get(attr[0].upper() + attr[1:]):
            # if pointer meta exist then use it
            if "_" + attr.lower() in self.__dict__:
                className = self.__dict__["_" + attr.lower()]
            else:
                className = attr[0].upper() + attr[1:]
            q = {}
            if "include" in constraints:
                q["include"] = constraints['include']
            res = parse("GET", "classes/" + className +\
                    "/" + self.__dict__.get(attr[0].upper() +\
                    attr[1:]), query=q)
            if res and "error" not in res:
                setattr(self, attr, get_class(className)(**res))
            else:
                return None

        # Relation cache
        elif attr[0].islower() and attr[0].upper() + attr[1:] +\
                "_" in self.__dict__:
            className = self.__dict__[attr[0].upper() + attr[1:] + "_"]
            # need to use _user as classname if it is the USER_CLASS
            if className == USER_CLASS:
                tmp = "_User"
            else:
                tmp = className
            relName = attr[0].upper() + attr[1:]
            where_dict = {
                        "$relatedTo":{ 
                        "object":{
                            "__type": "Pointer",
                            "className": self.path().split('/')[1],
                            "objectId": self.objectId},
                        "key": relName},  }
            where_dict.update(query(constraints, where_only=True))
            q = {}
            q.update({"where":dumps(where_dict)})
            # add the not where options
            for k,v in constraints.iteritems():
                if k in NOT_WHERE_CONSTRAINTS:
                    q.update({k:v})
            res = parse("GET", 'classes/' + tmp, query=q)
            if res and "error" not in res:
                if len(res['results']) == 0:
                    setattr(self, attr, None)
                else:
                    c = get_class(className)
                    setattr(self, attr, 
                                [ c(**d) for d in res['results'] ])
                if 'count' in res:
                    return res['count']
            else:
                if 'count' in constraints:
                    return 0
                return None 
                
        # date object
        elif attr.startswith("date_"):
            res = parse("GET", self.path(), query={"keys":attr,
                    "where":dumps({"objectId":self.objectId})})
            if 'results' in res and res['results']:
                setattr(self, attr, 
                    parser.parse(res.get('results')[0].get(\
                        attr).get("iso")))
                        
        # Image types 
        elif is_image(attr) and attr.endswith("_url") and\
            attr.replace("_url", "") in self.__dict__:
            attr_name = attr.replace("_url","")
            
            res = parse("GET", self.path(), query={"keys":attr_name,
                    "where":dumps({"objectId":self.objectId})})
                    
            if 'results' in res and res['results']:
                img = res['results'][0].get(attr_name)
                if img:
                    setattr(self, attr, img.get('url').replace(\
                        "http:/", "https://s3.amazonaws.com")) 
                    setattr(self, attr_name, img.get('name'))
                    
        # attr is a geopoint
        elif attr == "coordinates" and attr in self.__dict__:
            res = parse("GET", self.path(), query={"keys":attr,
                    "where":dumps({"objectId":self.objectId})})
            if 'results' in res and res['results']:
                coordinates = res['results'][0].get("coordinates")
                latitude = coordinates.get("latitude")
                longitude = coordinates.get("longitude")
                if coordinates and latitude and longitude:
                    setattr(self, attr, [latitude, longitude])
                else:
                    setattr(self, attr, None)
                    
        # array of pointers
        elif "_" + attr.upper() in self.__dict__:
            q={"keys":attr,
                    "where":dumps({"objectId":self.objectId})}
            if "include" in constraints:
                q["include"] = constraints['include']     
                
            res = parse("GET", self.path(), query=q)
            if 'results' in res and res['results']:
                result = res['results'][0][attr]
                if result is not None:
                    setattr(self, attr, [ get_class(\
                        v['className'])(**v) for v in result ])
            
        # attr is a regular attr or Pointer/Relation attr
        elif attr in self.__dict__: 
            res = parse("GET", self.path(), query={"keys":attr,
                    "where":dumps({"objectId":self.objectId})})
            if 'results' in res and res['results']:
                # what if Pointer attr was set to None?
                # getting them will return a dict!
                if attr[0].isupper() and not attr.endswith("_"):
                    p = res.get('results')[0].get(attr)
                    if type(p) is dict:
                        setattr(self, attr, p.get("objectId") )
                    else:
                        setattr(self, attr, None)
                else:
                    setattr(self, attr, res.get('results')[0].get(attr) )
                
        return self.__dict__.get(attr)
Exemplo n.º 28
0
def request_password_reset(email):
    res = parse("POST", "requestPasswordReset", {
            "email":email
        })
    # success if res is {}
    return len(res) == 0
Exemplo n.º 29
0
def relational_query(src_id, src_class, src_key, dst_class,
        dst_class_key, dst_class_key_class, dst_class_key_where,
        dst_class_where=None, dst_class_key_where_exclude=False,
        count=False, order="createdAt", limit=900, skip=0):
    """ 
    Make a query in an object's relation where the query involves
    a pointer to another class.
    
    src_id : the objectId of the of the object in the class in which 
            the relation column exists.
    src_class : the name of the class of the object with the src_id
    src_key : the name of the relation column of the src_class

    dst_class : the output object's class - the class we are querying.
    dst_class_where : append more constraints to the where clause.
    dst_class_key : the name of the column in the dst_class in which
                    the inQuery applies.
    dst_class_key_class : the class name of the dst_class_key
    dst_class_key_where : where parameter of the dst_class_key_class
    dst_class_key_where_exclude : inQuery if false

    count : if True, will only return the count of the results
    """
    if dst_class_key_where_exclude:
        x = "$notInQuery"
    else:
        x = "$inQuery"
    where = {
                # specify the relation (which class contains
                # it and which column is it
                "$relatedTo": {
                    "object": {
                        "__type": "Pointer",
                        "className": src_class,
                        "objectId": src_id
                    },
                    "key": src_key
                }, 
                # this is how queries are done to Pointer types
                dst_class_key:{
                    x:{
                        "where":query(dst_class_key_where,
                                    where_only=True),
                        "className": dst_class_key_class,
                        # inner limit applies!
                        "limit":990, 
                    }
                }      
            }
    if dst_class_where:
        where.update(query(dst_class_where, where_only=True))
    if count:
        res = parse("GET", "classes" + "/" + dst_class, query={
            "where":json.dumps(where), "count":1, "limit":0,
        })
        if 'error' not in res:
            return res['count']
        # May occur if the class or the relation column does not yet exist
        return 0
        
    res = parse("GET", "classes" + "/" + dst_class, query={
        "where":json.dumps(where), 
        "limit":limit, "order":order, "skip":skip,
    })
    
    
    if 'error' not in res:
        return res
        
    # May occur if the class or the relation column does not yet exist
    return None
Exemplo n.º 30
0
 def delete(self):
     """ delete the row corresponding to this object in Parse """
     res = parse("DELETE", self.path() + '/' + self.objectId)
     if 'error' not in res:
         return True
     return False
Exemplo n.º 31
0
    def get(self, attr, **constraints):
        """ 
        returns attr if it is not None, otherwise fetches the 
        attr from the Parse DB and returns that. 

        If the attr is a #2, then it is treated
        as a cache for a ParseObject. Note that all of this 
        attribute's data is retrieved.
        
        Getting an array of pointers using this method will return
        a list of ParseObjects with only the objectId set even if
        an include is provided.

        Constraints may also be provided to filter objects
        in a relation. If limit of 0 is given or result is empty, 
        then the cache will be set to None. If count is given,
        then this method will return the count and not the list.
        """
        # all objects have these by default. These should not be
        # manually set to None!
        if attr in ParseObject.BUILTINS:
            return self.__dict__.get(attr)

        if self.__dict__.get(attr) is not None:
            # make sure that if count constraints are
            # present the cache does not block
            if not (attr[0].islower() and attr[0].upper() +\
                attr[1:] + "_" in self.__dict__ and\
                'count' in constraints):
                return self.__dict__.get(attr)

        # Pointer cache
        if attr[0].islower() and\
            self.__dict__.get(attr[0].upper() + attr[1:]):
            # if pointer meta exist then use it
            if "_" + attr.lower() in self.__dict__:
                className = self.__dict__["_" + attr.lower()]
            else:
                className = attr[0].upper() + attr[1:]
            q = {}
            if "include" in constraints:
                q["include"] = constraints['include']
            res = parse("GET", "classes/" + className +\
                    "/" + self.__dict__.get(attr[0].upper() +\
                    attr[1:]), query=q)
            if res and "error" not in res:
                setattr(self, attr, get_class(className)(**res))
            else:
                return None

        # Relation cache
        elif attr[0].islower() and attr[0].upper() + attr[1:] +\
                "_" in self.__dict__:
            className = self.__dict__[attr[0].upper() + attr[1:] + "_"]
            # need to use _user as classname if it is the USER_CLASS
            if className == USER_CLASS:
                tmp = "_User"
            else:
                tmp = className
            relName = attr[0].upper() + attr[1:]
            where_dict = {
                "$relatedTo": {
                    "object": {
                        "__type": "Pointer",
                        "className": self.path().split('/')[1],
                        "objectId": self.objectId
                    },
                    "key": relName
                },
            }
            where_dict.update(query(constraints, where_only=True))
            q = {}
            q.update({"where": dumps(where_dict)})
            # add the not where options
            for k, v in constraints.iteritems():
                if k in NOT_WHERE_CONSTRAINTS:
                    q.update({k: v})
            res = parse("GET", 'classes/' + tmp, query=q)
            if res and "error" not in res:
                if len(res['results']) == 0:
                    setattr(self, attr, None)
                else:
                    c = get_class(className)
                    setattr(self, attr, [c(**d) for d in res['results']])
                if 'count' in res:
                    return res['count']
            else:
                if 'count' in constraints:
                    return 0
                return None

        # date object
        elif attr.startswith("date_"):
            res = parse("GET",
                        self.path(),
                        query={
                            "keys": attr,
                            "where": dumps({"objectId": self.objectId})
                        })
            if 'results' in res and res['results']:
                setattr(self, attr,
                    parser.parse(res.get('results')[0].get(\
                        attr).get("iso")))

        # Image types
        elif is_image(attr) and attr.endswith("_url") and\
            attr.replace("_url", "") in self.__dict__:
            attr_name = attr.replace("_url", "")

            res = parse("GET",
                        self.path(),
                        query={
                            "keys": attr_name,
                            "where": dumps({"objectId": self.objectId})
                        })

            if 'results' in res and res['results']:
                img = res['results'][0].get(attr_name)
                if img:
                    setattr(self, attr, img.get('url').replace(\
                        "http:/", "https://s3.amazonaws.com"))
                    setattr(self, attr_name, img.get('name'))

        # attr is a geopoint
        elif attr == "coordinates" and attr in self.__dict__:
            res = parse("GET",
                        self.path(),
                        query={
                            "keys": attr,
                            "where": dumps({"objectId": self.objectId})
                        })
            if 'results' in res and res['results']:
                coordinates = res['results'][0].get("coordinates")
                latitude = coordinates.get("latitude")
                longitude = coordinates.get("longitude")
                if coordinates and latitude and longitude:
                    setattr(self, attr, [latitude, longitude])
                else:
                    setattr(self, attr, None)

        # array of pointers
        elif "_" + attr.upper() in self.__dict__:
            q = {"keys": attr, "where": dumps({"objectId": self.objectId})}
            if "include" in constraints:
                q["include"] = constraints['include']

            res = parse("GET", self.path(), query=q)
            if 'results' in res and res['results']:
                result = res['results'][0][attr]
                if result is not None:
                    setattr(self, attr, [ get_class(\
                        v['className'])(**v) for v in result ])

        # attr is a regular attr or Pointer/Relation attr
        elif attr in self.__dict__:
            res = parse("GET",
                        self.path(),
                        query={
                            "keys": attr,
                            "where": dumps({"objectId": self.objectId})
                        })
            if 'results' in res and res['results']:
                # what if Pointer attr was set to None?
                # getting them will return a dict!
                if attr[0].isupper() and not attr.endswith("_"):
                    p = res.get('results')[0].get(attr)
                    if type(p) is dict:
                        setattr(self, attr, p.get("objectId"))
                    else:
                        setattr(self, attr, None)
                else:
                    setattr(self, attr, res.get('results')[0].get(attr))

        return self.__dict__.get(attr)