예제 #1
0
    def compose_headers (self, protocol=None):
        """
        Compose the response headers.

        @param protocol (str)
        """

        if self._is_web_socket_connection:
            out_headers  = "%s 101 Switching Protocols\r\n" % self.in_headers["SERVER_PROTOCOL"]
            out_headers += "Upgrade: WebSocket\r\n"
            out_headers += "Connection: Upgrade\r\n"

            # allow specific WebSocket Protocol to be set.
            if protocol:
                out_headers += "Sec-WebSocket-Protocol: %s\r\n" % protocol

            out_headers += "Sec-WebSocket-Origin: %s\r\n" % self.in_headers["HTTP_ORIGIN"]
            out_headers += "Sec-WebSocket-Location: ws://%s%s\r\n\r\n" % (self.in_headers["HTTP_HOST"],
                                                                          self.in_headers["REQUEST_URI"])
            out_headers += self.response_token

            self.write(out_headers)

        else:
            # compose non-websocket headers
            HttpClient.compose_headers(self)
예제 #2
0
    def handle_content_negotiation (self):
        """
        This callback will be executed after the headers have been parsed and content negotiation needs to start.
        """

        if self.in_headers.get("SERVER_PROTOCOL") == "HTTP/1.1" and self.in_headers.get("HTTP_UPGRADE") == "WebSocket" and\
           self.in_headers.get("HTTP_CONNECTION") == "Upgrade":
            # websocket http request
            self._is_web_socket_connection = True

            if "HTTP_SEC_WEBSOCKET_PROTOCOL" in self.in_headers:
                self.in_web_socket_protocol = self.in_headers["HTTP_SEC_WEBSOCKET_PROTOCOL"]

            # read in 3rd security key and build response token
            self.read_length(8, self.handle_response_token)

            self.handle_web_socket_connect()

            self._listen_for_message()

            return

        else:
            # non-websocket http request
            self._is_web_socket_connection = False

            HttpClient.handle_content_negotiation(self)
예제 #3
0
    def __init__ (self, *args):
        """
        Create a new WebSocketClient instance.
        """

        HttpClient.__init__(self, *args)

        self._is_web_socket_connection = False
예제 #4
0
    def handle_write_finished (self):
        """
        This callback will be executed when the entire write buffer has been written.
        """

        if self._is_web_socket_connection:
            # allowing another request
            self.clear_write_buffer()

        else:
            HttpClient.handle_write_finished(self)
예제 #5
0
 def __init__(self):
     self.hosturl = 'http://sep.ucas.ac.cn'
     self.loginurl = 'http://sep.ucas.ac.cn/slogin'
     self.req = HttpClient()
     config = configparser.ConfigParser()
     config.read('./config.ini')
     self.usrname = config.get('USER', 'usrname')
     self.passwd = config.get('USER', 'passwd')
     self.pwd = config.get('USER', 'savedir')
     if not (self.usrname and self.passwd and self.pwd):
         print('Please setup your account in \'config.ini\'')
         pause()
         sys.exit()
