def send_message(self, fakeid, content):

url = '<STR_LIT>'<EOL>payload = {<EOL>'<STR_LIT>': fakeid,<EOL>'<STR_LIT:type>': <NUM_LIT:1>,<EOL>'<STR_LIT>': self.__token,<EOL>'<STR_LIT:content>': content,<EOL>'<STR_LIT>': <NUM_LIT:1>,<EOL>}<EOL>headers = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'.format(<EOL>fakeid=fakeid,<EOL>token=self.__token,<EOL>),<EOL>'<STR_LIT>': self.__cookies,<EOL>}<EOL>r = requests.post(url, data=payload, headers=headers)<EOL>try:<EOL><INDENT>message = json.loads(r.text)<EOL><DEDENT>except ValueError:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>try:<EOL><INDENT>if message['<STR_LIT>']['<STR_LIT>'] == -<NUM_LIT>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if message['<STR_LIT>']['<STR_LIT>'] != <NUM_LIT:0>:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT><DEDENT>except KeyError:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>

主动发送文本消息
:param fakeid: 用户的 UID (即 fakeid )
:param content: 发送的内容
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据
:raises ValueError: 参数出错, 具体内容有 ``fake id not exist``


url = '<STR_LIT>'<EOL>payload = {<EOL>'<STR_LIT:username>': self.__username,<EOL>'<STR_LIT>': self.__password,<EOL>'<STR_LIT>': verify_code,<EOL>'<STR_LIT:f>': '<STR_LIT>',<EOL>}<EOL>headers = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': self.__cookies,<EOL>}<EOL>r = requests.post(url, data=payload, headers=headers)<EOL>s = re.search(r'<STR_LIT>', r.text)<EOL>if not s:<EOL><INDENT>try:<EOL><INDENT>error_code = json.loads(r.text)['<STR_LIT>']['<STR_LIT>']<EOL><DEDENT>except (KeyError, ValueError):<EOL><INDENT>raise LoginError(r.text)<EOL><DEDENT>if error_code in [-<NUM_LIT:8>, -<NUM_LIT>]:<EOL><INDENT>raise LoginVerifyCodeError(r.text)<EOL><DEDENT>elif re.search(r'<STR_LIT>', r.text):<EOL><INDENT>raise LoginError('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>raise LoginError(r.text)<EOL><DEDENT><DEDENT>self.__token = int(s.group(<NUM_LIT:1>))<EOL>self.__cookies = '<STR_LIT>'<EOL>for cookie in r.cookies:<EOL><INDENT>self.__cookies += cookie.name + '<STR_LIT:=>' + cookie.value + '<STR_LIT:;>'<EOL><DEDENT>

登录微信公众平台
注意在实例化 ``WechatExt`` 的时候，如果没有传入 ``token`` 及 ``cookies`` ，将会自动调用该方法，无需手动调用
当且仅当捕获到 ``NeedLoginError`` 异常时才需要调用此方法进行登录重试
:param verify_code: 验证码, 不传入则为无验证码
:raises LoginVerifyCodeError: 需要验证码或验证码出错，该异常为 ``LoginError`` 的子类
:raises LoginError: 登录出错异常，异常内容为微信服务器响应的内容，可作为日志记录下来


if not self.__appid:<EOL><INDENT>self._init_plugin_token_appid()<EOL><DEDENT>

初始化公众号自身的 ``appid`` 值
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据


if not news:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>for item in news:<EOL><INDENT>if '<STR_LIT:title>' not in item or '<STR_LIT:content>' not in item:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT><DEDENT>url = '<STR_LIT>'.format(<EOL>token=self.__token,<EOL>)<EOL>payload = {<EOL>'<STR_LIT>': self.__token,<EOL>'<STR_LIT:type>': <NUM_LIT:10>,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': <NUM_LIT:1>,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT:error>': '<STR_LIT:false>',<EOL>}<EOL>headers = {<EOL>'<STR_LIT>': '<STR_LIT>'.format(<EOL>token=self.__token<EOL>),<EOL>'<STR_LIT>': self.__cookies,<EOL>}<EOL>i = <NUM_LIT:0><EOL>for item in news:<EOL><INDENT>payload['<STR_LIT:title>'+str(i)] = item.get('<STR_LIT:title>')<EOL>payload['<STR_LIT>'+str(i)] = item.get('<STR_LIT>')<EOL>payload['<STR_LIT>'+str(i)] = item.get('<STR_LIT>')<EOL>payload['<STR_LIT:content>'+str(i)] = item.get('<STR_LIT:content>')<EOL>payload['<STR_LIT>'+str(i)] = item.get('<STR_LIT>')<EOL>payload['<STR_LIT>'+str(i)] = item.get('<STR_LIT>')<EOL>i += <NUM_LIT:1><EOL><DEDENT>payload['<STR_LIT:count>'] = i<EOL>r = requests.post(url, data=payload, headers=headers)<EOL>try:<EOL><INDENT>message = json.loads(r.text)<EOL><DEDENT>except ValueError:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>try:<EOL><INDENT>if message['<STR_LIT>'] != '<STR_LIT:0>':<EOL><INDENT>raise ValueError(r.text)<EOL><DEDENT><DEDENT>except KeyError:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>

在素材库中创建图文消息

:param news: list 对象, 其中的每个元素为一个 dict 对象, 代表一条图文, key 值分别为 ``title``, ``author``, ``summary``,
             ``content``, ``picture_id``, ``from_url``, 对应内容为标题, 作者, 摘要, 内容, 素材库里的
             图片ID(可通过 ``upload_file`` 函数上传获取), 来源链接。

             其中必须提供的 key 值为 ``title`` 和 ``content``

             示例::

                 [
                     {
                         'title': '图文标题',
                         'author': '图文作者',
                         'summary': '图文摘要',
                         'content': '图文内容',
                         'picture_id': '23412341',
                         'from_url': 'http://www.baidu.com',
                     },
                     {
                         'title': '最少图文标题',
                         'content': '图文内容',
                     }
                 ]
:raises ValueError: 参数提供错误时抛出
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据


return self.send_file(fakeid, fid, <NUM_LIT:3>)<EOL>

给指定用户 fakeid 发送语音信息
:param fakeid: 用户的 UID (即 fakeid)
:param fid: 文件 ID
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据
:raises ValueError: 参数出错, 错误原因直接打印异常即可 (常见错误内容: ``system error`` 或 ``can not send this type of msg``: 文件类型不匹配, ``user not exist``: 用户 fakeid 不存在, ``file not exist``: 文件 fid 不存在, 还有其他错误请自行检查)


url = '<STR_LIT>'<EOL>payload = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT:f>': '<STR_LIT>',<EOL>'<STR_LIT>': fakeid,<EOL>'<STR_LIT:type>': <NUM_LIT:10>,<EOL>'<STR_LIT>': self.__token,<EOL>'<STR_LIT>': msgid,<EOL>'<STR_LIT>': msgid,<EOL>'<STR_LIT:error>': '<STR_LIT:false>',<EOL>'<STR_LIT>': <NUM_LIT:1>,<EOL>'<STR_LIT>': random.random(),<EOL>}<EOL>headers = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'.format(<EOL>fakeid=fakeid,<EOL>),<EOL>'<STR_LIT>': self.__cookies,<EOL>}<EOL>r = requests.post(url, data=payload, headers=headers)<EOL>try:<EOL><INDENT>message = json.loads(r.text)<EOL><DEDENT>except ValueError:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>try:<EOL><INDENT>if message['<STR_LIT>']['<STR_LIT>'] == <NUM_LIT> or message['<STR_LIT>']['<STR_LIT>'] == -<NUM_LIT>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if message['<STR_LIT>']['<STR_LIT>'] == <NUM_LIT>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if message['<STR_LIT>']['<STR_LIT>'] != <NUM_LIT:0>:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT><DEDENT>except KeyError:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>

向指定用户发送图文消息 （必须从图文库里选取消息ID传入)
:param fakeid: 用户的 UID (即 fakeid)
:param msgid: 图文消息 ID
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据
:raises ValueError: 参数出错, 具体内容有 ``fake id not exist`` 及 ``message id not exist``


return self.send_file(fakeid, fid, <NUM_LIT:2>)<EOL>

给指定用户 fakeid 发送图片信息
:param fakeid: 用户的 UID (即 fakeid)
:param fid: 文件 ID
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据
:raises ValueError: 参数出错, 错误原因直接打印异常即可 (常见错误内容: ``system error`` 或 ``can not send this type of msg``: 文件类型不匹配, ``user not exist``: 用户 fakeid 不存在, ``file not exist``: 文件 fid 不存在, 还有其他错误请自行检查)


def get_file_list(self, type, page, count=<NUM_LIT:10>):

url = '<STR_LIT>'.format(<EOL>token=self.__token,<EOL>type=type,<EOL>random=round(random.random(), <NUM_LIT:3>),<EOL>begin=page*count,<EOL>count=count,<EOL>)<EOL>headers = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'.format(<EOL>token=self.__token,<EOL>),<EOL>'<STR_LIT>': self.__cookies,<EOL>}<EOL>r = requests.get(url, headers=headers)<EOL>try:<EOL><INDENT>message = json.dumps(json.loads(r.text)['<STR_LIT>'], ensure_ascii=False)<EOL><DEDENT>except (KeyError, ValueError):<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>return message<EOL>

获取素材库文件列表

返回JSON示例::

    {
        "type": 2,
        "file_item": [
            {
                "update_time": 1408723089,
                "name": "Doraemonext.png",
                "play_length": 0,
                "file_id": 206471048,
                "type": 2,
                "size": "53.7 K"
            },
            {
                "update_time": 1408722328,
                "name": "Doraemonext.png",
                "play_length": 0,
                "file_id": 206470809,
                "type": 2,
                "size": "53.7 K"
            }
        ],
        "file_cnt": {
            "voice_cnt": 1,
            "app_msg_cnt": 10,
            "commondity_msg_cnt": 0,
            "video_cnt": 0,
            "img_cnt": 29,
            "video_msg_cnt": 0,
            "total": 40
        }
    }

:param type: 文件类型 (2: 图片, 3: 音频, 4: 视频)
:param page: 页码 (从 0 开始)
:param count: 每页大小
:return: 返回的 JSON 数据
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据


def stat_article_detail_list(self, page=<NUM_LIT:1>, start_date=str(date.today()+timedelta(days=-<NUM_LIT:30>)), end_date=str(date.today())):

self._init_plugin_token_appid()<EOL>url = '<STR_LIT>'.format(<EOL>page=page,<EOL>appid=self.__appid,<EOL>token=self.__plugin_token,<EOL>rnd=int(time.time()),<EOL>start_date=start_date,<EOL>end_date=end_date,<EOL>)<EOL>headers = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'.format(<EOL>page=page,<EOL>appid=self.__appid,<EOL>token=self.__plugin_token,<EOL>rnd=int(time.time()),<EOL>start_date=start_date,<EOL>end_date=end_date,<EOL>),<EOL>'<STR_LIT>': self.__cookies,<EOL>}<EOL>r = requests.get(url, headers=headers)<EOL>if not re.search(r'<STR_LIT>', self.__cookies):<EOL><INDENT>for cookie in r.cookies:<EOL><INDENT>self.__cookies += cookie.name + '<STR_LIT:=>' + cookie.value + '<STR_LIT:;>'<EOL><DEDENT><DEDENT>try:<EOL><INDENT>data = json.loads(r.text)<EOL>if data.get('<STR_LIT>'):<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>message = json.dumps(data, ensure_ascii=False)<EOL><DEDENT>except (KeyError, ValueError):<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>return message<EOL>

获取图文分析数据

