signature:
def stat_article_detail_list ( self , page = 1 , start_date = str ( date . today ( ) + timedelta ( days = - 30 ) ) , end_date = str ( date . today ( ) ) ) :
    """获取图文分析数据
 返回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 : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据"""

implementation:
self . _init_plugin_token_appid ( )
url = 'http://mta.qq.com/mta/wechat/ctr_article_detail/get_list?sort=RefDate%20desc&keyword=&page={page}&appid={appid}&pluginid=luopan&token={token}&from=&src=false&devtype=3&time_type=day&start_date={start_date}&end_date={end_date}&need_compare=0&app_id=&rnd={rnd}&ajax=1' . format ( page = page , appid = self . __appid , token = self . __plugin_token , rnd = int ( time . time ( ) ) , start_date = start_date , end_date = end_date , )
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'http://mta.qq.com/mta/wechat/ctr_article_detail/get_list?sort=RefDate%20desc&keyword=&page={page}&appid={appid}&pluginid=luopan&token={token}&from=&src=false&devtype=3&time_type=day&start_date={start_date}&end_date={end_date}&need_compare=0&app_id=&rnd={rnd}&ajax=1' . format ( page = page , appid = self . __appid , token = self . __plugin_token , rnd = int ( time . time ( ) ) , start_date = start_date , end_date = end_date , ) , 'cookie' : self . __cookies , }
r = requests . get ( url , headers = headers )
if not re . search ( r'wechat_token' , self . __cookies ) :
    for cookie in r . cookies :
        self . __cookies += cookie . name + '=' + cookie . value + ';'
try :
    data = json . loads ( r . text )
    if data . get ( 'is_session_expire' ) :
        raise NeedLoginError ( r . text )
    message = json . dumps ( data , ensure_ascii = False )
except ( KeyError , ValueError ) :
    raise NeedLoginError ( r . text )
return message


signature:
def get_group_list ( self ) :
    """获取分组列表
 返回JSON示例 : :
 " groups " : [
 " cnt " : 8,
 " id " : 0,
 " name " : " 未分组 "
 " cnt " : 0,
 " id " : 1,
 " name " : " 黑名单 "
 " cnt " : 0,
 " id " : 2,
 " name " : " 星标组 "
 : return : 返回的 JSON 数据
 : raises NeedLoginError : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据"""

implementation:
url = 'https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&f=json&token={token}' . format ( token = self . __token , )
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&token=' . format ( token = self . __token , ) , 'cookie' : self . __cookies , }
r = requests . get ( url , headers = headers )
try :
    message = json . loads ( r . text ) [ 'group_list' ]
except ( KeyError , ValueError ) :
    raise NeedLoginError ( r . text )
return message


signature:
def get_news_list ( self , page , pagesize = 10 ) :
    """获取图文信息列表
 返回JSON示例 : :
 " multi _ item " : [
 " seq " : 0,
 " title " : " 98路公交线路 " ,
 " show _ cover _ pic " : 1,
 " author " : " " ,
 " cover " : " https : / / mmbiz . qlogo . cn / mmbiz / D2pflbZwStFibz2Sb1kWOuHrxtDMPKJic3GQgcgkDSoEm668gClFVDt3BR8GGQ5eB8HoL4vDezzKtSblIjckOf7A / 0 " ,
 " content _ url " : " http : / / mp . weixin . qq . com / s ? _ _ biz = MjM5MTA2ODcwOA = = & mid = 204884970 & idx = 1 & sn = bf25c51f07260d4ed38305a1cbc0ce0f # rd " ,
 " source _ url " : " " ,
 " file _ id " : 204884939,
 " digest " : " 98路线路1 . 农大 - 2 . 金阳小区 - 3 . 市客运司 - 4 . 市制药厂 - 5 . 新农大 - 6 . 独山子酒店 - 7 . 三 "
 " seq " : 0,
 " title " : " 98路公交线路 " ,
 " show _ cover _ pic " : 1,
 " author " : " " ,
 " app _ id " : 204884970,
 " content _ url " : " http : / / mp . weixin . qq . com / s ? _ _ biz = MjM5MTA2ODcwOA = = & mid = 204884970 & idx = 1 & sn = bf25c51f07260d4ed38305a1cbc0ce0f # rd " ,
 " create _ time " : " 1405237966 " ,
 " file _ id " : 204884939,
 " img _ url " : " https : / / mmbiz . qlogo . cn / mmbiz / D2pflbZwStFibz2Sb1kWOuHrxtDMPKJic3GQgcgkDSoEm668gClFVDt3BR8GGQ5eB8HoL4vDezzKtSblIjckOf7A / 0 " ,
 " digest " : " 98路线路1 . 农大 - 2 . 金阳小区 - 3 . 市客运司 - 4 . 市制药厂 - 5 . 新农大 - 6 . 独山子酒店 - 7 . 三 "
 " multi _ item " : [
 " seq " : 0,
 " title " : " 2013年新疆软件园大事记 " ,
 " show _ cover _ pic " : 0,
 " author " : " " ,
 " cover " : " https : / / mmbiz . qlogo . cn / mmbiz / D2pflbZwStFibz2Sb1kWOuHrxtDMPKJic3icvFgkxZRyIrkLbic9I5ZKLa3XB8UqNlkT8CYibByHuraSvVoeSzdTRLQ / 0 " ,
 " content _ url " : " http : / / mp . weixin . qq . com / s ? _ _ biz = MjM5MTA2ODcwOA = = & mid = 204883415 & idx = 1 & sn = 68d62215052d29ece3f2664e9c4e8cab # rd " ,
 " source _ url " : " " ,
 " file _ id " : 204883412,
 " digest " : " 1月1 . 新疆软件园展厅设计方案汇报会2013年1月15日在维泰大厦4楼9号会议室召开新疆软件园展厅设计工作完 "
 " seq " : 1,
 " title " : " 2012年新疆软件园大事记 " ,
 " show _ cover _ pic " : 0,
 " author " : " " ,
 " cover " : " https : / / mmbiz . qlogo . cn / mmbiz / D2pflbZwStFibz2Sb1kWOuHrxtDMPKJic3oErGEhSicRQc82icibxZOZ2YAGNgiaGYfOFYppmPzOOS0v1xfZ1nvyT58g / 0 " ,
 " content _ url " : " http : / / mp . weixin . qq . com / s ? _ _ biz = MjM5MTA2ODcwOA = = & mid = 204883415 & idx = 2 & sn = e7db9b30d770c85c61008d2f523b8610 # rd " ,
 " source _ url " : " " ,
 " file _ id " : 204883398,
 " digest " : " 1月1 . 新疆软件园环评顺利通过专家会评审2012年1月30日 , 新疆软件园环境影响评价顺利通过专家会评审 , 与会 "
 " seq " : 2,
 " title " : " 2011年新疆软件园大事记 " ,
 " show _ cover _ pic " : 0,
 " author " : " " ,
 " cover " : " https : / / mmbiz . qlogo . cn / mmbiz / D2pflbZwStFibz2Sb1kWOuHrxtDMPKJic3qA7tEN8GvkgDwnOfKsGsicJeQ6PxQSgWuJXfQaXkpM4VNlQicOWJM4Tg / 0 " ,
 " content _ url " : " http : / / mp . weixin . qq . com / s ? _ _ biz = MjM5MTA2ODcwOA = = & mid = 204883415 & idx = 3 & sn = 4cb1c6d25cbe6dfeff37f52a62532bd0 # rd " ,
 " source _ url " : " " ,
 " file _ id " : 204883393,
 " digest " : " 6月1 . 软件园召开第一次建设领导小组会议2011年6月7日 , 第一次软件园建设领导小组会议召开 , 会议认为 , 新疆 "
 " seq " : 3,
 " title " : " 2010年新疆软件园大事记 " ,
 " show _ cover _ pic " : 0,
 " author " : " " ,
 " cover " : " https : / / mmbiz . qlogo . cn / mmbiz / D2pflbZwStFibz2Sb1kWOuHrxtDMPKJic3YG4sSuf9X9ecMPjDRju842IbIvpFWK7tuZs0Po4kZCz4URzOBj5rnQ / 0 " ,
 " content _ url " : " http : / / mp . weixin . qq . com / s ? _ _ biz = MjM5MTA2ODcwOA = = & mid = 204883415 & idx = 4 & sn = 4319f7f051f36ed972e2f05a221738ec # rd " ,
 " source _ url " : " " ,
 " file _ id " : 204884043,
 " digest " : " 5月1 . 新疆软件园与开发区 ( 头屯河区 ) 管委会 、 经信委签署 《 新疆软件园建设战略合作协议 》 2010年5月12日 , "
 " seq " : 1,
 " title " : " 2013年新疆软件园大事记 " ,
 " show _ cover _ pic " : 0,
 " author " : " " ,
 " app _ id " : 204883415,
 " content _ url " : " http : / / mp . weixin . qq . com / s ? _ _ biz = MjM5MTA2ODcwOA = = & mid = 204883415 & idx = 1 & sn = 68d62215052d29ece3f2664e9c4e8cab # rd " ,
 " create _ time " : " 1405232974 " ,
 " file _ id " : 204883412,
 " img _ url " : " https : / / mmbiz . qlogo . cn / mmbiz / D2pflbZwStFibz2Sb1kWOuHrxtDMPKJic3icvFgkxZRyIrkLbic9I5ZKLa3XB8UqNlkT8CYibByHuraSvVoeSzdTRLQ / 0 " ,
 " digest " : " 1月1 . 新疆软件园展厅设计方案汇报会2013年1月15日在维泰大厦4楼9号会议室召开新疆软件园展厅设计工作完 "
 : param page : 页码 ( 从 0 开始 )
 : param pagesize : 每页数目
 : return : 返回的 JSON 数据
 : raises NeedLoginError : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据"""

implementation:
begin = page * pagesize
url = "https://mp.weixin.qq.com/cgi-bin/appmsg?token={token}&lang=zh_CN&type=10&action=list&begin={begin}&count={pagesize}&f=json&random={random}" . format ( token = self . __token , begin = begin , pagesize = pagesize , random = round ( random . random ( ) , 3 ) , )
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token={token}&lang=zh_CN' . format ( token = self . __token , ) , 'cookie' : self . __cookies , }
r = requests . get ( url , headers = headers )
try :
    message = json . dumps ( json . loads ( r . text ) [ 'app_msg_info' ] [ 'item' ] , ensure_ascii = False )
except ( KeyError , ValueError ) :
    raise NeedLoginError ( r . text )
return message