예제 #6
0
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        self.friend_list = {}

        self.client_id = int(random.uniform(111111, 888888))
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get(
            "global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0
예제 #7
0
 def reply(self, reply_content, fail_times=0):
     fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t")).decode("utf-8")
     rsp = ""
     try:
         req_url = "http://d.web2.qq.com/channel/send_qun_msg2"
         data = (
             ('r', '{{"group_uin":{0}, "face":564,"content":"[\\"{4}\\",[\\"font\\",{{\\"name\\":\\"Arial\\",\\"size\\":\\"10\\",\\"style\\":[0,0,0],\\"color\\":\\"000000\\"}}]]","clientid":"{1}","msg_id":{2},"psessionid":"{3}"}}'.format(self.guin, self.__operator.client_id, self.msg_id + 1, self.__operator.psessionid, fix_content)),
             ('clientid', self.__operator.client_id),
             ('psessionid', self.__operator.psessionid)
         )
         rsp = HttpClient().Post(req_url, data, self.__operator.default_config.conf.get("global", "connect_referer"))
         rsp_json = json.loads(rsp)
         if rsp_json['retcode'] != 0:
             raise ValueError("reply group chat error" + str(rsp_json['retcode']))
         logging.info("Reply successfully.")
         logging.debug("Reply response: " + str(rsp))
         self.msg_id += 1
         return rsp_json
     except:
         if fail_times < 5:
             logging.warning("Response Error.Wait for 2s and Retrying." + str(fail_times))
             logging.debug(rsp)
             time.sleep(2)
             self.reply(reply_content, fail_times + 1)
         else:
             logging.warning("Response Error over 5 times.Exit.reply content:" + str(reply_content))
             return False
예제 #8
0
    def uploadRecord(self, data, client):
        '''
        刷卡记录上传
        :param data:
        :param client:
        :return:
        '''
        requestBody = {
            'serial': CommonUtils.bytesToHex(data[0:6]),
            'carNum': CommonUtils.bytesToHex(data[7:12]),
            'dateTime': CommonUtils.bytesToHex(data[12:])
        }

        logger.debug('上传刷卡记录:%s' % (requestBody))

        response = HttpClient.doGet(Config.doorRecord + '?type=1&mac=' +
                                    requestBody['serial'] + '&cardNum=' +
                                    requestBody['carNum'])

        logger.debug('刷卡记录上传结果:%s' % (response))

        data = requestBody['serial'] + '01' + requestBody['carNum']

        if response['success']:
            data += '4F4B'
        else:
            data += '4445'

        data = CommonUtils.xorOperation(bytes.fromhex(data))

        logger.debug('响应UDP门禁:hex=%s' % (CommonUtils.bytesToHex(data)))

        UdpClient.sendUdpData(data, client)
예제 #9
0
    def uploadPassRecord(self, data, client):
        '''
        密码开门记录上传
        :param data:
        :param client:
        :return:
        '''
        requestBody = {
            'serial': CommonUtils.bytesToHex(data[0:6]),
            'pass': CommonUtils.bytesToHex(data[7:9]),
        }

        logger.debug('上传密码开门记录:%s' % (requestBody))

        response = HttpClient.doGet(Config.doorRecord + '?type=2&mac=' +
                                    requestBody['serial'] + '&cardNum=' +
                                    requestBody['pass'])

        logger.debug('密码开门记录上传结果:%s' % (response))

        data = requestBody['serial'] + '0A4F4B'

        data = CommonUtils.xorOperation(bytes.fromhex(data))

        logger.debug('响应UDP门禁:hex=%s' % (CommonUtils.bytesToHex(data)))

        UdpClient.sendUdpData(data, client)
예제 #10
0
 def test_url(self):
     resp_list = []
     for i in range(self.times):
         client = HttpClient.HttpClient(self.url)
         resp = client.send_request()
         resp_list.append(resp)
     return resp_list
예제 #11
0
    def elevatorCardUpload(self, data, client):
        '''
        梯控刷卡记录上传
        :param data:
        :param client:
        :return:
        '''
        requestBody = {
            'mac': CommonUtils.bytesToHex(data[0:6]),
            'carNum': CommonUtils.bytesToHex(data[7:12]),
            'dateTime': CommonUtils.bytesToHex(data[12:])
        }
        logger.debug('梯控卡号上传:%s' % (requestBody))
        # 提交记录到云平台,返回该卡可以使用的楼层
        response = HttpClient.doPost(Config.elevatorRecord, requestBody)
        logger.debug('梯控卡号上传结果:%s' % (response))

        message = None

        if response['success']:
            message = requestBody['mac'] + '11' + requestBody[
                'carNum'] + CommonUtils.getFloorHex(response['data'])
        else:
            message = requestBody['mac'] + '11' + requestBody['carNum'] + '4445'

        message = CommonUtils.xorOperation(bytes.fromhex(message))

        logger.debug('梯控卡号上传响应:%s' % (CommonUtils.bytesToHex(message)))

        UdpClient.sendUdpData(message, client)
예제 #12
0
 def elevatorTempPassValidate(self, data, client):
     '''
     梯控临时密码校验
     :param data:
     :param celint:
     :return:
     '''
     requestBody = {
         'serial': CommonUtils.bytesToHex(data[0:6]),
         'pass': CommonUtils.bytesToHex(data[7:9]),
     }
     logger.debug('梯控临时密码校验:%s' % (requestBody))
     response = HttpClient.doPost(Config.elevatorTempPassValidate,
                                  requestBody)
     logger.debug('梯控临时密码校验结果:%s' % (response))
     if response['success']:
         floors = response['data']
         message = None
         if floors:
             # 存在一个或者多个楼层权限
             message = requestBody[
                 'serial'] + '15' + CommonUtils.getFloorHex(floors) + '4F4B'
         else:
             # 校验失败,不存在楼层权限
             message = requestBody['serial'] + '15' + '4445'
         message = CommonUtils.xorOperation(bytes.fromhex(message))
         logger.debug('梯控临时密码响应:%s' % (CommonUtils.bytesToHex(message)))
         UdpClient.sendUdpData(message, client)
예제 #13
0
파일: Sess.py 프로젝트: yankaics/SmartQQBot
 def get_group_sig(self, fail_time=0):
     if fail_time > 10:
         logging.error(
             "can not get group_sig, check the internet connection.")
         raise IOError(
             "can not get group_sig, check the internet connection.")
     ts = time.time()
     while ts < 1000000000000:
         ts *= 10
     ts = int(ts)
     try:
         logging.info("trying to get group_sig")
         group_sig = HttpClient().Get(
             'http://d.web2.qq.com/channel/get_c2cmsg_sig2?id={0}&to_uin={1}&clientid={2}&psessionid={3}&service_type={4}&t={5}'
             .format(
                 self.id,
                 self.tuin,
                 self.__operator.client_id,
                 self.__operator.psessionid,
                 self.service_type,
                 ts,
             ),
             self.__operator.default_config.conf.get(
                 'global', 'connect_referer'))
         logging.debug("group_sig response:  " + str(group_sig))
         group_sig = json.loads(group_sig)['result']['value']
         if group_sig == "":
             logging.warning("Receive a None when getting group sig")
             raise ValueError("Receive a None when getting group sig")
         return group_sig
     except BaseException, e:
         logging.warning("Getting group sig met an error: " + str(e) +
                         " Retrying...")
         return self.get_group_sig(fail_time + 1)
예제 #14
0
    def elevatorHeartBeat(self, data, client):
        '''
        梯控心跳
        :return:
        '''
        requestBody = {
            'sourceIp': client[0],
            'sourcePort': client[1],
            'mac': CommonUtils.bytesToHex(data[0:6]),
            'targetIp': '' if not Config.udpServerIp else Config.udpServerIp,
            'targetPort': Config.udpServerPort,
            'date': CommonUtils.now(),
        }
        logger.debug("梯控心跳:%s" % (requestBody))
        response = HttpClient.doPost(Config.elevatorHeartbeat, requestBody)
        logger.debug('梯控心跳结果:%s' % (response))
        if response['success']:
            cardFormat = response['data']['cardFormat']
            key = response['data']['key']
            if not key:
                logger.error('没有密钥')
                return
            if not cardFormat:
                cardFormat = '04'

            message = requestBody['mac'] + '17' + key + time.strftime(
                "%y%m%d%H%M%S") + cardFormat
            message = CommonUtils.xorOperation(bytes.fromhex(message))
            logger.debug('梯控心跳响应:%s' % (CommonUtils.bytesToHex(message)))
            UdpClient.sendUdpData(message, client)
예제 #15
0
    def __init__(self):
        self.fig = None
        self.a = None

        self.HttpClientRam = HttpClient("ram")
        self.HttpClientCpu = HttpClient("cpu")

        ramResponse = self.HttpClientRam.callURI()
        cpuResponse = self.HttpClientCpu.callURI()
        ramUsage = self.HttpClientRam.readContent(ramResponse)
        cpuUsage = self.HttpClientCpu.readContent(cpuResponse)

        self.ramFig = plt.Figure(figsize=(3, 3))
        self.ramFig.set_facecolor("#000000")
        self.ramA = self.ramFig.add_subplot(111)
        self.ramA.pie(
            [100 - float(ramUsage), float(ramUsage)],
            startangle=90,
            labels=[100 - float(ramUsage),
                    float(ramUsage)],
            autopct='%1.1f%%')
        self.ramA.legend(["free", "ram"])

        self.cpuFig = plt.Figure(figsize=(3, 3))
        self.cpuFig.set_facecolor("#000000")
        self.cpuA = self.cpuFig.add_subplot(111)
        self.cpuA.pie(
            [100 - float(cpuUsage), float(cpuUsage)],
            startangle=90,
            labels=[100 - float(cpuUsage),
                    float(cpuUsage)],
            autopct='%1.1f%%')
        self.cpuA.legend(["free", "cpu"])

        self.window = tk.Tk()
        self.window.title('VPS perfs')

        self.ramCanvas = FigureCanvasTkAgg(self.ramFig, master=self.window)
        self.ramCanvas.get_tk_widget().grid(row=0, column=0)
        self.ramCanvas.draw()

        self.cpuCanvas = FigureCanvasTkAgg(self.cpuFig, master=self.window)
        self.cpuCanvas.get_tk_widget().grid(row=0, column=1)
        self.cpuCanvas.draw()

        self.window.after(300000, self.updateInterface)
        self.window.mainloop()
예제 #16
0
 def heartbeat(self, data, client):
     '''
     普通心跳
     :param data:
     :param client:
     :return:
     '''
     requestBody = {
         'sourceIp': client[0],  # 门禁ip
         'sourcePort': client[1],  # 门禁端口
         'mac': CommonUtils.bytesToHex(data),  # 序列号
         'targetIp': Config.udpServerIp,  # 目标服务器ip(当前服务器ip)
         'targetPort': Config.udpServerPort,  # 目标服务器端口
         'date': CommonUtils.now(),  # 心跳时间
     }
     logger.debug('心跳注册:%s' % (requestBody))
     HttpClient.doPost(Config.doorHeartbeat, requestBody)
예제 #17
0
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        # cache
        self.friend_list = {}
        self.__groupSig_list = {}
        self.__self_info = {}

        self.client_id = 53999199
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0

        init_logging()
예제 #18
0
class Instagram:
    def __init__(self, token=None):
        self._access_token = token
        self._http_client = HttpClient()
        self.error_msg = False

    def media(self):
        response = self._get('users/self/media/recent')
        return response

    @property
    def access_token(self):
        return self._access_token

    @access_token.setter
    def access_token(self, value):
        self._access_token = value

    def _get(self, path):
        """
        Получает ответ от API
        :return: словарь из json ответа
        """
        try:
            self._check_exists_token()
            url = self._build_api_url(path)
            response = self._http_client.send_request(url)
            parsed_response = json.loads(response)

            return parsed_response['data']
        except Exception as e:
            self.error_msg = e
            print(e)
            return False

    def _build_api_url(self, path, params=None):
        """
        Собирает URL для запроса
        :param path: end point Инстаграма
        :param params: параметры для запроса
        :return: URL
        """
        try:
            url = 'https://api.instagram.com/v1/'
            params = {'access_token': self._access_token}
            return url + path + '/?' + parse.urlencode(params)
        except Exception as e:
            self.error_msg = e
            print(e)
            return False

    def _check_exists_token(self):
        if not self._access_token:
            raise Exception('Token is None')
예제 #19
0
    def __init__(self, sys_paras):
        self.sys_paras = sys_paras
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        self.init_info_lists()
        self.last_refresh = time.time()
        self.refresh_interval = int(
            self.default_config.conf.get("global", "refresh_interval"))

        self.client_id = int(random.uniform(111111, 888888))
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = sys_paras['qrcode_path'] if sys_paras[
            'qrcode_path'] else self.default_config.conf.get(
                "global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0
예제 #20
0
def urlretrieve(url, port, directory, iface='eth0', reporthook=None):
    '''
    Retrieve the file at the given url to local with
    the given filename
    '''
    hostname, uri, filename = _parse_url(url)
    client = C.HttpClient(hostname, port, iface)
    rc, headers, content = client.GET(uri)
    filepath = '/'.join([directory, filename])
    with open(filepath, 'w') as f:
        f.write(content)
    return filepath
예제 #21
0
 def __init__(self):
     self.default_config = DefaultConfigs()
     self.req = HttpClient()
     self.redis=redis.StrictRedis(host='localhost', port=6379, db=0)
     self.friend_list = {}
     self.client_id = int(random.uniform(111111, 888888))
     self.ptwebqq = ''
     self.psessionid = ''
     self.appid = 0
     self.vfwebqq = ''
     self.qrcode_path = self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
     self.username = ''
     self.account = 0
예제 #22
0
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        self.msg_id = int(random.randint(1111, 8888) * 10000)
        self.client_id = int(random.uniform(111111, 888888))
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0
예제 #23
0
    def heartbeatWithStatus(self, data, client):
        '''
        带有状态的心跳包
        :param data:
        :param client:
        :return:
        '''
        requestBody = {
            'sourceIp': client[0],
            'sourcePort': client[1],
            'mac': CommonUtils.bytesToHex(data[0:6]),
            'targetIp': '' if not Config.udpServerIp else Config.udpServerIp,
            'targetPort': Config.udpServerPort,
            'status': CommonUtils.bytesToHex(data[7:8]),
            'date': CommonUtils.now(),
        }

        logger.debug('状态心跳:%s' % (requestBody))

        response = HttpClient.doPost(Config.doorHeartbeat, requestBody)

        logger.debug('状态响应:%s' % (response))

        if not response['success']:
            logger.error('服务器异常:%s' % (response['message']))
            return

        if 'data' not in response or not response['data']:
            logger.error('门禁没有密钥和卡片输出格式:serital=%s' % (requestBody['mac']))
            return

        if 'key' not in response['data']:
            logger.error('门禁没有密钥信息:serital=%s' % (requestBody['mac']))
            return

        key = response['data']['key']

        if 'cardOutFormat' not in response['data']:
            cardFormat = '04'
        else:
            cardFormat = response['data']['cardOutFormat'].zfill(2)

        responseHex = requestBody['mac'] + '07' + key + time.strftime(
            "%y%m%d%H%M%S") + cardFormat

        data = CommonUtils.xorOperation(bytes.fromhex(responseHex))

        logger.debug('状态响应包:hex=%s' % (CommonUtils.bytesToHex(data)))

        UdpClient.sendUdpData(data, client)
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        self.init_info_lists()
        self.last_refresh = time.time()
        self.refresh_interval = int(self.default_config.conf.get("global", "refresh_interval"))

        self.client_id = int(random.uniform(111111, 888888))
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0
예제 #25
0
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        # cache
        self.friend_list = {}
        self.__groupSig_list = {}
        self.__self_info = {}

        self.client_id = int(random.uniform(111111, 888888))
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0
예제 #26
0
    def uin_to_account(self, tuin):
        uin_str = str(tuin)
        if uin_str not in self.friend_list:
            try:
                logging.info("Requesting the account by uin:    " + str(tuin))
                info = json.loads(HttpClient().Get(
                    'http://s.web2.qq.com/api/get_friend_uin2?tuin={0}&type=1&vfwebqq={1}'
                    .format(uin_str, self.vfwebqq),
                    self.default_config.conf.get("global", "connect_referer")))
                logging.debug("uin_request html:    " + str(info))
                if info['retcode'] != 0:
                    raise TypeError('uin to account result error')
                info = info['result']
                self.friend_list[uin_str] = info['account']

            except BaseException, error:
                logging.warning(error)
예제 #27
0
 def uploadElevatorPass(self, data, client):
     '''
     梯控密码记录上传
     :param data:
     :param client:
     :return:
     '''
     requestBody = {
         'mac': CommonUtils.bytesToHex(data[0:6]),
         'pass': CommonUtils.bytesToHex(data[7:12]),
     }
     logger.debug('梯控密码记录上传:%s' % (requestBody))
     response = HttpClient.doPost(Config.elevatorPassRecord, requestBody)
     logger.debug('梯控密码记录上传结果:%s' % (response))
     if response['success']:
         message = requestBody['mac'] + '1A4F4B'
         message = CommonUtils.xorOperation(bytes.fromhex(message))
         logger.debug('梯控密码记录上传响应:%s' % (CommonUtils.bytesToHex(message)))
         UdpClient.sendUdpData(message, client)
예제 #28
0
    def tempPassValidate(self, data, client):
        '''
        临时密码校验
        :param data:
        :param client:
        :return:
        '''
        requestBody = {
            'serial': CommonUtils.bytesToHex(data[0:6]),
            'pass': CommonUtils.bytesToHex(data[7:9]),
        }

        logger.debug('临时密码校验:%s', requestBody)

        #response = HttpClient.doGet(Config.doorTempPassValidate + '?mac=' + requestBody['serial'] + '&code=' + requestBody['pass'])
        with request.urlopen(Config.doorTempPassValidate + '?mac=' +
                             requestBody['serial'] + '&code=' +
                             requestBody['pass']) as response:
            '''
            响应非标准JSON
            '''
            response = str(response.read(), 'UTF_8')

            logger.debug('临时密码校验结果:%s' % (response))

            data = requestBody['serial'] + '05'

            if response:
                data += '4F4B'
                # 服务端有响应任何数据,则校验成功,进行密码记录开门上传
                response = HttpClient.doGet(Config.doorRecord +
                                            '?type=2&mac=' +
                                            requestBody['serial'] +
                                            '&cardNum=' + requestBody['pass'])
                logger.debug('密码开门记录上传结果:%s' % (response))
            else:
                data += '4445'

            data = CommonUtils.xorOperation(bytes.fromhex(data))

            logger.debug('临时密码校验响应:hex=%s' % (CommonUtils.bytesToHex(data)))

            UdpClient.sendUdpData(data, client)
예제 #29
0
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        # cache
        self.friend_list = {}
        self.__groupSig_list = {}
        self.__self_info = {}

        self.client_id = 53999199
        self.ptwebqq = ""
        self.psessionid = ""
        self.appid = 0
        self.vfwebqq = ""
        self.qrcode_path = self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
        self.username = ""
        self.account = 0

        init_logging()
예제 #30
0
#!/usr/bin/env python
# coding:utf8


from HttpClient import *

if __name__ == '__main__':
    httpClient = HttpClient()
    headers = [
        ('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'),
        ('User-Agent',
         'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36')
    ]
    # set headers
    httpClient.setHeaders(headers)
    
    url = "http://*****:*****@239"
    
    # GET
    url_data = url + "?" + data
    
    request = httpClient.doGet(url_data)
    print request  # {"rest":20525534516,"stat":"OK"}
    
    # POST
    data = {}
    data['token'] = '-92mtvqrRJo@239'
    
    # data to json
    httpClient.post_dataToJsonDump(data)
예제 #31
0
class QQ:
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        # cache
        self.friend_list = {}
        self.__groupSig_list = {}
        self.__self_info = {}

        self.client_id = 53999199
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get(
            "global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0

        init_logging()

    def __hash_digest(self, uin, ptwebqq):
        """
        计算hash,貌似TX的这个算法会经常变化,暂时不使用
        get_user_friends2, get_group_name_list_mask2 会依赖此数据
        提取自http://pub.idqqimg.com/smartqq/js/mq.js
        :param uin:
        :param ptwebqq:
        :return:
        """
        N = [0, 0, 0, 0]
        print(N[0])
        for t in range(len(ptwebqq)):
            N[t % 4] ^= ord(ptwebqq[t])
        U = ["EC", "OK"]
        V = [0, 0, 0, 0]
        V[0] = int(uin) >> 24 & 255 ^ ord(U[0][0])
        V[1] = int(uin) >> 16 & 255 ^ ord(U[0][1])
        V[2] = int(uin) >> 8 & 255 ^ ord(U[1][0])
        V[3] = int(uin) & 255 ^ ord(U[1][1])
        U = [0, 0, 0, 0, 0, 0, 0, 0]
        for T in range(8):
            if T % 2 == 0:
                U[T] = N[T >> 1]
            else:
                U[T] = V[T >> 1]
        N = [
            "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C",
            "D", "E", "F"
        ]
        V = ""
        for T in range(len(U)):
            V += N[U[T] >> 4 & 15]
            V += N[U[T] & 15]
        return V

    def __getGroupSig(self, guin, tuin, service_type=0):
        key = '%s --> %s' % (guin, tuin)
        if key not in self.__groupSig_list:
            url = "http://d1.web2.qq.com/channel/get_c2cmsg_sig2?id=%s&to_uin=%s&service_type=%s&clientid=%s&psessionid=%s&t=%d" % (
                guin, tuin, service_type, self.client_id, self.psessionid,
                int(time.time() * 100))
            response = self.req.Get(url)
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                return ""
            sig = rsp_json["result"]["value"]
            self.__groupSig_list[key] = sig
        if key in self.__groupSig_list:
            return self.__groupSig_list[key]
        return ""

    def login_by_qrcode(self):
        logging.info("Requesting the login pages...")
        initurl_html = self.req.Get(
            self.default_config.conf.get("global", "smartqq_url"))
        logging.debug("login page html: " + str(initurl_html))
        initurl = get_revalue(initurl_html, r'\.src = "(.+?)"',
                              "Get Login Url Error.", 1)
        html = self.req.Get(initurl + '0')

        appid = get_revalue(
            html, r'<input type="hidden" name="aid" value="(\d+)" />',
            'Get AppId Error', 1)
        sign = get_revalue(html, r'g_login_sig=encodeURIComponent\("(.*?)"\)',
                           'Get Login Sign Error', 0)
        js_ver = get_revalue(html,
                             r'g_pt_version=encodeURIComponent\("(\d+)"\)',
                             'Get g_pt_version Error', 1)
        mibao_css = get_revalue(html,
                                r'g_mibao_css=encodeURIComponent\("(.+?)"\)',
                                'Get g_mibao_css Error', 1)

        star_time = date_to_millis(datetime.datetime.utcnow())

        error_times = 0
        ret = []
        while True:
            error_times += 1
            print 'download QR code image...'
            self.req.Download(
                'https://ssl.ptlogin2.qq.com/ptqrshow?appid={0}&e=0&l=L&s=8&d=72&v=4'
                .format(appid), self.qrcode_path)
            logging.info("Please scan the downloaded QRCode")
            thread.start_new_thread(display_QRCode, (self.qrcode_path, ))

            while True:
                html = self.req.Get(
                    'https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid={0}&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-{1}&mibao_css={2}&t=undefined&g=1&js_type=0&js_ver={3}&login_sig={4}'
                    .format(
                        appid,
                        date_to_millis(datetime.datetime.utcnow()) - star_time,
                        mibao_css, js_ver, sign), initurl)
                logging.debug("QRCode check html:   " + str(html))
                ret = html.split("'")
                if ret[1] in (
                        '0', '65'):  # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中
                    break
            if ret[1] == '0' or error_times > 10:
                break

        if ret[1] != '0':
            return
        logging.info("QRCode scaned, now logging in.")

        # 删除QRCode文件
        if os.path.exists(self.qrcode_path):
            os.remove(self.qrcode_path)

        # 记录登陆账号的昵称
        self.username = ret[11]

        html = self.req.Get(ret[5])
        logging.debug("mibao_res html:  " + str(html))

        # url = get_revalue(html, r' src="(.+?)"', 'Get mibao_res Url Error.', 0)
        # if url != '':
        #     html = self.req.Get(url.replace('&amp;', '&'))
        #     url = get_revalue(html, r'location\.href="(.+?)"', 'Get Redirect Url Error', 1)
        #     self.req.Get(url)

        self.ptwebqq = self.req.getCookie('ptwebqq')

        # 测试用请求
        self.req.Get("http://w.qq.com/proxy.html?login2qq=1&webqq_type=10")
        self.req.Get("http://web2.qq.com/web2_cookie_proxy.html")
        self.req.Get(
            "http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")
        self.req.Get(
            "http://s.web2.qq.com/api/getvfwebqq?ptwebqq={0}&clientid={1}&psessionid={2}&t={3}"
            .format(self.ptwebqq, self.client_id, self.psessionid,
                    date_to_millis(datetime.datetime.utcnow()) - star_time))
        self.req.Get(
            "http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2")

        login_error = 1
        ret = {}
        while login_error > 0:
            try:
                html = self.req.Post(
                    'http://d1.web2.qq.com/channel/login2', {
                        'r':
                        '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'
                        .format(self.ptwebqq, self.client_id, self.psessionid)
                    }, self.default_config.conf.get("global",
                                                    "connect_referer"))
                logging.debug("login html:  " + str(html))
                ret = json.loads(html)
                login_error = 0
            except:
                login_error += 1
                logging.info("login fail, retrying...")

        if ret['retcode'] != 0:
            logging.debug(str(ret))
            logging.warning("return code:" + str(ret['retcode']))
            return

        self.vfwebqq = ret['result']['vfwebqq']
        self.psessionid = ret['result']['psessionid']
        self.account = ret['result']['uin']

        logging.info("QQ:{0} login successfully, Username:{1}".format(
            self.account, self.username))

    def relogin(self, error_times=0):
        if error_times >= 10:
            return False
        try:
            html = self.req.Post(
                'http://d1.web2.qq.com/channel/login2', {
                    'r':
                    '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","key":"","status":"online"}}'
                    .format(self.ptwebqq, self.client_id, self.psessionid)
                }, self.default_config.conf.get("global", "connect_referer"))
            logging.debug("relogin html:  " + str(html))
            ret = json.loads(html)
            self.vfwebqq = ret['result']['vfwebqq']
            self.psessionid = ret['result']['psessionid']
            return True
        except:
            logging.info("login fail, retryng..." + str(error_times))
            return self.relogin(error_times + 1)

    def check_msg(self, error_times=0):
        if error_times >= 5:
            if not self.relogin():
                raise IOError("Account offline.")
            else:
                error_times = 0

        # 调用后进入单次轮询,等待服务器发回状态。
        html = self.req.Post(
            'http://d1.web2.qq.com/channel/poll2', {
                'r':
                '{{"ptwebqq":"{1}","clientid":{2},"psessionid":"{0}","key":""}}'
                .format(self.psessionid, self.ptwebqq, self.client_id)
            }, self.default_config.conf.get("global", "connect_referer"))
        logging.debug("check_msg html:  " + str(html))
        try:
            if html == "":
                return self.check_msg()
            ret = json.loads(html)

            ret_code = ret['retcode']

            # if ret_code in (0,):
            #     logging.info("received retcode: " + str(ret_code) + ": No message.")
            #     time.sleep(1)
            #     return

            if ret_code in (103, ):
                logging.warning("received retcode: " + str(ret_code) +
                                ": Check error.retrying.." + str(error_times))
                time.sleep(1)
                return self.check_msg(error_times + 1)

            if ret_code in (121, ):
                logging.warning("received retcode: " + str(ret_code))
                return self.check_msg(5)

            elif ret_code == 0:
                if len(ret['result']) == 0:
                    logging.info("received retcode: " + str(ret_code) +
                                 ": No message.")
                    time.sleep(1)
                    return
                msg_list = []
                pm_list = []
                sess_list = []
                group_list = []
                notify_list = []
                for msg in ret['result']:
                    ret_type = msg['poll_type']
                    if ret_type == 'message':
                        pm_list.append(PmMsg(msg))
                    elif ret_type == 'group_message':
                        group_list.append(GroupMsg(msg))
                    elif ret_type == 'sess_message':
                        sess_list.append(SessMsg(msg))
                    elif ret_type == 'input_notify':
                        notify_list.append(InputNotify(msg))
                    elif ret_code == 'kick_message':
                        notify_list.append(KickMessage(msg))
                    else:
                        logging.warning("unknown message type: " +
                                        str(ret_type) + "details:    " +
                                        str(msg))

                group_list.sort(key=lambda x: x.msg_id)
                msg_list += pm_list + sess_list + group_list + notify_list
                if not msg_list:
                    return
                return msg_list

            elif ret_code == 100006:
                logging.warning("POST data error")
                return

            elif ret_code == 116:
                self.ptwebqq = ret['p']
                logging.info("ptwebqq updated.")
                return

            else:
                logging.warning("unknown retcode " + str(ret_code))
                return

        except ValueError, e:
            logging.warning("Check error occured: " + str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)

        except BaseException, e:
            logging.warning("Unknown check error occured, retrying. Error: " +
                            str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)
예제 #32
0
class QQ:
    def __init__(self, sys_paras):
        self.sys_paras = sys_paras
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        self.init_info_lists()
        self.last_refresh = time.time()
        self.refresh_interval = int(self.default_config.conf.get("global", "refresh_interval"))

        self.client_id = int(random.uniform(111111, 888888))
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = sys_paras['qrcode_path'] if sys_paras['qrcode_path'] else self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0

    def login_by_qrcode(self):
        logging.info("Requesting the login pages...")
        initurl_html = self.req.Get(self.default_config.conf.get("global", "smartqq_url"))
        logging.debug("login page html: " + str(initurl_html))
        initurl = get_revalue(initurl_html, r'\.src = "(.+?)"', "Get Login Url Error.", 1)
        html = self.req.Get(initurl + '0')

        appid = get_revalue(html, r'g_appid=encodeURIComponent\("(\d+)"\)', 'Get AppId Error', 1)
        sign = get_revalue(html, r'g_login_sig=encodeURIComponent\("(.*?)"\)', 'Get Login Sign Error', 0)
        js_ver = get_revalue(html, r'g_pt_version=encodeURIComponent\("(\d+)"\)', 'Get g_pt_version Error', 1)
        mibao_css = get_revalue(html, r'g_mibao_css=encodeURIComponent\("(.+?)"\)', 'Get g_mibao_css Error', 1)

        star_time = date_to_millis(datetime.datetime.utcnow())

        error_times = 0
        ret = []
        while True:
            error_times += 1
            self.req.Download('https://ssl.ptlogin2.qq.com/ptqrshow?appid={0}&e=0&l=L&s=8&d=72&v=4'.format(appid),
                              self.qrcode_path)
            if self.sys_paras['debug']: os.system("open %s" % self.qrcode_path)
            logging.info("Please scan the downloaded QRCode")

            while True:
                html = self.req.Get(
                    'https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid={0}&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-{1}&mibao_css={2}&t=undefined&g=1&js_type=0&js_ver={3}&login_sig={4}'.format(
                        appid, date_to_millis(datetime.datetime.utcnow()) - star_time, mibao_css, js_ver, sign),
                    initurl)
                logging.debug("QRCode check html:   " + str(html))
                ret = html.split("'")
                if ret[1] in ('0', '65'):  # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中
                    break
            if ret[1] == '0' or error_times > self.sys_paras['login_retry_time']:
                break

        if ret[1] != '0':
            return False
        logging.info("QRCode scaned, now logging in.")

        # 删除QRCode文件
        if os.path.exists(self.qrcode_path):
            os.remove(self.qrcode_path)

        # 记录登陆账号的昵称
        self.username = ret[11]

        html = self.req.Get(ret[5])
        logging.debug("mibao_res html:  " + str(html))
        url = get_revalue(html, r' src="(.+?)"', 'Get mibao_res Url Error.', 0)
        if url != '':
            html = self.req.Get(url.replace('&amp;', '&'))
            url = get_revalue(html, r'location\.href="(.+?)"', 'Get Redirect Url Error', 1)
            self.req.Get(url)

        self.ptwebqq = self.req.getCookie('ptwebqq')

        login_error = 1
        ret = {}
        while login_error > 0:
            try:
                html = self.req.Post('http://d.web2.qq.com/channel/login2', {
                    'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'.format(self.ptwebqq,
                                                                                                          self.client_id,
                                                                                                          self.psessionid)
                }, self.default_config.conf.get("global", "connect_referer"))
                logging.debug("login html:  " + str(html))
                ret = json.loads(html)
                login_error = 0
            except:
                login_error += 1
                logging.info("login fail, retrying...")

        if ret['retcode'] != 0:
            logging.debug(str(ret))
            logging.warning("return code:" + str(ret['retcode']))
            return False

        self.vfwebqq = ret['result']['vfwebqq']
        self.psessionid = ret['result']['psessionid']
        self.account = ret['result']['uin']

        logging.info("QQ:{0} login successfully, Username:{1}".format(self.account, self.username))
        return True

    def relogin(self, error_times=0):
        if error_times >= 10:
            return False
        try:
            html = self.req.Post('http://d.web2.qq.com/channel/login2', {
                'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","key":"","status":"online"}}'.format(
                    self.ptwebqq,
                    self.client_id,
                    self.psessionid)
            }, self.default_config.conf.get("global", "connect_referer"))
            logging.debug("relogin html:  " + str(html))
            ret = json.loads(html)
            self.vfwebqq = ret['result']['vfwebqq']
            self.psessionid = ret['result']['psessionid']
            return True
        except:
            logging.info("login fail, retryng..." + str(error_times))
            return self.relogin(error_times + 1)

    def check_msg(self, error_times=0):
        if error_times >= 5:
            if not self.relogin():
                raise IOError("Account offline.")
            else:
                error_times = 0

        # 调用后进入单次轮询,等待服务器发回状态。
        html = self.req.Post('http://d.web2.qq.com/channel/poll2', {
            'r': '{{"ptwebqq":"{1}","clientid":{2},"psessionid":"{0}","key":""}}'.format(self.psessionid, self.ptwebqq,
                                                                                         self.client_id)
        }, self.default_config.conf.get("global", "connect_referer"))
        logging.debug("check_msg html:  " + str(html))
        try:
            if html == "":
                return self.check_msg()
            ret = json.loads(html)

            ret_code = ret['retcode']

            if ret_code in (102,):
                logging.info("received retcode: " + str(ret_code) + ": No message.")
                time.sleep(1)
                return

            if ret_code in (103,):
                logging.warning("received retcode: " + str(ret_code) + ": Check error.retrying.." + str(error_times))
                time.sleep(1)
                return self.check_msg(error_times + 1)

            if ret_code in (121,):
                logging.warning("received retcode: " + str(ret_code))
                return self.check_msg(5)

            elif ret_code == 0:
                msg_list = []
                pm_list = []
                sess_list = []
                group_list = []
                notify_list = []
                for msg in ret['result']:
                    ret_type = msg['poll_type']
                    if ret_type == 'message':
                        pm_list.append(PmMsg(msg))
                    elif ret_type == 'group_message':
                        group_list.append(GroupMsg(msg))
                    elif ret_type == 'sess_message':
                        sess_list.append(SessMsg(msg))
                    elif ret_type == 'input_notify':
                        notify_list.append(InputNotify(msg))
                    elif ret_code == 'kick_message':
                        notify_list.append(KickMessage(msg))
                    else:
                        logging.warning("unknown message type: " + str(ret_type) + "details:    " + str(msg))

                group_list.sort(key=lambda x: x.seq)
                msg_list += pm_list + sess_list + group_list + notify_list
                if not msg_list:
                    return
                return msg_list

            elif ret_code == 100006:
                logging.warning("POST data error")
                return

            elif ret_code == 116:
                self.ptwebqq = ret['p']
                logging.info("ptwebqq updated.")
                return

            else:
                logging.warning("unknown retcode " + str(ret_code))
                return

        except ValueError, e:
            logging.warning("Check error occured: " + str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)

        except BaseException, e:
            logging.warning("Unknown check error occured, retrying. Error: " + str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)
예제 #33
0
class QQ:
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        # cache
        self.friend_list = {}
        self.__groupSig_list = {}
        self.__self_info = {}

        self.client_id = 53999199
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0

        init_logging()

    def __hash_digest(self, uin, ptwebqq):
        """
        计算hash,貌似TX的这个算法会经常变化,暂时不使用
        get_user_friends2, get_group_name_list_mask2 会依赖此数据
        提取自http://pub.idqqimg.com/smartqq/js/mq.js
        :param uin:
        :param ptwebqq:
        :return:
        """
        N = [0, 0, 0, 0]
        # print(N[0])
        for t in range(len(ptwebqq)):
            N[t % 4] ^= ord(ptwebqq[t])
        U = ["EC", "OK"]
        V = [0, 0, 0, 0]
        V[0] = int(uin) >> 24 & 255 ^ ord(U[0][0])
        V[1] = int(uin) >> 16 & 255 ^ ord(U[0][1])
        V[2] = int(uin) >> 8 & 255 ^ ord(U[1][0])
        V[3] = int(uin) & 255 ^ ord(U[1][1])
        U = [0, 0, 0, 0, 0, 0, 0, 0]
        for T in range(8):
            if T % 2 == 0:
                U[T] = N[T >> 1]
            else:
                U[T] = V[T >> 1]
        N = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]
        V = ""
        for T in range(len(U)):
            V += N[U[T] >> 4 & 15]
            V += N[U[T] & 15]
        return V

    def __getGroupSig(self, guin, tuin, service_type=0):
        key = '%s --> %s' % (guin, tuin)
        if key not in self.__groupSig_list:
            url = "http://d1.web2.qq.com/channel/get_c2cmsg_sig2?id=%s&to_uin=%s&service_type=%s&clientid=%s&psessionid=%s&t=%d" % (
                guin, tuin, service_type, self.client_id, self.psessionid, int(time.time() * 100))
            response = self.req.Get(url)
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                return ""
            sig = rsp_json["result"]["value"]
            self.__groupSig_list[key] = sig
        if key in self.__groupSig_list:
            return self.__groupSig_list[key]
        return ""

    def __login(self, times=10):
        login_error = 1
        while login_error > 0:
            try:
                logging.info("Tring to login in with cookies. {0}".format(login_error))
                print('Tring to auto login in.')
                self.ptwebqq = self.req.getCookie('ptwebqq')

                html = self.req.Post('http://d1.web2.qq.com/channel/login2', {
                    'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'.format(self.ptwebqq,
                                                                                                          self.client_id,
                                                                                                          self.psessionid)
                }, self.default_config.conf.get("global", "connect_referer"))
                logging.debug("login html:  " + str(html))
                ret = json.loads(html)

                html2 = self.req.Get(
                        "http://s.web2.qq.com/api/getvfwebqq?ptwebqq={0}&clientid={1}&psessionid={2}&t={3}".format(
                                self.ptwebqq,
                                self.client_id,
                                self.psessionid,
                                self.req.getTimeStamp()
                        ))
                logging.debug("getvfwebqq html:  " + str(html2))
                ret2 = json.loads(html2)

                if (ret['retcode'] != 0) or (ret2['retcode'] != 0):
                    logging.debug(str(ret))
                    logging.debug(str(ret2))
                    logging.warning(
                        "login2 retcode: {login2}, getvfwebqq retcode: {getvfwebqq}".format(login2=str(ret['retcode']),
                                                                                            getvfwebqq=str(
                                                                                                    ret2['retcode'])))
                    raise

                self.psessionid = ret['result']['psessionid']
                self.account = ret['result']['uin']
                self.vfwebqq = ret2['result']['vfwebqq']
                logging.info("Login successfully.")
                print('Login successfully.')
                return True
            except:
                login_error += 1
                logging.info("login fail, retrying...")
                print('auto login fail')
                if login_error > times:
                    return False

    def __login_by_qrcode(self):
        try:
            logging.info("Trying to login by qrcode.")
            logging.info("Requesting the qrcode login pages...")
            initurl_html = self.req.Get(self.default_config.conf.get("global", "smartqq_url"))
            logging.debug("login page html: " + str(initurl_html))
            initurl = get_revalue(initurl_html, r'\.src = "(.+?)"', "Get Login Url Error.", 1)
            html = self.req.Get(initurl + '0')

            appid = get_revalue(html, r'<input type="hidden" name="aid" value="(\d+)" />', 'Get AppId Error', 1)
            sign = get_revalue(html, r'g_login_sig=encodeURIComponent\("(.*?)"\)', 'Get Login Sign Error', 0)
            js_ver = get_revalue(html, r'g_pt_version=encodeURIComponent\("(\d+)"\)', 'Get g_pt_version Error', 1)
            mibao_css = get_revalue(html, r'g_mibao_css=encodeURIComponent\("(.+?)"\)', 'Get g_mibao_css Error', 1)

            star_time = date_to_millis(datetime.datetime.utcnow())

            error_times = 0
            ret = []
            while True:
                error_times += 1
                print('download QR code image...')
                self.req.Download('https://ssl.ptlogin2.qq.com/ptqrshow?appid={0}&e=0&l=L&s=8&d=72&v=4'.format(appid),
                                  self.qrcode_path)
                logging.info("Please scan the downloaded QRCode")
                _thread.start_new_thread(display_QRCode, (self.qrcode_path,))

                while True:
                    html = self.req.Get(
                            'https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid={0}&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-{1}&mibao_css={2}&t=undefined&g=1&js_type=0&js_ver={3}&login_sig={4}'.format(
                                    appid, date_to_millis(datetime.datetime.utcnow()) - star_time, mibao_css, js_ver,
                                    sign),
                            initurl)
                    logging.debug("QRCode check html:   " + str(html))
                    ret = html.split("'")
                    if ret[1] in ('0', '65'):  # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中
                        break
                    time.sleep(1)
                if ret[1] == '0' or error_times > 10:
                    break

            if ret[1] != '0':
                return False

            # 删除QRCode文件
            if os.path.exists(self.qrcode_path):
                os.remove(self.qrcode_path)

            html = self.req.Get(ret[5])
            logging.debug("mibao_res html:  " + str(html))
            return True
        except:
            logging.info("qr login fail")
            print('qr login fail')
            return False

    def login(self):
        if not self.__login(1):
            while True:
                if self.__login_by_qrcode():
                    if self.__login(): break
        ret = self.get_self_info2()
        self.username = ret['nick']

        logging.info("QQ:{0} login successfully, Username:{1}".format(self.account, self.username))

    def check_msg(self, error_times=0):
        if error_times >= 5:
            if not self.__login(1):
                raise IOError("Account offline.")
            else:
                error_times = 0

        # 调用后进入单次轮询,等待服务器发回状态。
        html = self.req.Post('http://d1.web2.qq.com/channel/poll2', {
            'r': '{{"ptwebqq":"{ptwebqq}","clientid":{clientid},"psessionid":"{psessionid}","key":""}}'.format(
                psessionid=self.psessionid,
                ptwebqq=self.ptwebqq,
                clientid=self.client_id)
        }, self.default_config.conf.get("global", "connect_referer"))
        logging.debug("check_msg html:  " + str(html))
        try:
            if html == "":
                return self.check_msg()
            ret = json.loads(html)

            ret_code = ret['retcode']

            # if ret_code in (0,):
            #     logging.info("received retcode: " + str(ret_code) + ": No message.")
            #     time.sleep(1)
            #     return

            if ret_code in (103,):
                logging.warning("received retcode: " + str(ret_code) + ": Check error.retrying.." + str(error_times))
                time.sleep(1)
                return self.check_msg(error_times + 1)

            if ret_code in (121,):
                logging.warning("received retcode: " + str(ret_code))
                return self.check_msg(5)

            elif ret_code == 0:
                if 'result' not in ret or len(ret['result']) == 0:
                    logging.info("received retcode: " + str(ret_code) + ": No message.")
                    time.sleep(1)
                    return
                msg_list = []
                pm_list = []
                sess_list = []
                group_list = []
                notify_list = []
                for msg in ret['result']:
                    ret_type = msg['poll_type']
                    if ret_type == 'message':
                        pm_list.append(PmMsg(msg))
                    elif ret_type == 'group_message':
                        group_list.append(GroupMsg(msg))
                    elif ret_type == 'sess_message':
                        sess_list.append(SessMsg(msg))
                    elif ret_type == 'input_notify':
                        notify_list.append(InputNotify(msg))
                    elif ret_code == 'kick_message':
                        notify_list.append(KickMessage(msg))
                    else:
                        logging.warning("unknown message type: " + str(ret_type) + "details:    " + str(msg))

                group_list.sort(key=lambda x: x.msg_id)
                msg_list += pm_list + sess_list + group_list + notify_list
                if not msg_list:
                    return
                return msg_list

            elif ret_code == 100006:
                logging.warning("POST data error")
                return

            elif ret_code == 116:
                self.ptwebqq = ret['p']
                logging.info("ptwebqq updated.")
                return

            else:
                logging.warning("unknown retcode " + str(ret_code))
                return

        except ValueError as e:
            logging.warning("Check error occured: " + str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)

        except BaseException as e:
            logging.warning("Unknown check error occured, retrying. Error: " + str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)

    def uin_to_account(self, tuin):
        """
        将uin转换成用户QQ号
        :param tuin:
        :return:str 用户昵称
        """
        uin_str = str(tuin)
        try:
            logging.info("Requesting the account by uin:    " + str(tuin))
            info = json.loads(self.req.Get(
                    'http://s.web2.qq.com/api/get_friend_uin2?tuin={0}&type=1&vfwebqq={1}&t={2}'.format(uin_str,
                                                                                                        self.vfwebqq,
                                                                                                        self.req.getTimeStamp()),
                    self.default_config.conf.get("global", "connect_referer")))
            logging.debug("uin_to_account html:    " + str(info))
            if info['retcode'] != 0:
                raise TypeError('uin_to_account retcode error')
            info = info['result']['account']
            return info

        except:
            logging.exception("uin_to_account")
            return None

    # 获取自己的信息
    def get_self_info2(self):
        """
        获取自己的信息
        get_self_info2
        {"retcode":0,"result":{"birthday":{"month":1,"year":1989,"day":30},"face":555,"phone":"","occupation":"","allow":1,"college":"","uin":2609717081,"blood":0,"constel":1,"lnick":"","vfwebqq":"68b5ff5e862ac589de4fc69ee58f3a5a9709180367cba3122a7d5194cfd43781ada3ac814868b474","homepage":"","vip_info":0,"city":"青岛","country":"中国","personal":"","shengxiao":5,"nick":"要有光","email":"","province":"山东","account":2609717081,"gender":"male","mobile":""}}
        :return:dict
        """
        if not self.__self_info:
            url = "http://s.web2.qq.com/api/get_self_info2"
            response = self.req.Get(url)
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                return {}
            self.__self_info = rsp_json["result"]
        return self.__self_info

    # 获取好友详情信息
    def get_friend_info2(self, tuin):
        """
        获取好友详情信息
        get_friend_info2
        {"retcode":0,"result":{"face":0,"birthday":{"month":1,"year":1989,"day":30},"occupation":"","phone":"","allow":1,"college":"","uin":3964575484,"constel":1,"blood":3,"homepage":"http://blog.lovewinne.com","stat":20,"vip_info":0,"country":"中国","city":"","personal":"","nick":" 信","shengxiao":5,"email":"*****@*****.**","province":"山东","gender":"male","mobile":"158********"}}
        :return:dict
        """
        uin_str = str(tuin)
        try:
            logging.info("Requesting the account info by uin:    " + str(tuin))
            info = json.loads(self.req.Get(
                    'http://s.web2.qq.com/api/get_friend_info2?tuin={0}&vfwebqq={1}&clientid={2}&psessionid={3}&t={4}'
                        .format(
                            uin_str,
                            self.vfwebqq,
                            self.client_id,
                            self.psessionid,
                            self.req.getTimeStamp()),
            ))
            logging.debug("get_friend_info2 html:    " + str(info))
            if info['retcode'] != 0:
                raise TypeError('get_friend_info2 result error')
            info = info['result']
            return info

        except:
            logging.exception("get_friend_info2")
            return None

    # 获取好友详情信息
    def get_friend_info(self, tuin):
        uin_str = str(tuin)
        if uin_str not in self.friend_list:
            info = self.get_friend_info2(tuin) or {'nick': '群用户'}
            info['account'] = self.uin_to_account(tuin)
            self.friend_list[uin_str] = info

        try:
            return '【{0}({1})】'.format(self.friend_list[uin_str]['nick'], self.friend_list[uin_str]['account'])
        except:
            logging.warning("get_friend_info return fail.")
            logging.debug("now uin list:    " + str(self.friend_list[uin_str]))

    # 获取好友的签名信息
    def get_single_long_nick2(self, tuin):
        """
        获取好友的签名信息
        get_single_long_nick2
        {"retcode":0,"result":[{"uin":3964575484,"lnick":"幸福,知道自己在哪里,知道下一个目标在哪里,心不累~"}]}
        :return:dict
        """
        url = "http://s.web2.qq.com/api/get_single_long_nick2?tuin=%s&vfwebqq=%s&t=%s" % (
            tuin, self.vfwebqq, int(time.time() * 100))
        response = self.req.Get(url)
        rsp_json = json.loads(response)
        if rsp_json["retcode"] != 0:
            return {}
        return rsp_json["result"]

    #获取群列表信息
    '''
    def get_group_name_list(self, vfwebqq):   
        try:   
            url="http://s.web2.qq.com/api/get_group_name_list_mask2"   
            postdata="r=%7B%22vfwebqq%22%3A%22{$vfwebqq}%22%7D"   
            postdatapostdata=postdata.replace("{$vfwebqq}",vfwebqq)   
            ret=self.Post(url,postdata,QQRobot.HOST[1],QQRobot.REFERER[1],QQRobot.ORIGIN[1])   
            print 'Step5: GetGroupList'   
            retjson=json.loads(ret)   
            retjsonretjson=retjson["result"]   
            self.grouplist=retjson   
            for group in self.grouplist['gnamelist']:   
                print group["code"],group["name"]   
                   
        except Exception,e:   
            print "GetGroupNameList error"+str(e)
    '''

    # 获取群信息(对于易变的信息,请在外层做缓存处理)
    def get_group_info_ext2(self, gcode):
        """
        获取群信息
        get_group_info_ext2
        {"retcode":0,"result":{"stats":[],"minfo":[{"nick":" 信","province":"山东","gender":"male","uin":3964575484,"country":"中国","city":""},{"nick":"崔震","province":"","gender":"unknown","uin":2081397472,"country":"","city":""},{"nick":"云端的猫","province":"山东","gender":"male","uin":3123065696,"country":"中国","city":"青岛"},{"nick":"要有光","province":"山东","gender":"male","uin":2609717081,"country":"中国","city":"青岛"},{"nick":"小莎机器人","province":"广东","gender":"female","uin":495456232,"country":"中国","city":"深圳"}],"ginfo":{"face":0,"memo":"http://hujj009.ys168.com\r\n0086+区(没0)+电话\r\n0086+手机\r\nhttp://john123951.xinwen365.net/qq/index.htm","class":395,"fingermemo":"","code":3943922314,"createtime":1079268574,"flag":16778241,"level":0,"name":"ぁQQぁ","gid":3931577475,"owner":3964575484,"members":[{"muin":3964575484,"mflag":192},{"muin":2081397472,"mflag":65},{"muin":3123065696,"mflag":128},{"muin":2609717081,"mflag":0},{"muin":495456232,"mflag":0}],"option":2},"cards":[{"muin":3964575484,"card":"●s.Εx2(22222)□"},{"muin":495456232,"card":"小莎机器人"}],"vipinfo":[{"vip_level":0,"u":3964575484,"is_vip":0},{"vip_level":0,"u":2081397472,"is_vip":0},{"vip_level":0,"u":3123065696,"is_vip":0},{"vip_level":0,"u":2609717081,"is_vip":0},{"vip_level":0,"u":495456232,"is_vip":0}]}}
        :return:dict
        """
        if gcode == 0:
            return {}
        try:
            url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode=%s&vfwebqq=%s&t=%s" % (
                gcode, self.vfwebqq, int(time.time() * 100))
            response = self.req.Get(url)
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                return {}
            return rsp_json["result"]
        except Exception as ex:
            logging.warning("get_group_info_ext2. Error: " + str(ex))
            return {}

    # 发送群消息
    def send_qun_msg(self, guin, reply_content, msg_id, fail_times=0):
        fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t"))
        rsp = ""
        try:
            req_url = "http://d1.web2.qq.com/channel/send_qun_msg2"
            data = (
                ('r',
                 '{{"group_uin":{0}, "face":564,"content":"[\\"{4}\\",[\\"font\\",{{\\"name\\":\\"Arial\\",\\"size\\":\\"10\\",\\"style\\":[0,0,0],\\"color\\":\\"000000\\"}}]]","clientid":{1},"msg_id":{2},"psessionid":"{3}"}}'.format(
                         guin, self.client_id, msg_id, self.psessionid, fix_content)),
                ('clientid', self.client_id),
                ('psessionid', self.psessionid)
            )
            rsp = self.req.Post(req_url, data, self.default_config.conf.get("global", "connect_referer"))
            rsp_json = json.loads(rsp)
            if 'retcode' in rsp_json and rsp_json['retcode'] != 0:
                raise ValueError("reply group chat error" + str(rsp_json['retcode']))
            logging.info("send_qun_msg: Reply successfully.")
            logging.debug("send_qun_msg: Reply response: " + str(rsp))
            return rsp_json
        except:
            logging.exception("send_qun_msg exception")
            if fail_times < 5:
                logging.warning("send_qun_msg: Response Error.Wait for 2s and Retrying." + str(fail_times))
                logging.debug(rsp)
                time.sleep(2)
                self.send_qun_msg(guin, reply_content, msg_id, fail_times + 1)
            else:
                logging.warning("send_qun_msg: Response Error over 5 times.Exit.reply content:" + str(reply_content))
                return False

    # 发送私密消息
    def send_buddy_msg(self, tuin, reply_content, msg_id, fail_times=0):
        fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t"))
        rsp = ""
        try:
            req_url = "http://d1.web2.qq.com/channel/send_buddy_msg2"
            data = (
                ('r',
                 '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}"}}'.format(
                         tuin, self.client_id, msg_id, self.psessionid, fix_content)),
                ('clientid', self.client_id),
                ('psessionid', self.psessionid)
            )
            rsp = self.req.Post(req_url, data, self.default_config.conf.get("global", "connect_referer"))
            rsp_json = json.loads(rsp)
            if 'errCode' in rsp_json and rsp_json['errCode'] != 0:
                raise ValueError("reply pmchat error" + str(rsp_json['retcode']))
            logging.info("Reply successfully.")
            logging.debug("Reply response: " + str(rsp))
            return rsp_json
        except:
            if fail_times < 5:
                logging.warning("Response Error.Wait for 2s and Retrying." + str(fail_times))
                logging.debug(rsp)
                time.sleep(2)
                self.send_buddy_msg(tuin, reply_content, msg_id, fail_times + 1)
            else:
                logging.warning("Response Error over 5 times.Exit.reply content:" + str(reply_content))
                return False

    # 发送临时消息
    def send_sess_msg2(self, tuin, reply_content, msg_id, group_sig, service_type=0, fail_times=0):
        fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t"))
        rsp = ""
        try:
            req_url = "http://d1.web2.qq.com/channel/send_sess_msg2"
            data = (
                ('r',
                 '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}", "group_sig":"{5}", "service_type":{6}}}'.format(
                         tuin,
                         self.client_id,
                         msg_id,
                         self.psessionid,
                         fix_content,
                         group_sig,
                         service_type)
                 ),
                ('clientid', self.client_id),
                ('psessionid', self.psessionid),
                ('group_sig', group_sig),
                ('service_type', service_type)
            )
            rsp = self.req.Post(req_url, data, self.default_config.conf.get("global", "connect_referer"))
            rsp_json = json.loads(rsp)
            if 'retcode' in rsp_json and rsp_json['retcode'] != 0:
                raise ValueError("reply sess chat error" + str(rsp_json['retcode']))
            logging.info("Reply successfully.")
            logging.debug("Reply response: " + str(rsp))
            return rsp_json
        except:
            if fail_times < 5:
                logging.warning("Response Error.Wait for 2s and Retrying." + str(fail_times))
                logging.debug(rsp)
                time.sleep(2)
                self.send_sess_msg2(tuin, reply_content, msg_id, group_sig, service_type, fail_times + 1)
            else:
                logging.warning("Response Error over 5 times.Exit.reply content:" + str(reply_content))
                return False

    # 主动发送临时消息
    def send_sess_msg2_fromGroup(self, guin, tuin, reply_content, msg_id, service_type=0, fail_times=0):
        group_sig = self.__getGroupSig(guin, tuin, service_type)
        fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t"))
        rsp = ""
        try:
            req_url = "http://d1.web2.qq.com/channel/send_sess_msg2"
            data = (
                ('r',
                 '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}", "group_sig":"{5}", "service_type":{6}}}'.format(
                         tuin,
                         self.client_id,
                         msg_id,
                         self.psessionid,
                         fix_content,
                         group_sig,
                         service_type)
                 ),
                ('clientid', self.client_id),
                ('psessionid', self.psessionid),
                ('group_sig', group_sig),
                ('service_type', service_type)
            )
            rsp = self.req.Post(req_url, data, self.default_config.conf.get("global", "connect_referer"))
            rsp_json = json.loads(rsp)
            if 'retcode' in rsp_json and rsp_json['retcode'] != 0:
                raise ValueError("reply sess chat error" + str(rsp_json['retcode']))
            logging.info("send_sess_msg2_fromGroup: Reply successfully.")
            logging.debug("send_sess_msg2_fromGroup: Reply response: " + str(rsp))
            return rsp_json
        except:
            if fail_times < 5:
                logging.warning("send_sess_msg2_fromGroup: Response Error.Wait for 2s and Retrying." + str(fail_times))
                logging.debug(rsp)
                time.sleep(2)
                self.send_sess_msg2_fromGroup(guin, tuin, reply_content, msg_id, service_type, fail_times + 1)
            else:
                logging.warning(
                    "send_sess_msg2_fromGroup: Response Error over 5 times.Exit.reply content:" + str(reply_content))
                return False
예제 #34
0
class Course:
    def __init__(self):
        self.hosturl = 'http://sep.ucas.ac.cn'
        self.loginurl = 'http://sep.ucas.ac.cn/slogin'
        self.req = HttpClient()
        config = configparser.ConfigParser()
        config.read('./config.ini')
        self.usrname = config.get('USER', 'usrname')
        self.passwd = config.get('USER', 'passwd')
        self.pwd = config.get('USER', 'savedir')
        if not (self.usrname and self.passwd and self.pwd):
            print('Please setup your account in \'config.ini\'')
            pause()
            sys.exit()

    def login(self):

        self.req.Get(self.hosturl)
        postData = {'userName': self.usrname, 'pwd': self.passwd, 'sb': 'sb'}
        html = self.req.Post(self.loginurl, postData)
        logging.info('login success')

        course_index = 'http://sep.ucas.ac.cn/portal/site/16'
        html = self.req.Get(course_index)

        Identity = get_revalue(html, r'Identity=(.+?)"', 'get Identity error',
                               1)
        logging.debug("Identity=" + Identity)

        html = self.req.Get(
            "http://course.ucas.ac.cn/portal/plogin?Identity={0}".format(
                Identity))
        session = get_revalue(html, r'session=(.+?)&', 'get session error', 1)
        _mid = get_revalue(html, r'_mid=(.+?)"', 'get mid error', 1)
        guid = get_revalue(html, r'guid=(.+?)"', 'get guid error', 1)
        logging.debug("session=" + session)
        logging.debug("_mid=" + _mid)
        logging.debug("guid=" + guid)

        html = self.req.Get(
            "http://course.ucas.ac.cn/portal?sakai.session={0}&_mid={1}".
            format(session, _mid))
        course_urls = re.findall(r'http://course.ucas.ac.cn/portal/site/\d+',
                                 html.decode('utf-8'))
        #return course_urls
        for test_url in course_urls:
            self.get_resource(test_url)

    def get_resource(self, url):
        import html.parser
        import os

        html_parser = html.parser.HTMLParser()
        html = self.req.Get(url)
        res_url = get_revalue(html,
                              r'class="icon-sakai-resources" href="(.+?)"',
                              'get resource error', 1)
        logging.debug("res_url= " + res_url)
        html = self.req.Get(res_url)
        wtf_url = get_revalue(
            html, r'http://course.ucas.ac.cn/portal/tool-reset/(.+?)/',
            'what the fuxk error', 1)
        logging.debug("wtf_url= " + wtf_url)
        html = self.req.Get(
            "http://course.ucas.ac.cn/portal/tool-reset/{0}/?panel=Main".
            format(wtf_url))
        html = unescape(html.decode('utf-8'))
        #logging.debug(html)

        title = get_revalue(html, r'<img src =.*?/>([\s\S]+?)</h3>',
                            'get title error', 1).strip().replace(' ', '_')

        logging.debug(title)

        folders = [
            x for x in re.findall(r'onclick="javascript[\s\S]+?submit', html)
            if 'doNavigate' in x
        ]
        folders = [re.findall(r'group/\d+/[\s\S]+?/', x) for x in folders][1:]
        folders = ['/' + x[0] for x in folders]
        #print folders

        res = re.findall(
            r'http://course.ucas.ac.cn/access/content/group/[^"]+', html)
        res = [x[:-1] if x.endswith(";") else x for x in res]
        res = list(set(res))
        # logging.debug(html)
        self.download(title, res)

        for folder in folders:
            postData = {
                'source': 0,
                'collectionId': folder,
                'criteria': 'title',
                'sakai_action': 'doNavigate'
            }
            content = self.req.Post(
                "http://course.ucas.ac.cn/portal/tool/{0}/?panel=Main".format(
                    wtf_url), postData)
            tmp = re.findall(
                r'http://course.ucas.ac.cn/access/content/group/[^"]+',
                content.decode('utf-8'))
            tmp = list(set(tmp))
            name = get_revalue(folder, r'([^/]+?)/$', 'folder error',
                               1).replace(' ', '_')
            #print name
            self.download(os.path.join(title, name), tmp)

        logging.debug(str(res))

    def download(self, title, res):
        import os
        print(('Linking' + '  ' + title))
        logging.info('linking... ' + title)
        if not os.path.exists(self.pwd):
            os.makedirs(self.pwd)
        _pwd = os.path.join(self.pwd, title)
        if not os.path.exists(_pwd):
            os.makedirs(_pwd)
        for f in res:
            name = get_revalue(f, r'([^/]+?)$', 'get name error',
                               1).replace(' ', '_')

            if name.__contains__('copyrightAlertWindow'):
                f = re.findall(
                    "http://course.ucas.ac.cn/access/content/group/[^']+",
                    f)[0]
                name = get_revalue(f, r'([^/]+?)$', 'get name error',
                                   1).replace(' ', '_')
                content = self.req.Get(f)
                #logging.debug(content)
                f = get_revalue(content, r'a href="(.+?)"',
                                'get wotongyi error', 1)
                #print  title + ' has contents which is protected by COPYRIGHT, failed to download'

            __pwd = os.path.join(_pwd, name)
            if (not force_update_flag) and check_existed(__pwd):
                print(('skip' + '  ' + name + ' already exists, skip'))
                logging.info(name + ' already exists, skip')
                continue

            #print 'downloading ' + name
            logging.info('downloading ' + name)
            self.req.Download(f, __pwd)
예제 #35
0
    def __init__(self):
        self.client = HttpClient.HttpClient()
        self.dao = Dao.Mysql()

        pass
예제 #36
0
class QQ:
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        # cache
        self.friend_list = {}
        self.__groupSig_list = {}
        self.__self_info = {}

        self.client_id = 53999199
        self.ptwebqq = ""
        self.psessionid = ""
        self.appid = 0
        self.vfwebqq = ""
        self.qrcode_path = self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
        self.username = ""
        self.account = 0

        init_logging()

    def __hash_digest(self, uin, ptwebqq):
        """
        计算hash,貌似TX的这个算法会经常变化,暂时不使用
        get_user_friends2, get_group_name_list_mask2 会依赖此数据
        提取自http://pub.idqqimg.com/smartqq/js/mq.js
        :param uin:
        :param ptwebqq:
        :return:
        """
        N = [0, 0, 0, 0]
        print (N[0])
        for t in range(len(ptwebqq)):
            N[t % 4] ^= ord(ptwebqq[t])
        U = ["EC", "OK"]
        V = [0, 0, 0, 0]
        V[0] = int(uin) >> 24 & 255 ^ ord(U[0][0])
        V[1] = int(uin) >> 16 & 255 ^ ord(U[0][1])
        V[2] = int(uin) >> 8 & 255 ^ ord(U[1][0])
        V[3] = int(uin) & 255 ^ ord(U[1][1])
        U = [0, 0, 0, 0, 0, 0, 0, 0]
        for T in range(8):
            if T % 2 == 0:
                U[T] = N[T >> 1]
            else:
                U[T] = V[T >> 1]
        N = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]
        V = ""
        for T in range(len(U)):
            V += N[U[T] >> 4 & 15]
            V += N[U[T] & 15]
        return V

    def __getGroupSig(self, guin, tuin, service_type=0):
        key = "%s --> %s" % (guin, tuin)
        if key not in self.__groupSig_list:
            url = (
                "http://d1.web2.qq.com/channel/get_c2cmsg_sig2?id=%s&to_uin=%s&service_type=%s&clientid=%s&psessionid=%s&t=%d"
                % (guin, tuin, service_type, self.client_id, self.psessionid, int(time.time() * 100))
            )
            response = self.req.Get(url)
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                return ""
            sig = rsp_json["result"]["value"]
            self.__groupSig_list[key] = sig
        if key in self.__groupSig_list:
            return self.__groupSig_list[key]
        return ""

    def login_by_qrcode(self):
        logging.info("Requesting the login pages...")
        initurl_html = self.req.Get(self.default_config.conf.get("global", "smartqq_url"))
        logging.debug("login page html: " + str(initurl_html))
        initurl = get_revalue(initurl_html, r'\.src = "(.+?)"', "Get Login Url Error.", 1)
        html = self.req.Get(initurl + "0")

        appid = get_revalue(html, r'<input type="hidden" name="aid" value="(\d+)" />', "Get AppId Error", 1)
        sign = get_revalue(html, r'g_login_sig=encodeURIComponent\("(.*?)"\)', "Get Login Sign Error", 0)
        js_ver = get_revalue(html, r'g_pt_version=encodeURIComponent\("(\d+)"\)', "Get g_pt_version Error", 1)
        mibao_css = get_revalue(html, r'g_mibao_css=encodeURIComponent\("(.+?)"\)', "Get g_mibao_css Error", 1)

        star_time = date_to_millis(datetime.datetime.utcnow())

        error_times = 0
        ret = []
        while True:
            error_times += 1
            print "download QR code image..."
            self.req.Download(
                "https://ssl.ptlogin2.qq.com/ptqrshow?appid={0}&e=0&l=L&s=8&d=72&v=4".format(appid), self.qrcode_path
            )
            logging.info("Please scan the downloaded QRCode")
            thread.start_new_thread(display_QRCode, (self.qrcode_path,))

            while True:
                html = self.req.Get(
                    "https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid={0}&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-{1}&mibao_css={2}&t=undefined&g=1&js_type=0&js_ver={3}&login_sig={4}".format(
                        appid, date_to_millis(datetime.datetime.utcnow()) - star_time, mibao_css, js_ver, sign
                    ),
                    initurl,
                )
                logging.debug("QRCode check html:   " + str(html))
                ret = html.split("'")
                if ret[1] in ("0", "65"):  # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中
                    break
            if ret[1] == "0" or error_times > 10:
                break

        if ret[1] != "0":
            return
        logging.info("QRCode scaned, now logging in.")

        # 删除QRCode文件
        if os.path.exists(self.qrcode_path):
            os.remove(self.qrcode_path)

        # 记录登陆账号的昵称
        self.username = ret[11]

        html = self.req.Get(ret[5])
        logging.debug("mibao_res html:  " + str(html))

        # url = get_revalue(html, r' src="(.+?)"', 'Get mibao_res Url Error.', 0)
        # if url != '':
        #     html = self.req.Get(url.replace('&amp;', '&'))
        #     url = get_revalue(html, r'location\.href="(.+?)"', 'Get Redirect Url Error', 1)
        #     self.req.Get(url)

        self.ptwebqq = self.req.getCookie("ptwebqq")

        # 测试用请求
        self.req.Get("http://w.qq.com/proxy.html?login2qq=1&webqq_type=10")
        self.req.Get("http://web2.qq.com/web2_cookie_proxy.html")
        self.req.Get("http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")
        self.req.Get(
            "http://s.web2.qq.com/api/getvfwebqq?ptwebqq={0}&clientid={1}&psessionid={2}&t={3}".format(
                self.ptwebqq, self.client_id, self.psessionid, date_to_millis(datetime.datetime.utcnow()) - star_time
            )
        )
        self.req.Get("http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2")

        login_error = 1
        ret = {}
        while login_error > 0:
            try:
                html = self.req.Post(
                    "http://d1.web2.qq.com/channel/login2",
                    {
                        "r": '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'.format(
                            self.ptwebqq, self.client_id, self.psessionid
                        )
                    },
                    self.default_config.conf.get("global", "connect_referer"),
                )
                logging.debug("login html:  " + str(html))
                ret = json.loads(html)
                login_error = 0
            except:
                login_error += 1
                logging.info("login fail, retrying...")

        if ret["retcode"] != 0:
            logging.debug(str(ret))
            logging.warning("return code:" + str(ret["retcode"]))
            return

        self.vfwebqq = ret["result"]["vfwebqq"]
        self.psessionid = ret["result"]["psessionid"]
        self.account = ret["result"]["uin"]

        logging.info("QQ:{0} login successfully, Username:{1}".format(self.account, self.username))

    def relogin(self, error_times=0):
        if error_times >= 10:
            return False
        try:
            html = self.req.Post(
                "http://d1.web2.qq.com/channel/login2",
                {
                    "r": '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","key":"","status":"online"}}'.format(
                        self.ptwebqq, self.client_id, self.psessionid
                    )
                },
                self.default_config.conf.get("global", "connect_referer"),
            )
            logging.debug("relogin html:  " + str(html))
            ret = json.loads(html)
            self.vfwebqq = ret["result"]["vfwebqq"]
            self.psessionid = ret["result"]["psessionid"]
            return True
        except:
            logging.info("login fail, retryng..." + str(error_times))
            return self.relogin(error_times + 1)

    def check_msg(self, error_times=0):
        if error_times >= 5:
            if not self.relogin():
                raise IOError("Account offline.")
            else:
                error_times = 0

        # 调用后进入单次轮询,等待服务器发回状态。
        html = self.req.Post(
            "http://d1.web2.qq.com/channel/poll2",
            {
                "r": '{{"ptwebqq":"{1}","clientid":{2},"psessionid":"{0}","key":""}}'.format(
                    self.psessionid, self.ptwebqq, self.client_id
                )
            },
            self.default_config.conf.get("global", "connect_referer"),
        )
        logging.debug("check_msg html:  " + str(html))
        try:
            if html == "":
                return self.check_msg()
            ret = json.loads(html)

            ret_code = ret["retcode"]

            # if ret_code in (0,):
            #     logging.info("received retcode: " + str(ret_code) + ": No message.")
            #     time.sleep(1)
            #     return

            if ret_code in (103,):
                logging.warning("received retcode: " + str(ret_code) + ": Check error.retrying.." + str(error_times))
                time.sleep(1)
                return self.check_msg(error_times + 1)

            if ret_code in (121,):
                logging.warning("received retcode: " + str(ret_code))
                return self.check_msg(5)

            elif ret_code == 0:
                if len(ret["result"]) == 0:
                    logging.info("received retcode: " + str(ret_code) + ": No message.")
                    time.sleep(1)
                    return
                msg_list = []
                pm_list = []
                sess_list = []
                group_list = []
                notify_list = []
                for msg in ret["result"]:
                    ret_type = msg["poll_type"]
                    if ret_type == "message":
                        pm_list.append(PmMsg(msg))
                    elif ret_type == "group_message":
                        group_list.append(GroupMsg(msg))
                    elif ret_type == "sess_message":
                        sess_list.append(SessMsg(msg))
                    elif ret_type == "input_notify":
                        notify_list.append(InputNotify(msg))
                    elif ret_code == "kick_message":
                        notify_list.append(KickMessage(msg))
                    else:
                        logging.warning("unknown message type: " + str(ret_type) + "details:    " + str(msg))

                group_list.sort(key=lambda x: x.msg_id)
                msg_list += pm_list + sess_list + group_list + notify_list
                if not msg_list:
                    return
                return msg_list

            elif ret_code == 100006:
                logging.warning("POST data error")
                return

            elif ret_code == 116:
                self.ptwebqq = ret["p"]
                logging.info("ptwebqq updated.")
                return

            else:
                logging.warning("unknown retcode " + str(ret_code))
                return

        except ValueError, e:
            logging.warning("Check error occured: " + str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)

        except BaseException, e:
            logging.warning("Unknown check error occured, retrying. Error: " + str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)
