设为首页 收藏本站
查看: 696|回复: 0

[经验分享] 两个不错的Python Fetion的东西

[复制链接]

尚未签到

发表于 2017-5-3 10:05:14 | 显示全部楼层 |阅读模式
  两个不错的Python Fetion的东西,现在我还不懂,转贴到这里,以后再研究研究。。

1. It's so large, so I have to copy hyperlink here.
http://code.google.com/p/pytool/source/browse/trunk/PyFetion/PyFetion.py
Home page: http://cocobear.info/blog/2008/12/03/write-fetion-with-python-pyfetion/

2. Copy the source code here.
#----------------------------------------------------------------------------------------------------------------------
#!/usr/bin/env python
# -*- coding: gbk -*-

import binascii
import hashlib
import re
import StringIO
import urllib
import urllib2
import uuid
import xml.etree.ElementTree as ET

from getpass import getpass
from optparse import OptionParser

FETION_URL = 'http://221.130.45.203/ht/sd.aspx'
FETION_SIPC = '221.130.45.203:8080'
FETION_LOGIN_URL = 'https://nav.fetion.com.cn/ssiportal/SSIAppSignIn.aspx'
FETION_CONFIG_URL = 'http://nav.fetion.com.cn/nav/getsystemconfig.aspx'
FETION_SIPP = 'SIPP'

DEBUG = False