signature:
def get_dialog_message ( self , fakeid , last_msgid = 0 , create_time = 0 ) :
    """获取与指定用户的对话内容 , 获取的内容由 ` ` last _ msgid ` ` ( 需要获取的对话中时间最早的 * * 公众号发送给用户 * * 的消息ID ) 和 ` ` create _ time ` ` ( 需要获取的对话中时间最早的消息时间戳 ) 进行过滤
 消息过滤规则 :
 1 . 首先按照 ` ` last _ msgid ` ` 过滤 ( 不需要按照 ` ` last _ msgid ` ` 过滤则不需要传入此参数 )
 a . ` ` fakeid ` ` 为用户 UID
 b . 通过 ` ` last _ msgid ` ` 去匹配公众号过去发送给用户的某一条消息
 c . 如果匹配成功 , 则返回这条消息之后与这个用户相关的所有消息内容 ( 包括发送的消息和接收的 )
 d . 如果匹配失败 ( 没有找到 ) , 则返回与这个用户相关的所有消息 ( 包括发送的消息和接收的 )
 2 . 第一条规则返回的消息内容接着按照 ` ` create _ time ` ` 进行过滤 , 返回 ` ` create _ time ` ` 时间戳之时及之后的所有消息 ( 不需要按照 ` ` create _ time ` ` 过滤则不需要传入此参数 )
 返回JSON示例 : :
 " to _ nick _ name " : " Doraemonext " ,
 " msg _ items " : {
 " msg _ item " : [
 " date _ time " : 1408671873,
 " has _ reply " : 0,
 " multi _ item " : [ ] ,
 " msg _ status " : 4,
 " nick _ name " : " Doraemonext " ,
 " to _ uin " : 2391068708,
 " content " : " 你呢 " ,
 " source " : " " ,
 " fakeid " : " 844735403 " ,
 " send _ stat " : {
 " fail " : 0,
 " succ " : 0,
 " total " : 0
 " refuse _ reason " : " " ,
 " type " : 1,
 " id " : 206439567
 " date _ time " : 1408529750,
 " send _ stat " : {
 " fail " : 0,
 " succ " : 0,
 " total " : 0
 " app _ sub _ type " : 3,
 " multi _ item " : [
 " seq " : 0,
 " title " : " 软件企业有望拎包入住新疆软件园 " ,
 " show _ cover _ pic " : 1,
 " author " : " " ,
 " cover " : " https : / / mmbiz . qlogo . cn / mmbiz / D2pflbZwStFibz2Sb1kWOuHrxtDMPKJic3oErGEhSicRQc82icibxZOZ2YAGNgiaGYfOFYppmPzOOS0v1xfZ1nvyT58g / 0 " ,
 " content _ url " : " http : / / mp . weixin . qq . com / s ? _ _ biz = MjM5MTA2ODcwOA = = & mid = 204885255 & idx = 1 & sn = 40e07d236a497e36d2d3e9711dfe090a # rd " ,
 " source _ url " : " " ,
 " content " : " " ,
 " file _ id " : 204885252,
 " vote _ id " : [ ] ,
 " digest " : " 12月8日 , 国家软件公共服务平台新疆分平台在乌鲁木齐经济技术开发区 ( 头屯河区 ) 揭牌 。 这意味着 , 软件企业有 "
 " msg _ status " : 2,
 " title " : " 软件企业有望拎包入住新疆软件园 " ,
 " nick _ name " : " Doraemonext " ,
 " to _ uin " : 844735403,
 " content _ url " : " http : / / mp . weixin . qq . com / s ? _ _ biz = MjM5MTA2ODcwOA = = & mid = 204885255 & idx = 1 & sn = 40e07d236a497e36d2d3e9711dfe090a # rd " ,
 " show _ type " : 1,
 " content " : " " ,
 " source " : " biz " ,
 " fakeid " : " 2391068708 " ,
 " file _ id " : 204885252,
 " has _ reply " : 0,
 " refuse _ reason " : " " ,
 " type " : 6,
 " id " : 206379033,
 " desc " : " 12月8日 , 国家软件公共服务平台新疆分平台在乌鲁木齐经济技术开发区 ( 头屯河区 ) 揭牌 。 这意味着 , 软件企业有 "
 : param fakeid : 用户 UID ( 即 fakeid )
 : param last _ msgid : 公众号之前发送给用户 ( fakeid ) 的消息 ID , 为 0 则表示全部消息
 : param create _ time : 获取这个时间戳之时及之后的消息 , 为 0 则表示全部消息
 : return : 返回的 JSON 数据
 : raises NeedLoginError : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据"""

implementation:
self . _init_fakeid ( )
url = 'https://mp.weixin.qq.com/cgi-bin/singlesendpage?tofakeid={fakeid}&action=sync&lastmsgfromfakeid={fromfakeid}&lastmsgid={last_msgid}&createtime={create_time}&token={token}&lang=zh_CN&f=json&ajax=1' . format ( fakeid = fakeid , fromfakeid = self . __fakeid , last_msgid = last_msgid , create_time = create_time , token = self . __token , )
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&token={token}&lang=zh_CN' . format ( token = self . __token ) , 'cookie' : self . __cookies , }
r = requests . get ( url , headers = headers )
try :
    message = json . dumps ( json . loads ( r . text ) [ 'page_info' ] , ensure_ascii = False )
except ( KeyError , ValueError ) :
    raise NeedLoginError ( r . text )
return message


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

implementation:
url = 'https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response'
payload = { 'lang' : 'zh_CN' , 'f' : 'json' , 'tofakeid' : fakeid , 'type' : 10 , 'token' : self . __token , 'appmsgid' : msgid , 'app_id' : msgid , 'error' : 'false' , 'ajax' : 1 , 'random' : random . random ( ) , }
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/cgi-bin/singlemsgpage?fromfakeid={fakeid}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN' . format ( fakeid = fakeid , ) , 'cookie' : self . __cookies , }
r = requests . post ( url , data = payload , headers = headers )
try :
    message = json . loads ( r . text )
except ValueError :
    raise NeedLoginError ( r . text )
try :
    if message [ 'base_resp' ] [ 'ret' ] == 10700 or message [ 'base_resp' ] [ 'ret' ] == - 21 :
        raise ValueError ( 'fake id not exist' )
    if message [ 'base_resp' ] [ 'ret' ] == 10705 :
        raise ValueError ( 'message id not exist' )
    if message [ 'base_resp' ] [ 'ret' ] != 0 :
        raise NeedLoginError ( r . text )
except KeyError :
    raise NeedLoginError ( r . text )


signature:
def add_news ( self , news ) :
    """在素材库中创建图文消息
 : 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 : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据"""

implementation:
if not news :
    raise ValueError ( 'The news cannot be empty' )
for item in news :
    if 'title' not in item or 'content' not in item :
        raise ValueError ( 'The news item needs to provide at least two arguments: title, content' )
