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) time.sleep(10) else: INFO('已将二维码发送至邮箱%s', self.mailAgent.account) if self.qrcodeServer: break else: lastSubject = self.qrcodeMail['subject'] else: time.sleep(20) try: INFO('开始查询邮箱 %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: INFO('最近的邮件: %s', lastSubject)
def Run(self): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.bind((HOST, self.port)) self.sock.listen(5) except socket.error as e: WARN('无法开启 QQBot term 服务器。%s', e) else: time.sleep(0.1) INFO('已在 %s 端口开启 QQBot-Term 服务器', self.port) if CallInNewConsole(['python', __file__, str(self.port)]) != 0: WARN('无法自动打开新控制台运行 QTerm 客户端,' '请手动打开新控制台并运行 qterm %s 命令', self.port) while True: try: sock, addr = self.sock.accept() except socket.error: WARN('QQBot-Term 服务器出现 accept 错误') else: name = 'QTerm 客户端<%s:%s>' % addr sock.settimeout(5.0) try: data = sock.recv(1024) except socket.error: sock.close() else: INFO('来自 %s 的消息:%s', name, data) yield TermMessage(name, sock, data)
def Run(self): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind((HOST, self.port)) self.sock.listen(5) except socket.error as e: WARN('无法开启 QQBot term 服务器。%s', e) WARN(' qq 命令无法使用') else: time.sleep(0.1) INFO('已在 %s 端口开启 QQBot-Term 服务器,', self.port) INFO('请在其他控制台窗口使用 qq 命令来控制 QQBot ,' '示例: qq send buddy jack hello') while True: try: sock, addr = self.sock.accept() except socket.error: WARN('QQBot-Term 服务器出现 accept 错误') else: name = 'QTerm客户端"%s:%s"' % addr sock.settimeout(5.0) try: data = sock.recv(1024) except socket.error: sock.close() else: INFO('QTerm 命令:%s', repr(data)) yield TermMessage(name, sock, data)
def Show(self, qrcode): if self.mailAgent is None: with open(self.qrcodePath, 'wb') as f: f.write(qrcode) try: showImage(self.qrcodePath) except Exception as e: WARN('弹出二维码失败 %s,请手动打开 file://%s', e, self.qrcodePath) else: if not self.hasSent: needSend = True self.hasSent = True else: try: with self.mailAgent.IMAP() as imap: last_subject = imap.getUnSeenSubject(-1)[0] except Exception as e: WARN('查询 %s 中的邮件失败 %s', self.mailAgent.account, e) needSend = True else: needSend = (last_subject != self.qrcodeMail['subject']) if needSend: 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)
def waitForAuth(self, conf): qrcodeManager = QrcodeManager(conf) try: qrcodeManager.Show(self.getQrcode()) while True: time.sleep(3) authStatus = self.getAuthStatus() if '二维码未失效' in authStatus: INFO('登录 Step2 - 等待二维码扫描及授权') elif '二维码认证中' in authStatus: INFO('二维码已扫描,等待授权') elif '二维码已失效' in authStatus: WARN('二维码已失效, 重新获取二维码') qrcodeManager.Show(self.getQrcode()) elif '登录成功' in authStatus: INFO('已获授权') items = authStatus.split(',') self.nick = str(items[-1].split("'")[1]) self.qq = str(int(self.session.cookies['superuin'][1:])) self.urlPtwebqq = items[2].strip().strip("'") break else: CRITICAL('获取二维码扫描状态时出错, html="%s"', authStatus) sys.exit(1) finally: qrcodeManager.Destroy()
def Reply(self, rep): try: self.sock.sendall(rep and str(rep) or '\r\n') except socket.error: WARN('回复 %s 失败', self.name) finally: self.sock.close()
def delMail(self): try: time.sleep(1) with self.mailAgent.IMAP() as imap: imap.delMail(subject=self.qrcodeMail['subject']) except Exception as e: WARN('删除二维码邮件失败 %s', e)
def fetchForever(self): try: INFO('已在后台运行 fetchForever 方法,每隔 5 分钟获取一次联系人资料') while True: time.sleep(300) yield Message('fetchcomplete', contacts=self.fetch()) finally: WARN('fetchForever方法出错,停止在后台获取联系人资料')
def fetchForever(self): INFO('已在后台运行 fetchForever 方法,每隔 5 分钟获取一次联系人资料') while True: time.sleep(300) try: contacts = self.fetch() except QSession.Error: WARN(' fetchForever 方法出错') else: yield Message('fetchcomplete', contacts=contacts)
def Show(self, qrcode): with open(self.qrcodePath, 'wb') as f: f.write(qrcode) if self.qrcodeServer is None and self.mailAgent is None: try: showImage(self.qrcodePath) except Exception as e: WARN('弹出二维码失败(%s),请手动打开 file://%s', e, self.qrcodePath) if self.qrcodeServer: INFO('请使用浏览器访问二维码,图片地址: %s', self.qrcodeURL) if self.mailAgent: if not self.hasSent: needSend = True self.hasSent = True elif self.qrcodeServer: needSend = False else: try: with self.mailAgent.IMAP() as imap: last_subject = imap.getSubject(-1) except Exception as e: WARN('查询 %s 中的邮件失败(%s)', self.mailAgent.account, e) needSend = True else: needSend = (last_subject != self.qrcodeMail['subject']) if not needSend: INFO('最近发送的二维码邮件尚未被删除,因此不再重复发送') if needSend: if not self.qrcodeServer: self.qrcodeMail['png_content'] = qrcode try: with self.mailAgent.SMTP() as smtp: smtp.send(**self.qrcodeMail) except Exception as e: WARN('无法将二维码发送至邮箱%s(%s)', self.mailAgent.account, e) else: INFO('已将二维码发送至邮箱%s', self.mailAgent.account)
def dumpSessionInfo(self): self.pollSession = pickle.loads(pickle.dumps(self.session)) picklePath = self.conf.PicklePath() nonDump = CutDict(self.__dict__, self.nonDumpAttrs) try: with open(picklePath, 'wb') as f: f.write(pickle.dumps(self.__dict__)) except IOError: WARN('保存 Session info 失败:IOError %s', picklePath) else: INFO('Session info 已保存至文件:file://%s' % picklePath) self.__dict__.update(nonDump)
def autoLogin(self): try: self.loadSessionInfo() self.testLogin() return True except RequestError: e = '上次保存的 Session info 已过期' except Exception as e: e = str(e) WARN('自动登录失败,原因:%s', e) return False
def QLogin(qq=None, user=None, conf=None): if conf is None: conf = QConf(qq, user) if conf.qq: INFO('开始自动登录...') picklePath = conf.PicklePath() try: with open(picklePath, 'rb') as f: session, contacts = pickle.load(f) except Exception as e: WARN('自动登录失败,原因:%s', e) else: INFO('成功从文件 "%s" 中恢复登录信息和联系人' % picklePath) try: session.TestLogin() except QSession.Error: WARN('自动登录失败,原因:上次保存的登录信息已过期') else: INFO('登录成功。登录账号:%s(%s)', session.nick, session.qq) return session, contacts INFO('开始手动登录...') session = QSession() contacts = session.Login(conf) INFO('登录成功。登录账号:%s(%s)', session.nick, session.qq) conf.qq = session.qq picklePath = conf.PicklePath() try: with open(picklePath, 'wb') as f: pickle.dump((session, contacts), f) except IOError: WARN('保存登录信息及联系人失败:IOError %s', picklePath) else: INFO('登录信息及联系人已保存至文件:file://%s' % picklePath) return session, contacts
def Show(self, qrcode): with open(self.qrcodePath, 'wb') as f: f.write(qrcode) try: showImage(self.qrcodePath) except Exception as e: WARN('无法弹出二维码图片 file://%s 。%s', self.qrcodePath, e) if self.qrcodeServer: INFO('请使用浏览器访问二维码,图片地址: %s', self.qrcodeURL) if self.mailAgent: if self.qrcode.getVal() is None: self.qrcode.setVal(qrcode) StartThread(self.sendEmail, daemon=True) else: self.qrcode.setVal(qrcode)
def urlGet(self, url, data=None, **kw): self.session.headers.update(kw) try: if data is None: return self.session.get(url) else: return self.session.post(url, data=data) except (requests.exceptions.SSLError, AttributeError): # by @staugur, @pandolia if self.session.verify: self.session.verify = False ERROR('无法和腾讯服务器建立私密连接,' ' 10 秒后将尝试使用非私密连接和腾讯服务器通讯。' '若您不希望使用非私密连接,请按 Ctrl+C 退出本程序。') time.sleep(10) WARN('已开始尝试使用非私密连接和腾讯服务器通讯。') requests.packages.urllib3.disable_warnings( requests.packages.urllib3.exceptions.InsecureRequestWarning ) return self.urlGet(url, data, **kw) else: raise