예제 #37
0
class QQ:
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        self.msg_id = int(random.randint(1111, 8888) * 10000)
        self.client_id = int(random.uniform(111111, 888888))
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get("global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0

    @catch
    def __hash_digest(self, uin, ptwebqq):
        """
        计算hash,貌似TX的这个算法会经常变化,暂时不使用
        get_user_friends2, get_group_name_list_mask2 会依赖此数据
        提取自http://pub.idqqimg.com/smartqq/js/mq.js
        :param uin:
        :param ptwebqq:
        :return:
        """
        N = [0, 0, 0, 0]
        print(N[0])
        for t in range(len(ptwebqq)):
            N[t % 4] ^= ord(ptwebqq[t])
        U = ["EC", "OK"]
        V = [0, 0, 0, 0]
        V[0] = int(uin) >> 24 & 255 ^ ord(U[0][0])
        V[1] = int(uin) >> 16 & 255 ^ ord(U[0][1])
        V[2] = int(uin) >> 8 & 255 ^ ord(U[1][0])
        V[3] = int(uin) & 255 ^ ord(U[1][1])
        U = [0, 0, 0, 0, 0, 0, 0, 0]
        for T in range(8):
            if T % 2 == 0:
                U[T] = N[T >> 1]
            else:
                U[T] = V[T >> 1]
        N = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]
        V = ""
        for T in range(len(U)):
            V += N[U[T] >> 4 & 15]
            V += N[U[T] & 15]
        return V

    @cache
    @catch
    def getGroupSig(self, guin, tuin, service_type=0):
        url = "http://d.web2.qq.com/channel/get_c2cmsg_sig2?id=%s&to_uin=%s&service_type=%s&clientid=%s&psessionid=%s&t=%d" % (
            guin, tuin, service_type, self.client_id, self.psessionid, int(time.time() * 100))
        response = self.req.Get(url)
        rsp_json = json.loads(response)
        if rsp_json["retcode"] != 0:
            return ""
        sig = rsp_json["result"]["value"]
        return sig

    def login_by_qrcode(self):
        def get_revalue(html, rex, er, ex):
            v = re.search(rex, html)

            if v is None:

                if ex:
                    logging.error(er)
                    raise TypeError(er)
                else:
                    logging.warning(er)
                return ''

            return v.group(1)

        def date_to_millis(d):
            return int(time.mktime(d.timetuple())) * 1000

        logging.info("Requesting the login pages...")
        initurl_html = self.req.Get(self.default_config.conf.get("global", "smartqq_url"))
        logging.debug("login page html: " + str(initurl_html))
        initurl = get_revalue(initurl_html, r'\.src = "(.+?)"', "Get Login Url Error.", 1)
        html = self.req.Get(initurl + '0')

        appid = get_revalue(html, r'<input type="hidden" name="aid" value="(\d+)" />', 'Get AppId Error', 1)
        sign = get_revalue(html, r'g_login_sig=encodeURIComponent\("(.*?)"\)', 'Get Login Sign Error', 0)
        js_ver = get_revalue(html, r'g_pt_version=encodeURIComponent\("(\d+)"\)', 'Get g_pt_version Error', 1)
        mibao_css = get_revalue(html, r'g_mibao_css=encodeURIComponent\("(.+?)"\)', 'Get g_mibao_css Error', 1)
        star_time = date_to_millis(datetime.datetime.utcnow())

        error_times = 0
        ret = []
        while True:
            error_times += 1
            print ('download QR code image...')
            self.req.Download('https://ssl.ptlogin2.qq.com/ptqrshow?appid={0}&e=0&l=L&s=8&d=72&v=4'.format(appid), self.qrcode_path)
            logging.info("Please scan the downloaded QRCode")

            while True:
                html = self.req.Get(
                    'https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid={0}&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-{1}&mibao_css={2}&t=undefined&g=1&js_type=0&js_ver={3}&login_sig={4}'.format(
                        appid, date_to_millis(datetime.datetime.utcnow()) - star_time, mibao_css, js_ver, sign),
                    initurl)
                logging.debug(u"QRCode check html:   " + str(html))
                ret = html.split("'")
                if ret[1] in ('0', '65'):  # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中
                    break
            if ret[1] == '0':
                break
            if error_times > 10:
                time.sleep(120)  # 继续重新下载验证码,设置等待时间

        if ret[1] != '0':
            return
        logging.info("QRCode scaned, now logging in.")

        # 删除QRCode文件
        if os.path.exists(self.qrcode_path):
            os.remove(self.qrcode_path)

        # 记录登陆账号的昵称
        self.username = ret[11]

        html = self.req.Get(ret[5])
        logging.debug("mibao_res html:  " + str(html))
        url = get_revalue(html, r' src="(.+?)"', 'Get mibao_res Url Error.', 0)
        if url != '':
            html = self.req.Get(url.replace('&amp;', '&'))
            url = get_revalue(html, r'location\.href="(.+?)"', 'Get Redirect Url Error', 1)
            self.req.Get(url)

        self.ptwebqq = self.req.getCookie('ptwebqq')

        login_error = 1
        ret = {}
        while login_error > 0:
            try:
                html = self.req.Post('http://d.web2.qq.com/channel/login2', {
                    'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'.format(self.ptwebqq,
                                                                                                          self.client_id,
                                                                                                          self.psessionid)
                }, self.default_config.conf.get("global", "connect_referer"))
                logging.debug("login html:  " + str(html))
                ret = json.loads(html)
                login_error = 0
            except:
                login_error += 1
                logging.info("login fail, retrying...")

        if ret['retcode'] != 0:
            logging.debug(str(ret))
            logging.warning("return code:" + str(ret['retcode']))
            return

        self.vfwebqq = ret['result']['vfwebqq']
        self.psessionid = ret['result']['psessionid']
        self.account = ret['result']['uin']

        # 修改状态
        self.change_status2(self.default_config.conf.get('global', 'status'))

        logging.info(u"QQ:{0} login successfully, Username:{1}".format(self.account, self.username))

    @retry(10)
    def relogin(self):
        html = self.req.Post('http://d.web2.qq.com/channel/login2', {
            'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","key":"","status":"online"}}'.format(
                self.ptwebqq,
                self.client_id,
                self.psessionid)
        }, self.default_config.conf.get("global", "connect_referer"))
        logging.debug("relogin html:  " + str(html))
        ret = json.loads(html)
        self.vfwebqq = ret['result']['vfwebqq']
        self.psessionid = ret['result']['psessionid']
        return True

    @retry(5)
    def check_msg(self):

        # 调用后进入单次轮询,等待服务器发回状态。
        html = self.req.Post('http://d.web2.qq.com/channel/poll2', {
            'r': '{{"ptwebqq":"{1}","clientid":{2},"psessionid":"{0}","key":""}}'.format(self.psessionid, self.ptwebqq, self.client_id)
        }, self.default_config.conf.get("global", "connect_referer"))
        logging.debug("check_msg html:  " + str(html))

        if html == "":
            return self.check_msg()

        ret = json.loads(html)
        ret_code = ret['retcode']

        if ret_code in (102,):
            logging.info("received retcode: " + str(ret_code) + ": No message.")
            time.sleep(1.5)
            return None

        if ret_code in (103, 121):
            logging.warning("received retcode: " + str(ret_code))
            time.sleep(1)
            raise Exception(str(ret_code))

        elif ret_code == 0:
            msg_list = []
            pm_list = []
            sess_list = []
            group_list = []
            notify_list = []
            for msg in ret['result']:
                ret_type = msg['poll_type']

                if ret_type == 'message':
                    pm_list.append(PmMsg(msg))
                elif ret_type == 'group_message':
                    group_list.append(GroupMsg(msg))
                elif ret_type == 'sess_message':
                    sess_list.append(SessMsg(msg))
                elif ret_type == 'input_notify':
                    notify_list.append(InputNotify(msg))
                elif ret_type == 'sys_g_msg':
                    if msg['value'] and msg['value']['type'] == 'group_request_join':
                        notify_list.append(GroupAddMessage(msg))
                elif ret_type == 'kick_message':
                    notify_list.append(KickMessage(msg))
                else:
                    logging.warning("unknown message type: " + str(ret_type) + "details:    " + str(msg))

            group_list.sort(key=lambda x: x.seq)
            msg_list += pm_list + sess_list + group_list + notify_list
            if not msg_list:
                return None
            return msg_list

        elif ret_code == 100006:
            logging.warning("POST data error")
            return

        elif ret_code == 116:
            self.ptwebqq = ret['p']
            logging.info("ptwebqq updated.")
            return

        else:
            logging.warning("unknown retcode " + str(ret_code))
            return

    # 查询QQ号
    @cache
    def uin_to_account(self, tuin):
        """
        将uin转换成用户QQ号
        :param tuin:
        :return:str 用户QQ号
        """
        uin_str = str(tuin)
        logging.info("Requesting the account by uin:    " + str(tuin))
        info = json.loads(self.req.Get('http://s.web2.qq.com/api/get_friend_uin2?tuin={0}&type=1&vfwebqq={1}'.format(uin_str, self.vfwebqq),
                                       self.default_config.conf.get("global", "connect_referer")))
        logging.debug("uin_request html:    " + str(info))
        if info['retcode'] != 0:
            raise TypeError('uin to account result error')
        info = info['result']
        return info['account']

    # 获取自己的信息
    @cache
    @catch
    def get_self_info2(self):
        """
        获取自己的信息
        get_self_info2
        {"retcode":0,"result":{"birthday":{"month":1,"year":1989,"day":30},"face":555,"phone":"","occupation":"","allow":1,"college":"","uin":2609717081,"blood":0,"constel":1,"lnick":"","vfwebqq":"68b5ff5e862ac589de4fc69ee58f3a5a9709180367cba3122a7d5194cfd43781ada3ac814868b474","homepage":"","vip_info":0,"city":"青岛","country":"中国","personal":"","shengxiao":5,"nick":"要有光","email":"","province":"山东","account":2609717081,"gender":"male","mobile":""}}
        :return:dict
        """
        url = "http://s.web2.qq.com/api/get_self_info2"
        response = self.req.Get(url)
        rsp_json = json.loads(response)
        if rsp_json["retcode"] != 0:
            return {}
        return rsp_json["result"]

    # 获取好友详情信息
    @catch
    def get_friend_info2(self, tuin):
        """
        获取好友详情信息
        get_friend_info2
        {"retcode":0,"result":{"face":0,"birthday":{"month":1,"year":1989,"day":30},"occupation":"","phone":"","allow":1,"college":"","uin":3964575484,"constel":1,"blood":3,"homepage":"http://blog.lovewinne.com","stat":20,"vip_info":0,"country":"中国","city":"","personal":"","nick":" 信","shengxiao":5,"email":"*****@*****.**","province":"山东","gender":"male","mobile":"158********"}}
        :return:dict
        """
        url = "http://s.web2.qq.com/api/get_friend_info2?tuin=%s&vfwebqq=%s&clientid=%s&psessionid=%s&t=%s" % (
            tuin, self.vfwebqq, self.client_id, self.psessionid, int(time.time() * 100))
        response = self.req.Get(url)
        rsp_json = json.loads(response)
        if rsp_json["retcode"] != 0:
            return {}
        return rsp_json["result"]

    # 获取好友的签名信息
    @catch
    def get_single_long_nick2(self, tuin):
        """
        获取好友的签名信息
        get_single_long_nick2
        {"retcode":0,"result":[{"uin":3964575484,"lnick":"幸福,知道自己在哪里,知道下一个目标在哪里,心不累~"}]}
        :return:dict
        """
        url = "http://s.web2.qq.com/api/get_single_long_nick2?tuin=%s&vfwebqq=%s&t=%s" % (tuin, self.vfwebqq, int(time.time() * 100))
        response = self.req.Get(url)
        rsp_json = json.loads(response)
        if rsp_json["retcode"] != 0:
            return {}
        return rsp_json["result"]

    # 获取群信息(对于易变的信息,请在外层做缓存处理)
    @catch
    def get_group_info_ext2(self, gcode):
        """
        获取群信息
        get_group_info_ext2
        {"retcode":0,"result":{"stats":[],"minfo":[{"nick":" 信","province":"山东","gender":"male","uin":3964575484,"country":"中国","city":""},{"nick":"崔震","province":"","gender":"unknown","uin":2081397472,"country":"","city":""},{"nick":"云端的猫","province":"山东","gender":"male","uin":3123065696,"country":"中国","city":"青岛"},{"nick":"要有光","province":"山东","gender":"male","uin":2609717081,"country":"中国","city":"青岛"},{"nick":"小莎机器人","province":"广东","gender":"female","uin":495456232,"country":"中国","city":"深圳"}],"ginfo":{"face":0,"memo":"http://hujj009.ys168.com\r\n0086+区(没0)+电话\r\n0086+手机\r\nhttp://john123951.xinwen365.net/qq/index.htm","class":395,"fingermemo":"","code":3943922314,"createtime":1079268574,"flag":16778241,"level":0,"name":"ぁQQぁ","gid":3931577475,"owner":3964575484,"members":[{"muin":3964575484,"mflag":192},{"muin":2081397472,"mflag":65},{"muin":3123065696,"mflag":128},{"muin":2609717081,"mflag":0},{"muin":495456232,"mflag":0}],"option":2},"cards":[{"muin":3964575484,"card":"●s.Εx2(22222)□"},{"muin":495456232,"card":"小莎机器人"}],"vipinfo":[{"vip_level":0,"u":3964575484,"is_vip":0},{"vip_level":0,"u":2081397472,"is_vip":0},{"vip_level":0,"u":3123065696,"is_vip":0},{"vip_level":0,"u":2609717081,"is_vip":0},{"vip_level":0,"u":495456232,"is_vip":0}]}}
        :return:dict
        """
        if gcode == 0:
            return {}
        url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode=%s&vfwebqq=%s&t=%s" % (gcode, self.vfwebqq, int(time.time() * 100))
        response = self.req.Get(url)
        rsp_json = json.loads(response)
        if rsp_json["retcode"] != 0:
            return {}
        return rsp_json["result"]

    # 发送群消息
    @retry(3)
    def send_qun_msg(self, guin, reply_content):
        self.msg_id += 1
        fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t")).decode("utf-8")
        req_url = "http://d.web2.qq.com/channel/send_qun_msg2"
        data = (
            ('r',
             '{{"group_uin":{0}, "face":564,"content":"[\\"{4}\\",[\\"font\\",{{\\"name\\":\\"Arial\\",\\"size\\":\\"10\\",\\"style\\":[0,0,0],\\"color\\":\\"000000\\"}}]]","clientid":"{1}","msg_id":{2},"psessionid":"{3}"}}'.format(
                 guin, self.client_id, self.msg_id, self.psessionid, fix_content)),
            ('clientid', self.client_id),
            ('psessionid', self.psessionid)
        )
        rsp = self.req.Post(req_url, data, self.default_config.conf.get("global", "connect_referer"))
        rsp_json = json.loads(rsp)
        if rsp_json['retcode'] != 0:
            raise ValueError("reply group chat error" + str(rsp_json['retcode']))
        logging.info("send_qun_msg: Reply successfully.")
        logging.debug("send_qun_msg: Reply response: " + str(rsp))
        return rsp_json

    # 发送私密消息
    @retry(3)
    def send_buddy_msg(self, tuin, reply_content):
        self.msg_id += 1
        fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t")).decode("utf-8")
        req_url = "http://d.web2.qq.com/channel/send_buddy_msg2"
        data = (
            ('r',
             '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":"{1}", "msg_id":{2}, "psessionid":"{3}"}}'.format(
                 tuin, self.client_id, self.msg_id, self.psessionid, fix_content)),
            ('clientid', self.client_id),
            ('psessionid', self.psessionid)
        )
        rsp = self.req.Post(req_url, data, self.default_config.conf.get("global", "connect_referer"))
        rsp_json = json.loads(rsp)
        if rsp_json['retcode'] != 0:
            raise ValueError("reply pmchat error" + str(rsp_json['retcode']))
        logging.info("Reply successfully.")
        logging.debug("Reply response: " + str(rsp))
        return rsp_json

    # 发送临时消息
    @retry(3)
    def send_sess_msg2(self, tuin, reply_content, group_sig, service_type=0):
        self.msg_id += 1
        fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t")).decode("utf-8")
        req_url = "http://d.web2.qq.com/channel/send_sess_msg2"
        data = (
            ('r',
             '{{"to":{0},"content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]","face":570,"clientid":"{1}","msg_id":{2},"psessionid":"{3}","group_sig":"{5}","service_type":{6}}}'.format(
                 tuin,
                 self.client_id,
                 self.msg_id,
                 self.psessionid,
                 fix_content,
                 group_sig,
                 service_type)
             ),
            # ('clientid', self.client_id),
            # ('psessionid', self.psessionid),
            # ('group_sig', group_sig),
            # ('service_type', service_type)
        )
        rsp = self.req.Post(req_url, data, self.default_config.conf.get("global", "connect_referer"))
        rsp_json = json.loads(rsp)
        if rsp_json['retcode'] != 0:
            raise ValueError("reply sess chat error" + str(rsp_json['retcode']))
        logging.info("Reply successfully.")
        logging.debug("Reply response: " + str(rsp))
        return rsp_json

    # 修改在线状态
    @catch
    def change_status2(self, status='callme'):
        url = 'http://d.web2.qq.com/channel/change_status2?newstatus=%s&clientid=%s&psessionid=%s&t=%s' % (status, self.client_id, self.psessionid, time.time())
        response = self.req.Get(url, self.default_config.conf.get("global", "connect_referer"))
        rsp_json = json.loads(response)
        return rsp_json

    def op_group_join_req(self, group_uin, req_uin, optype, msg=''):
        """
        处理入群请求 (貌似接口已经不能用了)
        :param group_uin:
        :param req_uin:
        :param optype: 2:通过  3:拒绝
        :param msg: 拒绝理由
        :return:
        """
        self.msg_id += 1

        req_url = "http://d.web2.qq.com/channel/op_group_join_req"
        data = (('group_uin', group_uin),
                ('req_uin', req_uin),
                ('msg', msg),
                ('op_type', optype),
                ('clientid', self.client_id),
                ('psessionid', self.psessionid),
                ('t', time.time()))
        rsp = self.req.Post(req_url, data, self.default_config.conf.get("global", "connect_referer"))
        pass
