Пример #1
0
    def sendEmail(self):
        lastSubject = ''
        while True:
            qrcode = self.qrcode.getVal()

            if qrcode is None:
                break

            if lastSubject != self.qrcodeMail['subject']:
                qrcode = '' if self.qrcodeServer else qrcode
                try:
                    with self.mailAgent.SMTP() as smtp:
                        smtp.send(png_content=qrcode, **self.qrcodeMail)
                except Exception as e:
                    WARN('无法将二维码发送至邮箱%s %s', self.mailAgent.account, e)
                else:
                    INFO('已将二维码发送至邮箱%s', self.mailAgent.account)
                    if self.qrcodeServer:
                        break
                    else:
                        lastSubject = self.qrcodeMail['subject']
            else:
                time.sleep(30)
                try:
                    DEBUG('开始查询邮箱 %s 中的最近的邮件', self.mailAgent.account)
                    with self.mailAgent.IMAP() as imap:
                        lastSubject = imap.getSubject(-1)
                except Exception as e:
                    WARN('查询邮箱 %s 中的邮件失败 %s', self.mailAgent.account, e)
                else:
                    DEBUG('最近的邮件: %s', lastSubject)
Пример #2
0
    def smartRequest(self,
                     url,
                     data=None,
                     repeatOnDeny=2,
                     sessionObj=None,
                     **kw):
        session = sessionObj or self.session
        i, j = 0, 0
        while True:
            html, timeOut = '', False
            session.headers.update(**kw)
            try:
                if data is None:
                    resp = session.get(url)
                else:
                    resp = session.post(url, data=data)

                if url == 'https://d1.web2.qq.com/channel/poll2':
                    # DEBUG('POLL RESULT: status_code=%s, html=%s',
                    #        resp.status_code, resp.content)

                    if resp.status_code in (502, 504):
                        timeOut = True
                    else:
                        html = resp.content
                        try:
                            result = JsonLoads(html)
                        except ValueError:
                            timeOut = True

                    if timeOut:
                        session.get(
                            ('http://pinghot.qq.com/pingd?dm=w.qq.com.hot&'
                             'url=/&hottag=smartqq.im.polltimeout&hotx=9999&'
                             'hoty=9999&rand=%s') %
                            random.randint(10000, 99999))
                        continue
                else:
                    html = resp.content
                    result = JsonLoads(html)

            except (requests.ConnectionError, ValueError):
                i += 1
                errorInfo = '网络错误或url地址错误'
            else:
                retcode = result.get('retcode', result.get('errCode', -1))
                if retcode in (0, 1202, 100003):
                    return result.get('result', result)
                else:
                    j += 1
                    errorInfo = '请求被拒绝错误'

            # 出现网络错误可以多试几次 (i <= 4);
            # 若 retcode 有误,一般连续 3 次都出错就没必要再试了 (j <= 2)
            if i <= 4 and j <= repeatOnDeny:
                DEBUG('第%d次请求“%s”时出现“%s”, html:\n%s', i + j, url, errorInfo,
                      html)
            else:
                CRITICAL('第%d次请求“%s”时出现“%s”,终止 QQBot', i + j, url, errorInfo)
                raise RequestError