返回JSON示例 ::

    {
        "hasMore": true,  // 说明是否可以增加 page 页码来获取数据
        "data": [
            {
                "index": [
                    "20,816",  // 送达人数
                    "1,944",  // 图文页阅读人数
                    "2,554",  // 图文页阅读次数
                    "9.34%",  // (图文页阅读人数 / 送达人数)
                    "0",  // 原文页阅读人数
                    "0",  // 原文页阅读次数
                    "0%",  // （原文页阅读人数 / 图文页阅读人数)
                    "47",  // 分享转发人数
                    "61",  // 分享转发次数
                    "1"  // 微信收藏人数
                ],
                "time": "2015-01-21",
                "table_data": "{\"fields\":{\"TargetUser\":{\"thText\":\"\\u9001\\u8fbe\\u4eba\\u6570\",\"number\":false,\"colAlign\":\"center\",\"needOrder\":false,\"precision\":0},\"IntPageReadUser\":{\"thText\":\"\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"IntPageReadCount\":{\"thText\":\"\\u6b21\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"PageConversion\":{\"thText\":\"\\u56fe\\u6587\\u8f6c\\u5316\\u7387\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":\"2\"},\"OriPageReadUser\":{\"thText\":\"\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"OriPageReadCount\":{\"thText\":\"\\u6b21\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"Conversion\":{\"thText\":\"\\u539f\\u6587\\u8f6c\\u5316\\u7387\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":\"2\"},\"ShareUser\":{\"thText\":\"\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"ShareCount\":{\"thText\":\"\\u6b21\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"AddToFavUser\":{\"thText\":\"\\u5fae\\u4fe1\\u6536\\u85cf\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0}},\"data\":[{\"MsgId\":\"205104027_1\",\"Title\":\"\\u56de\\u5bb6\\u5927\\u4f5c\\u6218 | \\u5feb\\u6765\\u5e26\\u6211\\u56de\\u5bb6\",\"RefDate\":\"20150121\",\"TargetUser\":\"20,816\",\"IntPageReadUser\":\"1,944\",\"IntPageReadCount\":\"2,554\",\"OriPageReadUser\":\"0\",\"OriPageReadCount\":\"0\",\"ShareUser\":\"47\",\"ShareCount\":\"61\",\"AddToFavUser\":\"1\",\"Conversion\":\"0%\",\"PageConversion\":\"9.34%\"}],\"fixedRow\":false,\"cssSetting\":{\"\":\"\"},\"complexHeader\":[[{\"field\":\"TargetUser\",\"thText\":\"\\u9001\\u8fbe\\u4eba\\u6570\",\"rowSpan\":2,\"colSpan\":1},{\"thText\":\"\\u56fe\\u6587\\u9875\\u9605\\u8bfb\",\"colSpan\":3},{\"thText\":\"\\u539f\\u6587\\u9875\\u9605\\u8bfb\",\"colSpan\":3},{\"thText\":\"\\u5206\\u4eab\\u8f6c\\u53d1\",\"colSpan\":2},{\"field\":\"AddToFavUser\",\"thText\":\"\\u5fae\\u4fe1\\u6536\\u85cf\\u4eba\\u6570\",\"rowSpan\":2,\"enable\":true}],[{\"field\":\"IntPageReadUser\",\"thText\":\"\\u4eba\\u6570\"},{\"field\":\"IntPageReadCount\",\"thText\":\"\\u6b21\\u6570\"},{\"field\":\"PageConversion\",\"thText\":\"\\u56fe\\u6587\\u8f6c\\u5316\\u7387\"},{\"field\":\"OriPageReadUser\",\"thText\":\"\\u4eba\\u6570\"},{\"field\":\"OriPageReadCount\",\"thText\":\"\\u6b21\\u6570\"},{\"field\":\"Conversion\",\"thText\":\"\\u539f\\u6587\\u8f6c\\u5316\\u7387\"},{\"field\":\"ShareUser\",\"thText\":\"\\u4eba\\u6570\"},{\"field\":\"ShareCount\",\"thText\":\"\\u6b21\\u6570\"}]]}",
                "id": "205104027_1",
                "title": "回家大作战 | 快来带我回家"
            },
            {
                "index": [
                    "20,786",  // 送达人数
                    "2,598",  // 图文页阅读人数
                    "3,368",  // 图文页阅读次数
                    "12.5%",  // (图文页阅读人数 / 送达人数)
                    "0",  // 原文页阅读人数
                    "0",  // 原文页阅读次数
                    "0%",  // （原文页阅读人数 / 图文页阅读人数)
                    "73",  // 分享转发人数
                    "98",  // 分享转发次数
                    "1"  // 微信收藏人数
                ],
                "time": "2015-01-20",
                "table_data": "{\"fields\":{\"TargetUser\":{\"thText\":\"\\u9001\\u8fbe\\u4eba\\u6570\",\"number\":false,\"colAlign\":\"center\",\"needOrder\":false,\"precision\":0},\"IntPageReadUser\":{\"thText\":\"\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"IntPageReadCount\":{\"thText\":\"\\u6b21\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"PageConversion\":{\"thText\":\"\\u56fe\\u6587\\u8f6c\\u5316\\u7387\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":\"2\"},\"OriPageReadUser\":{\"thText\":\"\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"OriPageReadCount\":{\"thText\":\"\\u6b21\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"Conversion\":{\"thText\":\"\\u539f\\u6587\\u8f6c\\u5316\\u7387\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":\"2\"},\"ShareUser\":{\"thText\":\"\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"ShareCount\":{\"thText\":\"\\u6b21\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"AddToFavUser\":{\"thText\":\"\\u5fae\\u4fe1\\u6536\\u85cf\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0}},\"data\":[{\"MsgId\":\"205066833_1\",\"Title\":\"\\u56de\\u5bb6\\u5927\\u4f5c\\u6218 | \\u5982\\u4f55\\u4f18\\u96c5\\u5730\\u53bb\\u5f80\\u8f66\\u7ad9\\u548c\\u673a\\u573a\",\"RefDate\":\"20150120\",\"TargetUser\":\"20,786\",\"IntPageReadUser\":\"2,598\",\"IntPageReadCount\":\"3,368\",\"OriPageReadUser\":\"0\",\"OriPageReadCount\":\"0\",\"ShareUser\":\"73\",\"ShareCount\":\"98\",\"AddToFavUser\":\"1\",\"Conversion\":\"0%\",\"PageConversion\":\"12.5%\"}],\"fixedRow\":false,\"cssSetting\":{\"\":\"\"},\"complexHeader\":[[{\"field\":\"TargetUser\",\"thText\":\"\\u9001\\u8fbe\\u4eba\\u6570\",\"rowSpan\":2,\"colSpan\":1},{\"thText\":\"\\u56fe\\u6587\\u9875\\u9605\\u8bfb\",\"colSpan\":3},{\"thText\":\"\\u539f\\u6587\\u9875\\u9605\\u8bfb\",\"colSpan\":3},{\"thText\":\"\\u5206\\u4eab\\u8f6c\\u53d1\",\"colSpan\":2},{\"field\":\"AddToFavUser\",\"thText\":\"\\u5fae\\u4fe1\\u6536\\u85cf\\u4eba\\u6570\",\"rowSpan\":2,\"enable\":true}],[{\"field\":\"IntPageReadUser\",\"thText\":\"\\u4eba\\u6570\"},{\"field\":\"IntPageReadCount\",\"thText\":\"\\u6b21\\u6570\"},{\"field\":\"PageConversion\",\"thText\":\"\\u56fe\\u6587\\u8f6c\\u5316\\u7387\"},{\"field\":\"OriPageReadUser\",\"thText\":\"\\u4eba\\u6570\"},{\"field\":\"OriPageReadCount\",\"thText\":\"\\u6b21\\u6570\"},{\"field\":\"Conversion\",\"thText\":\"\\u539f\\u6587\\u8f6c\\u5316\\u7387\"},{\"field\":\"ShareUser\",\"thText\":\"\\u4eba\\u6570\"},{\"field\":\"ShareCount\",\"thText\":\"\\u6b21\\u6570\"}]]}",
                "id": "205066833_1",
                "title": "回家大作战 | 如何优雅地去往车站和机场"
            },
            {
                "index": [
                    "20,745",  // 送达人数
                    "1,355",  // 图文页阅读人数
                    "1,839",  // 图文页阅读次数
                    "6.53%",  // (图文页阅读人数 / 送达人数)
                    "145",  // 原文页阅读人数
                    "184",  // 原文页阅读次数
                    "10.7%",  // （原文页阅读人数 / 图文页阅读人数)
                    "48",  // 分享转发人数
                    "64",  // 分享转发次数
                    "5"  // 微信收藏人数
                ],
                "time": "2015-01-19",
                "table_data": "{\"fields\":{\"TargetUser\":{\"thText\":\"\\u9001\\u8fbe\\u4eba\\u6570\",\"number\":false,\"colAlign\":\"center\",\"needOrder\":false,\"precision\":0},\"IntPageReadUser\":{\"thText\":\"\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"IntPageReadCount\":{\"thText\":\"\\u6b21\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"PageConversion\":{\"thText\":\"\\u56fe\\u6587\\u8f6c\\u5316\\u7387\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":\"2\"},\"OriPageReadUser\":{\"thText\":\"\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"OriPageReadCount\":{\"thText\":\"\\u6b21\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"Conversion\":{\"thText\":\"\\u539f\\u6587\\u8f6c\\u5316\\u7387\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":\"2\"},\"ShareUser\":{\"thText\":\"\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"ShareCount\":{\"thText\":\"\\u6b21\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0},\"AddToFavUser\":{\"thText\":\"\\u5fae\\u4fe1\\u6536\\u85cf\\u4eba\\u6570\",\"number\":true,\"colAlign\":\"right\",\"needOrder\":false,\"precision\":0}},\"data\":[{\"MsgId\":\"205028693_1\",\"Title\":\"\\u5145\\u7535\\u65f6\\u95f4 | \\u542c\\u542c\\u7535\\u53f0\\uff0c\\u4f18\\u96c5\\u5730\\u63d0\\u5347\\u5b66\\u4e60\\u6548\\u7387\",\"RefDate\":\"20150119\",\"TargetUser\":\"20,745\",\"IntPageReadUser\":\"1,355\",\"IntPageReadCount\":\"1,839\",\"OriPageReadUser\":\"145\",\"OriPageReadCount\":\"184\",\"ShareUser\":\"48\",\"ShareCount\":\"64\",\"AddToFavUser\":\"5\",\"Conversion\":\"10.7%\",\"PageConversion\":\"6.53%\"}],\"fixedRow\":false,\"cssSetting\":{\"\":\"\"},\"complexHeader\":[[{\"field\":\"TargetUser\",\"thText\":\"\\u9001\\u8fbe\\u4eba\\u6570\",\"rowSpan\":2,\"colSpan\":1},{\"thText\":\"\\u56fe\\u6587\\u9875\\u9605\\u8bfb\",\"colSpan\":3},{\"thText\":\"\\u539f\\u6587\\u9875\\u9605\\u8bfb\",\"colSpan\":3},{\"thText\":\"\\u5206\\u4eab\\u8f6c\\u53d1\",\"colSpan\":2},{\"field\":\"AddToFavUser\",\"thText\":\"\\u5fae\\u4fe1\\u6536\\u85cf\\u4eba\\u6570\",\"rowSpan\":2,\"enable\":true}],[{\"field\":\"IntPageReadUser\",\"thText\":\"\\u4eba\\u6570\"},{\"field\":\"IntPageReadCount\",\"thText\":\"\\u6b21\\u6570\"},{\"field\":\"PageConversion\",\"thText\":\"\\u56fe\\u6587\\u8f6c\\u5316\\u7387\"},{\"field\":\"OriPageReadUser\",\"thText\":\"\\u4eba\\u6570\"},{\"field\":\"OriPageReadCount\",\"thText\":\"\\u6b21\\u6570\"},{\"field\":\"Conversion\",\"thText\":\"\\u539f\\u6587\\u8f6c\\u5316\\u7387\"},{\"field\":\"ShareUser\",\"thText\":\"\\u4eba\\u6570\"},{\"field\":\"ShareCount\",\"thText\":\"\\u6b21\\u6570\"}]]}",
                "id": "205028693_1",
                "title": "充电时间 | 听听电台，优雅地提升学习效率"
            }
        ]
    }

:param page: 页码 (由于腾讯接口限制，page 从 1 开始，3 条数据为 1 页)
:param start_date: 开始时间，默认是今天-30天 (类型: str 格式示例: "2015-01-15")
:param end_date: 结束时间，默认是今天 (类型: str 格式示例: "2015-02-01")
:return: 返回的 JSON 数据，具体的各项内容解释参见上面的 JSON 返回示例
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据


url = '<STR_LIT>'<EOL>payloads = {<EOL>'<STR_LIT>': <NUM_LIT:1>,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': round(random.random(), <NUM_LIT:3>),<EOL>'<STR_LIT>': self.__token,<EOL>'<STR_LIT:t>': '<STR_LIT>',<EOL>'<STR_LIT>': fakeid,<EOL>}<EOL>headers = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'.format(<EOL>token=self.__token,<EOL>),<EOL>'<STR_LIT>': self.__cookies,<EOL>}<EOL>r = requests.post(url, data=payloads, headers=headers)<EOL>try:<EOL><INDENT>message = json.dumps(json.loads(r.text)['<STR_LIT>'], ensure_ascii=False)<EOL><DEDENT>except (KeyError, ValueError):<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>return message<EOL>

获取指定用户的个人信息

返回JSON示例::

    {
        "province": "湖北",
        "city": "武汉",
        "gender": 1,
        "nick_name": "Doraemonext",
        "country": "中国",
        "remark_name": "",
        "fake_id": 844735403,
        "signature": "",
        "group_id": 0,
        "user_name": ""
    }

:param fakeid: 用户的 UID (即 fakeid)
:return: 返回的 JSON 数据
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据


url = '<STR_LIT>'.format(token=self.__token)<EOL>headers = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': self.__cookies,<EOL>}<EOL>r = requests.get(url, headers=headers)<EOL>ticket_id = re.search(r'<STR_LIT>', r.text)<EOL>if not ticket_id:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>self.__ticket_id = ticket_id.group(<NUM_LIT:1>)<EOL>ticket = re.search(r'<STR_LIT>', r.text)<EOL>if not ticket:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>self.__ticket = ticket.group(<NUM_LIT:1>)<EOL>fakeid = re.search(r'<STR_LIT>', r.text)<EOL>if not fakeid:<EOL><INDENT>raise NeedLoginError(r.text)<EOL><DEDENT>self.__fakeid = fakeid.group(<NUM_LIT:1>)<EOL>

初始化公众号自身的属性值 (目前包括 ``Ticket`` 值 及 公众号自身的 ``fakeid`` 值)
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据


return self.get_message_list(count=<NUM_LIT:1>)<EOL>

获取最新一条消息

返回JSON示例::

    {
        "msg_item": [
            {
                "id": 206448489,
                "type": 2,
                "fakeid": "844735403",
                "nick_name": "Doraemonext",
                "date_time": 1408696938,
                "source": "",
                "msg_status": 4,
                "has_reply": 0,
                "refuse_reason": "",
                "multi_item": [ ],
                "to_uin": 2391068708,
                "send_stat": {
                    "total": 0,
                    "succ": 0,
                    "fail": 0
                }
            }
        ]
    }

:return: 返回的 JSON 数据
:raises NeedLoginError: 操作未执行成功, 需要再次尝试登录, 异常内容为服务器返回的错误数据


if not isinstance(data, list):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>result = []<EOL>for item in data:<EOL><INDENT>if isinstance(item, dict):<EOL><INDENT>result.append(cls._transcoding_dict(item))<EOL><DEDENT>elif isinstance(item, list):<EOL><INDENT>result.append(cls._transcoding_list(item))<EOL><DEDENT>else:<EOL><INDENT>result.append(item)<EOL><DEDENT><DEDENT>return result<EOL>

编码转换 for list
        :param data: 需要转换的 list 数据
        :return: 转换好的 list


if not data:<EOL><INDENT>return data<EOL><DEDENT>result = None<EOL>if isinstance(data, str) and hasattr(data, '<STR_LIT>'):<EOL><INDENT>result = data.decode('<STR_LIT:utf-8>')<EOL><DEDENT>else:<EOL><INDENT>result = data<EOL><DEDENT>return result<EOL>

编码转换
        :param data: 需要转换的数据
        :return: 转换好的数据


if not isinstance(data, dict):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>result = {}<EOL>for k, v in data.items():<EOL><INDENT>k = cls._transcoding(k)<EOL>if isinstance(v, dict):<EOL><INDENT>v = cls._transcoding_dict(v)<EOL><DEDENT>elif isinstance(v, list):<EOL><INDENT>v = cls._transcoding_list(v)<EOL><DEDENT>else:<EOL><INDENT>v = cls._transcoding(v)<EOL><DEDENT>result.update({k: v})<EOL><DEDENT>return result<EOL>

编码转换 for dict
:param data: 需要转换的 dict 数据
:return: 转换好的 dict


self.__token = token<EOL>self._update_crypto()<EOL>


return self.__appid<EOL>


return self.__paysignkey<EOL>

获取商户签名密钥 Key


if self.__encrypt_mode in ['<STR_LIT>', '<STR_LIT>'] and self.__encoding_aes_key is not None:<EOL><INDENT>if self.__token is None or self.__appid is None:<EOL><INDENT>raise NeedParamError('<STR_LIT>')<EOL><DEDENT>self.__crypto = BasicCrypto(self.__token, self.__encoding_aes_key, self.__appid)<EOL><DEDENT>else:<EOL><INDENT>self.__crypto = None<EOL><DEDENT>

