def send(self, from_client, message, to_clients=None, transient=False, push_data=None): """ 在指定会话中发送消息。 :param from_client: 发送者 id :param message: 消息内容 :param to_clients: 接受者 id,只在系统会话中生效 :param transient: 是否以暂态形式发送消息 :param push_data: 推送消息内容,参考:https://url.leanapp.cn/pushData """ if isinstance(message, dict): message = json.dumps(message) params = { 'from_peer': from_client, 'conv_id': self.id, 'transient': transient, 'message': message, } if to_clients: params['to_peers'] = to_clients if push_data: params['push_data'] = push_data client.post('/rtm/messages', params=params).json()
def request_password_reset_by_sms_code(cls, phone_number, validate_token=None): params = {'mobilePhoneNumber': phone_number} if validate_token is not None: params['validate_token'] = validate_token client.post('/requestPasswordResetBySmsCode', params)
def request_password_reset_by_sms_code(cls, phone_number, validate_token=None): params = {"mobilePhoneNumber": phone_number} if validate_token is not None: params["validate_token"] = validate_token client.post("/requestPasswordResetBySmsCode", params)
def request_change_phone_number(cls, phone_number, ttl=None, validate_token=None): params = {"mobilePhoneNumber": phone_number} if ttl is not None: params["ttl"] = ttl if validate_token is not None: params["validate_token"] = validate_token client.post("/requestChangePhoneNumber", params)
def send(self, from_client, message, to_clients=None, transient=False, push_data=None): """ 在指定会话中发送消息。 :param from_client: 发送者 id :param message: 消息内容 :param to_clients: 接受者 id,只在系统会话中生效 :param transient: 是否以暂态形式发送消息 :param push_data: 推送消息内容,参考:https://url.leanapp.cn/pushData """ if isinstance(message, dict): message = json.dumps(message) params = { "from_peer": from_client, "conv_id": self.id, "transient": transient, "message": message, } if to_clients: params["to_peers"] = to_clients if push_data: params["push_data"] = push_data client.post("/rtm/messages", params=params).json()
def f(): try: client.post("/fileCallback", { "token": token, "result": successed }) except LeanCloudError as e: logger.warning("call file callback failed, error: %s", e)
def f(): try: client.post('/fileCallback', { 'token': token, 'result': successed, }) except LeanCloudError as e: logger.warning('call file callback failed, error: %s', e)
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 _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 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 _save_to_cos(self): hex_octet = lambda: hex(int(0x10000 * (1 + random.random())))[-4:] key = ''.join(hex_octet() for _ in range(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('/fileTokens', data) content = response.json() self.id = content['objectId'] self._url = content['url'] uptoken = content['token'] headers = { 'Authorization': uptoken, } self._source.seek(0) data = { 'op': 'upload', 'filecontent': self._source.read(), } response = requests.post(content['upload_url'], headers=headers, files=data) self._source.seek(0) info = response.json() if info['code'] != 0: raise LeanCloudError(1, 'this file is not saved, qcloud cos status code: {}'.format(info['code']))
def destroy_all(cls, objs): """ 在一个请求中 destroy 多个 leancloud.Object 对象实例。 :param objs: 需要 destroy 的对象 :type objs: list """ if not objs: return if any(x.is_new() for x in objs): raise ValueError("Could not destroy unsaved object") dumped_objs = [] for obj in objs: dumped_obj = { 'method': 'DELETE', 'path': '/{0}/classes/{1}/{2}'.format(client.SERVER_VERSION, obj._class_name, obj.id), 'body': obj._flags, } dumped_objs.append(dumped_obj) response = client.post('/batch', params={'requests': dumped_objs}).json() errors = [] for idx, obj in enumerate(objs): content = response[idx] error = content.get('error') if error: errors.append(leancloud.LeanCloudError(error.get('code'), error.get('error'))) if errors: # TODO: how to raise list of errors? # raise MultipleValidationErrors(errors) # add test raise errors[0]
def save(self, where=None, fetch_when_save=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 unsaved_children or unsaved_files: self._deep_save(unsaved_children, unsaved_files, exclude=self._attributes) data = self._dump_save() fetch_when_save = 'true' if 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._update_data(response.json())
def _save_to_qiniu(self): import qiniu output = BytesIO() 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 range_type(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 = response.json() 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 _save_to_cos(self): hex_octet = lambda: hex(int(0x10000 * (1 + random.random())))[-4:] key = ''.join(hex_octet() for _ in range(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('/fileTokens', data) content = response.json() self.id = content['objectId'] self._url = content['url'] uptoken = content['token'] headers = { 'Authorization': uptoken, } self._source.seek(0) data = { 'op': 'upload', 'filecontent': self._source.read(), } response = requests.post(content['upload_url'], headers=headers, files=data) self._source.seek(0) info = response.json() if info['code'] != 0: raise LeanCloudError( 1, 'this file is not saved, qcloud cos status code: {}'.format( info['code']))
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_to_qiniu(self): import qiniu output = BytesIO() 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 range_type(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 = response.json() 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 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): 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 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 表的查询条件 leancloud.Query 对象 :type where: leancloud.Query :param cql: 一个查询 _Installation 表的查询条件 CQL 语句 :type cql: string_types :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 client.USE_PRODUCTION == '0': params['prod'] = 'dev' if channels: params['channels'] = channels if push_time: tzinfo = push_time.tzinfo if tzinfo is None: tzinfo = tz.tzlocal() params['push_time'] = arrow.get( push_time, tzinfo).to('utc').format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z' if expiration_time: params['expiration_time'] = expiration_time.isoformat() if expiration_interval: params['expiration_interval'] = expiration_interval if where: params['where'] = where.dump().get('where', {}) if cql: params['cql'] = cql result = client.post('/push', params=params).json() notification = Notification.create_without_data(result['objectId']) return notification
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 follow(self, target_id): """ 关注一个用户。 :param target_id: 需要关注的用户的 id """ if self.id is None: raise ValueError('Please sign in') response = client.post('/users/{0}/friendship/{1}'.format(self.id, target_id), None) assert response.ok
def follow(self, target_id): """ 关注一个用户。 :param target_id: 需要关注的用户的 id """ if self.id is None: raise ValueError("Please sign in") response = client.post("/users/{0}/friendship/{1}".format(self.id, target_id), None) assert response.ok
def _save_external(self): data = { "name": self._name, "ACL": self._acl, "metaData": self._metadata, "mime_type": self.mime_type, "url": self._url, } response = client.post("/files".format(self._name), data) content = response.json() self.id = content["objectId"]
def send(data, channels=None, push_time=None, expiration_time=None, expiration_interval=None, where=None, cql=None, flow_control=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 表的查询条件 leancloud.Query 对象 :type where: leancloud.Query :param cql: 一个查询 _Installation 表的查询条件 CQL 语句 :type cql: string_types :param data: 推送给设备的具体信息,详情查看 https://leancloud.cn/docs/push_guide.html#消息内容_Data :rtype: Notification :param flow_control: 不为 None 时开启平滑推送,值为每秒推送的目标终端用户数。开启时指定低于 1000 的值,按 1000 计。 :type: flow_control: int """ if expiration_interval and expiration_time: raise TypeError('Both expiration_time and expiration_interval can\'t be set') params = { 'data': data, } if client.USE_PRODUCTION == '0': params['prod'] = 'dev' if channels: params['channels'] = channels if push_time: params['push_time'] = _encode_time(push_time) if expiration_time: params['expiration_time'] = _encode_time(expiration_time) if expiration_interval: params['expiration_interval'] = expiration_interval if where: params['where'] = where.dump().get('where', {}) if cql: params['cql'] = cql # Do not change this to `if flow_control`, because 0 is falsy in Python, # but `flow_control = 0` will enable smooth push, and it is in fact equivlent to `flow_control = 1000`. if flow_control is not None: params['flow_control'] = flow_control result = client.post('/push', params=params).json() notification = Notification.create_without_data(result['objectId']) return notification
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 = response.json() self._update_data(content) self._handle_save_result(True) if 'smsCode' not in content: self._attributes.pop('smsCode', None)
def broadcast(self, from_client, message, valid_till=None, push_data=None): """ 发送广播消息,只能以系统会话名义发送。全部用户都会收到此消息,不论是否在此会话中。 :param from_client: 发送者 id :param message: 消息内容 :param valid_till: 指定广播消息过期时间 :param puhs_data: 推送消息内容,参考:https://url.leanapp.cn/pushData """ if isinstance(message, dict): message = json.dumps(message) params = { 'from_peer': from_client, 'conv_id': self.id, 'message': message, } if push_data: params['push_data'] = push_data if valid_till: if isinstance(valid_till, datetime): valid_till = arrow.get(valid_till).datetime params['valid_till'] = valid_till client.post('/rtm/broadcast', params=params).json()
def _deep_save(self, unsaved_children, unsaved_files, exclude=None, ignore_failed=True): import leancloud from leancloud import client if exclude: # unsaved_children = [x for x in unsaved_children if x != exclude] unsaved_children = filter(lambda x: x != exclude, unsaved_children) for f in unsaved_files: f.save() if not unsaved_children: return dumped_objs = [] for obj in unsaved_children: method = ('PUT', 'POST')[obj.id is None] path = '/{0}/classes/{1}'.format(client.SERVER_VERSION, obj._class_name) path += ("/{}".format(obj.id), "")[obj.id is None] body = obj._dump_save() dumped_obj = { 'method': method, 'path': path, 'body': body, } dumped_objs.append(dumped_obj) response = client.post('/batch', params={'requests': dumped_objs}).json() 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'))) else: obj._update_data(content['success']) if errors: # TODO: how to raise list of errors? # raise MultipleValidationErrors(errors) # add test if ignore_failed: continue raise errors[0]
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 表的查询条件 leancloud.Query 对象 :type where: leancloud.Query :param cql: 一个查询 _Installation 表的查询条件 CQL 语句 :type cql: string_types :param data: 推送给设备的具体信息,详情查看 https://leancloud.cn/docs/push_guide.html#消息内容_Data :rtype: Notification """ if expiration_interval and expiration_time: raise TypeError('Both expiration_time and expiration_interval can\'t be set') params = { 'data': data, } if client.USE_PRODUCTION == '0': params['prod'] = 'dev' if channels: params['channels'] = channels if push_time: tzinfo = push_time.tzinfo if tzinfo is None: tzinfo = tz.tzlocal() params['push_time'] = arrow.get(push_time, tzinfo).to('utc').format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z' if expiration_time: params['expiration_time'] = expiration_time.isoformat() if expiration_interval: params['expiration_interval'] = expiration_interval if where: params['where'] = where.dump().get('where', {}) if cql: params['cql'] = cql result = client.post('/push', params=params).json() notification = Notification.create_without_data(result['objectId']) return notification
def execute(self): resp = client.post('/batch', params={'requests': self._requests}) data = resp.json() result = [] for post_fn, resp in zip(self._post_response, data): if 'error' in resp: result.append(( resp.get('code', 1), resp.get('error', 'Unknown Error'), )) else: result.append((0, post_fn(resp.get('success', {})))) self._requests = [] self._post_response = [] return result
def _get_file_token(self): data = { "name": self._name, "ACL": self._acl, "mime_type": self.mime_type, "metaData": self._metadata, } if self.key is not None: data["key"] = self.key response = client.post("/fileTokens", data) content = response.json() self.id = content["objectId"] self._url = content["url"] self.key = content["key"] return content
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 = response.json() 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 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 _save_to_leancloud(self): self._source.seek(0) encoded = codecs.encode(self._source.read(), 'base64') data = { 'base64': encoded, '_ContentType': self._type, 'ACL': self._acl, 'mime_type': self._type, 'metaData': self._metadata, } response = client.post('/files/{}'.format(self._name), data) response.raise_for_status() content = response.json() self.id = content['objectId'] self._url = content['url'] self._name = content['name']
def send(self, query): current_user = User.get_current() if not current_user: raise ValueError('Please sign in an user') params = { 'inboxType': self.inbox_type, 'data': self._data, 'query': query.dump(), 'source': self._data.get('source') or current_user._to_pointer(), } params['query']['className'] = query._query_class._class_name content = client.post('/statuses', params=params).json() self.id = content['objectId'] self.created_at = utils.decode('createdAt', content['createdAt'])
def send(self, query): current_user = User.get_current() if not current_user: raise ValueError("Please sign in an user") params = { "inboxType": self.inbox_type, "data": self._data, "query": query.dump(), "source": self._data.get("source") or current_user._to_pointer(), } params["query"]["className"] = query._query_class._class_name content = client.post("/statuses", params=params).json() self.id = content["objectId"] self.created_at = utils.decode("createdAt", content["createdAt"])
def _save_to_leancloud(self): self._source.seek(0) encoded = codecs.encode(self._source.read(), 'base64') data = { 'base64': encoded.decode('utf-8'), '_ContentType': self._type, 'ACL': self._acl, 'mime_type': self._type, 'metaData': self._metadata, } response = client.post('/files/{}'.format(self._name), data) response.raise_for_status() content = response.json() self.id = content['objectId'] self._url = content['url'] self._name = content['name']
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 = response.json() user = cls() user._update_data(content) user._handle_save_result(True) if 'smsCode' not in content: user._attributes.pop('smsCode', None) return user
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 = response.json() user = cls() user._update_data(content) user._handle_save_result(True) if "smsCode" not in content: user._attributes.pop("smsCode", None) return user
def _get_file_token(self): hex_octet = lambda: hex(int(0x10000 * (1 + random.random())))[-4:] key = ''.join(hex_octet() for _ in range(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('/fileTokens', data) content = response.json() self.id = content['objectId'] self._url = content['url'] content['key'] = key return content
def _get_file_token(self): key = uuid.uuid4().hex if self.extension: key = '{0}.{1}'.format(key, self.extension) data = { 'name': self._name, 'key': key, 'ACL': self._acl, 'mime_type': self.mime_type, 'metaData': self._metadata, } response = client.post('/fileTokens', data) content = response.json() self.id = content['objectId'] self._url = content['url'] content['key'] = key return content
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 _save_external(self): data = { 'name': self._name, 'ACL': self._acl, 'metaData': self._metadata, 'mime_type': self.mime_type, 'url': self._url, } response = client.post('/files/{0}'.format(self._name), data) content = response.json() self._name = content['name'] self._url = content['url'] self.id = content['objectId'] if 'size' in content: self._metadata['size'] = content['size'] else: raise ValueError
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 = response.json() user = cls() user._update_data(content) user._handle_save_result(True) if 'smsCode' not in content: user._attributes.pop('smsCode', None) return user
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 _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: if obj.id is None: method = 'POST' path = '/{0}/classes/{1}'.format(client.SERVER_VERSION, obj._class_name) else: method = 'PUT' path = '/{0}/classes/{1}/{2}'.format(client.SERVER_VERSION, obj._class_name, obj.id) body = obj._dump_save() dumped_obj = { 'method': method, 'path': path, 'body': body, } dumped_objs.append(dumped_obj) response = client.post('/batch', params={'requests': dumped_objs}).json() errors = [] for idx, obj in enumerate(unsaved_children): content = response[idx] error = content.get('error') if error: errors.append(leancloud.LeanCloudError(error.get('code'), error.get('error'))) else: obj._update_data(content['success']) if errors: # TODO: how to raise list of errors? # raise MultipleValidationErrors(errors) # add test raise errors[0]
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 _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 = client.post('/batch', params={'requests': dumped_objs}).json() 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 request_login_sms_code(cls, phone_number): params = {"mobilePhoneNumber": phone_number} client.post("/requestLoginSmsCode", params)
def verify_mobile_phone_number(cls, sms_code): client.post("/verfyMobilePhone/" + sms_code, {})