Пример #3
0
    def smartRequest(self, url, data=None,
                     timeoutRetVal=None, repeateOnDeny=2, **kw):
        nCE, nTO, nUE, nDE = 0, 0, 0, 0
        while True:
            url = url.format(rand=repr(random.random()))
            html = ''
            errorInfo = ''
            self.session.headers.update(**kw)
            try:
                if data is None:
                    resp = self.session.get(url, verify=self.httpsVerify)
                else:
                    resp = self.session.post(url, data=data,
                                             verify=self.httpsVerify)
            except requests.ConnectionError as e:
                nCE += 1
                errorInfo = '网络错误 %s' % e
            else:
                html = resp.content
                if resp.status_code in (502, 504, 404):
                    self.session.get(
                        ('http://pinghot.qq.com/pingd?dm=w.qq.com.hot&'
                         'url=/&hottag=smartqq.im.polltimeout&hotx=9999&'
                         'hoty=9999&rand=%s') % random.randint(10000, 99999)
                    )
                    if url == 'https://d1.web2.qq.com/channel/poll2':
                        return {'errmsg': ''}
                    nTO += 1
                    errorInfo = '超时'
                else:
                    try:
                        result = JsonLoads(html)
                    except ValueError:
                        nUE += 1
                        errorInfo = ' URL 地址错误'
                    else:
                        retcode = result.get('retcode', 
                                             result.get('errCode',
                                                        result.get('ec', -1)))
                        if retcode in (0, 1202, 100003, 100100):
                            return result.get('result', result)
                        else:
                            nDE += 1
                            errorInfo = '请求被拒绝错误'

            # 出现网络错误、超时、 URL 地址错误可以多试几次 
            # 若网络没有问题但 retcode 有误,一般连续 3 次都出错就没必要再试了
            if nCE < 5 and nTO < 20 and nUE < 5 and nDE <= repeateOnDeny:
                DEBUG('第%d次请求“%s”时出现“%s”, html=%s',
                      nCE+nTO+nUE+nDE, url, errorInfo, repr(html))
                time.sleep(0.5)
            elif nTO == 20 and timeoutRetVal: # by @killerhack
                return timeoutRetVal
            else:
                CRITICAL('第%d次请求“%s”时出现“%s”',
                         nCE+nTO+nUE+nDE, url, errorInfo)
                raise QSession.Error
Пример #4
0
 def fetchForever(self):
     INFO('已在后台运行 fetchForever 方法,每隔 5 分钟获取一次联系人资料')
     while True:
         time.sleep(300)
         try:
             contacts = self.fetch()
         except (QSession.Error, Exception):
             WARN(' fetchForever 方法出错')
             DEBUG('', exc_info=True)
         else:
             yield Message('fetchcomplete', contacts=contacts)
Пример #5
0
    def poll(self):
        result = self.smartRequest(
            url='https://d1.web2.qq.com/channel/poll2',
            data={
                'r':
                JsonDumps({
                    'ptwebqq': self.ptwebqq,
                    'clientid': self.clientid,
                    'psessionid': self.psessionid,
                    'key': ''
                })
            },
            sessionObj=self.pollSession,
            Referer=('http://d1.web2.qq.com/proxy.html?v=20151105001&'
                     'callback=1&id=2'))
        if not result or 'errmsg' in result:
            DEBUG('无消息')
            return ('', 0, 0, '')  # 无消息
        else:
            result = result[0]

            msgType = {
                'message': 'buddy',
                'group_message': 'group',
                'discu_message': 'discuss'
            }[result['poll_type']]
            from_uin = result['value']['from_uin']
            buddy_uin = result['value'].get('send_uin', from_uin)
            msg = ''.join(
                ('[face%d]' % m[1]) if isinstance(m, list) else str(m)
                for m in result['value']['content'][1:])

            if msgType == 'buddy':
                bName = self.getBuddyByUin(buddy_uin)['name']
                INFO('来自 好友“%s” 的消息: "%s"' % (bName, msg))
            elif msgType == 'group':
                group = self.getGroupByUin(from_uin)
                gName = group['name']
                bName = group['member'].get(buddy_uin, 'unknown')
                INFO('来自 群“%s”[成员“%s”] 的消息: "%s"' % (gName, bName, msg))
            else:
                discuss = self.getDiscussByUin(from_uin)
                gName = discuss['name']
                bName = discuss['member'].get(buddy_uin, 'unknown')
                INFO('来自 讨论组“%s”[成员“%s”] 的消息: "%s"' % (gName, bName, msg))

            return (msgType, from_uin, buddy_uin, msg)