class Fetion:
       ssic = ''
       sid = ''
       domain = ''

       call = 0
       seq = 0
       guid = None
       contacts = []

       def __init__(self, mobileno, password):
           self.mobileno = mobileno
           self.password = password
           self.http_tunnel = FETION_URL
           self.sipc_proxy = FETION_SIPC

       def login(self):
           re_ssic = re.compile('ssic=(.*?);')
           re_sid = re.compile('sip:(\d+)@(.+);')
          
           login_url = FETION_LOGIN_URL
           data = {'mobileno' : self.mobileno, 'pwd' : self.password}
           conn = urllib2.urlopen(login_url, urllib.urlencode(data))

           # Get ssic
           headers = str(conn.headers)
           res = re_ssic.findall(headers)
           if res:
               ssic = res[0]
              
           response = conn.read()

           # Get other attribs from response
           xmldoc = ET.XML(response)
           status_code = xmldoc.attrib['status-code']
           user_node = xmldoc.find('user')
           uri = user_node.attrib['uri']
           mobile_no = user_node.attrib['mobile-no']
           user_status = user_node.attrib['user-status']

           # get sid and domain from uri
           res = re_sid.findall(uri)
           if res:
               sid, domain = res[0]

           self.ssic = ssic
           self.sid = sid
           self.domain = domain

       def http_register(self):
        arg= '<args><device type="PC" version="0"client-version="3.1.0480" /><capsvalue="fetion-im;im-session;temp-group" /><eventsvalue="contact;permission;system-message" /><user-infoattributes="all" /><presence><basic value="400" desc=""/></presence></args>'

           _call = self.next_call()

           # request 1
           _url = self.next_url('i')
           response = self.send_request(_url, FETION_SIPP)

           # request 2
        msg = self.create_sip_data('R fetion.com.cn SIP-C/2.0',(('F',self.sid), ('I',_call), ('Q','1 R')), arg) + FETION_SIPP
           _url = self.next_url()
           response = self.send_request(_url, msg)

           # request 3
           _url = self.next_url()
           response = self.send_request(_url, FETION_SIPP)
           re_nonce = re.compile('nonce="(\w+)"')
           nonce = re_nonce.findall(response)[0]

           # request 4
           _cnonce = self.calc_cnonce() # calculate cnonce
           _response = self.calc_response(nonce, _cnonce) # calculate response
           _salt = self.calc_salt()  # calculate salt
        msg = self.create_sip_data('R fetion.com.cn SIP-C/2.0', (('F',self.sid), ('I',_call), ('Q', '2 R'), ('A', 'Digestalgorithm="SHA1-sess",response="%s",cnonce="%s",salt="%s"' %(_response, _cnonce, _salt))), arg) + FETION_SIPP
           _url = self.next_url()
           response = self.send_request(_url, msg)

           # request 5
           _url = self.next_url()
           response = self.send_request(_url, FETION_SIPP)

       def get_contacts_list(self):
        arg = '<args><contacts><buddy-lists/><buddies attributes="all" /><mobile-buddiesattributes="all" /><chat-friends /><blacklist/></contacts></args>'
           _call = self.next_call()
        msg = self.create_sip_data('S fetion.com.cn SIP-C/2.0',(('F',self.sid), ('I',_call), ('Q','1 S'), ('N','GetContactList')),arg) + FETION_SIPP
           _url = self.next_url()
           self.send_request(_url, msg)
           _url = self.next_url()
           response = self.send_request(_url, FETION_SIPP)

           re_contacts = re.compile('uri="(sip[^"]+)"')
           res = re_contacts.findall(response)

           return res

       def get_contacts_info(self, contacts_list):
           if contacts_list:
               arg = '<args><contacts attributes="all">'
               for contact in contacts_list:
                   arg += '<contact uri="%s" />' % contact
               arg += '</contacts></args>'

               _call = self.next_call()
            msg = self.create_sip_data('S fetion.com.cn SIP-C/2.0',(('F',self.sid), ('I',_call), ('Q','1 S'), ('N','GetContactsInfo')),arg) + FETION_SIPP
               _url = self.next_url()
               self.send_request(_url, msg)
               _url = self.next_url()
               response = self.send_request(_url, FETION_SIPP)

               re_info = re.compile('uri="([^"]+)".*?mobile-no="([^"]+)"')
               res = re_info.findall(response)

               for contact in contacts_list:
                   if not filter(lambda x: x[0] == contact, res):
                       res.append((contact, ''))

               self.contacts = res

       def get_contact_sid(self, info):
           sid = None

           if info[:4] == 'sip:':
               sid = filter(lambda x: x[0] == info, self.contacts)
           elif len(info) == 9:
               sid = filter(lambda x: x[0][4:13] == info, self.contacts)
           elif len(info) == 11:
               sid = filter(lambda x: x[1] == info, self.contacts)

           return sid and sid[0][0] or None

       def get_system_config(self):
        msg = '<config><user mobile-no="%s" /><clienttype="PC" version="3.2.0540" platform="W5.1" /><serversversion="0" /><service-no version="0" /><parametersversion="0" /><hints version="0" /><http-applicationsversion="0" /></config>' % self.mobileno
           request = urllib2.Request(FETION_CONFIG_URL, data=msg)
           conn = urllib2.urlopen(request)
           response = conn.read()

           xmldoc = ET.parse(StringIO.StringIO(response))
           result = xmldoc.find('//http-tunnel').text
           if result:
               self.http_tunnel = result
           result = xmldoc.find('//sipc-proxy').text
           if result:
               self.sipc_proxy = result

       def send_sms(self, to, content):
           _call = self.next_call()
        msg = self.create_sip_data('M fetion.com.cn SIP-C/2.0',(('F',self.sid), ('I',_call), ('Q','1 M'), ('T',to), ('N','SendSMS')),content) + FETION_SIPP
           _url = self.next_url()
           self.send_request(_url, msg)
           _url = self.next_url()
           response = self.send_request(_url, FETION_SIPP)

           if 'Send SMS OK' in response:
               return True
           else:
               return False

       def send_cat_sms(self, to, content):
           _call = self.next_call()
        msg = self.create_sip_data('M fetion.com.cn SIP-C/2.0',(('F',self.sid), ('I',_call), ('Q','1 M'), ('T',to),('N','SendCatSMS')), content) + FETION_SIPP
           _url = self.next_url()
           self.send_request(_url, msg)
           _url = self.next_url()
           response = self.send_request(_url, FETION_SIPP)

           if 'Send SMS OK' in response:
               return True
           else:
               return False

       def send_request(self, url, data):
           if not self.guid:
               self.guid = str(uuid.uuid1())
           headers = {
                   'User-Agent' : 'IIC2.0/pc 3.1.0480',
                   'Cookie':'ssic=%s' % self.ssic,
                   'Content-Type' : 'application/oct-stream',
                   'Pragma' : 'xz4BBcV%s' % self.guid,
                   }
           request = urllib2.Request(url, headers=headers, data=data)
           conn = urllib2.urlopen(request)
           response = conn.read()
           if DEBUG:
               print 'DEBUG'.center(78, '*')
               print 'URL:', url
               print 'Data:', data
               print 'Response:', response
               print 'DEBUG'.center(78, '*')
               print

           return response

       def create_sip_data(self, invite, fields, arg=''):
           sip = invite + '\r\n'
           for k, v in fields:
               sip += '%s: %s\r\n' % (k, v)
           sip += 'L: %s\r\n\r\n%s' % (len(arg), arg)

           return sip


       def next_call(self):
           self.call += 1

           return self.call

       def next_url(self, t='s'):
           self.seq += 1

           return '%s?t=%s&i=%s' % (self.http_tunnel, t, self.seq)

       def calc_cnonce(self):
           md5 = hashlib.md5()
           md5.update(str(uuid.uuid1()))

           return md5.hexdigest().upper()

       def hash_password(self):
           salt = '%s%s%s%s' % (chr(0x77), chr(0x7A), chr(0x6D), chr(0x03))
           sha1 = hashlib.sha1()
           sha1.update(self.password)
           src = salt + sha1.digest()
           sha1 = hashlib.sha1()
           sha1.update(src)

           return '777A6D03' + sha1.hexdigest().upper()

       def calc_response(self, nonce, cnonce):
           hashpassword = self.hash_password()
           binstr = binascii.unhexlify(hashpassword[8:])
           sha1 = hashlib.sha1()
           sha1.update('%s:%s:%s' % (self.sid, self.domain, binstr))
           key = sha1.digest()
           md5 = hashlib.md5()
           md5.update('%s:%s:%s' % (key, nonce, cnonce))
           h1 = md5.hexdigest().upper()
           md5 = hashlib.md5()
           md5.update('REGISTER:%s' % self.sid)
           h2 = md5.hexdigest().upper()
           md5 = hashlib.md5()
           md5.update('%s:%s:%s' % (h1, nonce, h2))

           return md5.hexdigest().upper()

       def calc_salt(self):
           return self.hash_password()[:8]
      