根据当前配置内容更新 Crypto 类


def set_appid_appsecret(self, appid, appsecret):

self.__appid = appid<EOL>self.__appsecret = appsecret<EOL>self._update_crypto()<EOL>


self.__encoding_aes_key = encoding_aes_key<EOL>self._update_crypto()<EOL>


return self.__crypto<EOL>

获取当前 Crypto 实例


self._check_appid_appsecret()<EOL>if callable(self.__jsapi_ticket_refreshfunc):<EOL><INDENT>self.__jsapi_ticket, self.__jsapi_ticket_expires_at = self.__jsapi_ticket_refreshfunc()<EOL>return<EOL><DEDENT>response_json = self.__request.get(<EOL>url="<STR_LIT>",<EOL>params={<EOL>"<STR_LIT:type>": "<STR_LIT>",<EOL>},<EOL>access_token=self.access_token,<EOL>)<EOL>self.__jsapi_ticket = response_json['<STR_LIT>']<EOL>self.__jsapi_ticket_expires_at = int(time.time()) + response_json['<STR_LIT>']<EOL>if callable(self.__jsapi_ticket_setfunc):<EOL><INDENT>self.__jsapi_ticket_setfunc(self.__jsapi_ticket, self.__jsapi_ticket_expires_at)<EOL><DEDENT>return response_json<EOL>

获取 jsapi ticket 并更新当前配置
:return: 返回的 JSON 数据包 (传入 jsapi_ticket_refreshfunc 参数后返回 None)


