Пример #1
0
    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()
Пример #2
0
 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)
Пример #3
0
 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)
Пример #4
0
 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)
Пример #5
0
    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()
Пример #6
0
 def f():
     try:
         client.post("/fileCallback", {
             "token": token,
             "result": successed
         })
     except LeanCloudError as e:
         logger.warning("call file callback failed, error: %s", e)
Пример #7
0
 def f():
     try:
         client.post('/fileCallback', {
             'token': token,
             'result': successed,
         })
     except LeanCloudError as e:
         logger.warning('call file callback failed, error: %s', e)
Пример #8
0
 def f():
     try:
         client.post('/fileCallback', {
             'token': token,
             'result': successed,
         })
     except LeanCloudError as e:
         logger.warning('call file callback failed, error: %s', e)
Пример #9
0
    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
Пример #10
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()

        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]
Пример #11
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))
Пример #12
0
 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']))
Пример #13
0
    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]
Пример #14
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())
Пример #15
0
    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))
Пример #16
0
 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']))
Пример #17
0
    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
Пример #18
0
    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))
Пример #19
0
    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
Пример #20
0
    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
Пример #21
0
    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
Пример #22
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 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
Пример #23
0
    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
Пример #24
0
    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
Пример #25
0
    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
Пример #26
0
 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"]
Пример #27
0
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
Пример #28
0
 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)
Пример #29
0
    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()
Пример #30
0
    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()
Пример #31
0
    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()
Пример #32
0
 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)
Пример #33
0
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]
Пример #34
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
Пример #36
0
 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
Пример #37
0
 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)
Пример #38
0
 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)
Пример #39
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
Пример #40
0
 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']
Пример #41
0
    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'])
Пример #42
0
    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"])
Пример #43
0
 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']
Пример #44
0
    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
Пример #45
0
    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'])
Пример #46
0
    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
Пример #47
0
 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
Пример #48
0
 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
Пример #49
0
    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
Пример #50
0
    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
Пример #51
0
    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
Пример #52
0
    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
Пример #53
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:
            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]
Пример #54
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
Пример #55
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 = 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]
Пример #56
0
 def request_login_sms_code(cls, phone_number):
     params = {"mobilePhoneNumber": phone_number}
     client.post("/requestLoginSmsCode", params)
Пример #57
0
 def verify_mobile_phone_number(cls, sms_code):
     client.post("/verfyMobilePhone/" + sms_code, {})