def SendSMS(mobile,password,to,body):
      
       fetion = Fetion(mobile, password)
       fetion.get_system_config()
       fetion.login()
       fetion.http_register()
       fetion.get_contacts_info(fetion.get_contacts_list())

       if to:
           sid = fetion.get_contact_sid(to)
           if not sid:
               sid = to

           if sid:             
               if fetion.send_cat_sms(sid, body):
                   print 'Sent SMS'
               else:
                   print 'Error occurs'
      
def main():
       # create a options parser
       parser = OptionParser()
       parser.add_option('-m', '--mobile', dest='mobile', type='string',
                         help='mobile phone number')
       parser.add_option('-p', '--password', dest='password', type='string',
                         help='login password')
       parser.add_option('-t', '--to', dest='to', type='string',
                         help='SMS to')
       parser.add_option('-b', '--body', dest='body', type='string',
                         help='SMS body')
       parser.add_option('-l', '--long-body', dest='lbody', type='string',
                         help='SMS long body')

       (options, args) = parser.parse_args()

       # handle options
       if not options.mobile:
           parser.error('-m option is required')

       mobile = options.mobile
       if not options.password:
           password = getpass()
       else:
           password = options.password

       fetion = Fetion(mobile, password)
       fetion.get_system_config()
       fetion.login()
       fetion.http_register()
       fetion.get_contacts_info(fetion.get_contacts_list())

       if options.to:
           sid = fetion.get_contact_sid(options.to)

           if not sid:
               sid = options.to

           if sid:
               if options.body:
                   if fetion.send_sms(sid, options.body):
                       print 'Sent SMS'
                   else:
                       print 'Error occurs'
               elif options.lbody:
                   if fetion.send_cat_sms(sid, options.lbody):
                       print 'Sent SMS'
                   else:
                       print 'Error occurs'

if __name__ == '__main__':
       body_unicode = u"Send mail content"
       body_unicode *= 10
       body_utf  = body_unicode.encode('utf-8')
       #s.encode('utf-8')
       #s.encode('utf8')
       #s = unicode(s,"cp936")
       SendSMS('13557715959','550505','13551505755',body_utf)

#--------------------------------------------------------------------------------------------------------------------------

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-372418-1-1.html 上篇帖子: python模块介绍- binascii 二进制和ASCII转换 下篇帖子: Python Totorial入门指南 笔记 :5
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表