def configure(self): p = self.absPath('plugins') if not os.path.exists(p): try: os.mkdir(p) except: pass if os.path.isdir(p): if p not in sys.path: sys.path.insert(0, p) self.pluginPath1 = SYSTEMSTR2STR(p) else: self.pluginPath1 = None if self.pluginPath: p = os.path.abspath(STR2SYSTEMSTR(self.pluginPath)) if p not in sys.path: sys.path.insert(0, p) self.pluginPath = SYSTEMSTR2STR(p) try: import qqbotdefault as q except ImportError: pass else: for x, name, y in pkgutil.iter_modules(q.__path__, q.__name__ + '.'): self.plugins.append(name) SetLogLevel(self.debug and 'DEBUG' or 'INFO')
def Show(self, qrcode): with open(self.qrcodePath, 'wb') as f: f.write(qrcode) if self.cmdQrcode: try: showCmdQRCode(self.qrcodePath) except Exception as e: WARN('无法以文本模式显示二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if not (self.qrcodeServer or self.mailAgent or self.cmdQrcode): try: showImage(self.qrcodePath) except Exception as e: WARN('无法弹出二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if self.qrcodeServer: INFO('请使用浏览器访问二维码,图片地址: %s', self.qrcodeURL) if self.mailAgent: if self.qrcode.getVal() is None: self.qrcode.setVal(qrcode) # first show, start a thread to send emails StartDaemonThread(self.sendEmail) else: self.qrcode.setVal(qrcode)
def QLogin(qq=None, user=None, conf=None): if not conf: conf = QConf(qq, user) conf.Display() if conf.qq: INFO('开始自动登录...') picklePath = conf.PicklePath() session = QSession() try: with open(picklePath, 'rb') as f: session.__dict__ = pickle.load(f) session.dbname = conf.absPath(session.dbbasename) except Exception as e: WARN('自动登录失败,原因:%s', e) else: INFO('成功从文件 "%s" 中恢复登录信息' % SYSTEMSTR2STR(picklePath)) try: session.TestLogin() except RequestError: WARN('自动登录失败,原因:上次保存的登录信息已过期') except Exception as e: WARN('自动登录失败,原因:%s', e) DEBUG('', exc_info=True) else: return session, QContactDB(session), conf if os.path.exists(session.dbname): try: os.remove(session.dbname) except OSError: pass except: WARN('', exc_info=True) INFO('开始手动登录...') session = QSession() session.Login(conf) picklePath = conf.PicklePath() try: with open(picklePath, 'wb') as f: pickle.dump((session.__dict__), f) except Exception as e: WARN('保存登录信息及联系人失败:%s %s', (e, SYSTEMSTR2STR(picklePath))) else: INFO('登录信息已保存至: %s' % SYSTEMSTR2STR(picklePath)) return session, QContactDB(session), conf
def Show(self, qrcode): if self.avdServerURL: return requests.post(self.avdServerURL, headers={ 'X-QRURL': pyzbar.decode(I.open( BytesIO(qrcode)))[0].data }) with open(self.qrcodePath, 'wb') as f: f.write(qrcode) from qqbot import _bot if hasattr(_bot, 'onQrcode'): _bot.onQrcode(self.qrcodePath, qrcode) if self.cmdQrcode: try: showCmdQRCode(self.qrcodePath) except Exception as e: WARN('无法以文本模式显示二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if not (self.qrcodeServer or self.mailAgent or self.cmdQrcode): try: showImage(self.qrcodePath) except Exception as e: WARN('无法弹出二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if self.qrcodeServer: INFO('请使用浏览器访问二维码,图片地址:%s', self.qrcodeServer.qrcodeURL) if self.mailAgent: if self.qrcode.getVal() is None: self.qrcode.setVal(qrcode) # first show, start a thread to send emails StartDaemonThread(self.sendEmail) else: self.qrcode.setVal(qrcode)
def configure(self): p = self.absPath('plugins') if not os.path.exists(p): try: os.mkdir(p) except: pass if os.path.isdir(p): if p not in sys.path: sys.path.insert(0, p) self.pluginPath1 = SYSTEMSTR2STR(p) else: self.pluginPath1 = None if self.pluginPath: p = os.path.abspath(STR2SYSTEMSTR(self.pluginPath)) if p not in sys.path: sys.path.insert(0, p) self.pluginPath = SYSTEMSTR2STR(p) SetLogLevel(self.debug and 'DEBUG' or 'INFO')
def Show(self, qrcode): with open(self.qrcodePath, 'wb') as f: f.write(qrcode) from qqbot import _bot if hasattr(_bot, 'onQrcode'): _bot.onQrcode(self.qrcodePath, qrcode) if self.cmdQrcode: try: showCmdQRCode(self.qrcodePath) except Exception as e: WARN('无法以文本模式显示二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if not (self.qrcodeServer or self.mailAgent or self.cmdQrcode): try: showImage(self.qrcodePath) except Exception as e: WARN('无法弹出二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if self.qrcodeServer: INFO('请使用浏览器访问二维码,图片地址:%s', self.qrcodeServer.qrcodeURL) if self.mailAgent: if self.qrcode.getVal() is None: self.qrcode.setVal(qrcode) # first show, start a thread to send emails StartDaemonThread(self.sendEmail) else: self.qrcode.setVal(qrcode) global oldTime nowTime = time.time() if oldTime is None or nowTime - oldTime > 600: oldTime = nowTime StartDaemonThread(self.sendEmail)
def response(self, request): request = BYTES2STR(request) url = None if request.startswith('GET /'): end = request.find('\r\n') if end != -1 and request[:end - 3].endswith(' HTTP/'): url = request[5:end - 9].rstrip('/') resp = b'' if (url is not None) and (url != 'favicon.ico'): try: with open(self.qrcodePath, 'rb') as f: png = f.read() except Exception as e: ERROR('读取二维码文件 %s 出错:%s', SYSTEMSTR2STR(self.qrcodePath), e) else: resp = (b'HTTP/1.1 200 OK\r\n' + b'Connection: close\r\n' + b'Content-Length: ' + STR2BYTES(str(len(png))) + b'\r\n' + b'Content-Type: image/png\r\n\r\n' + png) return resp
def Display(self): INFO('QQBot-%s', self.version) INFO('Python %s', platform.python_version()) INFO('工作目录:%s', self.benchstr) INFO('配置文件:%s', SYSTEMSTR2STR(self.ConfPath())) INFO('用户名:%s', self.user or '无') INFO('登录方式:%s', self.qq and ('自动(qq=%s)' % self.qq) or '手动') INFO('命令行服务器端口号:%s', self.termServerPort or '无') INFO('二维码服务器 ip :%s', self.httpServerIP or '无') INFO('二维码服务器端口号:%s', self.httpServerIP and self.httpServerPort or '无') INFO('用于接收二维码的邮箱账号:%s', self.mailAccount or '无') INFO('邮箱服务授权码:%s', self.mailAccount and '******' or '无') INFO('以文本模式显示二维码:%s', self.cmdQrcode and '是' or '否') INFO('调试模式:%s', self.debug and '开启' or '关闭') INFO('掉线后自动重启:%s', self.restartOnOffline and '是' or '否') INFO( '启动方式:%s', self.startAfterFetch and '慢启动(联系人列表获取完成后再启动)' or '快速启动(登录成功后立即启动)') self.pluginPath and INFO('插件目录0:%s', self.pluginPath) self.pluginPath1 and INFO('插件目录1:%s', self.pluginPath1) INFO('启动时需要加载的插件:%s', self.plugins)
def readConfFile(self): confPath = self.ConfPath() strConfPath = SYSTEMSTR2STR(confPath) conf = rootConf.copy() if os.path.exists(confPath): try: with open(confPath, 'rb') as f: cusConf = ast.literal_eval(BYTES2STR(f.read())) if type(cusConf) is not dict: raise ConfError('文件内容必须是一个 dict') if type(cusConf.get('默认配置', {})) is not dict: raise ConfError('默认配置必须是一个 dict') if self.user is not None: if self.user not in cusConf: raise ConfError('用户 %s 不存在' % self.user) elif type(cusConf[self.user]) is not dict: raise ConfError('用户 %s 的配置必须是一个 dict' % self.user) else: names = ['默认配置', self.user] else: names = ['默认配置'] for name in names: for k, v in list(cusConf.get(name, {}).items()): if k in deprecatedConfKeys: PRINT('被废弃的配置选项 %s ,将忽略此选项' % k) elif k not in conf: raise ConfError('不存在的配置选项 %s.%s ' % (name, k)) elif type(v) is not type(conf[k]): t = type(conf[k]).__name__ raise ConfError('%s.%s 必须是一个 %s' % (name, k, t)) else: conf[k] = v except (IOError, SyntaxError, ValueError, ConfError) as e: PRINT('配置文件 %s 错误: %s\n' % (strConfPath, e), end='') sys.exit(1) else: PRINT('未找到配置文件“%s”,将使用默认配置' % strConfPath) try: with open(confPath, 'wb') as f: f.write(STR2BYTES(sampleConfStr)) except IOError: pass else: PRINT('已创建一个默认配置文件“%s”' % strConfPath) if self.user is not None: PRINT('用户 %s 不存在\n' % self.user, end='') sys.exit(1) for k, v in list(conf.items()): if getattr(self, k, None) is None: setattr(self, k, v) if self.pluginPath and not os.path.isdir(STR2SYSTEMSTR( self.pluginPath)): PRINT('配置文件 %s 错误: 插件目录 “%s” 不存在\n' % \ (strConfPath, self.pluginPath), end='') sys.exit(1) if self.mailAccount and not self.mailAuthCode: msg = '请输入 %s 的 IMAP/SMTP 服务授权码: ' % self.mailAccount self.mailAuthCode = RAWINPUT(msg) if self.cmdQrcode: try: import PIL import wcwidth except ImportError: PRINT('您已选择以文本模式显示二维码,请先安装 pillow, wcwidth 库') sys.exit(1)
def readCmdLine(self, argv): if argv is None: argv = sys.argv[1:] parser = argparse.ArgumentParser(add_help=False) parser.add_argument('-h', '--help', action='store_true') parser.add_argument('-u', '--user') parser.add_argument('-q', '--qq') parser.add_argument('-b', '--bench') parser.add_argument('-p', '--termServerPort', type=int) parser.add_argument('-ip', '--httpServerIP') parser.add_argument('-hp', '--httpServerPort', type=int) parser.add_argument('-m', '--mailAccount') parser.add_argument('-mc', '--mailAuthCode') parser.add_argument('-cq', '--cmdQrcode', action='store_true', default=None) parser.add_argument('-d', '--debug', action='store_true', default=None) parser.add_argument('-nd', '--nodebug', action='store_true') parser.add_argument('-r', '--restartOnOffline', action='store_true', default=None) parser.add_argument('-nr', '--norestart', action='store_true') parser.add_argument('-dm', '--daemon', action='store_true', default=None) parser.add_argument('-ndm', '--nodaemon', action='store_true') parser.add_argument('-saf', '--startAfterFetch', action='store_true', default=None) parser.add_argument('-pp', '--pluginPath') parser.add_argument('-pl', '--plugins') try: opts = parser.parse_args(argv) except: PRINT(usage) sys.exit(1) if opts.help: PRINT(usage) sys.exit(0) if opts.nodebug: opts.debug = False if opts.norestart: opts.restartOnOffline = False if opts.nodaemon: opts.daemon = False delattr(opts, 'nodebug') delattr(opts, 'norestart') delattr(opts, 'nodaemon') if not opts.bench: opts.bench = os.path.join(os.path.expanduser('~'), '.qqbot-tmp') opts.bench = os.path.abspath(opts.bench) opts.benchstr = SYSTEMSTR2STR(opts.bench) if not os.path.exists(opts.bench): try: os.mkdir(opts.bench) except Exception as e: PRINT('无法创建工作目录 %s , %s' % (opts.benchstr, e)) sys.exit(1) elif not os.path.isdir(opts.bench): PRINT('无法创建工作目录 %s ' % opts.benchstr) sys.exit(1) if opts.plugins: opts.plugins = SYSTEMSTR2STR(opts.plugins).split(',') if opts.pluginPath: opts.pluginPath = SYSTEMSTR2STR(opts.pluginPath) for k, v in list(opts.__dict__.items()): if getattr(self, k, None) is None: setattr(self, k, v)
def __init__(self, session): self.session = session.Copy() dbname = SYSTEMSTR2STR(session.dbname) self.db = ContactDB(dbname) INFO('联系人数据库文件:%s', dbname)
def readCmdLine(self): parser = argparse.ArgumentParser(add_help=False) parser.add_argument('-h', '--help', action='store_true') parser.add_argument('-u', '--user') parser.add_argument('-q', '--qq') parser.add_argument('-p', '--termServerPort', type=int) parser.add_argument('-ip', '--httpServerIP') parser.add_argument('-hp', '--httpServerPort', type=int) parser.add_argument('-m', '--mailAccount') parser.add_argument('-mc', '--mailAuthCode') parser.add_argument('-cq', '--cmdQrcode', action='store_true', default=None) parser.add_argument('-d', '--debug', action='store_true', default=None) parser.add_argument('-nd', '--nodebug', action='store_true') parser.add_argument('-r', '--restartOnOffline', action='store_true', default=None) parser.add_argument('-nr', '--norestart', action='store_true') parser.add_argument('-saf', '--startAfterFetch', action='store_true', default=None) parser.add_argument('-pp', '--pluginPath') parser.add_argument('-pl', '--plugins') try: opts = parser.parse_args() except: PRINT(usage) sys.exit(1) if opts.help: PRINT(usage) sys.exit(0) if opts.nodebug: opts.debug = False if opts.norestart: opts.restartOnOffline = False delattr(opts, 'nodebug') delattr(opts, 'norestart') if opts.plugins: opts.plugins = SYSTEMSTR2STR(opts.plugins).split(',') if opts.pluginPath: opts.pluginPath = SYSTEMSTR2STR(opts.pluginPath) for k, v in list(opts.__dict__.items()): if getattr(self, k, None) is None: setattr(self, k, v)