url = 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&t=ajax-response&sub=create&token={token}' . format ( token = self . __token , )
payload = { 'token' : self . __token , 'type' : 10 , 'lang' : 'zh_CN' , 'sub' : 'create' , 'ajax' : 1 , 'AppMsgId' : '' , 'error' : 'false' , }
headers = { 'referer' : 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&sub=edit&t=wxm-appmsgs-edit-new&type=10&subtype=3&token={token}' . format ( token = self . __token ) , 'cookie' : self . __cookies , }
i = 0
for item in news :
    payload [ 'title' + str ( i ) ] = item . get ( 'title' )
    payload [ 'author' + str ( i ) ] = item . get ( 'author' )
    payload [ 'digest' + str ( i ) ] = item . get ( 'summary' )
    payload [ 'content' + str ( i ) ] = item . get ( 'content' )
    payload [ 'fileid' + str ( i ) ] = item . get ( 'picture_id' )
    payload [ 'sourceurl' + str ( i ) ] = item . get ( 'from_url' )
    i += 1
payload [ 'count' ] = i
r = requests . post ( url , data = payload , headers = headers )
try :
    message = json . loads ( r . text )
except ValueError :
    raise NeedLoginError ( r . text )
try :
    if message [ 'ret' ] != '0' :
        raise ValueError ( r . text )
except KeyError :
    raise NeedLoginError ( r . text )


signature:
def upload_file ( self , filepath ) :
    """上传素材 ( 图片 / 音频 / 视频 )
 : param filepath : 本地文件路径
 : return : 直接返回上传后的文件 ID ( fid )
 : raises NeedLoginError : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据
 : raises ValueError : 参数出错 , 错误原因直接打印异常即可 ( 常见错误内容 : ` ` file not exist ` ` : 找不到本地文件 , ` ` audio too long ` ` : 音频文件过长 , ` ` file invalid type ` ` : 文件格式不正确 , 还有其他错误请自行检查 )"""

implementation:
self . _init_ticket ( )
url = 'https://mp.weixin.qq.com/cgi-bin/filetransfer?action=upload_material&f=json&ticket_id={ticket_id}&ticket={ticket}&token={token}&lang=zh_CN' . format ( ticket_id = self . __ticket_id , ticket = self . __ticket , token = self . __token , )
try :
    files = { 'file' : open ( filepath , 'rb' ) }
except IOError :
    raise ValueError ( 'file not exist' )
payloads = { 'Filename' : filepath , 'folder' : '/cgi-bin/uploads' , 'Upload' : 'Submit Query' , }
headers = { 'referer' : 'http://mp.weixin.qq.com/cgi-bin/indexpage?t=wxm-upload&lang=zh_CN&type=2&formId=1' , 'cookie' : self . __cookies , }
r = requests . post ( url , files = files , data = payloads , headers = headers )
try :
    message = json . loads ( r . text )
except ValueError :
    raise NeedLoginError ( r . text )
try :
    if message [ 'base_resp' ] [ 'ret' ] != 0 :
        raise ValueError ( message [ 'base_resp' ] [ 'err_msg' ] )
except KeyError :
    raise NeedLoginError ( r . text )
return message [ 'content' ]


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

implementation:
if type == 4 : # 此处判断为兼容历史版本 , 微信官方已经将视频类型修改为 15
    type = 15
url = 'https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response&f=json&token={token}&lang=zh_CN' . format ( token = self . __token , )
payloads = { }
if type == 2 or type == 3 : # 如果文件类型是图片或者音频
    payloads = { 'token' : self . __token , 'lang' : 'zh_CN' , 'f' : 'json' , 'ajax' : 1 , 'random' : random . random ( ) , 'type' : type , 'file_id' : fid , 'tofakeid' : fakeid , 'fileid' : fid , 'imgcode' : '' , }
elif type == 15 : # 如果文件类型是视频
    payloads = { 'token' : self . __token , 'lang' : 'zh_CN' , 'f' : 'json' , 'ajax' : 1 , 'random' : random . random ( ) , 'type' : type , 'app_id' : fid , 'tofakeid' : fakeid , 'appmsgid' : fid , 'imgcode' : '' , }
headers = { 'referer' : 'https://mp.weixin.qq.com/cgi-bin/singlesendpage?tofakeid={fakeid}&t=message/send&action=index&token={token}&lang=zh_CN' . format ( fakeid = fakeid , token = self . __token , ) , 'cookie' : self . __cookies , 'x-requested-with' : 'XMLHttpRequest' , }
r = requests . post ( url , data = payloads , headers = headers )
try :
    message = json . loads ( r . text )
except ValueError :
    raise NeedLoginError ( r . text )
try :
    if message [ 'base_resp' ] [ 'ret' ] != 0 :
        raise ValueError ( message [ 'base_resp' ] [ 'err_msg' ] )
except KeyError :
    raise NeedLoginError ( r . text )


signature:
def get_user_info ( self , fakeid ) :
    """获取指定用户的个人信息
 返回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 : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据"""

implementation:
url = 'https://mp.weixin.qq.com/cgi-bin/getcontactinfo'
payloads = { 'ajax' : 1 , 'lang' : 'zh_CN' , 'random' : round ( random . random ( ) , 3 ) , 'token' : self . __token , 't' : 'ajax-getcontactinfo' , 'fakeid' : fakeid , }
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token={token}' . format ( token = self . __token , ) , 'cookie' : self . __cookies , }
r = requests . post ( url , data = payloads , headers = headers )
try :
    message = json . dumps ( json . loads ( r . text ) [ 'contact_info' ] , ensure_ascii = False )
except ( KeyError , ValueError ) :
    raise NeedLoginError ( r . text )
return message


signature:
def get_avatar ( self , fakeid ) :
    """获取用户头像信息
 : param fakeid : 用户的 UID ( 即 fakeid )
 : return : 二进制 JPG 数据字符串 , 可直接作为 File Object 中 write 的参数
 : raises NeedLoginError : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据"""

implementation:
url = 'https://mp.weixin.qq.com/misc/getheadimg?fakeid={fakeid}&token={token}&lang=zh_CN' . format ( fakeid = fakeid , token = self . __token , )
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token={token}' . format ( token = self . __token , ) , 'cookie' : self . __cookies , }
r = requests . get ( url , headers = headers , stream = True )
return r . raw . data


signature:
def get_new_message_num ( self , lastid = 0 ) :
    """获取新消息的数目
 : param lastid : 最近获取的消息 ID , 为 0 时获取总消息数目
 : return : 消息数目"""

implementation:
url = 'https://mp.weixin.qq.com/cgi-bin/getnewmsgnum?f=json&t=ajax-getmsgnum&lastmsgid={lastid}&token={token}&lang=zh_CN' . format ( lastid = lastid , token = self . __token , )
payloads = { 'ajax' : 1 , 'f' : 'json' , 'random' : random . random ( ) , 'lang' : 'zh_CN' , 'token' : self . __token , }
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&token={token}&lang=zh_CN' . format ( token = self . __token , ) , 'cookie' : self . __cookies , }
r = requests . get ( url , data = payloads , headers = headers )
try :
    return int ( json . loads ( r . text ) [ 'newTotalMsgCount' ] )
except ( KeyError , ValueError ) :
    raise NeedLoginError ( r . text )


signature:
def get_message_list ( self , lastid = 0 , offset = 0 , count = 20 , day = 7 , star = False ) :
    """获取消息列表
 返回JSON示例 : :
 " msg _ item " : [
 " id " : 206439583,
 " type " : 1,
 " fakeid " : " 844735403 " ,
 " nick _ name " : " Doraemonext " ,
 " date _ time " : 1408671892,
 " content " : " 测试消息 " ,
 " source " : " " ,
 " msg _ status " : 4,
 " has _ reply " : 0,
 " refuse _ reason " : " " ,
 " multi _ item " : [ ] ,
 " to _ uin " : 2391068708,
 " send _ stat " : {
 " total " : 0,
 " succ " : 0,
 " fail " : 0
 " id " : 206439579,
 " type " : 1,
 " fakeid " : " 844735403 " ,
 " nick _ name " : " Doraemonext " ,
 " date _ time " : 1408671889,
 " content " : " wechat - python - sdk " ,
 " source " : " " ,
 " msg _ status " : 4,
 " has _ reply " : 0,
 " refuse _ reason " : " " ,
 " multi _ item " : [ ] ,
 " to _ uin " : 2391068708,
 " send _ stat " : {
 " total " : 0,
 " succ " : 0,
 " fail " : 0
 : param lastid : 传入最后的消息 id 编号 , 为 0 则从最新一条起倒序获取
 : param offset : lastid 起算第一条的偏移量
 : param count : 获取数目
 : param day : 最近几天消息 ( 0 : 今天 , 1 : 昨天 , 2 : 前天 , 3 : 更早 , 7 : 全部 ) , 这里的全部仅有5天
 : param star : 是否只获取星标消息
 : return : 返回的 JSON 数据
 : raises NeedLoginError : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据"""

implementation:
if star :
    star_param = '&action=star'
else :
    star_param = ''
if lastid == 0 :
    lastid = ''
url = 'https://mp.weixin.qq.com/cgi-bin/message?t=message/list&f=json&lang=zh_CN{star}&count={count}&day={day}&frommsgid={lastid}&offset={offset}&token={token}' . format ( star = star_param , count = count , day = day , lastid = lastid , offset = offset , token = self . __token , )
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&token={token}&lang=zh_CN' . format ( token = self . __token ) , 'cookie' : self . __cookies , }
r = requests . get ( url , headers = headers )
try :
    message = json . loads ( r . text ) [ 'msg_items' ]
except ( KeyError , ValueError ) :
    raise NeedLoginError ( r . text )
return message


signature:
def get_message_voice ( self , msgid ) :
    """根据消息 ID 获取语音消息内容
 : param msgid : 消息 ID
 : return : 二进制 MP3 音频字符串 , 可直接作为 File Object 中 write 的参数
 : raises NeedLoginError : 操作未执行成功 , 需要再次尝试登录 , 异常内容为服务器返回的错误数据
 : raises ValueError : 参数出错 , 错误原因直接打印异常即可 , 错误内容 : ` ` voice message not exist ` ` : msg参数无效"""

implementation:
url = 'https://mp.weixin.qq.com/cgi-bin/getvoicedata?msgid={msgid}&fileid=&token={token}&lang=zh_CN' . format ( msgid = msgid , token = self . __token , )
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/cgi-bin/message?t=message/list&token={token}&count=20&day=7' . format ( token = self . __token , ) , 'cookie' : self . __cookies , }
r = requests . get ( url , headers = headers , stream = True )
# 检测会话是否超时
if r . headers . get ( 'content-type' , None ) == 'text/html; charset=UTF-8' :
    raise NeedLoginError ( r . text )
# 检测语音是否存在
if not r . raw . data :
    raise ValueError ( 'voice message not exist' )
return r . raw . data


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

implementation:
url = 'https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token={token}' . format ( token = self . __token )
headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com' , 'cookie' : self . __cookies , }
r = requests . get ( url , headers = headers )
# 获取 Ticket ID 值
ticket_id = re . search ( r'user_name:\"(.*)\"' , r . text )
if not ticket_id :
    raise NeedLoginError ( r . text )
self . __ticket_id = ticket_id . group ( 1 )
# 获取 Ticket 值
ticket = re . search ( r'ticket:\"(.*)\"' , r . text )
if not ticket :
    raise NeedLoginError ( r . text )
self . __ticket = ticket . group ( 1 )
# 获取公众号自身的 fakeid 值
fakeid = re . search ( r'uin:\"(.*)\"' , r . text )
if not fakeid :
    raise NeedLoginError ( r . text )
self . __fakeid = fakeid . group ( 1 )


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

implementation:
if not self . __plugin_token or not self . __appid :
    url = 'https://mp.weixin.qq.com/misc/pluginloginpage?action=stat_article_detail&pluginid=luopan&t=statistics/index&token={token}&lang=zh_CN' . format ( token = self . __token , )
    headers = { 'x-requested-with' : 'XMLHttpRequest' , 'referer' : 'https://mp.weixin.qq.com/misc/pluginloginpage?action=stat_article_detail&pluginid=luopan&t=statistics/index&token={token}&lang=zh_CN' . format ( token = self . __token , ) , 'cookie' : self . __cookies , }
    r = requests . get ( url , headers = headers )
    plugin_token = re . search ( r"pluginToken : '(\S+)'," , r . text )
    if not plugin_token :
        raise NeedLoginError ( r . text )
    self . __plugin_token = plugin_token . group ( 1 )
    appid = re . search ( r"appid : '(\S+)'," , r . text )
    if not appid :
        raise NeedLoginError ( r . text )
    self . __appid = appid . group ( 1 )


signature:
def set_appid_appsecret ( self , appid , appsecret ) :
    """设置当前 App ID 及 App Secret"""

implementation:
self . __appid = appid
self . __appsecret = appsecret
self . _update_crypto ( )


signature:
def access_token ( self ) :
    """获取当前 access token 值 , 本方法会自行维护 access token 有效性"""

implementation:
self . _check_appid_appsecret ( )
if callable ( self . __access_token_getfunc ) :
    self . __access_token , self . __access_token_expires_at = self . __access_token_getfunc ( )
if self . __access_token :
    now = time . time ( )
    if self . __access_token_expires_at - now > 60 :
        return self . __access_token
self . grant_access_token ( )
# 从腾讯服务器获取 access token 并更新
return self . __access_token


signature:
def jsapi_ticket ( self ) :
    """获取当前 jsapi ticket 值 , 本方法会自行维护 jsapi ticket 有效性"""

implementation:
self . _check_appid_appsecret ( )
if callable ( self . __jsapi_ticket_getfunc ) :
    self . __jsapi_ticket , self . __jsapi_ticket_expires_at = self . __jsapi_ticket_getfunc ( )
if self . __jsapi_ticket :
    now = time . time ( )
    if self . __jsapi_ticket_expires_at - now > 60 :
        return self . __jsapi_ticket
self . grant_jsapi_ticket ( )
# 从腾讯服务器获取 jsapi ticket 并更新
return self . __jsapi_ticket


signature:
def grant_access_token ( self ) :
    """获取 access token 并更新当前配置
 : return : 返回的 JSON 数据包 ( 传入 access _ token _ refreshfunc 参数后返回 None )"""

implementation:
self . _check_appid_appsecret ( )
if callable ( self . __access_token_refreshfunc ) :
    self . __access_token , self . __access_token_expires_at = self . __access_token_refreshfunc ( )
    return
response_json = self . __request . get ( url = "https://api.weixin.qq.com/cgi-bin/token" , params = { "grant_type" : "client_credential" , "appid" : self . __appid , "secret" : self . __appsecret , } , access_token = self . __access_token )
self . __access_token = response_json [ 'access_token' ]
self . __access_token_expires_at = int ( time . time ( ) ) + response_json [ 'expires_in' ]
if callable ( self . __access_token_setfunc ) :
    self . __access_token_setfunc ( self . __access_token , self . __access_token_expires_at )
return response_json


signature:
def grant_jsapi_ticket ( self ) :
    """获取 jsapi ticket 并更新当前配置
 : return : 返回的 JSON 数据包 ( 传入 jsapi _ ticket _ refreshfunc 参数后返回 None )"""

implementation:
self . _check_appid_appsecret ( )
if callable ( self . __jsapi_ticket_refreshfunc ) :
    self . __jsapi_ticket , self . __jsapi_ticket_expires_at = self . __jsapi_ticket_refreshfunc ( )
    return
response_json = self . __request . get ( url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket" , params = { "type" : "jsapi" , } , access_token = self . access_token , )
self . __jsapi_ticket = response_json [ 'ticket' ]
self . __jsapi_ticket_expires_at = int ( time . time ( ) ) + response_json [ 'expires_in' ]
if callable ( self . __jsapi_ticket_setfunc ) :
    self . __jsapi_ticket_setfunc ( self . __jsapi_ticket , self . __jsapi_ticket_expires_at )
return response_json


signature:
def _update_crypto ( self ) :
    """根据当前配置内容更新 Crypto 类"""

implementation:
if self . __encrypt_mode in [ 'compatible' , 'safe' ] and self . __encoding_aes_key is not None :
    if self . __token is None or self . __appid is None :
        raise NeedParamError ( 'Please provide token and appid parameters in the construction of class.' )
    self . __crypto = BasicCrypto ( self . __token , self . __encoding_aes_key , self . __appid )
else :
    self . __crypto = None


signature:
def conf ( self , conf ) :
    """设置当前 WechatConf 实例"""

implementation:
self . __conf = conf
self . __request = WechatRequest ( conf = self . __conf )


signature:
def check_signature ( self , signature , timestamp , nonce ) :
    """验证微信消息真实性
 : param signature : 微信加密签名
 : param timestamp : 时间戳
 : param nonce : 随机数
 : return : 通过验证返回 True , 未通过验证返回 False"""

implementation:
if not signature or not timestamp or not nonce :
    return False
tmp_list = [ self . conf . token , timestamp , nonce ]
tmp_list . sort ( )
tmp_str = '' . join ( tmp_list )
if signature != hashlib . sha1 ( tmp_str . encode ( 'utf-8' ) ) . hexdigest ( ) :
    return False
return True


signature:
def generate_jsapi_signature ( self , timestamp , noncestr , url , jsapi_ticket = None ) :
    """使用 jsapi _ ticket 对 url 进行签名
 : param timestamp : 时间戳
 : param noncestr : 随机数
 : param url : 要签名的 url , 不包含 # 及其后面部分
 : param jsapi _ ticket : ( 可选参数 ) jsapi _ ticket 值 ( 如不提供将自动通过 appid 和 appsecret 获取 )
 : return : 返回sha1签名的hexdigest值"""

implementation:
if not jsapi_ticket :
    jsapi_ticket = self . conf . jsapi_ticket
data = { 'jsapi_ticket' : jsapi_ticket , 'noncestr' : noncestr , 'timestamp' : timestamp , 'url' : url , }
keys = list ( data . keys ( ) )
keys . sort ( )
data_str = '&' . join ( [ '%s=%s' % ( key , data [ key ] ) for key in keys ] )
signature = hashlib . sha1 ( data_str . encode ( 'utf-8' ) ) . hexdigest ( )
return signature


signature:
def parse_data ( self , data , msg_signature = None , timestamp = None , nonce = None ) :
    """解析微信服务器发送过来的数据并保存类中
 : param data : HTTP Request 的 Body 数据
 : param msg _ signature : EncodingAESKey 的 msg _ signature
 : param timestamp : EncodingAESKey 用时间戳
 : param nonce : EncodingAESKey 用随机数
 : raises ParseError : 解析微信服务器数据错误 , 数据不合法"""

implementation:
result = { }
if isinstance ( data , six . text_type ) : # unicode to str ( PY2 ) , str to bytes ( PY3)
    data = data . encode ( 'utf-8' )
if self . conf . encrypt_mode == 'safe' :
    if not ( msg_signature and timestamp and nonce ) :
        raise ParseError ( 'must provide msg_signature/timestamp/nonce in safe encrypt mode' )
    data = self . conf . crypto . decrypt_message ( msg = data , msg_signature = msg_signature , timestamp = timestamp , nonce = nonce , )
try :
    xml = XMLStore ( xmlstring = data )
except Exception :
    raise ParseError ( )
result = xml . xml2dict
result [ 'raw' ] = data
result [ 'type' ] = result . pop ( 'MsgType' ) . lower ( )
message_type = MESSAGE_TYPES . get ( result [ 'type' ] , UnknownMessage )
self . __message = message_type ( result )
self . __is_parse = True


signature:
def response_text ( self , content , escape = False ) :
    """将文字信息 content 组装为符合微信服务器要求的响应数据
 : param content : 回复文字
 : param escape : 是否转义该文本内容 ( 默认不转义 )
 : return : 符合微信服务器要求的 XML 响应数据"""

implementation:
self . _check_parse ( )
content = self . _transcoding ( content )
if escape :
    if six . PY2 :
        content = cgi . escape ( content )
    else :
        import html
        content = html . escape ( content )
response = TextReply ( message = self . __message , content = content ) . render ( )
return self . _encrypt_response ( response )


signature:
def response_image ( self , media_id ) :
    """将 media _ id 所代表的图片组装为符合微信服务器要求的响应数据
 : param media _ id : 图片的 MediaID
 : return : 符合微信服务器要求的 XML 响应数据"""

implementation:
self . _check_parse ( )
response = ImageReply ( message = self . __message , media_id = media_id ) . render ( )
return self . _encrypt_response ( response )


signature:
def response_voice ( self , media_id ) :
    """将 media _ id 所代表的语音组装为符合微信服务器要求的响应数据
 : param media _ id : 语音的 MediaID
 : return : 符合微信服务器要求的 XML 响应数据"""

implementation:
self . _check_parse ( )
response = VoiceReply ( message = self . __message , media_id = media_id ) . render ( )
return self . _encrypt_response ( response )


signature:
def response_video ( self , media_id , title = None , description = None ) :
    """将 media _ id 所代表的视频组装为符合微信服务器要求的响应数据
 : param media _ id : 视频的 MediaID
 : param title : 视频消息的标题
 : param description : 视频消息的描述
 : return : 符合微信服务器要求的 XML 响应数据"""

implementation:
self . _check_parse ( )
title = self . _transcoding ( title )
description = self . _transcoding ( description )
response = VideoReply ( message = self . __message , media_id = media_id , title = title , description = description ) . render ( )
return self . _encrypt_response ( response )


signature:
def response_music ( self , music_url , title = None , description = None , hq_music_url = None , thumb_media_id = None ) :
    """将音乐信息组装为符合微信服务器要求的响应数据
 : param music _ url : 音乐链接
 : param title : 音乐标题
 : param description : 音乐描述
 : param hq _ music _ url : 高质量音乐链接 , WIFI环境优先使用该链接播放音乐
 : param thumb _ media _ id : 缩略图的 MediaID
 : return : 符合微信服务器要求的 XML 响应数据"""

implementation:
self . _check_parse ( )
music_url = self . _transcoding ( music_url )
title = self . _transcoding ( title )
description = self . _transcoding ( description )
hq_music_url = self . _transcoding ( hq_music_url )
response = MusicReply ( message = self . __message , title = title , description = description , music_url = music_url , hq_music_url = hq_music_url , thumb_media_id = thumb_media_id ) . render ( )
return self . _encrypt_response ( response )


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

implementation:
self . _check_parse ( )
for article in articles :
    if article . get ( 'title' ) :
        article [ 'title' ] = self . _transcoding ( article [ 'title' ] )
    if article . get ( 'description' ) :
        article [ 'description' ] = self . _transcoding ( article [ 'description' ] )
    if article . get ( 'picurl' ) :
        article [ 'picurl' ] = self . _transcoding ( article [ 'picurl' ] )
    if article . get ( 'url' ) :
        article [ 'url' ] = self . _transcoding ( article [ 'url' ] )
news = ArticleReply ( message = self . __message )
for article in articles :
    article = Article ( ** article )
    news . add_article ( article )
response = news . render ( )
return self . _encrypt_response ( response )


signature:
def group_transfer_message ( self ) :
    """将 message 群发到多客服系统
 : return : 符合微信服务器要求的 XML 响应数据"""

implementation:
self . _check_parse ( )
response = GroupTransferReply ( message = self . __message ) . render ( )
return self . _encrypt_response ( response )


signature:
def create_menu ( self , menu_data ) :
    """创建自定义菜单 : :
 # - * - coding : utf - 8 - * -
 wechat = WechatBasic ( appid = ' appid ' , appsecret = ' appsecret ' )
 wechat . create _ menu ( {
 ' button ' : [
 ' type ' : ' click ' ,
 ' name ' : ' 今日歌曲 ' ,
 ' key ' : ' V1001 _ TODAY _ MUSIC '
 ' type ' : ' click ' ,
 ' name ' : ' 歌手简介 ' ,
 ' key ' : ' V1001 _ TODAY _ SINGER '
 ' name ' : ' 菜单 ' ,
 ' sub _ button ' : [
 ' type ' : ' view ' ,
 ' name ' : ' 搜索 ' ,
 ' url ' : ' http : / / www . soso . com / '
 ' type ' : ' view ' ,
 ' name ' : ' 视频 ' ,
 ' url ' : ' http : / / v . qq . com / '
 ' type ' : ' click ' ,
 ' name ' : ' 赞一下我们 ' ,
 ' key ' : ' V1001 _ GOOD '
 详情请参考 http : / / mp . weixin . qq . com / wiki / 13/43de8269be54a0a6f64413e4dfa94f39 . html
 : param menu _ data : Python 字典
 : return : 返回的 JSON 数据包"""

implementation:
menu_data = self . _transcoding_dict ( menu_data )
return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/menu/create' , data = menu_data )


signature:
def upload_media ( self , media_type , media_file , extension = '' ) :
    """上传多媒体文件
 详情请参考 http : / / mp . weixin . qq . com / wiki / 10/78b15308b053286e2a66b33f0f0f5fb6 . html
 : param media _ type : 媒体文件类型 , 分别有图片 ( image ) 、 语音 ( voice ) 、 视频 ( video ) 和缩略图 ( thumb )
 : param media _ file : 要上传的文件 , 一个 File object 或 StringIO object
 : param extension : 如果 media _ file 传入的为 StringIO object , 那么必须传入 extension 显示指明该媒体文件扩展名 , 如 ` ` mp3 ` ` , ` ` amr ` ` ; 如果 media _ file 传入的为 File object , 那么该参数请留空
 : return : 返回的 JSON 数据包"""

implementation:
if six . PY2 :
    return self . _upload_media_py2 ( media_type , media_file , extension )
else :
    return self . _upload_media_py3 ( media_type , media_file , extension )


signature:
def download_media ( self , media_id ) :
    """下载多媒体文件
 详情请参考 http : / / mp . weixin . qq . com / wiki / 10/78b15308b053286e2a66b33f0f0f5fb6 . html
 : param media _ id : 媒体文件 ID
 : return : requests 的 Response 实例"""

implementation: return self . request . get ( 'https://api.weixin.qq.com/cgi-bin/media/get' , params = { 'media_id' : media_id , } , stream = True , )


signature:
def move_user ( self , user_id , group_id ) :
    """移动用户分组
 详情请参考 http : / / mp . weixin . qq . com / wiki / 13 / be5272dc4930300ba561d927aead2569 . html
 : param user _ id : 用户 ID 。 就是你收到的 WechatMessage 的 source
 : param group _ id : 分组 ID
 : return : 返回的 JSON 数据包"""

implementation: return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/groups/members/update' , data = { 'openid' : user_id , 'to_groupid' : group_id , } )


signature:
def get_user_info ( self , user_id , lang = 'zh_CN' ) :
    """获取用户基本信息
 详情请参考 http : / / mp . weixin . qq . com / wiki / 14 / bb5031008f1494a59c6f71fa0f319c66 . html
 : param user _ id : 用户 ID , 就是你收到的 WechatMessage 的 source
 : param lang : 返回国家地区语言版本 , zh _ CN 简体 , zh _ TW 繁体 , en 英语
 : return : 返回的 JSON 数据包"""

implementation: return self . request . get ( url = 'https://api.weixin.qq.com/cgi-bin/user/info' , params = { 'openid' : user_id , 'lang' : lang , } )


signature:
def get_followers ( self , first_user_id = None ) :
    """获取关注者列表
 详情请参考 http : / / mp . weixin . qq . com / wiki / 3/17e6919a39c1c53555185907acf70093 . html
 : param first _ user _ id : 可选 。 第一个拉取的OPENID , 不填默认从头开始拉取
 : return : 返回的 JSON 数据包"""

implementation:
params = dict ( )
if first_user_id :
    params [ 'next_openid' ] = first_user_id
return self . request . get ( 'https://api.weixin.qq.com/cgi-bin/user/get' , params = params )


signature:
def send_text_message ( self , user_id , content ) :
    """发送文本消息
 详情请参考 http : / / mp . weixin . qq . com / wiki / 7/12a5a320ae96fecdf0e15cb06123de9f . html
 : param user _ id : 用户 ID , 就是你收到的 WechatMessage 的 source
 : param content : 消息正文
 : return : 返回的 JSON 数据包"""

implementation: return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send' , data = { 'touser' : user_id , 'msgtype' : 'text' , 'text' : { 'content' : content , } , } )


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

implementation: return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send' , data = { 'touser' : user_id , 'msgtype' : 'image' , 'image' : { 'media_id' : media_id , } , } )


signature:
def send_voice_message ( self , user_id , media_id ) :
    """发送语音消息
 详情请参考 http : / / mp . weixin . qq . com / wiki / 7/12a5a320ae96fecdf0e15cb06123de9f . html
 : param user _ id : 用户 ID , 就是你收到的 WechatMessage 的 source
 : param media _ id : 发送的语音的媒体ID 。 可以通过 : func : ` upload _ media ` 上传 。
 : return : 返回的 JSON 数据包"""

implementation: return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send' , data = { 'touser' : user_id , 'msgtype' : 'voice' , 'voice' : { 'media_id' : media_id , } , } )


signature:
def send_video_message ( self , user_id , media_id , title = None , description = None ) :
    """发送视频消息
 详情请参考 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 数据包"""

implementation:
video_data = { 'media_id' : media_id , }
if title :
    video_data [ 'title' ] = title
if description :
    video_data [ 'description' ] = description
return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send' , data = { 'touser' : user_id , 'msgtype' : 'video' , 'video' : video_data , } )


signature:
def send_article_message ( self , user_id , articles = None , media_id = None ) :
    """发送图文消息
 详情请参考 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 数据包"""

implementation:
# neither ' articles ' nor ' media _ id ' is specified
if articles is None and media_id is None :
    raise TypeError ( 'must provide one parameter in "articles" and "media_id"' )
# articles specified
if articles :
    articles_data = [ ]
    for article in articles :
        article = Article ( ** article )
        articles_data . append ( { 'title' : article . title , 'description' : article . description , 'url' : article . url , 'picurl' : article . picurl , } )
    return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send' , data = { 'touser' : user_id , 'msgtype' : 'news' , 'news' : { 'articles' : articles_data , } , } )
# media _ id specified
return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send' , data = { 'touser' : user_id , 'msgtype' : 'mpnews' , 'mpnews' : { 'media_id' : media_id , } , } )


signature:
def create_qrcode ( self , data ) :
    """创建二维码
 详情请参考 http : / / mp . weixin . qq . com / wiki / 18/28fc21e7ed87bec960651f0ce873ef8a . html
 : param data : 你要发送的参数 dict
 : return : 返回的 JSON 数据包"""

implementation:
data = self . _transcoding_dict ( data )
return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create' , data = data )


signature:
def set_template_industry ( self , industry_id1 , industry_id2 ) :
    """设置所属行业
 详情请参考 http : / / mp . weixin . qq . com / wiki / 17/304c1885ea66dbedf7dc170d84999a9d . html
 : param industry _ id1 : 主营行业代码
 : param industry _ id2 : 副营行业代码
 : return : 返回的 JSON 数据包"""

implementation: return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/template/api_set_industry' , data = { 'industry_id1' : str ( industry_id1 ) , 'industry_id2' : str ( industry_id2 ) , } )


signature:
def get_template_id ( self , template_id_short ) :
    """获得模板ID
 详情请参考 http : / / mp . weixin . qq . com / wiki / 17/304c1885ea66dbedf7dc170d84999a9d . html
 : param template _ id _ short : 模板库中模板的编号 , 有 “ TM * * ” 和 “ OPENTMTM * * ” 等形式
 : return : 返回的 JSON 数据包"""

implementation: return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/template/api_add_template' , data = { 'template_id_short' : str ( template_id_short ) , } )


signature:
def send_template_message ( self , user_id , template_id , data , url = '' , topcolor = '#FF0000' ) :
    """发送模版消息
 详情请参考 http : / / mp . weixin . qq . com / wiki / 17/304c1885ea66dbedf7dc170d84999a9d . html
 : param user _ id : 用户 ID , 就是你收到的 WechatMessage 的 source ( OpenID )
 : param template _ id : 模板ID
 : param data : 模板消息数据 ( dict形式 ) , 示例如下 :
 " first " : {
 " value " : " 恭喜你购买成功 ! " ,
 " color " : " # 173177"
 " keynote1 " : {
 " value " : " 巧克力 " ,
 " color " : " # 173177"
 " keynote2 " : {
 " value " : " 39.8元 " ,
 " color " : " # 173177"
 " keynote3 " : {
 " value " : " 2014年9月16日 " ,
 " color " : " # 173177"
 " remark " : {
 " value " : " 欢迎再次购买 ! " ,
 " color " : " # 173177"
 : param url : 跳转地址 ( 默认为空 )
 : param topcolor : 顶部颜色RGB值 ( 默认 ' # FF0000 ' )
 : return : 返回的 JSON 数据包"""

implementation:
unicode_data = { }
if data :
    unicode_data = self . _transcoding_dict ( data )
return self . request . post ( url = 'https://api.weixin.qq.com/cgi-bin/message/template/send' , data = { 'touser' : user_id , "template_id" : template_id , "url" : url , "topcolor" : topcolor , "data" : unicode_data } )


signature:
def _check_official_error ( self , json_data ) :
    """检测微信公众平台返回值中是否包含错误的返回码
 : raises OfficialAPIError : 如果返回码提示有错误 , 抛出异常 ; 否则返回 True"""

implementation:
if "errcode" in json_data and json_data [ "errcode" ] != 0 :
    raise OfficialAPIError ( errcode = json_data . get ( 'errcode' ) , errmsg = json_data . get ( 'errmsg' , '' ) )


signature:
def request ( self , method , url , access_token = None , ** kwargs ) :
    """向微信服务器发送请求
 : param method : 请求方法
 : param url : 请求地址
 : param access _ token : access token 值 , 如果初始化时传入 conf 会自动获取 , 如果没有传入则请提供此值
 : param kwargs : 附加数据
 : return : 微信服务器响应的 JSON 数据"""

implementation:
access_token = self . __conf . access_token if self . __conf is not None else access_token
if "params" not in kwargs :
    kwargs [ "params" ] = { "access_token" : access_token }
else :
    kwargs [ "params" ] [ "access_token" ] = access_token
if isinstance ( kwargs . get ( "data" , "" ) , dict ) :
    body = json . dumps ( kwargs [ "data" ] , ensure_ascii = False )
    if isinstance ( body , six . text_type ) :
        body = body . encode ( 'utf8' )
    kwargs [ "data" ] = body
r = requests . request ( method = method , url = url , ** kwargs )
r . raise_for_status ( )
try :
    response_json = r . json ( )
except ValueError : # 非 JSON 数据
    return r
headimgurl = response_json . get ( 'headimgurl' )
if headimgurl :
    response_json [ 'headimgurl' ] = headimgurl . replace ( '\\' , '' )
self . _check_official_error ( response_json )
return response_json


signature:
def post ( self , url , access_token = None , ** kwargs ) :
    """使用 POST 方法向微信服务器发出请求
 : param url : 请求地址
 : param access _ token : access token 值 , 如果初始化时传入 conf 会自动获取 , 如果没有传入则请提供此值
 : param kwargs : 附加数据
 : return : 微信服务器响应的 JSON 数据"""

implementation: return self . request ( method = "post" , url = url , access_token = access_token , ** kwargs )


signature:
def xml2dict ( self ) :
    """将 XML 转换为 dict"""

implementation:
self . _remove_whitespace_nodes ( self . _doc . childNodes [ 0 ] )
return self . _element2dict ( self . _doc . childNodes [ 0 ] )


signature:
def _element2dict ( self , parent ) :
    """将单个节点转换为 dict"""

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


signature:
def _remove_whitespace_nodes ( self , node , unlink = True ) :
    """删除空白无用节点"""

implementation:
remove_list = [ ]
for child in node . childNodes :
    if child . nodeType == Node . TEXT_NODE and not child . data . strip ( ) :
        remove_list . append ( child )
    elif child . hasChildNodes ( ) :
        self . _remove_whitespace_nodes ( child , unlink )
for node in remove_list :
    node . parentNode . removeChild ( node )
    if unlink :
        node . unlink ( )


signature:
def to_binary ( value , encoding = 'utf-8' ) :
    """将 values 转为 bytes , 默认编码 utf - 8
 : param value : 待转换的值
 : param encoding : 编码"""

implementation:
if not value :
    return b''
if isinstance ( value , six . binary_type ) :
    return value
if isinstance ( value , six . text_type ) :
    return value . encode ( encoding )
if six . PY3 :
    return six . binary_type ( str ( value ) , encoding )
    # For Python 3
return six . binary_type ( value )


signature:
def _transcoding ( cls , data ) :
    """编码转换
 : param data : 需要转换的数据
 : return : 转换好的数据"""

implementation:
if not data :
    return data
result = None
if isinstance ( data , str ) and hasattr ( data , 'decode' ) :
    result = data . decode ( 'utf-8' )
else :
    result = data
return result


signature:
def _transcoding_list ( cls , data ) :
    """编码转换 for list
 : param data : 需要转换的 list 数据
 : return : 转换好的 list"""

implementation:
if not isinstance ( data , list ) :
    raise ValueError ( 'Parameter data must be list object.' )
result = [ ]
for item in data :
    if isinstance ( item , dict ) :
        result . append ( cls . _transcoding_dict ( item ) )
    elif isinstance ( item , list ) :
        result . append ( cls . _transcoding_list ( item ) )
    else :
        result . append ( item )
return result


signature:
def _transcoding_dict ( cls , data ) :
    """编码转换 for dict
 : param data : 需要转换的 dict 数据
 : return : 转换好的 dict"""

implementation:
if not isinstance ( data , dict ) :
    raise ValueError ( 'Parameter data must be dict object.' )
result = { }
for k , v in data . items ( ) :
    k = cls . _transcoding ( k )
    if isinstance ( v , dict ) :
        v = cls . _transcoding_dict ( v )
    elif isinstance ( v , list ) :
        v = cls . _transcoding_list ( v )
    else :
        v = cls . _transcoding ( v )
    result . update ( { k : v } )
return result


signature:
def encode ( cls , text ) :
    """对需要加密的明文进行填充补位
 @ param text : 需要进行填充补位操作的明文
 @ return : 补齐明文字符串"""

implementation:
text_length = len ( text )
# 计算需要填充的位数
amount_to_pad = cls . block_size - ( text_length % cls . block_size )
if amount_to_pad == 0 :
    amount_to_pad = cls . block_size
# 获得补位所用的字符
pad = to_binary ( chr ( amount_to_pad ) )
return text + pad * amount_to_pad


signature:
def decode ( cls , decrypted ) :
    """删除解密后明文的补位字符
 @ param decrypted : 解密后的明文
 @ return : 删除补位字符后的明文"""

implementation:
pad = ord ( decrypted [ - 1 ] )
if pad < 1 or pad > 32 :
    pad = 0
return decrypted [ : - pad ]


signature:
def decrypt ( self , text , appid ) :
    """对解密后的明文进行补位删除
 @ param text : 密文
 @ return : 删除填充补位后的明文"""

implementation:
try :
    cryptor = AES . new ( self . key , self . mode , self . key [ : 16 ] )
    # 使用BASE64对密文进行解码 , 然后AES - CBC解密
    plain_text = cryptor . decrypt ( base64 . b64decode ( text ) )
except Exception as e :
    raise DecryptAESError ( e )
try :
    if six . PY2 :
        pad = ord ( plain_text [ - 1 ] )
    else :
        pad = plain_text [ - 1 ]
    # 去掉补位字符串
    # pkcs7 = PKCS7Encoder ( )
    # plain _ text = pkcs7 . encode ( plain _ text )
    # 去除16位随机字符串
    content = plain_text [ 16 : - pad ]
    xml_len = socket . ntohl ( struct . unpack ( "I" , content [ : 4 ] ) [ 0 ] )
    xml_content = content [ 4 : xml_len + 4 ]
    from_appid = content [ xml_len + 4 : ]
except Exception as e :
    raise IllegalBuffer ( e )
if from_appid != appid :
    raise ValidateAppIDError ( )
return xml_content


signature:
def get_random_str ( self ) :
    """随机生成16位字符串
 @ return : 16位字符串"""

implementation:
rule = string . ascii_letters + string . digits
return "" . join ( random . sample ( rule , 16 ) )


signature:
def _check_signature ( self , msg_signature , timestamp , nonce , echostr ) :
    """验证签名有效性
 : param msg _ signature : 签名串 , 对应URL参数的msg _ signature
 : param timestamp : 时间戳 , 对应URL参数的timestamp
 : param nonce : 随机串 , 对应URL参数的nonce
 : param echostr : 随机串 , 对应URL参数的echostr
 : return : 解密之后的echostr
 : raise ValidateSignatureError : 签名无效异常"""

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


signature:
def _encrypt_message ( self , msg , nonce , timestamp = None ) :
    """将公众号回复用户的消息加密打包
 : param msg : 待回复用户的消息 , xml格式的字符串
 : param nonce : 随机串 , 可以自己生成 , 也可以用URL参数的nonce
 : param timestamp : 时间戳 , 可以自己生成 , 也可以用URL参数的timestamp , 如为None则自动用当前时间
 : return : 加密后的可以直接回复用户的密文 , 包括msg _ signature , timestamp , nonce , encrypt的xml格式的字符串"""

implementation:
xml = """<xml>
<Encrypt><![CDATA[{encrypt}]]></Encrypt>
<MsgSignature><![CDATA[{signature}]]></MsgSignature>
<TimeStamp>{timestamp}</TimeStamp>
<Nonce><![CDATA[{nonce}]]></Nonce>
</xml>"""
nonce = to_binary ( nonce )
timestamp = to_binary ( timestamp ) or to_binary ( int ( time . time ( ) ) )
encrypt = self . __pc . encrypt ( to_text ( msg ) , self . __id )
# 生成安全签名
signature = get_sha1_signature ( self . __token , timestamp , nonce , encrypt )
return to_text ( xml . format ( encrypt = to_text ( encrypt ) , signature = to_text ( signature ) , timestamp = to_text ( timestamp ) , nonce = to_text ( nonce ) ) )


signature:
def _decrypt_message ( self , msg , msg_signature , timestamp , nonce ) :
    """检验消息的真实性 , 并且获取解密后的明文
 : param msg : 密文 , 对应POST请求的数据
 : param msg _ signature : 签名串 , 对应URL参数的msg _ signature
 : param timestamp : 时间戳 , 对应URL参数的timestamp
 : param nonce : 随机串 , 对应URL参数的nonce
 : return : 解密后的原文"""

implementation:
timestamp = to_binary ( timestamp )
nonce = to_binary ( nonce )
if isinstance ( msg , six . string_types ) :
    try :
        msg = xmltodict . parse ( to_text ( msg ) ) [ 'xml' ]
    except Exception as e :
        raise ParseError ( e )
encrypt = msg [ 'Encrypt' ]
signature = get_sha1_signature ( self . __token , timestamp , nonce , encrypt )
if signature != msg_signature :
    raise ValidateSignatureError ( )
return self . __pc . decrypt ( encrypt , self . __id )


signature:
def Lastovka_Shaw ( T , similarity_variable , cyclic_aliphatic = False ) :
    r'''Calculate ideal - gas constant - pressure heat capacitiy with the similarity
 variable concept and method as shown in [ 1 ] _ .
 . . math : :
 C _ p ^ 0 = \ left ( A _ 2 + \ frac { A _ 1 - A _ 2 } { 1 + \ exp ( \ frac { \ alpha - A _ 3 } { A _ 4 } ) } \ right )
 + ( B _ { 11 } + B _ { 12 } \ alpha ) \ left ( - \ frac { ( C _ { 11 } + C _ { 12 } \ alpha ) } { T } \ right ) ^ 2
 \ frac { \ exp ( - ( C _ { 11 } + C _ { 12 } \ alpha ) / T ) } { [ 1 - \ exp ( - ( C _ { 11 } + C _ { 12 } \ alpha ) / T ) ] ^ 2 } \ \
 + ( B _ { 21 } + B _ { 22 } \ alpha ) \ left ( - \ frac { ( C _ { 21 } + C _ { 22 } \ alpha ) } { T } \ right ) ^ 2
 \ frac { \ exp ( - ( C _ { 21 } + C _ { 22 } \ alpha ) / T ) } { [ 1 - \ exp ( - ( C _ { 21 } + C _ { 22 } \ alpha ) / T ) ] ^ 2}
 Parameters
 T : float
 Temperature of gas [ K ]
 similarity _ variable : float
 similarity variable as defined in [ 1 ] _ , [ mol / g ]
 Returns
 Cpg : float
 Gas constant - pressure heat capacitiy , [ J / kg / K ]
 Notes
 Original model is in terms of J / g / K . Note that the model is for predicting
 mass heat capacity , not molar heat capacity like most other methods !
 A1 = 0.58 , A2 = 1.25 , A3 = 0.17338003 , A4 = 0.014 , B11 = 0.73917383,
 B12 = 8.88308889 , C11 = 1188.28051 , C12 = 1813.04613 , B21 = 0.0483019,
 B22 = 4.35656721 , C21 = 2897.01927 , C22 = 5987.80407.
 Examples
 > > > Lastovka _ Shaw ( 1000.0 , 0.1333)
 2467.113309084757
 References
 . . [ 1 ] Lastovka , Vaclav , and John M . Shaw . " Predictive Correlations for
 Ideal Gas Heat Capacities of Pure Hydrocarbons and Petroleum Fractions . "
 Fluid Phase Equilibria 356 ( October 25 , 2013 ) : 338-370.
 doi : 10.1016 / j . fluid . 2013.07.023.'''


signature:
def Lastovka_Shaw_integral_over_T ( T , similarity_variable , cyclic_aliphatic = False ) :
    r'''Calculate the integral over temperature of ideal - gas constant - pressure
 heat capacitiy with the similarity variable concept and method as shown in
 [1 ] _ .
 Parameters
 T : float
 Temperature of gas [ K ]
 similarity _ variable : float
 similarity variable as defined in [ 1 ] _ , [ mol / g ]
 Returns
 S : float
 Difference in entropy from 0 K , [ J / kg / K ]
 Notes
 Original model is in terms of J / g / K . Note that the model is for predicting
 mass heat capacity , not molar heat capacity like most other methods !
 Integral was computed with SymPy .
 See Also
 Lastovka _ Shaw
 Lastovka _ Shaw _ integral
 Examples
 > > > Lastovka _ Shaw _ integral _ over _ T ( 300.0 , 0.1333)
 3609.791928945323
 References
 . . [ 1 ] Lastovka , Vaclav , and John M . Shaw . " Predictive Correlations for
 Ideal Gas Heat Capacities of Pure Hydrocarbons and Petroleum Fractions . "
 Fluid Phase Equilibria 356 ( October 25 , 2013 ) : 338-370.
 doi : 10.1016 / j . fluid . 2013.07.023.'''


signature:
def TRCCp ( T , a0 , a1 , a2 , a3 , a4 , a5 , a6 , a7 ) :
    r'''Calculates ideal gas heat capacity using the model developed in [ 1 ] _ .
 The ideal gas heat capacity is given by :
 . . math : :
 C _ p = R \ left ( a _ 0 + ( a _ 1 / T ^ 2 ) \ exp ( - a _ 2 / T ) + a _ 3 y ^ 2
 + ( a _ 4 - a _ 5 / ( T - a _ 7 ) ^ 2 ) y ^ j \ right )
 y = \ frac { T - a _ 7 } { T + a _ 6 } \ text { for } T > a _ 7 \ text { otherwise } 0
 Parameters
 T : float
 Temperature [ K ]
 a1 - a7 : float
 Coefficients
 Returns
 Cp : float
 Ideal gas heat capacity , [ J / mol / K ]
 Notes
 j is set to 8 . Analytical integrals are available for this expression .
 Examples
 > > > TRCCp ( 300 , 4.0 , 7.65E5 , 720 . , 3.565 , - 0.052 , - 1.55E6 , 52 . , 201 . )
 42.06525682312236
 References
 . . [ 1 ] Kabo , G . J . , and G . N . Roganov . Thermodynamics of Organic Compounds
 in the Gas State , Volume II : V . 2 . College Station , Tex : CRC Press , 1994.'''


signature:
def TRCCp_integral ( T , a0 , a1 , a2 , a3 , a4 , a5 , a6 , a7 , I = 0 ) :
    r'''Integrates ideal gas heat capacity using the model developed in [ 1 ] _ .
 Best used as a delta only .
 The difference in enthalpy with respect to 0 K is given by :
 . . math : :
 \ frac { H ( T ) - H ^ { ref } } { RT } = a _ 0 + a _ 1x ( a _ 2 ) / ( a _ 2T ) + I / T + h ( T ) / T
 h ( T ) = ( a _ 5 + a _ 7 ) \ left [ ( 2a _ 3 + 8a _ 4 ) \ ln ( 1 - y ) + \ left \ { a _ 3 \ left ( 1 +
 \ frac { 1 } { 1 - y } \ right ) + a _ 4 \ left ( 7 + \ frac { 1 } { 1 - y } \ right ) \ right \ } y
 + a _ 4 \ left \ { 3y ^ 2 + ( 5/3 ) y ^ 3 + y ^ 4 + ( 3/5 ) y ^ 5 + ( 1/3 ) y ^ 6 \ right \ }
 + ( 1/7 ) \ left \ { a _ 4 - \ frac { a _ 5 } { ( a _ 6 + a _ 7 ) ^ 2 } \ right \ } y ^ 7 \ right ]
 h ( T ) = 0 \ text { for } T \ le a _ 7
 y = \ frac { T - a _ 7 } { T + a _ 6 } \ text { for } T > a _ 7 \ text { otherwise } 0
 Parameters
 T : float
 Temperature [ K ]
 a1 - a7 : float
 Coefficients
 I : float , optional
 Integral offset
 Returns
 H - H ( 0 ) : float
 Difference in enthalpy from 0 K , [ J / mol ]
 Notes
 Analytical integral as provided in [ 1 ] _ and verified with numerical
 integration .
 Examples
 > > > TRCCp _ integral ( 298.15 , 4.0 , 7.65E5 , 720 . , 3.565 , - 0.052 , - 1.55E6 , 52 . ,
 . . . 201 . , 1.2)
 10802.532600592816
 References
 . . [ 1 ] Kabo , G . J . , and G . N . Roganov . Thermodynamics of Organic Compounds
 in the Gas State , Volume II : V . 2 . College Station , Tex : CRC Press , 1994.'''


signature:
def TRCCp_integral_over_T ( T , a0 , a1 , a2 , a3 , a4 , a5 , a6 , a7 , J = 0 ) :
    r'''Integrates ideal gas heat capacity over T using the model developed in
 [1 ] _ . Best used as a delta only .
 The difference in ideal - gas entropy with respect to 0 K is given by :
 . . math : :
 \ frac { S ^ \ circ } { R } = J + a _ 0 \ ln T + \ frac { a _ 1 } { a _ 2 ^ 2 } \ left ( 1
 + \ frac { a _ 2 } { T } \ right ) x ( a _ 2 ) + s ( T )
 s ( T ) = \ left [ \ left \ { a _ 3 + \ left ( \ frac { a _ 4 a _ 7 ^ 2 - a _ 5 } { a _ 6 ^ 2 } \ right )
 \ left ( \ frac { a _ 7 } { a _ 6 } \ right ) ^ 4 \ right \ } \ left ( \ frac { a _ 7 } { a _ 6 } \ right ) ^ 2
 \ ln z + ( a _ 3 + a _ 4 ) \ ln \ left ( \ frac { T + a _ 6 } { a _ 6 + a _ 7 } \ right )
 + \ sum _ { i = 1 } ^ 7 \ left \ { \ left ( \ frac { a _ 4 a _ 7 ^ 2 - a _ 5 } { a _ 6 ^ 2 } \ right ) \ left (
 \ frac { - a _ 7 } { a _ 6 } \ right ) ^ { 6 - i } - a _ 4 \ right \ } \ frac { y ^ i } { i }
 - \ left \ { \ frac { a _ 3 } { a _ 6 } ( a _ 6 + a _ 7 ) + \ frac { a _ 5 y ^ 6 } { 7a _ 7 ( a _ 6 + a _ 7 ) }
 \ right \ } y \ right ]
 s ( T ) = 0 \ text { for } T \ le a _ 7
 z = \ frac { T } { T + a _ 6 } \ cdot \ frac { a _ 7 + a _ 6 } { a _ 7}
 y = \ frac { T - a _ 7 } { T + a _ 6 } \ text { for } T > a _ 7 \ text { otherwise } 0
 Parameters
 T : float
 Temperature [ K ]
 a1 - a7 : float
 Coefficients
 J : float , optional
 Integral offset
 Returns
 S - S ( 0 ) : float
 Difference in entropy from 0 K , [ J / mol / K ]
 Notes
 Analytical integral as provided in [ 1 ] _ and verified with numerical
 integration .
 Examples
 > > > TRCCp _ integral _ over _ T ( 300 , 4.0 , 124000 , 245 , 50.539 , - 49.469,
 . . . 220440000 , 560 , 78)
 213.80148972435018
 References
 . . [ 1 ] Kabo , G . J . , and G . N . Roganov . Thermodynamics of Organic Compounds
 in the Gas State , Volume II : V . 2 . College Station , Tex : CRC Press , 1994.'''

implementation:
# Possible optimizations : pre - cache as much as possible .
# If this were replaced by a cache , much of this would not need to be computed .
if T <= a7 :
    y = 0.
else :
    y = ( T - a7 ) / ( T + a6 )
z = T / ( T + a6 ) * ( a7 + a6 ) / a7
if T <= a7 :
    s = 0.
else :
    a72 = a7 * a7
    a62 = a6 * a6
    a7_a6 = a7 / a6
    # a7 / a6
    a7_a6_2 = a7_a6 * a7_a6
    a7_a6_4 = a7_a6_2 * a7_a6_2
    x1 = ( a4 * a72 - a5 ) / a62
    # part of third , sum
    first = ( a3 + ( ( a4 * a72 - a5 ) / a62 ) * a7_a6_4 ) * a7_a6_2 * log ( z )
    second = ( a3 + a4 ) * log ( ( T + a6 ) / ( a6 + a7 ) )
    fourth = - ( a3 / a6 * ( a6 + a7 ) + a5 * y ** 6 / ( 7. * a7 * ( a6 + a7 ) ) ) * y
    third = sum ( [ ( x1 * ( - a7_a6 ) ** ( 6 - i ) - a4 ) * y ** i / i for i in range ( 1 , 8 ) ] )
    s = first + second + third + fourth
return R * ( J + a0 * log ( T ) + a1 / ( a2 * a2 ) * ( 1. + a2 / T ) * exp ( - a2 / T ) + s )


signature:
def Rowlinson_Poling ( T , Tc , omega , Cpgm ) :
    r'''Calculate liquid constant - pressure heat capacitiy with the [ 1 ] _ CSP method .
 This equation is not terrible accurate .
 The heat capacity of a liquid is given by :
 . . math : :
 \ frac { Cp ^ { L } - Cp ^ { g } } { R } = 1.586 + \ frac { 0.49 } { 1 - T _ r } +
 \ omega \ left [ 4.2775 + \ frac { 6.3(1 - T _ r ) ^ { 1/3 } } { T _ r } + \ frac { 0.4355 } { 1 - T _ r } \ right ]
 Parameters
 T : float
 Temperature of fluid [ K ]
 Tc : float
 Critical temperature of fluid [ K ]
 omega : float
 Acentric factor for fluid , [ - ]
 Cpgm : float
 Constant - pressure gas heat capacity , [ J / mol / K ]
 Returns
 Cplm : float
 Liquid constant - pressure heat capacitiy , [ J / mol / K ]
 Notes
 Poling compared 212 substances , and found error at 298K larger than 10%
 for 18 of them , mostly associating . Of the other 194 compounds , AARD is 2.5 % .
 Examples
 > > > Rowlinson _ Poling ( 350.0 , 435.5 , 0.203 , 91.21)
 143.80194441498296
 References
 . . [ 1 ] Poling , Bruce E . The Properties of Gases and Liquids . 5th edition .
 New York : McGraw - Hill Professional , 2000.'''


signature:
def Rowlinson_Bondi ( T , Tc , omega , Cpgm ) :
    r'''Calculate liquid constant - pressure heat capacitiy with the CSP method
 shown in [ 1 ] _ .
 The heat capacity of a liquid is given by :
 . . math : :
 \ frac { Cp ^ L - Cp ^ { ig } } { R } = 1.45 + 0.45(1 - T _ r ) ^ { - 1 } + 0.25 \ omega
 [17.11 + 25.2(1 - T _ r ) ^ { 1/3 } T _ r ^ { - 1 } + 1.742(1 - T _ r ) ^ { - 1 } ]
 Parameters
 T : float
 Temperature of fluid [ K ]
 Tc : float
 Critical temperature of fluid [ K ]
 omega : float
 Acentric factor for fluid , [ - ]
 Cpgm : float
 Constant - pressure gas heat capacity , [ J / mol / K ]
 Returns
 Cplm : float
 Liquid constant - pressure heat capacitiy , [ J / mol / K ]
 Notes
 Less accurate than ` Rowlinson _ Poling ` .
 Examples
 > > > Rowlinson _ Bondi ( T = 373.28 , Tc = 535.55 , omega = 0.323 , Cpgm = 119.342)
 175.39760730048116
 References
 . . [ 1 ] Poling , Bruce E . The Properties of Gases and Liquids . 5th edition .
 New York : McGraw - Hill Professional , 2000.
 . . [ 2 ] Gesellschaft , V . D . I . , ed . VDI Heat Atlas . 2nd edition .
 Berlin ; New York : : Springer , 2010.
 . . [ 3 ] J . S . Rowlinson , Liquids and Liquid Mixtures , 2nd Ed . ,
 Butterworth , London ( 1969 ) .'''


signature:
def Dadgostar_Shaw ( T , similarity_variable ) :
    r'''Calculate liquid constant - pressure heat capacitiy with the similarity
 variable concept and method as shown in [ 1 ] _ .
 . . math : :
 C _ { p } = 24.5 ( a _ { 11 } \ alpha + a _ { 12 } \ alpha ^ 2 ) + ( a _ { 21 } \ alpha
 + a _ { 22 } \ alpha ^ 2 ) T + ( a _ { 31 } \ alpha + a _ { 32 } \ alpha ^ 2 ) T ^ 2
 Parameters
 T : float
 Temperature of liquid [ K ]
 similarity _ variable : float
 similarity variable as defined in [ 1 ] _ , [ mol / g ]
 Returns
 Cpl : float
 Liquid constant - pressure heat capacitiy , [ J / kg / K ]
 Notes
 Many restrictions on its use .
 Original model is in terms of J / g / K . Note that the model is for predicting
 mass heat capacity , not molar heat capacity like most other methods !
 a11 = - 0.3416 ; a12 = 2.2671 ; a21 = 0.1064 ; a22 = - 0.3874l ;
 a31 = - 9.8231E - 05 ; a32 = 4.182E - 04
 Examples
 > > > Dadgostar _ Shaw ( 355.6 , 0.139)
 1802.5291501191516
 References
 . . [ 1 ] Dadgostar , Nafiseh , and John M . Shaw . " A Predictive Correlation for
 the Constant - Pressure Specific Heat Capacity of Pure and Ill - Defined
 Liquid Hydrocarbons . " Fluid Phase Equilibria 313 ( January 15 , 2012 ) :
 211-226 . doi : 10.1016 / j . fluid . 2011.09.015.'''

implementation:
a = similarity_variable
a11 = - 0.3416
a12 = 2.2671
a21 = 0.1064
a22 = - 0.3874
a31 = - 9.8231E-05
a32 = 4.182E-04
# Didn ' t seem to improve the comparison ; sum of errors on some
# points included went from 65.5 to 286.
# Author probably used more precision in their calculation .
# theta = 151.8675
# constant = 3 * R * ( theta / T ) * * 2 * exp ( theta / T ) / ( exp ( theta / T ) - 1 ) * * 2
constant = 24.5
Cp = ( constant * ( a11 * a + a12 * a ** 2 ) + ( a21 * a + a22 * a ** 2 ) * T + ( a31 * a + a32 * a ** 2 ) * T ** 2 )
Cp = Cp * 1000
# J / g / K to J / kg / K
return Cp


signature:
def Dadgostar_Shaw_integral ( T , similarity_variable ) :
    r'''Calculate the integral of liquid constant - pressure heat capacitiy
 with the similarity variable concept and method as shown in [ 1 ] _ .
 Parameters
 T : float
 Temperature of gas [ K ]
 similarity _ variable : float
 similarity variable as defined in [ 1 ] _ , [ mol / g ]
 Returns
 H : float
 Difference in enthalpy from 0 K , [ J / kg ]
 Notes
 Original model is in terms of J / g / K . Note that the model is for predicting
 mass heat capacity , not molar heat capacity like most other methods !
 Integral was computed with SymPy .
 See Also
 Dadgostar _ Shaw
 Dadgostar _ Shaw _ integral _ over _ T
 Examples
 > > > Dadgostar _ Shaw _ integral ( 300.0 , 0.1333)
 238908.15142664989
 References
 . . [ 1 ] Dadgostar , Nafiseh , and John M . Shaw . " A Predictive Correlation for
 the Constant - Pressure Specific Heat Capacity of Pure and Ill - Defined
 Liquid Hydrocarbons . " Fluid Phase Equilibria 313 ( January 15 , 2012 ) :
 211-226 . doi : 10.1016 / j . fluid . 2011.09.015.'''


signature:
def Dadgostar_Shaw_integral_over_T ( T , similarity_variable ) :
    r'''Calculate the integral of liquid constant - pressure heat capacitiy
 with the similarity variable concept and method as shown in [ 1 ] _ .
 Parameters
 T : float
 Temperature of gas [ K ]
 similarity _ variable : float
 similarity variable as defined in [ 1 ] _ , [ mol / g ]
 Returns
 S : float
 Difference in entropy from 0 K , [ J / kg / K ]
 Notes
 Original model is in terms of J / g / K . Note that the model is for predicting
 mass heat capacity , not molar heat capacity like most other methods !
 Integral was computed with SymPy .
 See Also
 Dadgostar _ Shaw
 Dadgostar _ Shaw _ integral
 Examples
 > > > Dadgostar _ Shaw _ integral _ over _ T ( 300.0 , 0.1333)
 1201.1409113147927
 References
 . . [ 1 ] Dadgostar , Nafiseh , and John M . Shaw . " A Predictive Correlation for
 the Constant - Pressure Specific Heat Capacity of Pure and Ill - Defined
 Liquid Hydrocarbons . " Fluid Phase Equilibria 313 ( January 15 , 2012 ) :
 211-226 . doi : 10.1016 / j . fluid . 2011.09.015.'''


signature:
def Zabransky_quasi_polynomial ( T , Tc , a1 , a2 , a3 , a4 , a5 , a6 ) :
    r'''Calculates liquid heat capacity using the model developed in [ 1 ] _ .
 . . math : :
 \ frac { C } { R } = A _ 1 \ ln ( 1 - T _ r ) + \ frac { A _ 2 } { 1 - T _ r }
 + \ sum _ { j = 0 } ^ m A _ { j + 3 } T _ r ^ j
 Parameters
 T : float
 Temperature [ K ]
 Tc : float
 Critical temperature of fluid , [ K ]
 a1 - a6 : float
 Coefficients
 Returns
 Cp : float
 Liquid heat capacity , [ J / mol / K ]
 Notes
 Used only for isobaric heat capacities , not saturation heat capacities .
 Designed for reasonable extrapolation behavior caused by using the reduced
 critical temperature . Used by the authors of [ 1 ] _ when critical temperature
 was available for the fluid .
 Analytical integrals are available for this expression .
 Examples
 > > > Zabransky _ quasi _ polynomial ( 330 , 591.79 , - 3.12743 , 0.0857315 , 13.7282 , 1.28971 , 6.42297 , 4.10989)
 165.4728226923247
 References
 . . [ 1 ] Zabransky , M . , V . Ruzicka Jr , V . Majer , and Eugene S . Domalski .
 Heat Capacity of Liquids : Critical Review and Recommended Values .
 2 Volume Set . Washington , D . C . : Amer Inst of Physics , 1996.'''


signature:
def Zabransky_quasi_polynomial_integral ( T , Tc , a1 , a2 , a3 , a4 , a5 , a6 ) :
    r'''Calculates the integral of liquid heat capacity using the
 quasi - polynomial model developed in [ 1 ] _ .
 Parameters
 T : float
 Temperature [ K ]
 a1 - a6 : float
 Coefficients
 Returns
 H : float
 Difference in enthalpy from 0 K , [ J / mol ]
 Notes
 The analytical integral was derived with SymPy ; it is a simple polynomial
 plus some logarithms .
 Examples
 > > > H2 = Zabransky _ quasi _ polynomial _ integral ( 300 , 591.79 , - 3.12743,
 . . . 0.0857315 , 13.7282 , 1.28971 , 6.42297 , 4.10989)
 > > > H1 = Zabransky _ quasi _ polynomial _ integral ( 200 , 591.79 , - 3.12743,
 . . . 0.0857315 , 13.7282 , 1.28971 , 6.42297 , 4.10989)
 > > > H2 - H1
 14662.026406892925
 References
 . . [ 1 ] Zabransky , M . , V . Ruzicka Jr , V . Majer , and Eugene S . Domalski .
 Heat Capacity of Liquids : Critical Review and Recommended Values .
 2 Volume Set . Washington , D . C . : Amer Inst of Physics , 1996.'''


signature:
def Zabransky_quasi_polynomial_integral_over_T ( T , Tc , a1 , a2 , a3 , a4 , a5 , a6 ) :
    r'''Calculates the integral of liquid heat capacity over T using the
 quasi - polynomial model developed in [ 1 ] _ .
 Parameters
 T : float
 Temperature [ K ]
 a1 - a6 : float
 Coefficients
 Returns
 S : float
 Difference in entropy from 0 K , [ J / mol / K ]
 Notes
 The analytical integral was derived with Sympy . It requires the
 Polylog ( 2 , x ) function , which is unimplemented in SciPy . A very accurate
 numerical approximation was implemented as : obj : ` thermo . utils . polylog2 ` .
 Relatively slow due to the use of that special function .
 Examples
 > > > S2 = Zabransky _ quasi _ polynomial _ integral _ over _ T ( 300 , 591.79 , - 3.12743,
 . . . 0.0857315 , 13.7282 , 1.28971 , 6.42297 , 4.10989)
 > > > S1 = Zabransky _ quasi _ polynomial _ integral _ over _ T ( 200 , 591.79 , - 3.12743,
 . . . 0.0857315 , 13.7282 , 1.28971 , 6.42297 , 4.10989)
 > > > S2 - S1
 59.16997291893654
 References
 . . [ 1 ] Zabransky , M . , V . Ruzicka Jr , V . Majer , and Eugene S . Domalski .
 Heat Capacity of Liquids : Critical Review and Recommended Values .
 2 Volume Set . Washington , D . C . : Amer Inst of Physics , 1996.'''

implementation:
term = T - Tc
logT = log ( T )
Tc2 = Tc * Tc
Tc3 = Tc2 * Tc
return R * ( a3 * logT - a1 * polylog2 ( T / Tc ) - a2 * ( - logT + 0.5 * log ( term * term ) ) + T * ( T * ( T * a6 / ( 3. * Tc3 ) + a5 / ( 2. * Tc2 ) ) + a4 / Tc ) )


signature:
def Zabransky_cubic ( T , a1 , a2 , a3 , a4 ) :
    r'''Calculates liquid heat capacity using the model developed in [ 1 ] _ .
 . . math : :
 \ frac { C } { R } = \ sum _ { j = 0 } ^ 3 A _ { j + 1 } \ left ( \ frac { T } { 100 } \ right ) ^ j
 Parameters
 T : float
 Temperature [ K ]
 a1 - a4 : float
 Coefficients
 Returns
 Cp : float
 Liquid heat capacity , [ J / mol / K ]
 Notes
 Most often form used in [ 1 ] _ .
 Analytical integrals are available for this expression .
 Examples
 > > > Zabransky _ cubic ( 298.15 , 20.9634 , - 10.1344 , 2.8253 , - 0.256738)
 75.31462591538556
 References
 . . [ 1 ] Zabransky , M . , V . Ruzicka Jr , V . Majer , and Eugene S . Domalski .
 Heat Capacity of Liquids : Critical Review and Recommended Values .
 2 Volume Set . Washington , D . C . : Amer Inst of Physics , 1996.'''


signature:
def Zabransky_cubic_integral ( T , a1 , a2 , a3 , a4 ) :
    r'''Calculates the integral of liquid heat capacity using the model
 developed in [ 1 ] _ .
 Parameters
 T : float
 Temperature [ K ]
 a1 - a4 : float
 Coefficients
 Returns
 H : float
 Difference in enthalpy from 0 K , [ J / mol ]
 Notes
 The analytical integral was derived with Sympy ; it is a simple polynomial .
 Examples
 > > > Zabransky _ cubic _ integral ( 298.15 , 20.9634 , - 10.1344 , 2.8253 , - 0.256738)
 31051.679845520586
 References
 . . [ 1 ] Zabransky , M . , V . Ruzicka Jr , V . Majer , and Eugene S . Domalski .
 Heat Capacity of Liquids : Critical Review and Recommended Values .
 2 Volume Set . Washington , D . C . : Amer Inst of Physics , 1996.'''


signature:
def Zabransky_cubic_integral_over_T ( T , a1 , a2 , a3 , a4 ) :
    r'''Calculates the integral of liquid heat capacity over T using the model
 developed in [ 1 ] _ .
 Parameters
 T : float
 Temperature [ K ]
 a1 - a4 : float
 Coefficients
 Returns
 S : float
 Difference in entropy from 0 K , [ J / mol / K ]
 Notes
 The analytical integral was derived with Sympy ; it is a simple polynomial ,
 plus a logarithm
 Examples
 > > > Zabransky _ cubic _ integral _ over _ T ( 298.15 , 20.9634 , - 10.1344 , 2.8253,
 . . . - 0.256738)
 24.73245695987246
 References
 . . [ 1 ] Zabransky , M . , V . Ruzicka Jr , V . Majer , and Eugene S . Domalski .
 Heat Capacity of Liquids : Critical Review and Recommended Values .
 2 Volume Set . Washington , D . C . : Amer Inst of Physics , 1996.'''


signature:
def Lastovka_solid ( T , similarity_variable ) :
    r'''Calculate solid constant - pressure heat capacitiy with the similarity
 variable concept and method as shown in [ 1 ] _ .
 . . math : :
 C _ p = 3 ( A _ 1 \ alpha + A _ 2 \ alpha ^ 2 ) R \ left ( \ frac { \ theta } { T } \ right ) ^ 2
 \ frac { \ exp ( \ theta / T ) } { [ \ exp ( \ theta / T ) - 1 ] ^ 2}
 + ( C _ 1 \ alpha + C _ 2 \ alpha ^ 2 ) T + ( D _ 1 \ alpha + D _ 2 \ alpha ^ 2 ) T ^ 2
 Parameters
 T : float
 Temperature of solid [ K ]
 similarity _ variable : float
 similarity variable as defined in [ 1 ] _ , [ mol / g ]
 Returns
 Cps : float
 Solid constant - pressure heat capacitiy , [ J / kg / K ]
 Notes
 Many restrictions on its use . Trained on data with MW from 12.24 g / mol
 to 402.4 g / mol , C mass fractions from 61.3 % to 95.2 % ,
 H mass fractions from 3.73 % to 15.2 % , N mass fractions from 0 to 15.4 % ,
 O mass fractions from 0 to 18.8 % , and S mass fractions from 0 to 29.6 % .
 Recommended for organic compounds with low mass fractions of hetero - atoms
 and especially when molar mass exceeds 200 g / mol . This model does not show
 and effects of phase transition but should not be used passed the triple
 point .
 Original model is in terms of J / g / K . Note that the model s for predicting
 mass heat capacity , not molar heat capacity like most other methods !
 A1 = 0.013183 ; A2 = 0.249381 ; theta = 151.8675 ; C1 = 0.026526;
 C2 = - 0.024942 ; D1 = 0.000025 ; D2 = - 0.000123.
 Examples
 > > > Lastovka _ solid ( 300 , 0.2139)
 1682.063629222013
 References
 . . [ 1 ] Laštovka , Václav , Michal Fulem , Mildred Becerra , and John M . Shaw .
 " A Similarity Variable for Estimating the Heat Capacity of Solid Organic
 Compounds : Part II . Application : Heat Capacity Calculation for
 Ill - Defined Organic Solids . " Fluid Phase Equilibria 268 , no . 1-2
 ( June 25 , 2008 ) : 134-41 . doi : 10.1016 / j . fluid . 2008.03.018.'''

implementation:
A1 = 0.013183
A2 = 0.249381
theta = 151.8675
C1 = 0.026526
C2 = - 0.024942
D1 = 0.000025
D2 = - 0.000123
Cp = ( 3 * ( A1 * similarity_variable + A2 * similarity_variable ** 2 ) * R * ( theta / T ) ** 2 * exp ( theta / T ) / ( exp ( theta / T ) - 1 ) ** 2 + ( C1 * similarity_variable + C2 * similarity_variable ** 2 ) * T + ( D1 * similarity_variable + D2 * similarity_variable ** 2 ) * T ** 2 )
Cp = Cp * 1000
# J / g / K to J / kg / K
return Cp


signature:
def Lastovka_solid_integral ( T , similarity_variable ) :
    r'''Integrates solid constant - pressure heat capacitiy with the similarity
 variable concept and method as shown in [ 1 ] _ .
 Uses a explicit form as derived with Sympy .
 Parameters
 T : float
 Temperature of solid [ K ]
 similarity _ variable : float
 similarity variable as defined in [ 1 ] _ , [ mol / g ]
 Returns
 H : float
 Difference in enthalpy from 0 K , [ J / kg ]
 Notes
 Original model is in terms of J / g / K . Note that the model is for predicting
 mass heat capacity , not molar heat capacity like most other methods !
 See Also
 Lastovka _ solid
 Examples
 > > > Lastovka _ solid _ integral ( 300 , 0.2139)
 283246.1242170376
 References
 . . [ 1 ] Laštovka , Václav , Michal Fulem , Mildred Becerra , and John M . Shaw .
 " A Similarity Variable for Estimating the Heat Capacity of Solid Organic
 Compounds : Part II . Application : Heat Capacity Calculation for
 Ill - Defined Organic Solids . " Fluid Phase Equilibria 268 , no . 1-2
 ( June 25 , 2008 ) : 134-41 . doi : 10.1016 / j . fluid . 2008.03.018.'''

implementation:
A1 = 0.013183
A2 = 0.249381
theta = 151.8675
C1 = 0.026526
C2 = - 0.024942
D1 = 0.000025
D2 = - 0.000123
similarity_variable2 = similarity_variable * similarity_variable
return ( T * T * T * ( 1000. * D1 * similarity_variable / 3. + 1000. * D2 * similarity_variable2 / 3. ) + T * T * ( 500. * C1 * similarity_variable + 500. * C2 * similarity_variable2 ) + ( 3000. * A1 * R * similarity_variable * theta + 3000. * A2 * R * similarity_variable2 * theta ) / ( exp ( theta / T ) - 1. ) )


signature:
def Lastovka_solid_integral_over_T ( T , similarity_variable ) :
    r'''Integrates over T solid constant - pressure heat capacitiy with the
 similarity variable concept and method as shown in [ 1 ] _ .
 Uses a explicit form as derived with Sympy .
 Parameters
 T : float
 Temperature of solid [ K ]
 similarity _ variable : float
 similarity variable as defined in [ 1 ] _ , [ mol / g ]
 Returns
 S : float
 Difference in entropy from 0 K , [ J / kg / K ]
 Notes
 Original model is in terms of J / g / K . Note that the model is for predicting
 mass heat capacity , not molar heat capacity like most other methods !
 See Also
 Lastovka _ solid
 Examples
 > > > Lastovka _ solid _ integral _ over _ T ( 300 , 0.2139)
 1947.553552666818
 References
 . . [ 1 ] Laštovka , Václav , Michal Fulem , Mildred Becerra , and John M . Shaw .
 " A Similarity Variable for Estimating the Heat Capacity of Solid Organic
 Compounds : Part II . Application : Heat Capacity Calculation for
 Ill - Defined Organic Solids . " Fluid Phase Equilibria 268 , no . 1-2
 ( June 25 , 2008 ) : 134-41 . doi : 10.1016 / j . fluid . 2008.03.018.'''

implementation:
A1 = 0.013183
A2 = 0.249381
theta = 151.8675
C1 = 0.026526
C2 = - 0.024942
D1 = 0.000025
D2 = - 0.000123
sim2 = similarity_variable * similarity_variable
exp_theta_T = exp ( theta / T )
return ( - 3000. * R * similarity_variable * ( A1 + A2 * similarity_variable ) * log ( exp_theta_T - 1. ) + T ** 2 * ( 500. * D1 * similarity_variable + 500. * D2 * sim2 ) + T * ( 1000. * C1 * similarity_variable + 1000. * C2 * sim2 ) + ( 3000. * A1 * R * similarity_variable * theta + 3000. * A2 * R * sim2 * theta ) / ( T * exp_theta_T - T ) + ( 3000. * A1 * R * similarity_variable * theta + 3000. * A2 * R * sim2 * theta ) / T )


signature:
def load_all_methods ( self ) :
    r'''Method which picks out coefficients for the specified chemical
 from the various dictionaries and DataFrames storing it . All data is
 stored as attributes . This method also sets : obj : ` Tmin ` , : obj : ` Tmax ` ,
 and : obj : ` all _ methods ` as a set of methods for which the data exists for .
 Called on initialization only . See the source code for the variables at
 which the coefficients are stored . The coefficients can safely be
 altered once the class is initialized . This method can be called again
 to reset the parameters .'''

implementation:
methods = [ ]
Tmins , Tmaxs = [ ] , [ ]
if self . CASRN in TRC_gas_data . index :
    methods . append ( TRCIG )
    _ , self . TRCIG_Tmin , self . TRCIG_Tmax , a0 , a1 , a2 , a3 , a4 , a5 , a6 , a7 , _ , _ , _ = _TRC_gas_data_values [ TRC_gas_data . index . get_loc ( self . CASRN ) ] . tolist ( )
    self . TRCIG_coefs = [ a0 , a1 , a2 , a3 , a4 , a5 , a6 , a7 ]
    Tmins . append ( self . TRCIG_Tmin ) ;
    Tmaxs . append ( self . TRCIG_Tmax )
if self . CASRN in Poling_data . index and not np . isnan ( Poling_data . at [ self . CASRN , 'a0' ] ) :
    _ , self . POLING_Tmin , self . POLING_Tmax , a0 , a1 , a2 , a3 , a4 , Cpg , Cpl = _Poling_data_values [ Poling_data . index . get_loc ( self . CASRN ) ] . tolist ( )
    methods . append ( POLING )
    self . POLING_coefs = [ a0 , a1 , a2 , a3 , a4 ]
    Tmins . append ( self . POLING_Tmin ) ;
    Tmaxs . append ( self . POLING_Tmax )
if self . CASRN in Poling_data . index and not np . isnan ( Poling_data . at [ self . CASRN , 'Cpg' ] ) :
    methods . append ( POLING_CONST )
    self . POLING_T = 298.15
    self . POLING_constant = float ( Poling_data . at [ self . CASRN , 'Cpg' ] )
if self . CASRN in CRC_standard_data . index and not np . isnan ( CRC_standard_data . at [ self . CASRN , 'Cpg' ] ) :
    methods . append ( CRCSTD )
    self . CRCSTD_T = 298.15
    self . CRCSTD_constant = float ( CRC_standard_data . at [ self . CASRN , 'Cpg' ] )
if self . CASRN in _VDISaturationDict : # NOTE : VDI data is for the saturation curve , i . e . at increasing
# pressure ; it is normally substantially higher than the ideal gas
# value
    methods . append ( VDI_TABULAR )
    Ts , props = VDI_tabular_data ( self . CASRN , 'Cp (g)' )
    self . VDI_Tmin = Ts [ 0 ]
    self . VDI_Tmax = Ts [ - 1 ]
    self . tabular_data [ VDI_TABULAR ] = ( Ts , props )
    Tmins . append ( self . VDI_Tmin ) ;
    Tmaxs . append ( self . VDI_Tmax )
if has_CoolProp and self . CASRN in coolprop_dict :
    methods . append ( COOLPROP )
    self . CP_f = coolprop_fluids [ self . CASRN ]
    Tmins . append ( self . CP_f . Tt ) ;
    Tmaxs . append ( self . CP_f . Tc )
if self . MW and self . similarity_variable :
    methods . append ( LASTOVKA_SHAW )
self . all_methods = set ( methods )
if Tmins and Tmaxs :
    self . Tmin , self . Tmax = min ( Tmins ) , max ( Tmaxs )


signature:
def calculate ( self , T , method ) :
    r'''Method to calculate surface tension of a liquid at temperature ` T `
 with a given method .
 This method has no exception handling ; see ` T _ dependent _ property `
 for that .
 Parameters
 T : float
 Temperature at which to calculate heat capacity , [ K ]
 method : str
 Method name to use
 Returns
 Cp : float
 Calculated heat capacity , [ J / mol / K ]'''

implementation:
if method == TRCIG :
    Cp = TRCCp ( T , * self . TRCIG_coefs )
elif method == COOLPROP :
    Cp = PropsSI ( 'Cp0molar' , 'T' , T , 'P' , 101325.0 , self . CASRN )
elif method == POLING :
    Cp = R * ( self . POLING_coefs [ 0 ] + self . POLING_coefs [ 1 ] * T + self . POLING_coefs [ 2 ] * T ** 2 + self . POLING_coefs [ 3 ] * T ** 3 + self . POLING_coefs [ 4 ] * T ** 4 )
elif method == POLING_CONST :
    Cp = self . POLING_constant
elif method == CRCSTD :
    Cp = self . CRCSTD_constant
elif method == LASTOVKA_SHAW :
    Cp = Lastovka_Shaw ( T , self . similarity_variable )
    Cp = property_mass_to_molar ( Cp , self . MW )
elif method in self . tabular_data :
    Cp = self . interpolate ( T , method )
return Cp