Пример #6
0
    def smartRequest(self,
                     url,
                     data=None,
                     repeatOnDeny=2,
                     sessionObj=None,
                     **kw):
        session = sessionObj or self.session
        nCE, nTO, nUE, nDE = 0, 0, 0, 0

        while True:
            url = url.format(rand=repr(random.random()))
            html, errorInfo = '', ''
            session.headers.update(**kw)
            try:
                if data is None:
                    resp = session.get(url)
                else:
                    resp = session.post(url, data=data)
            except requests.ConnectionError as e:
                nCE += 1
                errorInfo = '网络错误 %s' % e
            else:
                html = resp.content
                if resp.status_code in (502, 504):
                    session.get(
                        ('http://pinghot.qq.com/pingd?dm=w.qq.com.hot&'
                         'url=/&hottag=smartqq.im.polltimeout&hotx=9999&'
                         'hoty=9999&rand=%s') % random.randint(10000, 99999))
                    if url == 'https://d1.web2.qq.com/channel/poll2':
                        return {'errmsg': ''}
                    nTO += 1
                    errorInfo = '超时'
                else:
                    try:
                        result = JsonLoads(html)
                    except ValueError:
                        nUE += 1
                        errorInfo = ' URL 地址错误'
                    else:
                        retcode = \
                            result.get('retcode', result.get('errCode', -1))
                        if retcode in (0, 1202, 100003):
                            return result.get('result', result)
                        else:
                            nDE += 1
                            errorInfo = '请求被拒绝错误'

            # 出现网络错误或超时可以多试几次 (nCE < 5, nTO < 20);
            # 根据腾讯服务器的改标,增加了尝试次数
            # 若出现 URL 地址错误或 retcode 有误,一般连续 3 次都出错就没必要再试了
            if nCE < 5 and nTO < 20 and nUE < 3 and nDE <= repeatOnDeny:
                DEBUG('第%d次请求“%s”时出现“%s”, html=%s', nCE + nTO + nUE + nDE, url,
                      errorInfo, repr(html))
            else:
                if nTO == 20 and url.startswith(
                        'http://s.web2.qq.com/api/get_friend_uin2'):
                    # 针对某个好友获取不到的情况,先返回一个空值,以确保成功登陆
                    # 防止因个别好友无法获得触发SystemExit,如果是因为其他原因则退出
                    return {'account': -1}

                CRITICAL('第%d次请求“%s”时出现“%s”,终止 QQBot', nCE + nTO + nUE + nDE,
                         url, errorInfo)

                raise RequestError  # (SystemExit)
Пример #7
0
    def smartRequest(self,
                     url,
                     data=None,
                     repeatOnDeny=2,
                     sessionObj=None,
                     **kw):
        session = sessionObj or self.session
        nCE, nUE, nDE = 0, 0, 0
        while True:
            html, errorInfo = '', ''
            session.headers.update(**kw)
            try:
                if data is None:
                    resp = session.get(url)
                else:
                    resp = session.post(url, data=data)

            except requests.ConnectionError:
                nCE += 1
                errorInfo = '网络错误'

            else:
                if url == 'https://d1.web2.qq.com/channel/poll2':
                    timeOut = False
                    if resp.status_code in (502, 504):
                        timeOut = True
                    else:
                        html = resp.content
                        try:
                            result = JsonLoads(html)
                        except ValueError:
                            timeOut = True

                    if timeOut:
                        session.get(
                            ('http://pinghot.qq.com/pingd?dm=w.qq.com.hot&'
                             'url=/&hottag=smartqq.im.polltimeout&hotx=9999&'
                             'hoty=9999&rand=%s') %
                            random.randint(10000, 99999))
                        return {'errmsg': ''}

                else:
                    html = resp.content
                    try:
                        result = JsonLoads(html)
                    except ValueError:
                        nUE += 1
                        errorInfo = 'URL地址错误'

                if not errorInfo:
                    retcode = result.get('retcode', result.get('errCode', -1))
                    if retcode in (0, 1202, 100003):
                        return result.get('result', result)
                    else:
                        nDE += 1
                        errorInfo = '请求被拒绝错误'

            # 出现网络错误或URL地址错误可以多试几次 (nCE<=4 and nUE<=3);
            # 若 retcode 有误,一般连续 3 次都出错就没必要再试了(nDE<=2)
            if nCE <= 4 and nUE <= 3 and nDE <= repeatOnDeny:
                DEBUG('第%d次请求“%s”时出现“%s”, html=%s', nCE + nUE + nDE, url,
                      errorInfo, repr(html))
            else:
                CRITICAL('第%d次请求“%s”时出现“%s”,终止 QQBot', nCE + nUE + nDE, url,
                         errorInfo)
                raise RequestError  # (SystemExit)