self._check_appid_appsecret()<EOL>if callable(self.__access_token_refreshfunc):<EOL><INDENT>self.__access_token, self.__access_token_expires_at = self.__access_token_refreshfunc()<EOL>return<EOL><DEDENT>response_json = self.__request.get(<EOL>url="<STR_LIT>",<EOL>params={<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": self.__appid,<EOL>"<STR_LIT>": self.__appsecret,<EOL>},<EOL>access_token=self.__access_token<EOL>)<EOL>self.__access_token = response_json['<STR_LIT>']<EOL>self.__access_token_expires_at = int(time.time()) + response_json['<STR_LIT>']<EOL>if callable(self.__access_token_setfunc):<EOL><INDENT>self.__access_token_setfunc(self.__access_token, self.__access_token_expires_at)<EOL><DEDENT>return response_json<EOL>

获取 access token 并更新当前配置
:return: 返回的 JSON 数据包 (传入 access_token_refreshfunc 参数后返回 None)


self._check_appid_appsecret()<EOL>if callable(self.__jsapi_ticket_getfunc):<EOL><INDENT>self.__jsapi_ticket, self.__jsapi_ticket_expires_at = self.__jsapi_ticket_getfunc()<EOL><DEDENT>if self.__jsapi_ticket:<EOL><INDENT>now = time.time()<EOL>if self.__jsapi_ticket_expires_at - now > <NUM_LIT>:<EOL><INDENT>return self.__jsapi_ticket<EOL><DEDENT><DEDENT>self.grant_jsapi_ticket()  <EOL>return self.__jsapi_ticket<EOL>

获取当前 jsapi ticket 值, 本方法会自行维护 jsapi ticket 有效性


def __init__(self, token=None, appid=None, appsecret=None, partnerid=None,<EOL>partnerkey=None, paysignkey=None, access_token=None, access_token_expires_at=None,<EOL>jsapi_ticket=None, jsapi_ticket_expires_at=None, checkssl=False, conf=None):

if conf is not None:<EOL><INDENT>self.__conf = conf<EOL><DEDENT>elif isinstance(token, WechatConf):  <EOL><INDENT>self.__conf = token<EOL><DEDENT>else:  <EOL><INDENT>self.__conf = WechatConf(<EOL>token=token,<EOL>appid=appid,<EOL>appsecret=appsecret,<EOL>access_token=access_token,<EOL>access_token_expires_at=access_token_expires_at,<EOL>jsapi_ticket=jsapi_ticket,<EOL>jsapi_ticket_expires_at=jsapi_ticket_expires_at,<EOL>encrypt_mode='<STR_LIT>',<EOL>partnerid=partnerid,<EOL>partnerkey=partnerkey,<EOL>paysignkey=paysignkey,<EOL>checkssl=checkssl,<EOL>)<EOL><DEDENT>self.__request = WechatRequest(conf=self.__conf)<EOL>self.__is_parse = False<EOL>self.__message = None<EOL>

:param token: 微信 Token
:param appid: App ID
:param appsecret: App Secret
:param partnerid: 财付通商户身份标识, 支付权限专用
:param partnerkey: 财付通商户权限密钥 Key, 支付权限专用
:param paysignkey: 商户签名密钥 Key, 支付权限专用
:param access_token: 直接导入的 access_token 值, 该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取
:param access_token_expires_at: 直接导入的 access_token 的过期日期，该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取
:param jsapi_ticket: 直接导入的 jsapi_ticket 值, 该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取
:param jsapi_ticket_expires_at: 直接导入的 jsapi_ticket 的过期日期，该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取
:param checkssl: 是否检查 SSL, 默认为 False, 可避免 urllib3 的 InsecurePlatformWarning 警告
:param conf: WechatConf 配置类, 提供此参数将默认忽略其他所有参数, 所有数据均从此配置类中获取


def response_video(self, media_id, title=None, description=None):

self._check_parse()<EOL>title = self._transcoding(title)<EOL>description = self._transcoding(description)<EOL>response = VideoReply(message=self.__message, media_id=media_id, title=title, description=description).render()<EOL>return self._encrypt_response(response)<EOL>

将 media_id 所代表的视频组装为符合微信服务器要求的响应数据
:param media_id: 视频的 MediaID
:param title: 视频消息的标题
:param description: 视频消息的描述
:return: 符合微信服务器要求的 XML 响应数据


self._check_parse()<EOL>for article in articles:<EOL><INDENT>if article.get('<STR_LIT:title>'):<EOL><INDENT>article['<STR_LIT:title>'] = self._transcoding(article['<STR_LIT:title>'])<EOL><DEDENT>if article.get('<STR_LIT:description>'):<EOL><INDENT>article['<STR_LIT:description>'] = self._transcoding(article['<STR_LIT:description>'])<EOL><DEDENT>if article.get('<STR_LIT>'):<EOL><INDENT>article['<STR_LIT>'] = self._transcoding(article['<STR_LIT>'])<EOL><DEDENT>if article.get('<STR_LIT:url>'):<EOL><INDENT>article['<STR_LIT:url>'] = self._transcoding(article['<STR_LIT:url>'])<EOL><DEDENT><DEDENT>news = ArticleReply(message=self.__message)<EOL>for article in articles:<EOL><INDENT>article = Article(**article)<EOL>news.add_article(article)<EOL><DEDENT>response = news.render()<EOL>return self._encrypt_response(response)<EOL>

将新闻信息组装为符合微信服务器要求的响应数据
:param articles: list 对象, 每个元素为一个 dict 对象, key 包含 `title`, `description`, `picurl`, `url`
:return: 符合微信服务器要求的 XML 响应数据


if not self.__is_parse:<EOL><INDENT>raise NeedParseError()<EOL><DEDENT>

检查是否成功解析微信服务器传来的数据
:raises NeedParseError: 需要解析微信服务器传来的数据


if "<STR_LIT>" in json_data and json_data["<STR_LIT>"] != <NUM_LIT:0>:<EOL><INDENT>raise OfficialAPIError(errcode=json_data.get('<STR_LIT>'), errmsg=json_data.get('<STR_LIT>', '<STR_LIT>'))<EOL><DEDENT>

检测微信公众平台返回值中是否包含错误的返回码
:raises OfficialAPIError: 如果返回码提示有错误，抛出异常；否则返回 True


def send_video_message(self, user_id, media_id, title=None, description=None):

video_data = {<EOL>'<STR_LIT>': media_id,<EOL>}<EOL>if title:<EOL><INDENT>video_data['<STR_LIT:title>'] = title<EOL><DEDENT>if description:<EOL><INDENT>video_data['<STR_LIT:description>'] = description<EOL><DEDENT>return self.request.post(<EOL>url='<STR_LIT>',<EOL>data={<EOL>'<STR_LIT>': user_id,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': video_data,<EOL>}<EOL>)<EOL>

发送视频消息
详情请参考 http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html
:param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source
:param media_id: 发送的视频的媒体ID。 可以通过 :func:`upload_media` 上传。
:param title: 视频消息的标题
:param description: 视频消息的描述
:return: 返回的 JSON 数据包


return self.request.post(<EOL>url='<STR_LIT>',<EOL>data={<EOL>'<STR_LIT>': openid,<EOL>}<EOL>)<EOL>

查询用户所在分组
详情请参考 http://mp.weixin.qq.com/wiki/13/be5272dc4930300ba561d927aead2569.html
:param openid: 用户的OpenID
:return: 返回的 JSON 数据包


return requests.get(<EOL>url='<STR_LIT>',<EOL>params={<EOL>'<STR_LIT>': ticket<EOL>}<EOL>)<EOL>

通过ticket换取二维码
详情请参考 http://mp.weixin.qq.com/wiki/18/28fc21e7ed87bec960651f0ce873ef8a.html
:param ticket: 二维码 ticket 。可以通过 :func:`create_qrcode` 获取到
:return: 返回的 Request 对象


return self.request.get('<STR_LIT>')<EOL>

查询所有分组
详情请参考 http://mp.weixin.qq.com/wiki/13/be5272dc4930300ba561d927aead2569.html
:return: 返回的 JSON 数据包


return self.request.post(<EOL>url='<STR_LIT>',<EOL>data={<EOL>'<STR_LIT>': {<EOL>'<STR_LIT:name>': name,<EOL>},<EOL>}<EOL>)<EOL>

创建分组
详情请参考 http://mp.weixin.qq.com/wiki/13/be5272dc4930300ba561d927aead2569.html
:param name: 分组名字（30个字符以内）
:return: 返回的 JSON 数据包
:raise HTTPError: 微信api http 请求失败


def parse_data(self, data, msg_signature=None, timestamp=None, nonce=None):

result = {}<EOL>if isinstance(data, six.text_type):  <EOL><INDENT>data = data.encode('<STR_LIT:utf-8>')<EOL><DEDENT>if self.conf.encrypt_mode == '<STR_LIT>':<EOL><INDENT>if not (msg_signature and timestamp and nonce):<EOL><INDENT>raise ParseError('<STR_LIT>')<EOL><DEDENT>data = self.conf.crypto.decrypt_message(<EOL>msg=data,<EOL>msg_signature=msg_signature,<EOL>timestamp=timestamp,<EOL>nonce=nonce,<EOL>)<EOL><DEDENT>try:<EOL><INDENT>xml = XMLStore(xmlstring=data)<EOL><DEDENT>except Exception:<EOL><INDENT>raise ParseError()<EOL><DEDENT>result = xml.xml2dict<EOL>result['<STR_LIT>'] = data<EOL>result['<STR_LIT:type>'] = result.pop('<STR_LIT>').lower()<EOL>message_type = MESSAGE_TYPES.get(result['<STR_LIT:type>'], UnknownMessage)<EOL>self.__message = message_type(result)<EOL>self.__is_parse = True<EOL>

解析微信服务器发送过来的数据并保存类中
:param data: HTTP Request 的 Body 数据
:param msg_signature: EncodingAESKey 的 msg_signature
:param timestamp: EncodingAESKey 用时间戳
:param nonce: EncodingAESKey 用随机数
:raises ParseError: 解析微信服务器数据错误, 数据不合法


def send_image_message(self, user_id, media_id):

return self.request.post(<EOL>url='<STR_LIT>',<EOL>data={<EOL>'<STR_LIT>': user_id,<EOL>'<STR_LIT>': '<STR_LIT:image>',<EOL>'<STR_LIT:image>': {<EOL>'<STR_LIT>': media_id,<EOL>},<EOL>}<EOL>)<EOL>

发送图片消息
详情请参考 http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html
:param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source
:param media_id: 图片的媒体ID。 可以通过 :func:`upload_media` 上传。
:return: 返回的 JSON 数据包


def set_template_industry(self, industry_id1, industry_id2):

return self.request.post(<EOL>url='<STR_LIT>',<EOL>data={<EOL>'<STR_LIT>': str(industry_id1),<EOL>'<STR_LIT>': str(industry_id2),<EOL>}<EOL>)<EOL>

设置所属行业
详情请参考 http://mp.weixin.qq.com/wiki/17/304c1885ea66dbedf7dc170d84999a9d.html
:param industry_id1: 主营行业代码
:param industry_id2: 副营行业代码
:return: 返回的 JSON 数据包


return self.conf.grant_access_token()<EOL>

获取 Access Token
详情请参考 http://mp.weixin.qq.com/wiki/11/0e4b294685f817b95cbed85ba5e82b8f.html
:return: 返回的 JSON 数据包


def send_article_message(self, user_id, articles=None, media_id=None):

<EOL>if articles is None and media_id is None:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>if articles:<EOL><INDENT>articles_data = []<EOL>for article in articles:<EOL><INDENT>article = Article(**article)<EOL>articles_data.append({<EOL>'<STR_LIT:title>': article.title,<EOL>'<STR_LIT:description>': article.description,<EOL>'<STR_LIT:url>': article.url,<EOL>'<STR_LIT>': article.picurl,<EOL>})<EOL><DEDENT>return self.request.post(<EOL>url='<STR_LIT>',<EOL>data={<EOL>'<STR_LIT>': user_id,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': articles_data,<EOL>},<EOL>}<EOL>)<EOL><DEDENT>return self.request.post(<EOL>url='<STR_LIT>',<EOL>data={<EOL>'<STR_LIT>': user_id,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': media_id,<EOL>},<EOL>}<EOL>)<EOL>

发送图文消息
详情请参考 http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html
:param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source
:param articles: list 对象, 每个元素为一个 dict 对象, key 包含 `title`, `description`, `picurl`, `url`
:param media_id: 待发送的图文 Media ID
:return: 返回的 JSON 数据包


self.__conf = conf<EOL>self.__request = WechatRequest(conf=self.__conf)<EOL>


self.__request = request<EOL>


def get_user_info(self, user_id, lang='<STR_LIT>'):

return self.request.get(<EOL>url='<STR_LIT>',<EOL>params={<EOL>'<STR_LIT>': user_id,<EOL>'<STR_LIT>': lang,<EOL>}<EOL>)<EOL>

获取用户基本信息
详情请参考 http://mp.weixin.qq.com/wiki/14/bb5031008f1494a59c6f71fa0f319c66.html
:param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source
:param lang: 返回国家地区语言版本，zh_CN 简体，zh_TW 繁体，en 英语
:return: 返回的 JSON 数据包


return self.request.post(<EOL>url='<STR_LIT>',<EOL>data={<EOL>'<STR_LIT>': {<EOL>'<STR_LIT:id>': int(group_id),<EOL>'<STR_LIT:name>': name,<EOL>}<EOL>}<EOL>)<EOL>

修改分组名
详情请参考 http://mp.weixin.qq.com/wiki/13/be5272dc4930300ba561d927aead2569.html
:param group_id: 分组id，由微信分配
:param name: 分组名字（30个字符以内）
:return: 返回的 JSON 数据包


查询自定义菜单
详情请参考 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html
:return: 返回的 JSON 数据包


return self.__request<EOL>


self._check_parse()<EOL>response = ImageReply(message=self.__message, media_id=media_id).render()<EOL>return self._encrypt_response(response)<EOL>

将 media_id 所代表的图片组装为符合微信服务器要求的响应数据
:param media_id: 图片的 MediaID
:return: 符合微信服务器要求的 XML 响应数据


d = {}<EOL>for node in parent.childNodes:<EOL><INDENT>if not isinstance(node, minidom.Element):<EOL><INDENT>continue<EOL><DEDENT>if not node.hasChildNodes():<EOL><INDENT>continue<EOL><DEDENT>if node.childNodes[<NUM_LIT:0>].nodeType == minidom.Node.ELEMENT_NODE:<EOL><INDENT>try:<EOL><INDENT>d[node.tagName]<EOL><DEDENT>except KeyError:<EOL><INDENT>d[node.tagName] = []<EOL><DEDENT>d[node.tagName].append(self._element2dict(node))<EOL><DEDENT>elif len(node.childNodes) == <NUM_LIT:1> and node.childNodes[<NUM_LIT:0>].nodeType in [minidom.Node.CDATA_SECTION_NODE, minidom.Node.TEXT_NODE]:<EOL><INDENT>d[node.tagName] = node.childNodes[<NUM_LIT:0>].data<EOL><DEDENT><DEDENT>return d<EOL>

将单个节点转换为 dict


def _check_signature(self, msg_signature, timestamp, nonce, echostr):

signature = get_sha1_signature(self.__token, timestamp, nonce, echostr)<EOL>if not signature == msg_signature:<EOL><INDENT>raise ValidateSignatureError()<EOL><DEDENT>try:<EOL><INDENT>return self.__pc.decrypt(echostr, self.__id)<EOL><DEDENT>except DecryptAESError as e:<EOL><INDENT>raise ValidateSignatureError(e)<EOL><DEDENT>

验证签名有效性

        :param msg_signature: 签名串，对应URL参数的msg_signature
        :param timestamp: 时间戳，对应URL参数的timestamp
        :param nonce: 随机串，对应URL参数的nonce
        :param echostr: 随机串，对应URL参数的echostr
        :return: 解密之后的echostr
        :raise ValidateSignatureError: 签名无效异常


def __init__(self, token, encoding_aes_key, _id):

self.__key = base64.b64decode(to_binary(encoding_aes_key) + to_binary('<STR_LIT:=>'))<EOL>if len(self.__key) != <NUM_LIT:32>:<EOL><INDENT>raise ValidateAESKeyError(encoding_aes_key)<EOL><DEDENT>self.__token = to_binary(token)<EOL>self.__id = to_binary(_id)<EOL>self.__pc = BaseCrypto(self.__key)<EOL>

构造函数

        :param token: 公众平台上，开发者设置的Token
        :param encoding_aes_key: 公众平台上，开发者设置的EncodingAESKey
        :param _id: 公众号的 appid 或企业号的 corpid


try:<EOL><INDENT>cryptor = AES.new(self.key, self.mode, self.key[:<NUM_LIT:16>])<EOL>plain_text = cryptor.decrypt(base64.b64decode(text))<EOL><DEDENT>except Exception as e:<EOL><INDENT>raise DecryptAESError(e)<EOL><DEDENT>try:<EOL><INDENT>if six.PY2:<EOL><INDENT>pad = ord(plain_text[-<NUM_LIT:1>])<EOL><DEDENT>else:<EOL><INDENT>pad = plain_text[-<NUM_LIT:1>]<EOL><DEDENT>content = plain_text[<NUM_LIT:16>:-pad]<EOL>xml_len = socket.ntohl(struct.unpack("<STR_LIT:I>", content[: <NUM_LIT:4>])[<NUM_LIT:0>])<EOL>xml_content = content[<NUM_LIT:4>: xml_len + <NUM_LIT:4>]<EOL>from_appid = content[xml_len + <NUM_LIT:4>:]<EOL><DEDENT>except Exception as e:<EOL><INDENT>raise IllegalBuffer(e)<EOL><DEDENT>if from_appid != appid:<EOL><INDENT>raise ValidateAppIDError()<EOL><DEDENT>return xml_content<EOL>

对解密后的明文进行补位删除

        @param text: 密文
        @return: 删除填充补位后的明文


<EOL>text = self.get_random_str() + struct.pack("<STR_LIT:I>", socket.htonl(len(text))) + to_binary(text) + appid<EOL>pkcs7 = PKCS7Encoder()<EOL>text = pkcs7.encode(text)<EOL>cryptor = AES.new(self.key, self.mode, self.key[:<NUM_LIT:16>])<EOL>try:<EOL><INDENT>ciphertext = cryptor.encrypt(text)<EOL>return base64.b64encode(ciphertext)<EOL><DEDENT>except Exception as e:<EOL><INDENT>raise EncryptAESError(e)<EOL><DEDENT>

对明文进行加密

        @param text: 需要加密的明文
        @return: 加密得到的字符串


rule = string.ascii_letters + string.digits<EOL>return "<STR_LIT>".join(random.sample(rule, <NUM_LIT:16>))<EOL>

随机生成16位字符串

        @return: 16位字符串


def __init__(self, message, media_id, title=None, description=None):

title = title or '<STR_LIT>'<EOL>description = description or '<STR_LIT>'<EOL>super(VideoReply, self).__init__(message=message, media_id=media_id, title=title, description=description)<EOL>

:param message: WechatMessage对象
:param media_id: 视频的 MediaID
:param title: 视频消息的标题
:param description: 视频消息的描述


super(GroupTransferReply, self).__init__(message=message)<EOL>


super(VoiceReply, self).__init__(message=message, media_id=media_id)<EOL>

:param message: WechatMessage 对象
:param media_id: 语音的 MediaID


table = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>}<EOL>if extension in table:<EOL><INDENT>return table[extension]<EOL><DEDENT>raise ValueError("<STR_LIT>")<EOL>

将扩展名转换为 MIME 格式
    :return: mime string


raise NotImplementedError('<STR_LIT>')<EOL>


self._player_interface.UnHideVideo()<EOL>

Shows the video (to undo a `hide_video`)


return self._player_interface.Previous()<EOL>

Skip to the previous chapter

Returns:
    bool: Whether the player skipped to the previous chapter


return self._player_interface_property('<STR_LIT>')<EOL>

Returns:
    str: one of ("Playing" | "Paused" | "Stopped")


self._player_interface.SetAspectMode(ObjectPath('<STR_LIT>'), String(mode))<EOL>

Set the aspect mode of the video

Args:
    mode (str): One of ("letterbox" | "fill" | "stretch")


if self._process is None:<EOL><INDENT>logger.debug('<STR_LIT>')<EOL>return<EOL><DEDENT>try:<EOL><INDENT>logger.debug('<STR_LIT>')<EOL>process_group_id = os.getpgid(self._process.pid)<EOL>os.killpg(process_group_id, signal.SIGTERM)<EOL>logger.debug('<STR_LIT>' % process_group_id)<EOL>self._process_monitor.join()<EOL><DEDENT>except OSError:<EOL><INDENT>logger.error('<STR_LIT>')<EOL><DEDENT>self._process = None<EOL>

Quit the player, blocking until the process has died


return self._position_us() / (<NUM_LIT> * <NUM_LIT>)<EOL>


Returns:
    bool: whether the player can pause


Returns:
    float: maximum playback rate (as proportion of normal rate)


return self._player_interface.Next()<EOL>

Skip to the next chapter

Returns:
    bool: Whether the player skipped to the next chapter


@_check_player_is_active<EOL><INDENT>@_from_dbus_type<EOL>def set_video_crop(self, x1, y1, x2, y2):<DEDENT>

crop = "<STR_LIT>" % (str(x1),str(y1),str(x2),str(y2))<EOL>self._player_interface.SetVideoCropPos(ObjectPath('<STR_LIT>'), String(crop))<EOL>

Args:
    x1 (int): Top left x coordinate (px)
    y1 (int): Top left y coordinate (px)
    x2 (int): Bottom right x coordinate (px)
    y2 (int): Bottom right y coordinate (px)


if not self.is_playing():<EOL><INDENT>self.play_pause()<EOL>self._is_playing = True<EOL>self.playEvent(self)<EOL><DEDENT>

Play the video asynchronously returning control immediately to the calling code


return self._player_interface.ListAudio()<EOL>

Returns:
    [str]: A list of all known audio streams, each item is in the
           format: ``<index>:<language>:<name>:<codec>:<active>``


self._player_interface.PlayPause()<EOL>self._is_playing = not self._is_playing<EOL>if self._is_playing:<EOL><INDENT>self.playEvent(self)<EOL><DEDENT>else:<EOL><INDENT>self.pauseEvent(self)<EOL><DEDENT>

Pause playback if currently playing, otherwise start playing if currently paused.


Returns:
    bool: whether the player can seek


@_check_player_is_active<EOL><INDENT>@_from_dbus_type<EOL>def set_video_pos(self, x1, y1, x2, y2):<DEDENT>

position = "<STR_LIT>" % (str(x1),str(y1),str(x2),str(y2))<EOL>self._player_interface.VideoPos(ObjectPath('<STR_LIT>'), String(position))<EOL>

Set the video position on the screen

Args:
    x1 (int): Top left x coordinate (px)
    y1 (int): Top left y coordinate (px)
    x2 (int): Bottom right x coordinate (px)
    y2 (int): Bottom right y coordinate (px)


return self._player_interface.ShowSubtitles()<EOL>

Shows subtitles after :class:`hide_subtitles`


self._player_interface.SetAlpha(ObjectPath('<STR_LIT>'), Int64(alpha))<EOL>

Set the transparency of the video overlay

Args:
    alpha (float): The transparency (0..255)


return self._rate<EOL>

Returns:
    float: playback rate, 1 is the normal rate, 2 would be double speed.


self._rate = self._player_interface_property('<STR_LIT>', dbus.Double(rate))<EOL>return self._rate<EOL>

Set the playback rate of the video as a multiple of the default playback speed

Examples:
    >>> player.set_rate(2)
    # Will play twice as fast as normal speed
    >>> player.set_rate(0.5)
    # Will play half speed


return self._player_interface.SelectAudio(dbus.Int32(index))<EOL>

Select audio stream specified by the index of the stream in :class:`list_audio`

Args:
    index (int): index of audio stream returned by :class:`list_audio`


<EOL>if volume == <NUM_LIT:0>:<EOL><INDENT>volume = <NUM_LIT><EOL><DEDENT>return self._player_interface_property('<STR_LIT>', dbus.Double(volume))<EOL>

Args:
    float: volume in the interval [0, 10]


self._player_interface.Stop()<EOL>self.stopEvent(self)<EOL>


return self._root_interface_property('<STR_LIT>')<EOL>

Returns:
    str: list of supported URI schemes
Examples:
    >>> player.supported_uri_schemes()
    ["file", "http", "rtsp", "rtmp"]


return self._player_interface.HideSubtitles()<EOL>


Returns:
    bool: whether the player can quit or not


if self._is_muted:<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>return self._player_interface_property('<STR_LIT>')<EOL>

Returns:
    float: current player volume


self._is_muted = True<EOL>self._player_interface.Mute()<EOL>

Mute audio. If already muted, then this does not do anything


return self._player_interface_property('<STR_LIT>')<EOL>


return self._player_interface.SelectSubtitle(dbus.Int32(index))<EOL>

Enable a subtitle specified by the index it is listed in :class:`list_subtitles`

Args:
    index (int): index of subtitle listing returned by :class:`list_subtitles`


Returns:
    bool: whether the player can move to the next item in the playlist


self._is_muted = False<EOL>self._player_interface.Unmute()<EOL>

Unmutes the video. If already unmuted, then this does not do anything


Returns:
    bool: whether the player has a track list or not


possible_address_files = []<EOL>while not possible_address_files:<EOL><INDENT>isnt_pid_file = lambda path: not path.endswith('<STR_LIT>')<EOL>possible_address_files = list(filter(isnt_pid_file,<EOL>glob('<STR_LIT>')))<EOL>possible_address_files.sort(key=lambda path: os.path.getmtime(path))<EOL>time.sleep(<NUM_LIT>)<EOL><DEDENT>self.path = possible_address_files[-<NUM_LIT:1>]<EOL>

Finds the OMXPlayer DBus connection
Assumes there is an alive OMXPlayer process.
:return:


@wraps(f)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>raise_exception = kwargs.pop('<STR_LIT>', False)<EOL>try:<EOL><INDENT>return f(*args, **kwargs)<EOL><DEDENT>except KeyboardInterrupt:<EOL><INDENT>if not raise_exception:<EOL><INDENT>sys.exit()<EOL><DEDENT>raise KeyboardInterrupt<EOL><DEDENT><DEDENT>return wrapper<EOL>

Decorator that allows user to exit script by sending a keyboard interrupt
    (ctrl + c) without raising an exception.


fmts = ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>')<EOL>if fmt not in fmts:<EOL><INDENT>eprint("<STR_LIT>".format(fmt, fmts))<EOL>return<EOL><DEDENT>def stringify(val):<EOL><INDENT>if type(val) in (list, tuple):<EOL><INDENT>return '<STR_LIT:U+002CU+0020>'.join(str(e) for e in val)<EOL><DEDENT>return val<EOL><DEDENT>if fmt == '<STR_LIT>':<EOL><INDENT>return json.dumps(self.answers)<EOL><DEDENT>elif fmt == '<STR_LIT>':<EOL><INDENT>answers = [[k, v] for k, v in self.answers.items()]<EOL>return json.dumps(answers)<EOL><DEDENT>elif fmt == '<STR_LIT>':<EOL><INDENT>answers = '<STR_LIT:\n>'.join('<STR_LIT>'.format(k, stringify(v)) for k, v in self.answers.items())<EOL>return answers<EOL><DEDENT>


return self.questions.pop(key)<EOL>

Remove all questions associated with `key`. Raises exception if `key`
        doesn't exist.


if '<STR_LIT>' in kwargs and isinstance(kwargs['<STR_LIT>'], Question):<EOL><INDENT>question = kwargs['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>question = Question(*args, **kwargs)<EOL><DEDENT>self.questions.setdefault(question.key, []).append(question)<EOL>return question<EOL>

Add a Question instance to the questions dict. Each key points
        to a list of Question instances with that key. Use the `question`
        kwarg to pass a Question instance if you want, or pass in the same
        args you would pass to instantiate a question.


@register(key='<STR_LIT>')<EOL>def one(prompt, *args, **kwargs):

indicator = '<STR_LIT>'<EOL>if sys.version_info < (<NUM_LIT:3>, <NUM_LIT:0>):<EOL><INDENT>indicator = '<STR_LIT:>>'<EOL><DEDENT>def go_back(picker):<EOL><INDENT>return None, -<NUM_LIT:1><EOL><DEDENT>options, verbose_options = prepare_options(args)<EOL>idx = kwargs.get('<STR_LIT>', <NUM_LIT:0>)<EOL>picker = Picker(verbose_options, title=prompt, indicator=indicator, default_index=idx)<EOL>picker.register_custom_handler(ord('<STR_LIT:h>'), go_back)<EOL>picker.register_custom_handler(curses.KEY_LEFT, go_back)<EOL>with stdout_redirected(sys.stderr):<EOL><INDENT>option, index = picker.start()<EOL>if index == -<NUM_LIT:1>:<EOL><INDENT>raise QuestionnaireGoBack<EOL><DEDENT>if kwargs.get('<STR_LIT>', False):<EOL><INDENT>return index<EOL><DEDENT>return options[index]<EOL><DEDENT>

Instantiates a picker, registers custom handlers for going back,
    and starts the picker.


@register(key='<STR_LIT>')<EOL>def many(prompt, *args, **kwargs):

def get_options(options, chosen):<EOL><INDENT>return [options[i] for i, c in enumerate(chosen) if c]<EOL><DEDENT>def get_verbose_options(verbose_options, chosen):<EOL><INDENT>no, yes = '<STR_LIT:U+0020>', '<STR_LIT>'<EOL>if sys.version_info < (<NUM_LIT:3>, <NUM_LIT:3>):<EOL><INDENT>no, yes = '<STR_LIT:U+0020>', '<STR_LIT:@>'<EOL><DEDENT>opts = ['<STR_LIT>'.format(yes if c else no, verbose_options[i]) for i, c in enumerate(chosen)]<EOL>return opts + ['<STR_LIT>'.format('<STR_LIT:U+0020>', kwargs.get('<STR_LIT>', '<STR_LIT>'))]<EOL><DEDENT>options, verbose_options = prepare_options(args)<EOL>chosen = [False] * len(options)<EOL>index = kwargs.get('<STR_LIT>', <NUM_LIT:0>)<EOL>default = kwargs.get('<STR_LIT:default>', None)<EOL>if isinstance(default, list):<EOL><INDENT>for idx in default:<EOL><INDENT>chosen[idx] = True<EOL><DEDENT><DEDENT>if isinstance(default, int):<EOL><INDENT>chosen[default] = True<EOL><DEDENT>while True:<EOL><INDENT>try:<EOL><INDENT>index = one(prompt, *get_verbose_options(verbose_options, chosen), return_index=True, idx=index)<EOL><DEDENT>except QuestionnaireGoBack:<EOL><INDENT>if any(chosen):<EOL><INDENT>raise QuestionnaireGoBack(<NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>raise QuestionnaireGoBack<EOL><DEDENT><DEDENT>if index == len(options):<EOL><INDENT>return get_options(options, chosen)<EOL><DEDENT>chosen[index] = not chosen[index]<EOL><DEDENT>

Calls `pick` in a while loop to allow user to pick many
    options. Returns a list of chosen options.


def decorate(func):<EOL><INDENT>prompters[key] = func<EOL>return func<EOL><DEDENT>return decorate<EOL>

Add decorated functions to prompters dict.


def decorator(func):<EOL><INDENT>@functools.wraps(func)<EOL>def wrapper(*args, **kwds):<EOL><INDENT>try:<EOL><INDENT>return func(*args, **kwds)<EOL><DEDENT>finally:<EOL><INDENT>try:<EOL><INDENT>os.remove(path)<EOL><DEDENT>except (IOError, OSError):<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>return wrapper<EOL><DEDENT>return decorator<EOL>

Decorator to run function at `path`.

:type path: str
:arg path: relative path from repository root (e.g., 'pyqode' or 'test').


pass<EOL>


editor = None<EOL>if path:<EOL><INDENT>interpreter, pyserver, args = self._get_backend_parameters()<EOL>editor = self.tabWidget.open_document(<EOL>path, None, interpreter=interpreter, server_script=pyserver,<EOL>args=args)<EOL>if editor:<EOL><INDENT>self.setup_editor(editor)<EOL><DEDENT>self.recent_files_manager.open_file(path)<EOL>self.menu_recents.update_actions()<EOL><DEDENT>if line is not None:<EOL><INDENT>TextHelper(self.tabWidget.current_widget()).goto_line(line)<EOL><DEDENT>return editor<EOL>

Creates a new GenericCodeEdit, opens the requested file and adds it
to the tab widget.

:param path: Path of the file to open

:return The opened editor if open succeeded.


self.menuEdit.addActions(editor.actions())<EOL>self.menuEdit.addSeparator()<EOL>self.setup_mnu_style(editor)<EOL>

Setup the edit menu for the current editor. We show the current editor
context menu and a menu to change the python interpreter.

:param editor: new editor


editor = self.open_file(assignment.module_path)<EOL>if editor:<EOL><INDENT>TextHelper(editor).goto_line(assignment.line, assignment.column)<EOL><DEDENT>

Open the a new tab when goto goes out of the current document.

:param assignment: Destination


self.recent_files_manager = widgets.RecentFilesManager(<EOL>'<STR_LIT>', '<STR_LIT>')<EOL>self.menu_recents = widgets.MenuRecentFiles(<EOL>self.menuFile, title='<STR_LIT>',<EOL>recent_files_manager=self.recent_files_manager)<EOL>self.menu_recents.open_requested.connect(self.open_file)<EOL>self.menuFile.insertMenu(self.actionSave, self.menu_recents)<EOL>self.menuFile.insertSeparator(self.actionSave)<EOL>


filename, filter = QtWidgets.QFileDialog.getOpenFileName(self, '<STR_LIT>')<EOL>if filename:<EOL><INDENT>self.open_file(filename)<EOL><DEDENT>self.actionRun.setEnabled(True)<EOL>self.actionConfigure_run.setEnabled(True)<EOL>

Shows an open file dialog and open the file if the dialog was
accepted.


self.tabWidget.closeEvent(QCloseEvent)<EOL>

Delegates the close event to the tabWidget to be sure we do not quit
the application while there are some still some unsaved tabs.


filename = self.tabWidget.current_widget().file.path<EOL>wd = os.path.dirname(filename)<EOL>args = Settings().get_run_config_for_file(filename)<EOL>self.interactiveConsole.start_process(<EOL>Settings().interpreter, args=[filename] + args, cwd=wd)<EOL>self.dockWidget.show()<EOL>self.actionRun.setEnabled(False)<EOL>self.actionConfigure_run.setEnabled(False)<EOL>


action = self.sender()<EOL>action.panel.enabled = action.isChecked()<EOL>action.panel.setVisible(action.isChecked())<EOL>


string = self.settings.value('<STR_LIT>', '<STR_LIT:{}>')<EOL>return json.loads(string)<EOL>

Returns the dictionary of run configurations. A run configuration is
just a list of arguments to append to the run command.

This is internally stored as a json object


def detect_fold_level(self, prev_block, block):

<EOL>lvl = super(PythonFoldDetector, self).detect_fold_level(<EOL>prev_block, block)<EOL>prev_lvl = TextBlockHelper.get_fold_lvl(prev_block)<EOL>if prev_block and lvl > prev_lvl and not (<EOL>self._strip_comments(prev_block).endswith('<STR_LIT::>')):<EOL><INDENT>lvl = prev_lvl<EOL><DEDENT>lvl = self._handle_docstrings(block, lvl, prev_block)<EOL>lvl = self._handle_imports(block, lvl, prev_block)<EOL>return lvl<EOL>

Perfoms fold level detection for current block (take previous block
into account).

:param prev_block: previous block, None if `block` is the first block.
:param block: block to analyse.
:return: block fold level


return "<STR_LIT>" % name + "<STR_LIT:|>".join(alternates) + "<STR_LIT:)>"<EOL>

Return a named group pattern matching list of alternates.


if not self.tab_always_indent:<EOL><INDENT>super(PyIndenterMode, self).indent()<EOL><DEDENT>else:<EOL><INDENT>cursor = self.editor.textCursor()<EOL>assert isinstance(cursor, QtGui.QTextCursor)<EOL>if cursor.hasSelection():<EOL><INDENT>self.indent_selection(cursor)<EOL><DEDENT>else:<EOL><INDENT>tab_len = self.editor.tab_length<EOL>cursor.beginEditBlock()<EOL>if self.editor.use_spaces_instead_of_tabs:<EOL><INDENT>cursor.insertText(tab_len * "<STR_LIT:U+0020>")<EOL><DEDENT>else:<EOL><INDENT>cursor.insertText('<STR_LIT:\t>')<EOL><DEDENT>cursor.endEditBlock()<EOL>self.editor.setTextCursor(cursor)<EOL><DEDENT><DEDENT>


Called when the mode is activated/deactivated


Update terminal color scheme based on the pygments color scheme colors


super(PyInteractiveConsole, self).mousePressEvent(e)<EOL>cursor = self.cursorForPosition(e.pos())<EOL>p = cursor.positionInBlock()<EOL>usd = cursor.block().userData()<EOL>if usd and usd.start_pos_in_block <= p <= usd.end_pos_in_block:<EOL><INDENT>if e.button() == QtCore.Qt.LeftButton:<EOL><INDENT>self.open_file_requested.emit(usd.filename, usd.line)<EOL><DEDENT><DEDENT>

Emits open_file_requested if the press event occured  over
a file location string.


super(PyInteractiveConsole, self).mouseMoveEvent(e)<EOL>cursor = self.cursorForPosition(e.pos())<EOL>assert isinstance(cursor, QtGui.QTextCursor)<EOL>p = cursor.positionInBlock()<EOL>usd = cursor.block().userData()<EOL>if usd and usd.start_pos_in_block <= p <= usd.end_pos_in_block:<EOL><INDENT>if QtWidgets.QApplication.overrideCursor() is None:<EOL><INDENT>QtWidgets.QApplication.setOverrideCursor(<EOL>QtGui.QCursor(QtCore.Qt.PointingHandCursor))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if QtWidgets.QApplication.overrideCursor() is not None:<EOL><INDENT>QtWidgets.QApplication.restoreOverrideCursor()<EOL><DEDENT><DEDENT>

Extends mouseMoveEvent to display a pointing hand cursor when the
mouse cursor is over a file location


ICONS = {<EOL>'<STR_LIT>': ICON_CLASS,<EOL>'<STR_LIT>': ICON_NAMESPACE,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_NAMESPACE,<EOL>'<STR_LIT>': ICON_KEYWORD,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_VAR,<EOL>'<STR_LIT>': ICON_FUNC,<EOL>'<STR_LIT>': ICON_FUNC,<EOL>'<STR_LIT>': ICON_FUNC_PRIVATE,<EOL>'<STR_LIT>': ICON_FUNC_PROTECTED<EOL>}<EOL>ret_val = None<EOL>icon_type = icon_type.upper()<EOL>if hasattr(name, "<STR_LIT:string>"):<EOL><INDENT>name = name.string<EOL><DEDENT>if icon_type == "<STR_LIT>" or icon_type == "<STR_LIT>":<EOL><INDENT>icon_type = "<STR_LIT>"<EOL><DEDENT>if icon_type == "<STR_LIT>" or icon_type == "<STR_LIT>":<EOL><INDENT>if name.startswith("<STR_LIT>"):<EOL><INDENT>icon_type += "<STR_LIT>"<EOL><DEDENT>elif name.startswith("<STR_LIT:_>"):<EOL><INDENT>icon_type += "<STR_LIT>"<EOL><DEDENT><DEDENT>if icon_type in ICONS:<EOL><INDENT>ret_val = ICONS[icon_type]<EOL><DEDENT>elif icon_type:<EOL><INDENT>_logger().warning("<STR_LIT>", icon_type)<EOL><DEDENT>return ret_val<EOL>

Returns the icon resource filename that corresponds to the given typename.

:param name: name of the completion. Use to make the distinction between
    public and private completions (using the count of starting '_')
:pram typename: the typename reported by jedi

:returns: The associate icon resource filename or None.


global prev_results<EOL>from pyflakes import checker<EOL>import _ast<EOL>WARNING = <NUM_LIT:1><EOL>ERROR = <NUM_LIT:2><EOL>ret_val = []<EOL>code = request_data['<STR_LIT:code>']<EOL>path = request_data['<STR_LIT:path>']<EOL>encoding = request_data['<STR_LIT>']<EOL>if not encoding:<EOL><INDENT>encoding = '<STR_LIT:utf-8>'<EOL><DEDENT>if not path:<EOL><INDENT>path = os.path.join(tempfile.gettempdir(), '<STR_LIT>')<EOL><DEDENT>if not code:<EOL><INDENT>return []<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>tree = compile(code.encode(encoding), path, "<STR_LIT>",<EOL>_ast.PyCF_ONLY_AST)<EOL><DEDENT>except SyntaxError as value:<EOL><INDENT>msg = '<STR_LIT>' % value.args[<NUM_LIT:0>]<EOL>(lineno, offset, text) = value.lineno - <NUM_LIT:1>, value.offset, value.text<EOL>if text is None:<EOL><INDENT>_logger().warning("<STR_LIT>",<EOL>path)<EOL><DEDENT>else:<EOL><INDENT>ret_val.append((msg, ERROR, lineno))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>w = checker.Checker(tree, os.path.split(path)[<NUM_LIT:1>])<EOL>w.messages.sort(key=lambda m: m.lineno)<EOL>for message in w.messages:<EOL><INDENT>msg = "<STR_LIT>" % str(message).split('<STR_LIT::>')[-<NUM_LIT:1>].strip()<EOL>line = message.lineno - <NUM_LIT:1><EOL>status = WARNINGif message.__class__ not in PYFLAKES_ERROR_MESSAGESelse ERROR<EOL>ret_val.append((msg, status, line))<EOL><DEDENT><DEDENT><DEDENT>prev_results = ret_val<EOL>return ret_val<EOL>

Worker that run a frosted (the fork of pyflakes) code analysis on the
current editor text.


@staticmethod<EOL><INDENT>def complete(code, line, column, path, encoding, prefix):<DEDENT>

ret_val = []<EOL>try:<EOL><INDENT>script = jedi.Script(code, line + <NUM_LIT:1>, column, path, encoding)<EOL>completions = script.completions()<EOL>print('<STR_LIT>' % completions)<EOL><DEDENT>except jedi.NotFoundError:<EOL><INDENT>completions = []<EOL><DEDENT>for completion in completions:<EOL><INDENT>ret_val.append({<EOL>'<STR_LIT:name>': completion.name,<EOL>'<STR_LIT>': icon_from_typename(<EOL>completion.name, completion.type),<EOL>'<STR_LIT>': completion.description})<EOL><DEDENT>return ret_val<EOL>

Completes python code using `jedi`_.

:returns: a list of completion.


code = request_data['<STR_LIT:code>']<EOL>line = request_data['<STR_LIT>'] + <NUM_LIT:1><EOL>column = request_data['<STR_LIT>']<EOL>path = request_data['<STR_LIT:path>']<EOL>encoding = '<STR_LIT:utf-8>'<EOL>script = jedi.Script(code, line, column, path, encoding)<EOL>signatures = script.call_signatures()<EOL>for sig in signatures:<EOL><INDENT>results = (str(sig.module_name), str(sig.name),<EOL>[p.description for p in sig.params], sig.index,<EOL>sig.bracket_start, column)<EOL>return results<EOL><DEDENT>return []<EOL>

Worker that returns a list of calltips.

A calltips is a tuple made of the following parts:
  - module_name: name of the module of the function invoked
  - call_name: name of the function that is being called
  - params: the list of parameter names.
  - index: index of the current parameter
  - bracket_start

:returns tuple(module_name, call_name, params)


try:<EOL><INDENT>pidfile = open(self._pidfile, "<STR_LIT:a>")<EOL><DEDENT>except IOError as err:<EOL><INDENT>raise SystemExit(err)<EOL><DEDENT>try:<EOL><INDENT>fcntl.flock(pidfile.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)<EOL><DEDENT>except IOError:<EOL><INDENT>raise SystemExit('<STR_LIT>' + self._pidfile)<EOL><DEDENT>pidfile.seek(<NUM_LIT:0>)<EOL>pidfile.truncate()<EOL>pidfile.write(str(os.getpid()) + '<STR_LIT:\n>')<EOL>pidfile.flush()<EOL>self.pidfile = pidfile<EOL>atexit.register(self.release)<EOL>

Acquire the pidfile.

        Create the pidfile, lock it, write the pid into it
        and register the release with atexit.

        :return: None
        :raise: SystemExit


result = set()<EOL>files = [] if not self.files_preserve else self.files_preserve<EOL>files.extend([self.stdin, self.stdout, self.stderr])<EOL>for item in files:<EOL><INDENT>if hasattr(item, '<STR_LIT>'):<EOL><INDENT>result.add(item.fileno())<EOL><DEDENT>if isinstance(item, int):<EOL><INDENT>result.add(item)<EOL><DEDENT><DEDENT>return result<EOL>

create a set of protected files

        create a set of files, based on self.files_preserve and
        self.stdin, self,stdout and self.stderr, that should not get
        closed while daemonizing.

        :return: set


result = False<EOL>sock = socket.fromfd(<EOL>sys.__stdin__.fileno(),<EOL>socket.AF_INET,<EOL>socket.SOCK_RAW)<EOL>try:<EOL><INDENT>sock.getsockopt(socket.SOL_SOCKET, socket.SO_TYPE)<EOL>result = True<EOL><DEDENT>except (OSError, socket.error) as err:<EOL><INDENT>if not err.args[<NUM_LIT:0>] == errno.ENOTSOCK:<EOL><INDENT>result = True<EOL><DEDENT><DEDENT>return result<EOL>

Check if parent is inet

    Check if our parent seems ot be a superserver, aka inetd/xinetd.

    This is done by checking if sys.__stdin__ is a network socket.

    :return: bool


result = {}<EOL>for signum, handler in self.signal_map.items():<EOL><INDENT>result[signum] = self._get_signal_handler(handler)<EOL><DEDENT>return result<EOL>

Create the signal handler map

        create a dictionary with signal:handler mapping based on
        self.signal_map

        :return: dict


if self.is_open:<EOL><INDENT>return<EOL><DEDENT>try:<EOL><INDENT>os.chdir(self.working_directory)<EOL>if self.chroot_directory:<EOL><INDENT>os.chroot(self.chroot_directory)<EOL><DEDENT>os.setgid(self.gid)<EOL>os.setuid(self.uid)<EOL>os.umask(self.umask)<EOL><DEDENT>except OSError as err:<EOL><INDENT>raise DaemonError('<STR_LIT>'<EOL>.format(err))<EOL><DEDENT>if self.prevent_core:<EOL><INDENT>try:<EOL><INDENT>resource.setrlimit(resource.RLIMIT_CORE, (<NUM_LIT:0>, <NUM_LIT:0>))<EOL><DEDENT>except Exception as err:<EOL><INDENT>raise DaemonError('<STR_LIT>'<EOL>.format(err))<EOL><DEDENT><DEDENT>if self.detach_process:<EOL><INDENT>try:<EOL><INDENT>if os.fork() > <NUM_LIT:0>:<EOL><INDENT>os._exit(<NUM_LIT:0>)<EOL><DEDENT><DEDENT>except OSError as err:<EOL><INDENT>raise DaemonError('<STR_LIT>'.format(err))<EOL><DEDENT>os.setsid()<EOL>try:<EOL><INDENT>if os.fork() > <NUM_LIT:0>:<EOL><INDENT>os._exit(<NUM_LIT:0>)<EOL><DEDENT><DEDENT>except OSError as err:<EOL><INDENT>raise DaemonError('<STR_LIT>'.format(err))<EOL><DEDENT><DEDENT>for (signal_number, handler) in self._signal_handler_map.items():<EOL><INDENT>signal.signal(signal_number, handler)<EOL><DEDENT>close_filenos(self._files_preserve)<EOL>redirect_stream(sys.stdin, self.stdin)<EOL>redirect_stream(sys.stdout, self.stdout)<EOL>redirect_stream(sys.stderr, self.stderr)<EOL>if self.pidfile:<EOL><INDENT>self.pidfile.acquire()<EOL><DEDENT>self._is_open = True<EOL>

Daemonize this process

        Do everything that is needed to become a Unix daemon.

        :return: None
        :raise: DaemonError


if os.getppid() == <NUM_LIT:1>:<EOL><INDENT>return True<EOL><DEDENT>return False<EOL>

Check if parent is Init

    Check if the parent process is init, or something else that
    owns PID 1.

    :return: bool


maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[<NUM_LIT:1>]<EOL>if maxfd == resource.RLIM_INFINITY:<EOL><INDENT>maxfd = <NUM_LIT><EOL><DEDENT>for fileno in range(maxfd):<EOL><INDENT>if fileno not in preserve:<EOL><INDENT>try:<EOL><INDENT>os.close(fileno)<EOL><DEDENT>except OSError as err:<EOL><INDENT>if not err.errno == errno.EBADF:<EOL><INDENT>raise DaemonError(<EOL>'<STR_LIT>'<EOL>.format(fileno, err))<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

Close unprotected file descriptors

    Close all open file descriptors that are not in preserve.

    If ulimit -nofile is "unlimited", all is defined filenos <= 4096,
    else all is <= the output of resource.getrlimit().

    :param preserve: set with protected files
    :type preserve: set

    :return: None


def __exit__(self, exc_type, exc_val, exc_tb):

self.close()<EOL>

Context Handler, wrapping self.close()

        :return: None


return self._is_open<EOL>

True when this instances open method was called

        :return: bool


def __init__(<EOL>self, chroot_directory=None, working_directory='<STR_LIT:/>',<EOL>umask=<NUM_LIT:0>, uid=None, gid=None, prevent_core=True,<EOL>detach_process=None, files_preserve=None, pidfile=None,<EOL>stdin=None, stdout=None, stderr=None, signal_map=None):

self._is_open = False<EOL>self._working_directory = None<EOL>self.chroot_directory = chroot_directory<EOL>self.umask = umask<EOL>self.uid = uid if uid else os.getuid()<EOL>self.gid = gid if gid else os.getgid()<EOL>if detach_process is None:<EOL><INDENT>self.detach_process = detach_required()<EOL><DEDENT>else:<EOL><INDENT>self.detach_process = detach_process<EOL><DEDENT>self.signal_map = signal_map if signal_map else default_signal_map()<EOL>self.files_preserve = files_preserve<EOL>self.pidfile = pidfile<EOL>self.prevent_core = prevent_core<EOL>self.stdin = stdin<EOL>self.stdout = stdout<EOL>self.stderr = stderr<EOL>self.working_directory = working_directory<EOL>


name_map = {<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>'}<EOL>signal_map = {}<EOL>for name, target in name_map.items():<EOL><INDENT>if hasattr(signal, name):<EOL><INDENT>signal_map[getattr(signal, name)] = target<EOL><DEDENT><DEDENT>return signal_map<EOL>

Create the default signal map for this system.

    :return: dict


if target is None:<EOL><INDENT>target_fd = os.open(os.devnull, os.O_RDWR)<EOL><DEDENT>else:<EOL><INDENT>target_fd = target.fileno()<EOL><DEDENT>try:<EOL><INDENT>os.dup2(target_fd, system.fileno())<EOL><DEDENT>except OSError as err:<EOL><INDENT>raise DaemonError('<STR_LIT>'<EOL>.format(system, target, err))<EOL><DEDENT>

Redirect Unix streams

    If None, redirect Stream to /dev/null, else redirect to target.

    :param system: ether sys.stdin, sys.stdout, or sys.stderr
    :type system: file object

    :param target: File like object, or None
    :type target: None, File Object

    :return: None
    :raise: DaemonError


self._working_directory = value<EOL>

Set working directory

        New value is ignored if already daemonized.

        :param value: str
        :return:


create_db_and_user()<EOL>initialize_database()<EOL>populate_database(self.daily_files, self.quarterly_files)<EOL>

Use this to create a user, a database, and load the database with files.
It will take a while to run and will only work if your network allows FTP
file transfer.  It also requires you to have a postgres server running locally.


ftp = FTP('<STR_LIT>', timeout=None)<EOL>ftp.login()<EOL>name = file_path.replace('<STR_LIT:/>', '<STR_LIT:_>')<EOL>if not os.path.exists(directory):<EOL><INDENT>os.makedirs(directory)<EOL><DEDENT>with tempfile.TemporaryFile() as temp:<EOL><INDENT>ftp.retrbinary('<STR_LIT>' % file_path, temp.write)<EOL>temp.seek(<NUM_LIT:0>)<EOL>with open('<STR_LIT>'.format(directory, name), '<STR_LIT>') as f:<EOL><INDENT>f.write(temp.read().decode("<STR_LIT:utf-8>"))<EOL><DEDENT>f.closed<EOL>records = temp<EOL>retry = False<EOL><DEDENT>ftp.close()<EOL>

This function takes a file path beginning with edgar and stores the form in a directory.
The default directory is sec_filings but can be changed through a keyword argument.


def generate(grammar=None, num=<NUM_LIT:1>, output=sys.stdout, max_recursion=<NUM_LIT:10>, seed=None):

if seed is not None:<EOL><INDENT>gramfuzz.rand.seed(seed)<EOL><DEDENT>fuzzer = gramfuzz.GramFuzzer()<EOL>fuzzer.load_grammar(grammar)<EOL>cat_group = os.path.basename(grammar).replace("<STR_LIT>", "<STR_LIT>")<EOL>results = fuzzer.gen(cat_group=cat_group, num=num, max_recursion=max_recursion)<EOL>for res in results:<EOL><INDENT>output.write(res)<EOL><DEDENT>

Load and generate ``num`` number of top-level rules from the specified grammar.

    :param list grammar: The grammar file to load and generate data from
    :param int num: The number of times to generate data
    :param output: The output destination (an open, writable stream-type object. default=``sys.stdout``)
    :param int max_recursion: The maximum reference-recursion when generating data (default=``10``)
    :param int seed: The seed to initialize the PRNG with. If None, will not initialize it.


res = []<EOL>for verb in verbs:<EOL><INDENT>parts = verb.split()<EOL>if parts[<NUM_LIT:0>].endswith("<STR_LIT:e>"):<EOL><INDENT>parts[<NUM_LIT:0>] = parts[<NUM_LIT:0>][:-<NUM_LIT:1>] + "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>parts[<NUM_LIT:0>] = parts[<NUM_LIT:0>] + "<STR_LIT>"<EOL><DEDENT>res.append("<STR_LIT:U+0020>".join(parts))<EOL><DEDENT>return res<EOL>

Make the list of verbs into present participles

    E.g.:

        empower -> empowering
        drive -> driving


self.refname = refname<EOL>self.cat = kwargs.setdefault("<STR_LIT>", self.cat)<EOL>self.failsafe = kwargs.setdefault("<STR_LIT>", self.failsafe)<EOL>self.fuzzer = GramFuzzer.instance()<EOL>

Create a new ``Ref`` instance

        :param str refname: The name of the rule to reference
        :param str cat: The name of the category the rule is defined in


<EOL>self.shortest_vals = None<EOL>self.values = list(values)<EOL>if "<STR_LIT>" in kwargs and len(values) == <NUM_LIT:0>:<EOL><INDENT>self.values = kwargs["<STR_LIT>"]<EOL><DEDENT>self.rolling = kwargs.setdefault("<STR_LIT>", False)<EOL>

Create a new ``Or`` instance with the provide values

        :param list values: The list of values to choose randomly from


def __init__(self, value=None, **kwargs):

super(String, self).__init__(value, **kwargs)<EOL>self.charset = kwargs.setdefault("<STR_LIT>", self.charset)<EOL>

Create a new instance of the ``String`` field.

        :param value: The hard-coded value of the String field
        :param int min: The minimum size of the String when built
        :param int max: The maximum size of the String when built
        :param str charset: The character-set to be used when building the string


def __init__(self, name, *values, **options):

self.name = name<EOL>self.options = options<EOL>self.values = list(values)<EOL>self.sep = self.options.setdefault("<STR_LIT>", self.sep)<EOL>self.cat = self.options.setdefault("<STR_LIT>", self.cat)<EOL>self.no_prune = self.options.setdefault("<STR_LIT>", self.no_prune)<EOL>self.fuzzer = GramFuzzer.instance()<EOL>frame,mod_path,_,_,_,_ = inspect.stack()[<NUM_LIT:1>]<EOL>module_name = os.path.basename(mod_path).replace("<STR_LIT>", "<STR_LIT>").replace("<STR_LIT>", "<STR_LIT>")<EOL>if "<STR_LIT>" in frame.f_locals:<EOL><INDENT>self.fuzzer.cat_group_defaults[module_name] = frame.f_locals["<STR_LIT>"]<EOL><DEDENT>self.fuzzer.add_definition(self.cat, self.name, self, no_prune=self.no_prune, gram_file=module_name)<EOL>

Create a new rule definition. Simply instantiating a new rule definition
        will add it to the current ``GramFuzzer`` instance.

        :param str name: The name of the rule being defined
        :param list values: The list of values that define the value of the rule
            (will be concatenated when built)
        :param str cat: The category to create the rule in (default=``"default"``).
        :param bool no_prune: If this rule should not be pruned *EVEN IF* it is found to be
            unreachable (default=``False``)


super(Q, self).__init__(*values, **kwargs)<EOL>self.escape = kwargs.setdefault("<STR_LIT>", self.escape)<EOL>self.html_js_escape = kwargs.setdefault("<STR_LIT>", self.html_js_escape)<EOL>self.quote = kwargs.setdefault("<STR_LIT>", self.quote)<EOL>

Create the new ``Quote`` instance

        :param bool escape: Whether or not quoted data should be escaped (default=``False``)
        :param bool html_js_escape: Whether or not quoted data should be html-javascript escaped (default=``False``)
        :param str quote: The quote character to be used if ``escape`` and ``html_js_escape`` are ``False``


if len(self.odds) == <NUM_LIT:0>:<EOL><INDENT>self.odds = [(<NUM_LIT>, [self.min, self.max])]<EOL><DEDENT>rand_val = rand.random()<EOL>total = <NUM_LIT:0><EOL>for percent,v in self.odds:<EOL><INDENT>if total <= rand_val < total+percent:<EOL><INDENT>found_v = v<EOL>break<EOL><DEDENT>total += percent<EOL><DEDENT>res = None<EOL>if isinstance(v, (tuple,list)):<EOL><INDENT>rand_func = rand.randfloat if type(v[<NUM_LIT:0>]) is float else rand.randint<EOL>if len(v) == <NUM_LIT:2>:<EOL><INDENT>res = rand_func(v[<NUM_LIT:0>], v[<NUM_LIT:1>])<EOL><DEDENT>elif len(v) == <NUM_LIT:1>:<EOL><INDENT>res = v[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>res = v<EOL><DEDENT>return res<EOL>

Determine a new random value derived from the
        defined :any:`gramfuzz.fields.Field.odds` value.

        :returns: The derived value


RANDOM.seed(val)<EOL>

Set the seed for any subsequent random values/choices

    :param val: The random seed value


<EOL>if b is None:<EOL><INDENT>return _randint(<NUM_LIT:0>, a-<NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>return _randint(a, b-<NUM_LIT:1>)<EOL><DEDENT>

Return a random integer

    :param int a: Either the minimum value (inclusive) if ``b`` is set, or
    the maximum value if ``b`` is not set (non-inclusive, in which case the minimum
    is implicitly 0)
    :param int b: The maximum value to generate (non-inclusive)
    :returns: int


if cls.__instance__ is None:<EOL><INDENT>cls()<EOL><DEDENT>return cls.__instance__<EOL>

Return the singleton instance of the ``GramFuzzer``


def add_to_cat_group(self, cat, cat_group, def_name):

self.cat_groups.setdefault(cat, {}).setdefault(cat_group, deque()).append(def_name)<EOL>

Associate the provided rule definition name ``def_name`` with the
        category group ``cat_group`` in the category ``cat``.

        :param str cat: The category the rule definition was declared in
        :param str cat_group: The group within the category the rule belongs to
        :param str def_name: The name of the rule definition


to_prune = self._find_shortest_paths()<EOL>self._prune_rules(to_prune)<EOL>self._rules_processed = True<EOL>

Calculate shortest reference-paths of each rule (and Or field),
        and prune all unreachable rules.


import gramfuzz.fields<EOL>gramfuzz.fields.Ref.max_recursion = level<EOL>

Set the maximum reference-recursion depth (not the Python system maximum stack
        recursion level). This controls how many levels deep of nested references are allowed
        before gramfuzz attempts to generate the shortest (reference-wise) rules possible.

        :param int level: The new maximum reference level


if not os.path.exists(path):<EOL><INDENT>raise Exception("<STR_LIT>".format(path))<EOL><DEDENT>grammar_path = os.path.dirname(path)<EOL>if grammar_path not in sys.path:<EOL><INDENT>sys.path.append(grammar_path)<EOL><DEDENT>with open(path, "<STR_LIT:r>") as f:<EOL><INDENT>data = f.read()<EOL><DEDENT>code = compile(data, path, "<STR_LIT>")<EOL>locals_ = {"<STR_LIT>": self, "<STR_LIT>": path}<EOL>exec(code, locals_)<EOL>if "<STR_LIT>" in locals_:<EOL><INDENT>cat_group = os.path.basename(path).replace("<STR_LIT>", "<STR_LIT>")<EOL>self.set_cat_group_top_level_cat(cat_group, locals_["<STR_LIT>"])<EOL><DEDENT>

Load a grammar file (python file containing grammar definitions) by
        file path. When loaded, the global variable ``GRAMFUZZER`` will be set
        within the module. This is not always needed, but can be useful.

        :param str path: The path to the grammar file


def post_revert(self, cat, res, total_num, num, info):

if self._staged_defs is None:<EOL><INDENT>return<EOL><DEDENT>for cat,def_name,def_value in self._staged_defs:<EOL><INDENT>self.defs.setdefault(cat, {}).setdefault(def_name, deque()).append(def_value)<EOL><DEDENT>self._staged_defs = None<EOL>

Commit any staged rule definition changes (rule generation went
        smoothly).


self._staged_defs = None<EOL>

Revert after a single def errored during generate (throw away all
        staged rule definition changes)


return self._dumper_class is yaml.SafeDumper<EOL>

Returns ``True`` if the safe mode is being used with (de)serialization.


typename, marshalled_state = self.unwrap_callback(obj)<EOL>if typename is None:<EOL><INDENT>return obj<EOL><DEDENT>try:<EOL><INDENT>cls, unmarshaller = self.serializer.unmarshallers[typename]<EOL><DEDENT>except KeyError:<EOL><INDENT>raise LookupError('<STR_LIT>'.format(typename)) from None<EOL><DEDENT>if cls is not None:<EOL><INDENT>instance = cls.__new__(cls)<EOL>unmarshaller(instance, marshalled_state)<EOL>return instance<EOL><DEDENT>else:<EOL><INDENT>return unmarshaller(marshalled_state)<EOL><DEDENT>

Handle a dict that might contain a wrapped state for a custom type.


@abstractmethod<EOL><INDENT>def serialize(self, obj) -> bytes:<DEDENT>


def register_custom_type(<EOL>self, cls: type, marshaller: Optional[Callable[[Any], Any]] = default_marshaller,<EOL>unmarshaller: Union[Callable[[Any, Any], None],<EOL>Callable[[Any], Any], None] = default_unmarshaller, *,<EOL>typename: str = None, wrap_state: bool = True) -> None:

assert check_argument_types()<EOL>typename = typename or qualified_name(cls)<EOL>if marshaller:<EOL><INDENT>self.marshallers[cls] = typename, marshaller, wrap_state<EOL>self.custom_type_codec.register_object_encoder_hook(self)<EOL><DEDENT>if unmarshaller and self.custom_type_codec is not None:<EOL><INDENT>target_cls = cls  <EOL>if len(signature(unmarshaller).parameters) == <NUM_LIT:1>:<EOL><INDENT>target_cls = None<EOL><DEDENT>self.unmarshallers[typename] = target_cls, unmarshaller<EOL>self.custom_type_codec.register_object_decoder_hook(self)<EOL><DEDENT>

Register a marshaller and/or unmarshaller for the given class.

The state object returned by the marshaller and passed to the unmarshaller can be any
serializable type. Usually a dictionary mapping of attribute names to values is used.

.. warning:: Registering marshallers/unmarshallers for any custom type will override any
    serializer specific encoding/decoding hooks (respectively) already in place!

:param cls: the class to register
:param marshaller: a callable that takes the object to be marshalled as the argument and
      returns a state object
:param unmarshaller: a callable that either:

    * takes an uninitialized instance of ``cls`` and its state object as arguments and
      restores the state of the object
    * takes a state object and returns a new instance of ``cls``
:param typename: a unique identifier for the type (defaults to the ``module:varname``
    reference to the class)
:param wrap_state: ``True`` to wrap the marshalled state before serialization so that it
    can be recognized later for unmarshalling, ``False`` to serialize it as is


@abstractmethod<EOL><INDENT>def deserialize(self, payload: bytes):<DEDENT>


url = URL + "<STR_LIT>" + API_KEY + "<STR_LIT>" + word + "<STR_LIT>"<EOL>return requests.get(url)<EOL>

Fetch translate result from baidu api
    Args:
        word(str): query word
    Returns:
        (requests.models.Response): response object


Stores the PyPI password (encrypted) in the .travis.yml file.


def assert_equal_files(self, obtained_fn, expected_fn, fix_callback=lambda x:x, binary=False, encoding=None):

import os<EOL>from zerotk.easyfs import GetFileContents, GetFileLines<EOL>__tracebackhide__ = True<EOL>import io<EOL>def FindFile(filename):<EOL><INDENT>data_filename = self.get_filename(filename)<EOL>if os.path.isfile(data_filename):<EOL><INDENT>return data_filename<EOL><DEDENT>if os.path.isfile(filename):<EOL><INDENT>return filename<EOL><DEDENT>from ._exceptions import MultipleFilesNotFound<EOL>raise MultipleFilesNotFound([filename, data_filename])<EOL><DEDENT>obtained_fn = FindFile(obtained_fn)<EOL>expected_fn = FindFile(expected_fn)<EOL>if binary:<EOL><INDENT>obtained_lines = GetFileContents(obtained_fn, binary=True)<EOL>expected_lines = GetFileContents(expected_fn, binary=True)<EOL>assert obtained_lines == expected_lines<EOL><DEDENT>else:<EOL><INDENT>obtained_lines = fix_callback(GetFileLines(obtained_fn, encoding=encoding))<EOL>expected_lines = GetFileLines(expected_fn, encoding=encoding)<EOL>if obtained_lines != expected_lines:<EOL><INDENT>html_fn = os.path.splitext(obtained_fn)[<NUM_LIT:0>] + '<STR_LIT>'<EOL>html_diff = self._generate_html_diff(<EOL>expected_fn, expected_lines, obtained_fn, obtained_lines)<EOL>with io.open(html_fn, '<STR_LIT:w>') as f:<EOL><INDENT>f.write(html_diff)<EOL><DEDENT>import difflib<EOL>diff = ['<STR_LIT>', obtained_fn, expected_fn]<EOL>diff += ['<STR_LIT>' % html_fn]<EOL>diff += difflib.context_diff(obtained_lines, expected_lines)<EOL>raise AssertionError('<STR_LIT:\n>'.join(diff) + '<STR_LIT:\n>')<EOL><DEDENT><DEDENT>

Compare two files contents. If the files differ, show the diff and write a nice HTML
diff file into the data directory.

Searches for the filenames both inside and outside the data directory (in that order).

:param unicode obtained_fn: basename to obtained file into the data directory, or full path.

:param unicode expected_fn: basename to expected file into the data directory, or full path.

:param bool binary:
    Thread both files as binary files.

:param unicode encoding:
    File's encoding. If not None, contents obtained from file will be decoded using this
    `encoding`.

:param callable fix_callback:
    A callback to "fix" the contents of the obtained (first) file.
    This callback receives a list of strings (lines) and must also return a list of lines,
    changed as needed.
    The resulting lines will be used to compare with the contents of expected_fn.

:param bool binary:
    .. seealso:: zerotk.easyfs.GetFileContents


return self._data_dir<EOL>

:rtype: unicode
:returns:
    Returns the absolute path to data-directory name to use, standardized by StandardizePath.

@remarks:
    This method triggers the data-directory creation.


def _generate_html_diff(self, expected_fn, expected_lines, obtained_fn, obtained_lines):

import difflib<EOL>differ = difflib.HtmlDiff()<EOL>return differ.make_file(<EOL>fromlines=expected_lines,<EOL>fromdesc=expected_fn,<EOL>tolines=obtained_lines,<EOL>todesc=obtained_fn,<EOL>)<EOL>

Returns a nice side-by-side diff of the given files, as a string.


def _CopyFileLocal(source_filename, target_filename, copy_symlink=True):

import shutil<EOL>try:<EOL><INDENT>dir_name = os.path.dirname(target_filename)<EOL>if dir_name and not os.path.isdir(dir_name):<EOL><INDENT>os.makedirs(dir_name)<EOL><DEDENT>if copy_symlink and IsLink(source_filename):<EOL><INDENT>if os.path.isfile(target_filename) or IsLink(target_filename):<EOL><INDENT>DeleteFile(target_filename)<EOL><DEDENT>source_filename = ReadLink(source_filename)<EOL>CreateLink(source_filename, target_filename)<EOL><DEDENT>else:<EOL><INDENT>if sys.platform == '<STR_LIT:win32>':<EOL><INDENT>while IsLink(source_filename):<EOL><INDENT>link = ReadLink(source_filename)<EOL>if os.path.isabs(link):<EOL><INDENT>source_filename = link<EOL><DEDENT>else:<EOL><INDENT>source_filename = os.path.join(os.path.dirname(source_filename), link)<EOL><DEDENT><DEDENT><DEDENT>shutil.copyfile(source_filename, target_filename)<EOL>shutil.copymode(source_filename, target_filename)<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>reraise(e, '<STR_LIT>' % (source_filename, target_filename))<EOL><DEDENT>

Copy a file locally to a directory.

:param unicode source_filename:
    The filename to copy from.

:param unicode target_filename:
    The filename to copy to.

:param bool copy_symlink:
    If True and source_filename is a symlink, target_filename will also be created as
    a symlink.

    If False, the file being linked will be copied instead.


def CreateFile(filename, contents, eol_style=EOL_STYLE_NATIVE, create_dir=True, encoding=None, binary=False):

<EOL>if binary:<EOL><INDENT>if isinstance(contents, six.text_type):<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if not isinstance(contents, six.text_type):<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>contents = _HandleContentsEol(contents, eol_style)<EOL>encoding = encoding or sys.getfilesystemencoding()<EOL>contents = contents.encode(encoding)<EOL>binary = True<EOL><DEDENT>if create_dir:<EOL><INDENT>dirname = os.path.dirname(filename)<EOL>if dirname:<EOL><INDENT>CreateDirectory(dirname)<EOL><DEDENT><DEDENT>from six.moves.urllib.parse import urlparse<EOL>filename_url = urlparse(filename)<EOL>if _UrlIsLocal(filename_url):<EOL><INDENT>with open(filename, '<STR_LIT:wb>') as oss:<EOL><INDENT>oss.write(contents)<EOL><DEDENT><DEDENT>elif filename_url.scheme == '<STR_LIT>':<EOL><INDENT>from ._exceptions import NotImplementedProtocol<EOL>raise NotImplementedProtocol(directory_url.scheme)<EOL><DEDENT>else:<EOL><INDENT>from ._exceptions import NotImplementedProtocol<EOL>raise NotImplementedProtocol(filename_url.scheme)<EOL><DEDENT>return filename<EOL>

Create a file with the given contents.

:param unicode filename:
    Filename and path to be created.

:param unicode contents:
    The file contents as a string.

:type eol_style: EOL_STYLE_XXX constant
:param eol_style:
    Replaces the EOL by the appropriate EOL depending on the eol_style value.
    Considers that all content is using only "\n" as EOL.

:param bool create_dir:
    If True, also creates directories needed in filename's path

:param unicode encoding:
    Target file's content encoding. Defaults to sys.getfilesystemencoding()
    Ignored if `binary` = True

:param bool binary:
    If True, file is created in binary mode. In this case, `contents` must be `bytes` and not
    `unicode`

:return unicode:
    Returns the name of the file created.

:raises NotImplementedProtocol:
    If file protocol is not local or FTP

:raises ValueError:
    If trying to mix unicode `contents` without `encoding`, or `encoding` without
    unicode `contents`

.. seealso:: FTP LIMITATIONS at this module's doc for performance issues information


if target_filename is None:<EOL><INDENT>target_filename = source_filename + '<STR_LIT>'<EOL><DEDENT>from six.moves.urllib.parse import urlparse<EOL>source_url = urlparse(source_filename)<EOL>if _UrlIsLocal(source_url):<EOL><INDENT>md5_contents = Md5Hex(filename=source_filename)<EOL><DEDENT>else:<EOL><INDENT>md5_contents = Md5Hex(contents=GetFileContents(source_filename, binary=True))<EOL><DEDENT>CreateFile(target_filename, md5_contents)<EOL>

Creates a md5 file from a source file (contents are the md5 hash of source file)

:param unicode source_filename:
    Path to source file

:type target_filename: unicode or None
:param target_filename:
    Name of the target file with the md5 contents

    If None, defaults to source_filename + '.md5'


if not IsDir(source_dir):<EOL><INDENT>from ._exceptions import DirectoryNotFoundError<EOL>raise DirectoryNotFoundError(source_dir)<EOL><DEDENT>if Exists(target_dir):<EOL><INDENT>from ._exceptions import DirectoryAlreadyExistsError<EOL>raise DirectoryAlreadyExistsError(target_dir)<EOL><DEDENT>from six.moves.urllib.parse import urlparse<EOL>source_url = urlparse(source_dir)<EOL>target_url = urlparse(target_dir)<EOL>if _UrlIsLocal(source_url) and _UrlIsLocal(target_url):<EOL><INDENT>import shutil<EOL>shutil.move(source_dir, target_dir)<EOL><DEDENT>elif source_url.scheme == '<STR_LIT>' and target_url.scheme == '<STR_LIT>':<EOL><INDENT>from ._exceptions import NotImplementedProtocol<EOL>raise NotImplementedProtocol(target_url.scheme)<EOL><DEDENT>else:<EOL><INDENT>raise NotImplementedError('<STR_LIT>')<EOL><DEDENT>

Moves a directory.

:param unicode source_dir:

:param unicode target_dir:

:raises NotImplementedError:
    If trying to move anything other than:
        Local dir -> local dir
        FTP dir -> FTP dir (same host)


from six.moves.urllib.parse import urlparse<EOL>directory_url = urlparse(directory)<EOL>if _UrlIsLocal(directory_url):<EOL><INDENT>if not os.path.exists(directory):<EOL><INDENT>os.makedirs(directory)<EOL><DEDENT>return directory<EOL><DEDENT>elif directory_url.scheme == '<STR_LIT>':<EOL><INDENT>from ._exceptions import NotImplementedProtocol<EOL>raise NotImplementedProtocol(directory_url.scheme)<EOL><DEDENT>else:<EOL><INDENT>from ._exceptions import NotImplementedProtocol<EOL>raise NotImplementedProtocol(directory_url.scheme)<EOL><DEDENT>

Create directory including any missing intermediate directory.

:param unicode directory:

:return unicode|urlparse.ParseResult:
    Returns the created directory or url (see urlparse).

:raises NotImplementedProtocol:
    If protocol is not local or FTP.

.. seealso:: FTP LIMITATIONS at this module's doc for performance issues information


_AssertIsLocal(path)<EOL>if sys.platform != '<STR_LIT:win32>':<EOL><INDENT>return os.path.islink(path)<EOL><DEDENT>import jaraco.windows.filesystem<EOL>return jaraco.windows.filesystem.islink(path)<EOL>

:param unicode path:
    Path being tested

:returns bool:
    True if `path` is a link


def CopyFiles(source_dir, target_dir, create_target_dir=False, md5_check=False):

import fnmatch<EOL>if IsDir(source_dir):<EOL><INDENT>source_mask = '<STR_LIT:*>'<EOL><DEDENT>else:<EOL><INDENT>source_dir, source_mask = os.path.split(source_dir)<EOL><DEDENT>if not IsDir(target_dir):<EOL><INDENT>if create_target_dir:<EOL><INDENT>CreateDirectory(target_dir)<EOL><DEDENT>else:<EOL><INDENT>from ._exceptions import DirectoryNotFoundError<EOL>raise DirectoryNotFoundError(target_dir)<EOL><DEDENT><DEDENT>filenames = ListFiles(source_dir)<EOL>if filenames is None:<EOL><INDENT>return<EOL><DEDENT>for i_filename in filenames:<EOL><INDENT>if md5_check and i_filename.endswith('<STR_LIT>'):<EOL><INDENT>continue  <EOL><DEDENT>if fnmatch.fnmatch(i_filename, source_mask):<EOL><INDENT>source_path = source_dir + '<STR_LIT:/>' + i_filename<EOL>target_path = target_dir + '<STR_LIT:/>' + i_filename<EOL>if IsDir(source_path):<EOL><INDENT>CopyFiles(source_path, target_path, create_target_dir=True, md5_check=md5_check)<EOL><DEDENT>else:<EOL><INDENT>CopyFile(source_path, target_path, md5_check=md5_check)<EOL><DEDENT><DEDENT><DEDENT>

Copy files from the given source to the target.

:param unicode source_dir:
    A filename, URL or a file mask.
    Ex.
        x:\coilib50
        x:\coilib50\*
        http://server/directory/file
        ftp://server/directory/file

:param unicode target_dir:
    A directory or an URL
    Ex.
        d:\Temp
        ftp://server/directory

:param bool create_target_dir:
    If True, creates the target path if it doesn't exists.

:param bool md5_check:
    .. seealso:: CopyFile

:raises DirectoryNotFoundError:
    If target_dir does not exist, and create_target_dir is False

.. seealso:: CopyFile for documentation on accepted protocols

.. seealso:: FTP LIMITATIONS at this module's doc for performance issues information


def CopyDirectory(source_dir, target_dir, override=False):

_AssertIsLocal(source_dir)<EOL>_AssertIsLocal(target_dir)<EOL>if override and IsDir(target_dir):<EOL><INDENT>DeleteDirectory(target_dir, skip_on_error=False)<EOL><DEDENT>import shutil<EOL>shutil.copytree(source_dir, target_dir)<EOL>

Recursively copy a directory tree.

:param unicode source_dir:
    Where files will come from

:param unicode target_dir:
    Where files will go to

:param bool override:
    If True and target_dir already exists, it will be deleted before copying.

:raises NotImplementedForRemotePathError:
    If trying to copy to/from remote directories


_AssertIsLocal(source_filename)<EOL>_AssertIsLocal(target_filename)<EOL>import shutil<EOL>shutil.move(source_filename, target_filename)<EOL>

Moves a file.

:param unicode source_filename:

:param unicode target_filename:

:raises NotImplementedForRemotePathError:
    If trying to operate with non-local files.


def CreateLink(target_path, link_path, override=True):

_AssertIsLocal(target_path)<EOL>_AssertIsLocal(link_path)<EOL>if override and IsLink(link_path):<EOL><INDENT>DeleteLink(link_path)<EOL><DEDENT>dirname = os.path.dirname(link_path)<EOL>if dirname:<EOL><INDENT>CreateDirectory(dirname)<EOL><DEDENT>if sys.platform != '<STR_LIT:win32>':<EOL><INDENT>return os.symlink(target_path, link_path)  <EOL><DEDENT>else:<EOL><INDENT>import jaraco.windows.filesystem<EOL>return jaraco.windows.filesystem.symlink(target_path, link_path)<EOL>from ._easyfs_win32 import CreateSymbolicLink<EOL>try:<EOL><INDENT>dw_flags = <NUM_LIT:0><EOL>if target_path and os.path.isdir(target_path):<EOL><INDENT>dw_flags = <NUM_LIT:1><EOL><DEDENT>return CreateSymbolicLink(target_path, link_path, dw_flags)<EOL><DEDENT>except Exception as e:<EOL><INDENT>reraise(e, '<STR_LIT>' % locals())<EOL><DEDENT><DEDENT>

Create a symbolic link at `link_path` pointing to `target_path`.

:param unicode target_path:
    Link target

:param unicode link_path:
    Fullpath to link name

:param bool override:
    If True and `link_path` already exists as a link, that link is overridden.


_NATIVE_EOL_STYLE_MAP = {<EOL>'<STR_LIT:win32>' : EOL_STYLE_WINDOWS,<EOL>'<STR_LIT>' : EOL_STYLE_UNIX,<EOL>'<STR_LIT>' : EOL_STYLE_UNIX,<EOL>'<STR_LIT>' : EOL_STYLE_MAC,<EOL>}<EOL>result = _NATIVE_EOL_STYLE_MAP.get(platform)<EOL>if result is None:<EOL><INDENT>from ._exceptions import UnknownPlatformError<EOL>raise UnknownPlatformError(platform)<EOL><DEDENT>return result<EOL>

Internal function that determines EOL_STYLE_NATIVE constant with the proper value for the
current platform.


def _DoCopyFile(source_filename, target_filename, copy_symlink=True):

from six.moves.urllib.parse import urlparse<EOL>source_url = urlparse(source_filename)<EOL>target_url = urlparse(target_filename)<EOL>if _UrlIsLocal(source_url):<EOL><INDENT>if not Exists(source_filename):<EOL><INDENT>from ._exceptions import FileNotFoundError<EOL>raise FileNotFoundError(source_filename)<EOL><DEDENT>if _UrlIsLocal(target_url):<EOL><INDENT>_CopyFileLocal(source_filename, target_filename, copy_symlink=copy_symlink)<EOL><DEDENT>elif target_url.scheme in ['<STR_LIT>']:<EOL><INDENT>from ._exceptions import NotImplementedProtocol<EOL>raise NotImplementedProtocol(target_url.scheme)<EOL><DEDENT>else:<EOL><INDENT>from ._exceptions import NotImplementedProtocol<EOL>raise NotImplementedProtocol(target_url.scheme)<EOL><DEDENT><DEDENT>elif source_url.scheme in ['<STR_LIT:http>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>if _UrlIsLocal(target_url):<EOL><INDENT>from ._exceptions import NotImplementedProtocol<EOL>raise NotImplementedProtocol(target_url.scheme)<EOL><DEDENT>else:<EOL><INDENT>from ._exceptions import NotImplementedProtocol<EOL>raise NotImplementedProtocol(target_url.scheme)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>from ._exceptions import NotImplementedProtocol  <EOL>raise NotImplementedProtocol(source_url.scheme)<EOL><DEDENT>

:param unicode source_filename:
    The source filename.
    Schemas: local, ftp, http

:param unicode target_filename:
    Target filename.
    Schemas: local, ftp

:param  copy_symlink:
    @see _CopyFileLocal

:raises FileNotFoundError:
    If source_filename does not exist


if eol_style == EOL_STYLE_NONE:<EOL><INDENT>return contents<EOL><DEDENT>if eol_style == EOL_STYLE_UNIX:<EOL><INDENT>return contents.replace('<STR_LIT:\r\n>', eol_style).replace('<STR_LIT:\r>', eol_style)<EOL><DEDENT>if eol_style == EOL_STYLE_MAC:<EOL><INDENT>return contents.replace('<STR_LIT:\r\n>', eol_style).replace('<STR_LIT:\n>', eol_style)<EOL><DEDENT>if eol_style == EOL_STYLE_WINDOWS:<EOL><INDENT>return contents.replace('<STR_LIT:\r\n>', '<STR_LIT:\n>').replace('<STR_LIT:\r>', '<STR_LIT:\n>').replace('<STR_LIT:\n>', EOL_STYLE_WINDOWS)<EOL><DEDENT>raise ValueError('<STR_LIT>' % (eol_style,))<EOL>

Replaces eol on each line by the given eol_style.

:param unicode contents:
:type eol_style: EOL_STYLE_XXX constant
:param eol_style:


def GetFileLines(filename, newline=None, encoding=None):

return GetFileContents(<EOL>filename,<EOL>binary=False,<EOL>encoding=encoding,<EOL>newline=newline,<EOL>).split('<STR_LIT:\n>')<EOL>

Reads a file and returns its contents as a list of lines. Works for both local and remote files.

:param unicode filename:

:param None|''|'\n'|'\r'|'\r\n' newline:
    Controls universal newlines.
    See 'io.open' newline parameter documentation for more details.

:param unicode encoding:
    File's encoding. If not None, contents obtained from file will be decoded using this
    `encoding`.

:returns list(unicode):
    The file's lines

.. seealso:: FTP LIMITATIONS at this module's doc for performance issues information


if not IsFile(filename):<EOL><INDENT>from ._exceptions import FileNotFoundError<EOL>raise FileNotFoundError(filename)<EOL><DEDENT>

Check if the given file exists.

@filename: unicode
    The filename to check for existence.

@raise: FileNotFoundError
    Raises if the file does not exist.