예제 #38
0
class QQ:
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        self.friend_list = {}

        self.client_id = int(random.uniform(111111, 888888))
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get(
            "global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0

    def login_by_qrcode(self):
        logging.info("Requesting the login pages...")
        initurl_html = self.req.Get(
            self.default_config.conf.get("global", "smartqq_url"))
        logging.debug("login page html: " + str(initurl_html))
        initurl = get_revalue(initurl_html, r'\.src = "(.+?)"',
                              "Get Login Url Error.", 1)
        html = self.req.Get(initurl + '0')

        appid = get_revalue(
            html, r'<input type="hidden" name="aid" value="(\d+)" />',
            'Get AppId Error', 1)
        sign = get_revalue(html, r'g_login_sig=encodeURIComponent\("(.*?)"\)',
                           'Get Login Sign Error', 0)
        js_ver = get_revalue(html,
                             r'g_pt_version=encodeURIComponent\("(\d+)"\)',
                             'Get g_pt_version Error', 1)
        mibao_css = get_revalue(html,
                                r'g_mibao_css=encodeURIComponent\("(.+?)"\)',
                                'Get g_mibao_css Error', 1)

        star_time = date_to_millis(datetime.datetime.utcnow())

        error_times = 0
        ret = []
        while True:
            error_times += 1
            self.req.Download(
                'https://ssl.ptlogin2.qq.com/ptqrshow?appid={0}&e=0&l=L&s=8&d=72&v=4'
                .format(appid), self.qrcode_path)
            logging.info("Please scan the downloaded QRCode")

            while True:
                html = self.req.Get(
                    'https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid={0}&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-{1}&mibao_css={2}&t=undefined&g=1&js_type=0&js_ver={3}&login_sig={4}'
                    .format(
                        appid,
                        date_to_millis(datetime.datetime.utcnow()) - star_time,
                        mibao_css, js_ver, sign), initurl)
                logging.debug("QRCode check html:   " + str(html))
                ret = html.split("'")
                if ret[1] in (
                        '0', '65'):  # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中
                    break
            if ret[1] == '0' or error_times > 10:
                break

        if ret[1] != '0':
            return
        logging.info("QRCode scaned, now logging in.")

        # 删除QRCode文件
        if os.path.exists(self.qrcode_path):
            os.remove(self.qrcode_path)

        # 记录登陆账号的昵称
        self.username = ret[11]

        html = self.req.Get(ret[5])
        logging.debug("mibao_res html:  " + str(html))
        url = get_revalue(html, r' src="(.+?)"', 'Get mibao_res Url Error.', 0)
        if url != '':
            html = self.req.Get(url.replace('&amp;', '&'))
            url = get_revalue(html, r'location\.href="(.+?)"',
                              'Get Redirect Url Error', 1)
            self.req.Get(url)

        self.ptwebqq = self.req.getCookie('ptwebqq')

        login_error = 1
        ret = {}
        while login_error > 0:
            try:
                html = self.req.Post(
                    'http://d.web2.qq.com/channel/login2', {
                        'r':
                        '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'
                        .format(self.ptwebqq, self.client_id, self.psessionid)
                    }, self.default_config.conf.get("global",
                                                    "connect_referer"))
                logging.debug("login html:  " + str(html))
                ret = json.loads(html)
                login_error = 0
            except:
                login_error += 1
                logging.info("login fail, retrying...")

        if ret['retcode'] != 0:
            logging.debug(str(ret))
            logging.warning("return code:" + str(ret['retcode']))
            return

        self.vfwebqq = ret['result']['vfwebqq']
        self.psessionid = ret['result']['psessionid']
        self.account = ret['result']['uin']

        logging.info("QQ:{0} login successfully, Username:{1}".format(
            self.account, self.username))

    def relogin(self, error_times=0):
        if error_times >= 10:
            return False
        try:
            html = self.req.Post(
                'http://d.web2.qq.com/channel/login2', {
                    'r':
                    '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","key":"","status":"online"}}'
                    .format(self.ptwebqq, self.client_id, self.psessionid)
                }, self.default_config.conf.get("global", "connect_referer"))
            logging.debug("relogin html:  " + str(html))
            ret = json.loads(html)
            self.vfwebqq = ret['result']['vfwebqq']
            self.psessionid = ret['result']['psessionid']
            return True
        except:
            logging.info("login fail, retryng..." + str(error_times))
            return self.relogin(error_times + 1)

    def check_msg(self, error_times=0):
        if error_times >= 5:
            if not self.relogin():
                raise IOError("Account offline.")
            else:
                error_times = 0

        # 调用后进入单次轮询,等待服务器发回状态。
        html = self.req.Post(
            'http://d.web2.qq.com/channel/poll2', {
                'r':
                '{{"ptwebqq":"{1}","clientid":{2},"psessionid":"{0}","key":""}}'
                .format(self.psessionid, self.ptwebqq, self.client_id)
            }, self.default_config.conf.get("global", "connect_referer"))
        logging.debug("check_msg html:  " + str(html))
        try:
            if html == "":
                return self.check_msg()
            ret = json.loads(html)

            ret_code = ret['retcode']

            if ret_code in (102, ):
                logging.info("received retcode: " + str(ret_code) +
                             ": No message.")
                time.sleep(1)
                return

            if ret_code in (103, ):
                logging.warning("received retcode: " + str(ret_code) +
                                ": Check error.retrying.." + str(error_times))
                time.sleep(1)
                return self.check_msg(error_times + 1)

            if ret_code in (121, ):
                logging.warning("received retcode: " + str(ret_code))
                return self.check_msg(5)

            elif ret_code == 0:
                msg_list = []
                pm_list = []
                sess_list = []
                group_list = []
                notify_list = []
                for msg in ret['result']:
                    ret_type = msg['poll_type']
                    if ret_type == 'message':
                        pm_list.append(PmMsg(msg))
                    elif ret_type == 'group_message':
                        group_list.append(GroupMsg(msg))
                    elif ret_type == 'sess_message':
                        sess_list.append(SessMsg(msg))
                    elif ret_type == 'input_notify':
                        notify_list.append(InputNotify(msg))
                    elif ret_code == 'kick_message':
                        notify_list.append(KickMessage(msg))
                    else:
                        logging.warning("unknown message type: " +
                                        str(ret_type) + "details:    " +
                                        str(msg))

                group_list.sort(key=lambda x: x.seq)
                msg_list += pm_list + sess_list + group_list + notify_list
                if not msg_list:
                    return
                return msg_list

            elif ret_code == 100006:
                logging.warning("POST data error")
                return

            elif ret_code == 116:
                self.ptwebqq = ret['p']
                logging.info("ptwebqq updated.")
                return

            else:
                logging.warning("unknown retcode " + str(ret_code))
                return

        except ValueError, e:
            logging.warning("Check error occured: " + str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)

        except BaseException, e:
            logging.warning("Unknown check error occured, retrying. Error: " +
                            str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)
예제 #39
0
 def __init__(self, client, apikey):
     self.rbclient = HttpClient(client)
     self.apikey = apikey
     self.acc = 0
     self.lasttext = ''
     self.lastuser = ''
예제 #40
0
class QQ:
    def __init__(self):
        self.default_config = DefaultConfigs()
        self.req = HttpClient()

        # cache
        self.friend_list = {}
        self.__groupSig_list = {}
        self.__self_info = {}

        self.client_id = 53999199
        self.ptwebqq = ''
        self.psessionid = ''
        self.appid = 0
        self.vfwebqq = ''
        self.qrcode_path = self.default_config.conf.get(
            "global", "qrcode_path")  # QRCode保存路径
        self.username = ''
        self.account = 0

        init_logging()

    def __hash_digest(self, uin, ptwebqq):
        """
        计算hash,貌似TX的这个算法会经常变化,暂时不使用
        get_user_friends2, get_group_name_list_mask2 会依赖此数据
        提取自http://pub.idqqimg.com/smartqq/js/mq.js
        :param uin:
        :param ptwebqq:
        :return:
        """
        N = [0, 0, 0, 0]
        # print(N[0])
        for t in range(len(ptwebqq)):
            N[t % 4] ^= ord(ptwebqq[t])
        U = ["EC", "OK"]
        V = [0, 0, 0, 0]
        V[0] = int(uin) >> 24 & 255 ^ ord(U[0][0])
        V[1] = int(uin) >> 16 & 255 ^ ord(U[0][1])
        V[2] = int(uin) >> 8 & 255 ^ ord(U[1][0])
        V[3] = int(uin) & 255 ^ ord(U[1][1])
        U = [0, 0, 0, 0, 0, 0, 0, 0]
        for T in range(8):
            if T % 2 == 0:
                U[T] = N[T >> 1]
            else:
                U[T] = V[T >> 1]
        N = [
            "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C",
            "D", "E", "F"
        ]
        V = ""
        for T in range(len(U)):
            V += N[U[T] >> 4 & 15]
            V += N[U[T] & 15]
        return V

    def __getGroupSig(self, guin, tuin, service_type=0):
        key = '%s --> %s' % (guin, tuin)
        if key not in self.__groupSig_list:
            url = "http://d1.web2.qq.com/channel/get_c2cmsg_sig2?id=%s&to_uin=%s&service_type=%s&clientid=%s&psessionid=%s&t=%d" % (
                guin, tuin, service_type, self.client_id, self.psessionid,
                int(time.time() * 100))
            response = self.req.Get(url)
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                return ""
            sig = rsp_json["result"]["value"]
            self.__groupSig_list[key] = sig
        if key in self.__groupSig_list:
            return self.__groupSig_list[key]
        return ""

    def __login(self, times=10):
        login_error = 1
        while login_error > 0:
            try:
                logging.info(
                    "RUNTIMELOG Tring to login in with cookies. {0}".format(
                        login_error))
                print('Tring to auto login in.')
                self.ptwebqq = self.req.getCookie('ptwebqq')

                html = self.req.Post(
                    'http://d1.web2.qq.com/channel/login2', {
                        'r':
                        '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'
                        .format(self.ptwebqq, self.client_id, self.psessionid)
                    }, self.default_config.conf.get("global",
                                                    "connect_referer"))
                logging.debug("RESPONSE login html:  " + str(html))
                ret = json.loads(html)

                html2 = self.req.Get(
                    "http://s.web2.qq.com/api/getvfwebqq?ptwebqq={0}&clientid={1}&psessionid={2}&t={3}"
                    .format(self.ptwebqq, self.client_id, self.psessionid,
                            self.req.getTimeStamp()))
                logging.debug("RESPONSE getvfwebqq html:  " + str(html2))
                ret2 = json.loads(html2)

                if (ret['retcode'] != 0) or (ret2['retcode'] != 0):
                    logging.debug("RESPONSE " + str(ret))
                    logging.debug("RESPONSE " + str(ret2))
                    logging.warning(
                        "RUNTIMELOG login2 retcode: {login2}, getvfwebqq retcode: {getvfwebqq}"
                        .format(login2=str(ret['retcode']),
                                getvfwebqq=str(ret2['retcode'])))
                    raise

                self.psessionid = ret['result']['psessionid']
                self.account = ret['result']['uin']
                self.vfwebqq = ret2['result']['vfwebqq']
                logging.info("RUNTIMELOG Login successfully.")
                print('Login successfully.')
                return True
            except:
                login_error += 1
                logging.info("RUNTIMELOG Login fail, retrying...")
                print('auto login fail')
                if login_error > times:
                    return False

    def __login_by_qrcode(self):
        try:
            logging.info("RUNTIMELOG Trying to login by qrcode.")
            logging.info("RUNTIMELOG Requesting the qrcode login pages...")
            # initurl_html = self.req.Get(self.default_config.conf.get("global", "smartqq_url"))
            # logging.debug("RESPONSE login page html: " + str(initurl_html))
            # mqjs_url = get_revalue(initurl_html, r'<script src="(http://pub.idqqimg.com/smartqq/js/mq.js?t=\d+)', "Get mqjs_url Error.", 1)
            # mqjs = self.req.Get(mqjs_url)
            # initurl = get_revalue(initurl_html, r'\.src = "(.+?)"', "Get Login Url Error.", 1)
            # html = self.req.Get(initurl + '0')
            initurl = "https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=16&mibao_css=m_webqq&appid=501004106&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fw.qq.com%2Fproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20131024001"
            html = self.req.Get(
                "https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=16&mibao_css=m_webqq&appid=501004106&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fw.qq.com%2Fproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20131024001"
            )
            appid = get_revalue(
                html, r'<input type="hidden" name="aid" value="(\d+)" />',
                'Get AppId Error', 1)
            sign = get_revalue(html,
                               r'g_login_sig=encodeURIComponent\("(.*?)"\)',
                               'Get Login Sign Error', 0)
            js_ver = get_revalue(
                html, r'g_pt_version=encodeURIComponent\("(\d+)"\)',
                'Get g_pt_version Error', 1)
            mibao_css = get_revalue(
                html, r'g_mibao_css=encodeURIComponent\("(.+?)"\)',
                'Get g_mibao_css Error', 1)

            star_time = date_to_millis(datetime.datetime.utcnow())

            error_times = 0
            ret = []
            while True:
                error_times += 1
                print('download QRcode image...')
                self.req.Download(
                    'https://ssl.ptlogin2.qq.com/ptqrshow?appid={0}&e=0&l=L&s=8&d=72&v=4'
                    .format(appid), self.qrcode_path)
                print "请扫描二维码"
                _thread.start_new_thread(display_QRCode, (self.qrcode_path, ))

                while True:
                    html = self.req.Get(
                        'https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid={0}&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-{1}&mibao_css={2}&t=undefined&g=1&js_type=0&js_ver={3}&login_sig={4}'
                        .format(
                            appid,
                            date_to_millis(datetime.datetime.utcnow()) -
                            star_time, mibao_css, js_ver, sign), initurl)
                    logging.debug("RESPONSE QRCode check html:   " + str(html))
                    ret = html.split("'")
                    if ret[1] in (
                            '0',
                            '65'):  # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中
                        break
                    time.sleep(1)
                if ret[1] == '0' or error_times > 10:
                    break
                time.sleep(1)

            if ret[1] != '0':
                return False

            # 删除QRCode文件
            if os.path.exists(self.qrcode_path):
                os.remove(self.qrcode_path)

            html = self.req.Get(ret[5])
            logging.debug("RESPONSE mibao_res html:  " + str(html))
            return True
        except BaseException:
            logging.info("RUNTIMELOG QRcode login fail")
            print('二维码登陆失败')
            return False

    def login(self):
        if not self.__login(1):
            while True:
                if self.__login_by_qrcode():
                    if self.__login(): break
        ret = self.get_self_info2()
        try:
            self.username = ret['nick']
        except KeyError:
            print ret
            exit()

        logging.info(
            "RUNTIMELOG QQ:{0} login successfully, Username:{1}".format(
                self.account, self.username))
        print "QQ:{0} login successfully, Username:{1}".format(
            self.account, self.username)

    def check_msg(self, error_times=0):
        if error_times >= 5:
            if not self.__login(1):
                raise IOError("Account offline.")
            else:
                error_times = 0

        # 调用后进入单次轮询,等待服务器发回状态。
        html = self.req.Post(
            'http://d1.web2.qq.com/channel/poll2', {
                'r':
                '{{"ptwebqq":"{ptwebqq}","clientid":{clientid},"psessionid":"{psessionid}","key":""}}'
                .format(psessionid=self.psessionid,
                        ptwebqq=self.ptwebqq,
                        clientid=self.client_id)
            }, self.default_config.conf.get("global", "connect_referer"))
        logging.debug("RESPONSE check_msg html:  " + str(html))
        try:
            if html == "":
                return self.check_msg()
            ret = json.loads(html)

            ret_code = ret['retcode']

            # if ret_code in (0,):
            #     logging.info("received retcode: " + str(ret_code) + ": No message.")
            #     time.sleep(1)
            #     return

            if ret_code in (103, ):
                logging.warning("RUNTIMELOG received retcode: " +
                                str(ret_code) + ": Check error.retrying.." +
                                str(error_times))
                time.sleep(1)
                return self.check_msg(error_times + 1)

            elif ret_code in (121, ):
                logging.warning("RUNTIMELOG received retcode: " +
                                str(ret_code))
                return self.check_msg(5)

            elif ret_code == 0:
                if 'result' not in ret or len(ret['result']) == 0:
                    logging.info("RUNTIMELOG received retcode: " +
                                 str(ret_code) + ": No message.")
                    time.sleep(1)
                    return
                msg_list = []
                pm_list = []
                sess_list = []
                group_list = []
                notify_list = []
                for msg in ret['result']:
                    ret_type = msg['poll_type']
                    if ret_type == 'message':
                        pm_list.append(PmMsg(msg))
                    elif ret_type == 'group_message':
                        group_list.append(GroupMsg(msg))
                    elif ret_type == 'sess_message':
                        sess_list.append(SessMsg(msg))
                    elif ret_type == 'input_notify':
                        notify_list.append(InputNotify(msg))
                    elif ret_code == 'kick_message':
                        notify_list.append(KickMessage(msg))
                    else:
                        logging.warning("RUNTIMELOG unknown message type: " +
                                        str(ret_type) + "details:    " +
                                        str(msg))

                group_list.sort(key=lambda x: x.msg_id)
                msg_list += pm_list + sess_list + group_list + notify_list
                if not msg_list:
                    return
                return msg_list

            elif ret_code == 100006:
                logging.warning("RUNTIMELOG POST data error")
                return

            elif ret_code == 116:
                self.ptwebqq = ret['p']
                logging.info("RUNTIMELOG ptwebqq updated.")
                return

            else:
                logging.warning("RUNTIMELOG unknown retcode " + str(ret_code))
                return

        except KeyboardInterrupt:
            logging.info("User interrupted. Exit.")
            os._exit(0)

        except ValueError as e:
            logging.warning("RUNTIMELOG Check error occured: " + str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)

        except BaseException as e:
            logging.warning(
                "RUNTIMELOG Unknown check error occured, retrying. Error: " +
                str(e))
            time.sleep(1)
            return self.check_msg(error_times + 1)

    def uin_to_account(self, tuin):
        """
        将uin转换成用户QQ号
        :param tuin:
        :return:str 用户昵称
        """
        uin_str = str(tuin)
        try:
            logging.info("RUNTIMELOG Requesting the account by uin:    " +
                         str(tuin))
            info = json.loads(
                self.req.Get(
                    'http://s.web2.qq.com/api/get_friend_uin2?tuin={0}&type=1&vfwebqq={1}&t={2}'
                    .format(uin_str, self.vfwebqq, self.req.getTimeStamp()),
                    self.default_config.conf.get("global", "connect_referer")))
            logging.debug("RESPONSE uin_to_account html:    " + str(info))
            if info['retcode'] != 0:
                raise TypeError('uin_to_account retcode error')
            info = info['result']['account']
            return info

        except:
            logging.warning("RUNTIMELOG uin_to_account fail")
            return None

    # 获取自己的信息
    def get_self_info2(self):
        """
        获取自己的信息
        get_self_info2
        {"retcode":0,"result":{"birthday":{"month":1,"year":1989,"day":30},"face":555,"phone":"","occupation":"","allow":1,"college":"","uin":2609717081,"blood":0,"constel":1,"lnick":"","vfwebqq":"68b5ff5e862ac589de4fc69ee58f3a5a9709180367cba3122a7d5194cfd43781ada3ac814868b474","homepage":"","vip_info":0,"city":"青岛","country":"中国","personal":"","shengxiao":5,"nick":"要有光","email":"","province":"山东","account":2609717081,"gender":"male","mobile":""}}
        :return:dict
        """
        if not self.__self_info:
            url = "http://s.web2.qq.com/api/get_self_info2"
            response = self.req.Get(url)
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                return {}
            self.__self_info = rsp_json["result"]
        return self.__self_info

    # 获取好友详情信息
    def get_friend_info2(self, tuin):
        """
        获取好友详情信息
        get_friend_info2
        {"retcode":0,"result":{"face":0,"birthday":{"month":1,"year":1989,"day":30},"occupation":"","phone":"","allow":1,"college":"","uin":3964575484,"constel":1,"blood":3,"homepage":"http://blog.lovewinne.com","stat":20,"vip_info":0,"country":"中国","city":"","personal":"","nick":" 信","shengxiao":5,"email":"*****@*****.**","province":"山东","gender":"male","mobile":"158********"}}
        :return:dict
        """
        uin_str = str(tuin)
        try:
            logging.info("RUNTIMELOG Requesting the account info by uin:    " +
                         str(tuin))
            info = json.loads(
                self.req.Get(
                    'http://s.web2.qq.com/api/get_friend_info2?tuin={0}&vfwebqq={1}&clientid={2}&psessionid={3}&t={4}'
                    .format(uin_str, self.vfwebqq, self.client_id,
                            self.psessionid, self.req.getTimeStamp()), ))
            logging.debug("RESPONSE get_friend_info2 html:    " + str(info))
            if info['retcode'] != 0:
                raise TypeError('get_friend_info2 result error')
            info = info['result']
            return info

        except:
            logging.warning("RUNTIMELOG get_friend_info2 fail")
            return None

    # 获取好友详情信息
    def get_friend_info(self, tuin):
        uin_str = str(tuin)
        if uin_str not in self.friend_list:
            info = self.get_friend_info2(tuin) or {'nick': '群用户'}
            info['account'] = self.uin_to_account(tuin)
            self.friend_list[uin_str] = info

        try:
            return '【{0}({1})】'.format(self.friend_list[uin_str]['nick'],
                                       self.friend_list[uin_str]['account'])
        except:
            logging.warning("RUNTIMELOG get_friend_info return fail.")
            logging.debug("RUNTIMELOG now uin list:    " +
                          str(self.friend_list[uin_str]))

    # 获取好友的签名信息
    def get_single_long_nick2(self, tuin):
        """
        获取好友的签名信息
        get_single_long_nick2
        {"retcode":0,"result":[{"uin":3964575484,"lnick":"幸福,知道自己在哪里,知道下一个目标在哪里,心不累~"}]}
        :return:dict
        """
        url = "http://s.web2.qq.com/api/get_single_long_nick2?tuin=%s&vfwebqq=%s&t=%s" % (
            tuin, self.vfwebqq, int(time.time() * 100))
        response = self.req.Get(url)
        rsp_json = json.loads(response)
        if rsp_json["retcode"] != 0:
            return {}
        return rsp_json["result"]

    # 获取群信息(对于易变的信息,请在外层做缓存处理)
    def get_group_info_ext2(self, gcode):
        """
        获取群信息
        get_group_info_ext2
        {"retcode":0,"result":{"stats":[],"minfo":[{"nick":" 信","province":"山东","gender":"male","uin":3964575484,"country":"中国","city":""},{"nick":"崔震","province":"","gender":"unknown","uin":2081397472,"country":"","city":""},{"nick":"云端的猫","province":"山东","gender":"male","uin":3123065696,"country":"中国","city":"青岛"},{"nick":"要有光","province":"山东","gender":"male","uin":2609717081,"country":"中国","city":"青岛"},{"nick":"小莎机器人","province":"广东","gender":"female","uin":495456232,"country":"中国","city":"深圳"}],"ginfo":{"face":0,"memo":"http://hujj009.ys168.com\r\n0086+区(没0)+电话\r\n0086+手机\r\nhttp://john123951.xinwen365.net/qq/index.htm","class":395,"fingermemo":"","code":3943922314,"createtime":1079268574,"flag":16778241,"level":0,"name":"ぁQQぁ","gid":3931577475,"owner":3964575484,"members":[{"muin":3964575484,"mflag":192},{"muin":2081397472,"mflag":65},{"muin":3123065696,"mflag":128},{"muin":2609717081,"mflag":0},{"muin":495456232,"mflag":0}],"option":2},"cards":[{"muin":3964575484,"card":"●s.Εx2(22222)□"},{"muin":495456232,"card":"小莎机器人"}],"vipinfo":[{"vip_level":0,"u":3964575484,"is_vip":0},{"vip_level":0,"u":2081397472,"is_vip":0},{"vip_level":0,"u":3123065696,"is_vip":0},{"vip_level":0,"u":2609717081,"is_vip":0},{"vip_level":0,"u":495456232,"is_vip":0}]}}
        :return:dict
        """
        if gcode == 0:
            return {}
        try:
            url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode=%s&vfwebqq=%s&t=%s" % (
                gcode, self.vfwebqq, int(time.time() * 100))
            response = self.req.Get(url)
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                return {}
            return rsp_json["result"]
        except Exception as ex:
            logging.warning("RUNTIMELOG get_group_info_ext2. Error: " +
                            str(ex))
            return {}

    # 发送群消息
    def send_qun_msg(self, guin, reply_content, msg_id, fail_times=0):
        fix_content = str(
            reply_content.replace("\\", "\\\\\\\\").replace("\n",
                                                            "\\\\n").replace(
                                                                "\t", "\\\\t"))
        rsp = ""
        try:
            req_url = "http://d1.web2.qq.com/channel/send_qun_msg2"
            data = ((
                'r',
                '{{"group_uin":{0}, "face":564,"content":"[\\"{4}\\",[\\"font\\",{{\\"name\\":\\"Arial\\",\\"size\\":\\"10\\",\\"style\\":[0,0,0],\\"color\\":\\"000000\\"}}]]","clientid":{1},"msg_id":{2},"psessionid":"{3}"}}'
                .format(guin, self.client_id, msg_id, self.psessionid,
                        fix_content)), ('clientid', self.client_id),
                    ('psessionid', self.psessionid))
            rsp = self.req.Post(
                req_url, data,
                self.default_config.conf.get("global", "connect_referer"))
            rsp_json = json.loads(rsp)
            if 'retcode' in rsp_json and rsp_json['retcode'] != 0:
                raise ValueError("RUNTIMELOG reply group chat error" +
                                 str(rsp_json['retcode']))
            logging.info("RUNTIMELOG send_qun_msg: Reply successfully.")
            logging.debug("RESPONSE send_qun_msg: Reply response: " + str(rsp))
            return rsp_json
        except:
            logging.warning("RUNTIMELOG send_qun_msg fail")
            if fail_times < 5:
                logging.warning(
                    "RUNTIMELOG send_qun_msg: Response Error.Wait for 2s and Retrying."
                    + str(fail_times))
                logging.debug("RESPONSE send_qun_msg rsp:" + str(rsp))
                time.sleep(2)
                self.send_qun_msg(guin, reply_content, msg_id, fail_times + 1)
            else:
                logging.warning(
                    "RUNTIMELOG send_qun_msg: Response Error over 5 times.Exit.reply content:"
                    + str(reply_content))
                return False

    # 发送私密消息
    def send_buddy_msg(self, tuin, reply_content, msg_id, fail_times=0):
        fix_content = str(
            reply_content.replace("\\", "\\\\\\\\").replace("\n",
                                                            "\\\\n").replace(
                                                                "\t", "\\\\t"))
        rsp = ""
        try:
            req_url = "http://d1.web2.qq.com/channel/send_buddy_msg2"
            data = ((
                'r',
                '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}"}}'
                .format(tuin, self.client_id, msg_id, self.psessionid,
                        fix_content)), ('clientid', self.client_id),
                    ('psessionid', self.psessionid))
            rsp = self.req.Post(
                req_url, data,
                self.default_config.conf.get("global", "connect_referer"))
            rsp_json = json.loads(rsp)
            if 'errCode' in rsp_json and rsp_json['errCode'] != 0:
                raise ValueError("reply pmchat error" +
                                 str(rsp_json['retcode']))
            logging.info("RUNTIMELOG Reply successfully.")
            logging.debug("RESPONSE Reply response: " + str(rsp))
            return rsp_json
        except:
            if fail_times < 5:
                logging.warning(
                    "RUNTIMELOG Response Error.Wait for 2s and Retrying." +
                    str(fail_times))
                logging.debug("RESPONSE " + str(rsp))
                time.sleep(2)
                self.send_buddy_msg(tuin, reply_content, msg_id,
                                    fail_times + 1)
            else:
                logging.warning(
                    "RUNTIMELOG Response Error over 5 times.Exit.reply content:"
                    + str(reply_content))
                return False

    # 发送临时消息
    def send_sess_msg2(self,
                       tuin,
                       reply_content,
                       msg_id,
                       group_sig,
                       service_type=0,
                       fail_times=0):
        fix_content = str(
            reply_content.replace("\\", "\\\\\\\\").replace("\n",
                                                            "\\\\n").replace(
                                                                "\t", "\\\\t"))
        rsp = ""
        try:
            req_url = "http://d1.web2.qq.com/channel/send_sess_msg2"
            data = ((
                'r',
                '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}", "group_sig":"{5}", "service_type":{6}}}'
                .format(tuin, self.client_id, msg_id, self.psessionid,
                        fix_content, group_sig,
                        service_type)), ('clientid', self.client_id),
                    ('psessionid', self.psessionid), ('group_sig', group_sig),
                    ('service_type', service_type))
            rsp = self.req.Post(
                req_url, data,
                self.default_config.conf.get("global", "connect_referer"))
            rsp_json = json.loads(rsp)
            if 'retcode' in rsp_json and rsp_json['retcode'] != 0:
                raise ValueError("reply sess chat error" +
                                 str(rsp_json['retcode']))
            logging.info("RUNTIMELOG Reply successfully.")
            logging.debug("RESPONSE Reply response: " + str(rsp))
            return rsp_json
        except:
            if fail_times < 5:
                logging.warning(
                    "RUNTIMELOG Response Error.Wait for 2s and Retrying." +
                    str(fail_times))
                logging.debug("RESPONSE " + str(rsp))
                time.sleep(2)
                self.send_sess_msg2(tuin, reply_content, msg_id, group_sig,
                                    service_type, fail_times + 1)
            else:
                logging.warning(
                    "RUNTIMELOG Response Error over 5 times.Exit.reply content:"
                    + str(reply_content))
                return False

    # 主动发送临时消息
    def send_sess_msg2_fromGroup(self,
                                 guin,
                                 tuin,
                                 reply_content,
                                 msg_id,
                                 service_type=0,
                                 fail_times=0):
        group_sig = self.__getGroupSig(guin, tuin, service_type)
        fix_content = str(
            reply_content.replace("\\", "\\\\\\\\").replace("\n",
                                                            "\\\\n").replace(
                                                                "\t", "\\\\t"))
        rsp = ""
        try:
            req_url = "http://d1.web2.qq.com/channel/send_sess_msg2"
            data = ((
                'r',
                '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}", "group_sig":"{5}", "service_type":{6}}}'
                .format(tuin, self.client_id, msg_id, self.psessionid,
                        fix_content, group_sig,
                        service_type)), ('clientid', self.client_id),
                    ('psessionid', self.psessionid), ('group_sig', group_sig),
                    ('service_type', service_type))
            rsp = self.req.Post(
                req_url, data,
                self.default_config.conf.get("global", "connect_referer"))
            rsp_json = json.loads(rsp)
            if 'retcode' in rsp_json and rsp_json['retcode'] != 0:
                raise ValueError("RUNTIMELOG reply sess chat error" +
                                 str(rsp_json['retcode']))
            logging.info(
                "RUNTIMELOG send_sess_msg2_fromGroup: Reply successfully.")
            logging.debug(
                "RESPONSE send_sess_msg2_fromGroup: Reply response: " +
                str(rsp))
            return rsp_json
        except:
            if fail_times < 5:
                logging.warning(
                    "RUNTIMELOG send_sess_msg2_fromGroup: Response Error.Wait for 2s and Retrying."
                    + str(fail_times))
                logging.debug("RESPONSE " + str(rsp))
                time.sleep(2)
                self.send_sess_msg2_fromGroup(guin, tuin, reply_content,
                                              msg_id, service_type,
                                              fail_times + 1)
            else:
                logging.warning(
                    "RUNTIMELOG send_sess_msg2_fromGroup: Response Error over 5 times.Exit.reply content:"
                    + str(reply_content))
                return False
예제 #41
0
 def __init__(self, token=None):
     self._access_token = token
     self._http_client = HttpClient()
     self.error_msg = False
예제 #42
0
import HttpClient

httpClient = HttpClient.HttpClient()

# get login user info
loginUser = httpClient.getSelf()
print(loginUser)
loginSid = loginUser['ResultSet']['Result']['Usid']
print("login info:")
print(loginSid)

# get shotmail info
smailUserInfo = httpClient.getShortMailUser(loginSid)
sId = smailUserInfo['ResultSet']['Result']
print("smail info")
print(sId)

print(httpClient.sendShortMail())
예제 #43
0
__author__ = 'MarioJ'

import HttpClient
import sys

# get the parameter that references URL
url = sys.argv[1]

# Instance the Http Client to make request from server
client = HttpClient.Client(str(url))

# Make POST request to server and get response
response = client.POST()

# print response on the screen
print response
예제 #44
0
 def __init__(self, url):
     self.url = url
     self.hc = HttpClient.HttpClient(url=self.url)