def save(self): if self._source: output = cStringIO.StringIO() self._source.seek(0) base64.encode(self._source, output) self._source.seek(0) output.seek(0) hex_octet = lambda: hex(int(0x10000 * (1 + random.random())))[-4:] key = ''.join(hex_octet() for _ in xrange(4)) key = '{0}.{1}'.format(key, self.extension) data = { 'name': self._name, 'key': key, 'ACL': self._acl, 'mime_type': self._type, 'metaData': self._metadata, } response = client.post('/qiniu', data) content = utils.response_to_json(response) self.id = content['objectId'] self._url = content['url'] uptoken = content['token'] ret, info = qiniu.put_data(uptoken, key, self._source) if info.status_code != 200: raise LeanCloudError( 1, 'the file is not saved, qiniu status code: {0}'.format( info.status_code)) elif self._url and self.metadata.get('__source') == 'external': data = { 'name': self._name, 'ACL': self._acl, 'metaData': self._metadata, 'mime_type': self._type, 'url': self._url, } response = client.post('/files/{0}'.format(self._name), data) content = utils.response_to_json(response) self._name = content['name'] self._url = content['url'] self.id = content['objectId'] if 'size' in content: self._metadata['size'] = content['size'] else: raise ValueError return self
def save(self): if self._source: output = cStringIO.StringIO() self._source.seek(0) base64.encode(self._source, output) self._source.seek(0) data = { 'base64': output.getvalue(), '_ContentType': self._type, 'mime_type': self._type, 'metaData': self._metadata, } elif self._url and self.metadata['__source'] == 'external': data = { 'name': self._name, 'ACL': self._acl, 'metaData': self._metadata, 'mime_type': self._type, 'url': self._url, } else: raise ValueError response = client.post('/files/{0}'.format(self._name), data) content = utils.response_to_json(response) self._name = content['name'] self._url = content['url'] self.id = content['objectId'] if 'size' in content: self._metadata['size'] = content['size'] return self
def save(self): if self._source: if client.REGION == 'US': self._save_to_leancloud() else: self._save_to_qiniu() elif self._url and self.metadata.get('__source') == 'external': data = { 'name': self._name, 'ACL': self._acl, 'metaData': self._metadata, 'mime_type': self._type, 'url': self._url, } response = client.post('/files/{0}'.format(self._name), data) content = utils.response_to_json(response) self._name = content['name'] self._url = content['url'] self.id = content['objectId'] if 'size' in content: self._metadata['size'] = content['size'] else: raise ValueError return self
def save(self): """ 将对象数据保存至服务器 :return: None :rtype: None """ unsaved_children = [] unsaved_files = [] self._find_unsaved_children(self.attributes, unsaved_children, unsaved_files) if len(unsaved_children) + len(unsaved_files) > 0: self._deep_save(self.attributes) self._start_save() data = self._dump_save() method = 'PUT' if self.id is not None else 'POST' if method == 'PUT': response = client.put('/classes/{0}/{1}'.format(self._class_name, self.id), data) else: response = client.post('/classes/{0}'.format(self._class_name), data) self._finish_save(self.parse(utils.response_to_json(response), response.status_code))
def _deep_save(self, unsaved_children, unsaved_files, exclude=None): if exclude: unsaved_children = [x for x in unsaved_children if x != exclude] for f in unsaved_files: f.save() dumped_objs = [] for obj in unsaved_children: obj._start_save() method = 'POST' if obj.id is None else 'PUT' path = '/{0}/classes/{1}'.format(client.SERVER_VERSION, obj._class_name) body = obj._dump_save() dumped_obj = { 'method': method, 'path': path, 'body': body, } dumped_objs.append(dumped_obj) response = utils.response_to_json(client.post('/batch', params={'requests': dumped_objs})) errors = [] for idx, obj in enumerate(unsaved_children): content = response[idx] if not content.get('success'): errors.append(leancloud.LeanCloudError(content.get('code'), content.get('error'))) obj._cancel_save() else: result = obj.parse(content['success']) obj._finish_save(result) if errors: # TODO: how to raise list of errors? raise errors[0]
def fetch(self): response = client.get('/files/{0}'.format(self.id)) content = utils.response_to_json(response) self._name = content.get('name') self.id = content.get('objectId') self._url = content.get('url') self._type = content.get('mime_type') self._metadata = content.get('metaData')
def update_password(self, old_password, new_password): route = '/users/' + self.id + '/updatePassword' params = {'old_password': old_password, 'new_password': new_password} response = client.put(route, params) content = utils.response_to_json(response) server_data = self.parse(content, response.status_code) self._finish_fetch(server_data, True) self._handle_save_result(True)
def update_password(self, old_password, new_password): route = "/users/" + self.id + "/updatePassword" params = {"old_password": old_password, "new_password": new_password} response = client.put(route, params) content = utils.response_to_json(response) server_data = self.parse(content, response.status_code) self._finish_fetch(server_data, True) self._handle_save_result(True)
def save(self): if self._source: output = cStringIO.StringIO() self._source.seek(0) base64.encode(self._source, output) self._source.seek(0) output.seek(0) hex_octet = lambda: hex(int(0x10000 * (1 + random.random())))[-4:] key = ''.join(hex_octet() for _ in xrange(4)) key = '{0}.{1}'.format(key, self.extension) data = { 'name': self._name, 'key': key, 'ACL': self._acl, 'mime_type': self._type, 'metaData': self._metadata, } response = client.post('/qiniu', data) content = utils.response_to_json(response) self.id = content['objectId'] self._url = content['url'] uptoken = content['token'] ret, info = qiniu.put_data(uptoken, key, self._source) if info.status_code != 200: raise LeanCloudError(1, 'the file is not saved, qiniu status code: {0}'.format(info.status_code)) elif self._url and self.metadata['__source'] == 'external': data = { 'name': self._name, 'ACL': self._acl, 'metaData': self._metadata, 'mime_type': self._type, 'url': self._url, } response = client.post('/files/{0}'.format(self._name), data) content = utils.response_to_json(response) self._name = content['name'] self._url = content['url'] self.id = content['objectId'] if 'size' in content: self._metadata['size'] = content['size'] else: raise ValueError return self
def fetch(self): response = client.get('/files/{0}'.format(self.id)) content = utils.response_to_json(response) print content self._name = content.get('name') self.id = content.get('objectId') self._url = content.get('url') self._type = content.get('mime_type') self._metadata = content.get('metaData')
def fetch(self): """ 从服务器获取当前对象所有的值,如果与本地值不同,将会覆盖本地的值。 :return: 当前对象 """ response = client.get('/classes/{0}/{1}'.format(self._class_name, self.id), {}) result = self.parse(utils.response_to_json(response), response.status_code) self._finish_fetch(result, True)
def become(cls, session_token): response = client.get("/users/me", params={"session_token": session_token}) content = utils.response_to_json(response) user = cls() server_data = user.parse(content, response.status_code) user._finish_fetch(server_data, True) user._handle_save_result(True) if "smsCode" not in server_data: user.attributes.pop("smsCode", None) return user
def save(self): if self._source: output = cStringIO.StringIO() self._source.seek(0) base64.encode(self._source, output) self._source.seek(0) output.seek(0) hex_octet = hex(int(1 + random.random() * 0x10000))[1:] qiniu_UUID = hex_octet * 4 + self.extension data = { 'name': self._name, 'key': qiniu_UUID, 'ACL': self._acl, 'mime_type': self._type, 'metaData': self._metadata, } response = client.post('/qiniu', data) content = utils.response_to_json(response) uptoken = content['token'] ret, info = qiniu.put_data(uptoken, self._name, output, mime_type=self._type) if info.status_code != 200: raise LeanCloudError(1, 'the file {0} not saved'.format(ret['key'])) elif self._url and self.metadata['__source'] == 'external': data = { 'name': self._name, 'ACL': self._acl, 'metaData': self._metadata, 'mime_type': self._type, 'url': self._url, } else: raise ValueError response = client.post('/files/{0}'.format(self._name), data) content = utils.response_to_json(response) self._name = content['name'] self._url = content['url'] self.id = content['objectId'] if 'size' in content: self._metadata['size'] = content['size'] return self
def new_func(*args, **kwargs): response = func(*args, **kwargs) if response.headers.get("Content-Type") == "text/html": raise leancloud.LeanCloudError(-1, "Bad Request") content = utils.response_to_json(response) if "error" in content: raise leancloud.LeanCloudError(content.get("code", 1), content.get("error", "Unknown Error")) return response
def new_func(*args, **kwargs): response = func(*args, **kwargs) if response.headers['Content-Type'] == 'text/html': raise leancloud.LeanCloudError(-1, 'Bad Request') content = utils.response_to_json(response) if 'error' in content: raise leancloud.LeanCloudError(content.get('code', 1), content.get('error', 'Unknown Error')) return response
def count(self): """ 返回满足查询条件的对象的数量。 :rtype: int """ params = self.dump() params['limit'] = 0 params['count'] = 1 response = client.get('/classes/{0}'.format(self._query_class._class_name), params) return utils.response_to_json(response)['count']
def become(cls, session_token): response = client.get('/users/me', params={'session_token': session_token}) content = utils.response_to_json(response) user = cls() server_data = user.parse(content, response.status_code) user._finish_fetch(server_data, True) user._handle_save_result(True) if 'smsCode' not in server_data: user._attributes.pop('smsCode', None) return user
def count(self): """ 返回满足查询条件的对象的数量。 :rtype: int """ params = self.dump() params['limit'] = 0 params['count'] = 1 response = client.get( '/classes/{0}'.format(self._query_class._class_name), params) return utils.response_to_json(response)['count']
def run(_cloud_func_name, **params): """ 调用 LeanEngine 上的远程代码 :param name: 需要调用的远程 Cloud Code 的名称 :type name: basestring :param params: 调用参数 :return: 调用结果 """ response = leancloud.client.post('/functions/{0}'.format(_cloud_func_name), params=params) content = utils.response_to_json(response) return utils.decode(None, content)['result']
def new_func(*args, **kwargs): response = func(*args, **kwargs) if response.headers['Content-Type'] == 'text/html': raise leancloud.LeanCloudError(-1, 'Bad Request') content = utils.response_to_json(response) if 'error' in content: raise leancloud.LeanCloudError( content.get('code', 1), content.get('error', 'Unknown Error')) return response
def new_func(*args, **kwargs): response = func(*args, **kwargs) assert isinstance(response, requests.Response) if response.headers.get('Content-Type') == 'text/html': print(response.status_code) print(response.content) raise leancloud.LeanCloudError(-1, 'Bad Request') content = utils.response_to_json(response) if 'error' in content: raise leancloud.LeanCloudError(content.get('code', 1), content.get('error', 'Unknown Error')) return response
def login(self, username=None, password=None): """ 登陆用户。如果用户名和密码正确,服务器会返回用户的 sessionToken 。 """ if username: self.set("username", username) if password: self.set("password", password) response = client.post("/login", params=self.dump()) content = utils.response_to_json(response) server_data = self.parse(content, response.status_code) self._finish_fetch(server_data, False) self._handle_save_result(True) if "smsCode" not in server_data: self.attributes.pop("smsCode", None)
def find(self): """ 根据查询条件,获取包含所有满足条件的对象。 :rtype: list """ content = utils.response_to_json(client.get('/classes/{0}'.format(self._query_class._class_name), self.dump())) objs = [] for result in content['results']: obj = self._new_object() obj._finish_fetch(self._process_result(result), True) objs.append(obj) return objs
def login(self, username=None, password=None): """ 登陆用户。如果用户名和密码正确,服务器会返回用户的 sessionToken 。 """ if username: self.set('username', username) if password: self.set('password', password) response = client.post('/login', params=self.dump()) content = utils.response_to_json(response) server_data = self.parse(content, response.status_code) self._finish_fetch(server_data, False) self._handle_save_result(True) if 'smsCode' not in server_data: self._attributes.pop('smsCode', None)
def send(data, channels=None, push_time=None, expiration_time=None, expiration_interval=None, where=None, cql=None): """ 发送推送消息。返回结果为此条推送对应的 _Notification 表中的对象,但是如果需要使用其中的数据,需要调用 fetch() 方法将数据同步至本地。 :param channels: 需要推送的频道 :type channels: list or tuple :param push_time: 推送的时间 :type push_time: datetime :param expiration_time: 消息过期的绝对日期时间 :type expiration_time: datetime :param expiration_interval: 消息过期的相对时间,从调用 API 的时间开始算起,单位是秒 :type expiration_interval: int :param where: 一个查询 _Installation 表的查询条件 JSON 对象 :type where: leancloud.Query :param cql: 一个查询 _Installation 表的查询条件 CQL 语句 :type cql: basestring :param data: 推送给设备的具体信息,详情查看 https://leancloud.cn/docs/push_guide.html#消息内容_Data :rtype: Notification """ if push_time and expiration_time: raise TypeError( 'Both expiration_time and expiration_time_interval can\'t be set') params = { 'data': data, } if channels: params['channels'] = channels if push_time: params['push_time'] = push_time.isoformat() if expiration_time: params['expiration_time'] = expiration_time.isoformat() if expiration_interval: params['expiration_interval'] = expiration_interval if where: params['where'] = where.dump() if cql: params['cql'] = cql result = utils.response_to_json(client.post('/push', params=params)) notification = Notification.create_without_data(result['objectId']) return notification
def first(self): """ 根据查询获取最多一个对象。 :return: 查询结果 :rtype: Object :raise: LeanCloudError """ params = self.dump() params['limit'] = 1 content = utils.response_to_json(client.get('/classes/{0}'.format(self._query_class._class_name), params)) results = content['results'] if not results: raise LeanCloudError(101, 'Object not found') obj = self._new_object() obj._finish_fetch(self._process_result(results[0]), True) return obj
def find(self): """ 根据查询条件,获取包含所有满足条件的对象。 :rtype: list """ content = utils.response_to_json( client.get('/classes/{0}'.format(self._query_class._class_name), self.dump())) objs = [] for result in content['results']: obj = self._new_object() obj._finish_fetch(self._process_result(result), True) objs.append(obj) return objs
def signup_or_login_with_mobile_phone(cls, phone_number, sms_code): ''' param phone_nubmer: basestring param sms_code: basestring 在调用此方法前请先使用 request_sms_code 请求 sms code ''' data = {'mobilePhoneNumber': phone_number, 'smsCode': sms_code} response = client.post('/usersByMobilePhone', data) content = utils.response_to_json(response) user = cls() server_data = user.parse(content, response.status_code) user._finish_fetch(server_data, True) user._handle_save_result(True) if 'smsCode' not in server_data: user._attributes.pop('smsCode', None) return user
def signup_or_login_with_mobile_phone(cls, phone_number, sms_code): """ param phone_nubmer: basestring param sms_code: basestring 在调用此方法前请先使用 request_sms_code 请求 sms code """ data = {"mobilePhoneNumber": phone_number, "smsCode": sms_code} response = client.post("/usersByMobilePhone", data) content = utils.response_to_json(response) user = cls() server_data = user.parse(content, response.status_code) user._finish_fetch(server_data, True) user._handle_save_result(True) if "smsCode" not in server_data: user.attributes.pop("smsCode", None) return user
def first(self): """ 根据查询获取最多一个对象。 :return: 查询结果 :rtype: Object :raise: LeanCloudError """ params = self.dump() params['limit'] = 1 content = utils.response_to_json( client.get('/classes/{0}'.format(self._query_class._class_name), params)) results = content['results'] if not results: raise LeanCloudError(101, 'Object not found') obj = self._new_object() obj._finish_fetch(self._process_result(results[0]), True) return obj
def signup_or_login_with_mobile_phone(cls, phone_number, sms_code): ''' param phone_nubmer: string_types param sms_code: string_types 在调用此方法前请先使用 request_sms_code 请求 sms code ''' data = { 'mobilePhoneNumber': phone_number, 'smsCode': sms_code } response = client.post('/usersByMobilePhone', data) content = utils.response_to_json(response) user = cls() server_data = user.parse(content, response.status_code) user._finish_fetch(server_data, True) user._handle_save_result(True) if 'smsCode' not in server_data: user.attributes.pop('smsCode', None) return user
def send(data, channels=None, push_time=None, expiration_time=None, expiration_interval=None, where=None, cql=None): """ 发送推送消息。返回结果为此条推送对应的 _Notification 表中的对象,但是如果需要使用其中的数据,需要调用 fetch() 方法将数据同步至本地。 :param channels: 需要推送的频道 :type channels: list or tuple :param push_time: 推送的时间 :type push_time: datetime :param expiration_time: 消息过期的绝对日期时间 :type expiration_time: datetime :param expiration_interval: 消息过期的相对时间,从调用 API 的时间开始算起,单位是秒 :type expiration_interval: int :param where: 一个查询 _Installation 表的查询条件 JSON 对象 :type where: leancloud.Query :param cql: 一个查询 _Installation 表的查询条件 CQL 语句 :type cql: basestring :param data: 推送给设备的具体信息,详情查看 https://leancloud.cn/docs/push_guide.html#消息内容_Data :rtype: Notification """ if push_time and expiration_time: raise TypeError('Both expiration_time and expiration_time_interval can\'t be set') params = { 'data': data, } if channels: params['channels'] = channels if push_time: params['push_time'] = push_time.isoformat() if expiration_time: params['expiration_time'] = expiration_time.isoformat() if expiration_interval: params['expiration_interval'] = expiration_interval if where: params['where'] = where.dump() if cql: params['cql'] = cql result = utils.response_to_json(client.post('/push', params=params)) notification = Notification.create_without_data(result['objectId']) return notification
def _save_to_qiniu(self): self._source.seek(0) hex_octet = lambda: hex(int(0x10000 * (1 + random.random())))[-4:] key = ''.join(hex_octet() for _ in xrange(4)) key = '{0}.{1}'.format(key, self.extension) data = { 'name': self._name, 'key': key, 'ACL': self._acl, 'mime_type': self._type, 'metaData': self._metadata, } response = client.post('/qiniu', data) content = utils.response_to_json(response) self.id = content['objectId'] self._url = content['url'] uptoken = content['token'] ret, info = qiniu.put_data(uptoken, key, self._source) if info.status_code != 200: raise LeanCloudError(1, 'the file is not saved, qiniu status code: {0}'.format(info.status_code))
def _deep_save(self, exclude=None): # TODO: chunk unsaved_children = [] unsaved_files = [] self._find_unsaved_children(self.attributes, unsaved_children, unsaved_files) if exclude: unsaved_children = [x for x in unsaved_children if x != exclude] for f in unsaved_files: f.save() dumped_objs = [] for obj in unsaved_children: obj._start_save() method = 'POST' if obj.id is None else 'PUT' path = '/{0}/classes/{1}'.format(client.SERVER_VERSION, obj._class_name) body = obj._dump_save() dumped_obj = { 'method': method, 'path': path, 'body': body, } dumped_objs.append(dumped_obj) response = utils.response_to_json(client.post('/batch', params={'requests': dumped_objs})) errors = [] for idx, obj in enumerate(unsaved_children): content = response[idx] if not content.get('success'): errors.append(leancloud.LeanCloudError(content.get('code'), content.get('error'))) obj._cancel_save() else: result = obj.parse(content['success']) obj._finish_save(result) if errors: # TODO: how to raise list of errors? raise errors[0]
def _deep_save(self, unsaved_children, unsaved_files, exclude=None): if exclude: unsaved_children = [x for x in unsaved_children if x != exclude] for f in unsaved_files: f.save() if not unsaved_children: return dumped_objs = [] for obj in unsaved_children: obj._start_save() method = 'POST' if obj.id is None else 'PUT' path = '/{0}/classes/{1}'.format(client.SERVER_VERSION, obj._class_name) body = obj._dump_save() dumped_obj = { 'method': method, 'path': path, 'body': body, } dumped_objs.append(dumped_obj) response = utils.response_to_json(client.post('/batch', params={'requests': dumped_objs})) errors = [] for idx, obj in enumerate(unsaved_children): content = response[idx] if not content.get('success'): errors.append(leancloud.LeanCloudError(content.get('code'), content.get('error'))) obj._cancel_save() else: result = obj.parse(content['success']) obj._finish_save(result) if errors: # TODO: how to raise list of errors? # http://stackoverflow.com/questions/9875660/idiomatic-way-to-collect-report-multiple-exceptions-in-python raise errors[0]
def save(self, where=None): """ 将对象数据保存至服务器 :return: None :rtype: None """ if where and not isinstance(where, leancloud.Query): raise TypeError('where param type should be leancloud.Query, got %s', type(where)) if where and where._query_class._class_name != self._class_name: raise TypeError('where param\'s class name not equal to the current object\'s class name') if where and self.is_new(): raise TypeError('where params works only when leancloud.Object is saved') unsaved_children = [] unsaved_files = [] self._find_unsaved_children(self._attributes, unsaved_children, unsaved_files) if len(unsaved_children) + len(unsaved_files) > 0: self._deep_save(unsaved_children, unsaved_files, exclude=self._attributes) self._start_save() data = self._dump_save() fetch_when_save = 'true' if self.fetch_when_save else 'false' if self.is_new(): response = client.post('/classes/{0}?fetchWhenSave={1}'.format(self._class_name, fetch_when_save), data) else: url = '/classes/{0}/{1}?fetchWhenSave={2}'.format(self._class_name, self.id, fetch_when_save) if where: url += '&where=' + json.dumps(where.dump()['where'], separators=(',', ':')) response = client.put(url, data) self._finish_save(self.parse(utils.response_to_json(response), response.status_code))
def do_cloud_query(cls, cql, *pvalues): """ 使用 CQL 来构造查询。CQL 语法参考 `这里 <https://cn.avoscloud.com/docs/cql_guide.html>`_。 :param cql: CQL 语句 :param pvalues: 查询参数 :rtype: CQLResult """ params = {'cql': cql} if len(pvalues) == 1 and isinstance(pvalues[0], (tuple, list)): pvalues = json.dumps(pvalues[0]) if len(pvalues) > 0: params['pvalues'] = json.dumps(pvalues) content = utils.response_to_json(client.get('/cloudQuery', params)) objs = [] query = cls(content['className']) for result in content['results']: obj = query._new_object() obj._finish_fetch(query._process_result(result), True) objs.append(obj) return CQLResult(objs, content.get('count'), content.get('className'))
def do_cloud_query(cls, cql, *pvalues): """ 使用 CQL 来构造查询。CQL 语法参考 `这里 <https://cn.avoscloud.com/docs/cql_guide.html>`_。 :param cql: CQL 语句 :param pvalues: 查询参数 :rtype: CQLResult """ params = {'cql': cql} if len(pvalues) == 1 and isinstance(pvalues[0], (tuple, list)): pvalues = json.dumps(pvalues[0]) if len(pvalues) > 0: params['pvalues'] = json.dumps(pvalues) content = utils.response_to_json(client.get('/cloudQuery', params)) objs = [] query = Query(content['className']) for result in content['results']: obj = query._new_object() obj._finish_fetch(query._process_result(result), True) objs.append(obj) return CQLResult(objs, content.get('count'), content.get('className'))
def destroy(self): if not self.id: return False response = client.delete('/files/{0}'.format(self.id)) content = utils.response_to_json(response) return response