def __init__(self, *, data_path: str, scheduler: AsyncIOScheduler, quart_app: Quart, bot_api: Api, verinfo: str = None): # initialize config is_packaged = "_MEIPASS" in dir(sys) if is_packaged: basepath = os.path.dirname(sys.argv[0]) else: basepath = os.path.dirname(__file__) dirname = os.path.abspath(os.path.join(basepath, data_path)) if not os.path.exists(dirname): os.makedirs(dirname) config_f_path = os.path.join(dirname, "yobot_config.json") if is_packaged: default_config_f_path = os.path.join(sys._MEIPASS, "packedfiles", "default_config.json") else: default_config_f_path = os.path.join(os.path.dirname(__file__), "default_config.json") with open(default_config_f_path, "r", encoding="utf-8") as config_file: self.glo_setting = json.load(config_file) if not os.path.exists(config_f_path): shutil.copyfile(default_config_f_path, config_f_path) print("设置已初始化,发送help获取帮助") boss_filepath = os.path.join(dirname, "boss3.json") if not os.path.exists(boss_filepath): if is_packaged: default_boss_filepath = os.path.join(sys._MEIPASS, "packedfiles", "default_boss.json") else: default_boss_filepath = os.path.join(os.path.dirname(__file__), "default_boss.json") shutil.copyfile(default_boss_filepath, boss_filepath) pool_filepath = os.path.join(dirname, "pool3.json") if not os.path.exists(pool_filepath): if is_packaged: default_pool_filepath = os.path.join(sys._MEIPASS, "packedfiles", "default_pool.json") else: default_pool_filepath = os.path.join(os.path.dirname(__file__), "default_pool.json") shutil.copyfile(default_pool_filepath, pool_filepath) with open(config_f_path, "r+", encoding="utf-8") as config_file: cfg = json.load(config_file) for k in self.glo_setting.keys(): if k in cfg: self.glo_setting[k] = cfg[k] config_file.seek(0) config_file.truncate() json.dump(self.glo_setting, config_file, indent=4) if verinfo is None: verinfo = updater.get_version(self.Version, self.Version_id) print(verinfo['ver_name']) modified = False # initialize database ybdata.init(os.path.join(dirname, 'yobotdata.db')) # initialize web path if not self.glo_setting.get("public_address"): try: res = requests.get("http://ip-api.com/json/?fields=8192") ipaddr = res.json()["query"] except: with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: s.connect(("8.8.8.8", 53)) ipaddr = s.getsockname()[0] self.glo_setting["public_address"] = "http://{}:{}/".format( ipaddr, self.glo_setting["port"], ) modified = True if not self.glo_setting["public_address"].endswith("/"): self.glo_setting["public_address"] += "/" modified = True if not self.glo_setting["public_basepath"].startswith("/"): self.glo_setting["public_basepath"] = "/" + \ self.glo_setting["public_basepath"] modified = True if not self.glo_setting["public_basepath"].endswith("/"): self.glo_setting["public_basepath"] += "/" modified = True # initialize update time if self.glo_setting["update-time"] == "random": self.glo_setting["update-time"] = "{:02d}:{:02d}".format( random.randint(2, 4), random.randint(0, 59)) modified = True # initialize client salt if self.glo_setting["client_salt"] is None: self.glo_setting["client_salt"] = web_util.rand_string(16) modified = True # save initialization if modified: with open(config_f_path, "w", encoding="utf-8") as config_file: json.dump(self.glo_setting, config_file, indent=4) # initialize utils templating.Ver = self.Version[2:-1] # generate random secret_key if (quart_app.secret_key is None): quart_app.secret_key = bytes( (random.randint(0, 255) for _ in range(16))) # add mimetype mimetypes.init() mimetypes.add_type('application/javascript', '.js') mimetypes.add_type('image/webp', '.webp') # add route for static files @quart_app.route(urljoin(self.glo_setting["public_basepath"], "assets/<path:filename>"), methods=["GET"]) async def yobot_static(filename): return await send_file( os.path.join(os.path.dirname(__file__), "public", "static", filename)) # add route for output files if not os.path.exists(os.path.join(dirname, "output")): os.mkdir(os.path.join(dirname, "output")) @quart_app.route(urljoin(self.glo_setting["public_basepath"], "output/<path:filename>"), methods=["GET"]) async def yobot_output(filename): return await send_file(os.path.join(dirname, "output", filename)) # openCC self.ccs2t = OpenCC(self.glo_setting.get("zht_out_style", "s2t")) self.cct2s = OpenCC("t2s") # update runtime variables self.glo_setting.update({"dirname": dirname, "verinfo": verinfo}) kwargs = { "glo_setting": self.glo_setting, "bot_api": bot_api, "scheduler": scheduler, "app": quart_app, } # load plugins plug_all = [ updater.Updater(**kwargs), switcher.Switcher(**kwargs), yobot_msg.Message(**kwargs), gacha.Gacha(**kwargs), jjc_consult.Consult(**kwargs), boss_dmg.Boss_dmg(**kwargs), push_news.News(**kwargs), calender.Event(**kwargs), homepage.Index(**kwargs), marionette.Marionette(**kwargs), login.Login(**kwargs), settings.Setting(**kwargs), web_util.WebUtil(**kwargs), clan_battle.ClanBattle(**kwargs), ] self.plug_passive = [p for p in plug_all if p.Passive] self.plug_active = [p for p in plug_all if p.Active] for p in plug_all: if p.Request: p.register_routes(quart_app) # load new plugins self.plug_new = [ custom.Custom(**kwargs), test.Test(**kwargs), challenge_auto_reminder.auto_reminder(**kwargs), miner.mining_query(**kwargs) ]
def __init__(self, *, data_path: str, scheduler: AsyncIOScheduler, quart_app: Quart, bot_api: Api, verinfo: str = None): # initialize config is_packaged = "_MEIPASS" in dir(sys) if is_packaged: basepath = os.path.dirname(sys.argv[0]) else: basepath = os.path.dirname(__file__) dirname = os.path.abspath(os.path.join(basepath, data_path)) if not os.path.exists(dirname): os.makedirs(dirname) config_f_path = os.path.join(dirname, "yobot_config.json") if is_packaged: default_config_f_path = os.path.join(sys._MEIPASS, "packedfiles", "default_config.json") else: default_config_f_path = os.path.join(os.path.dirname(__file__), "packedfiles", "default_config.json") with open(default_config_f_path, "r", encoding="utf-8") as config_file: self.glo_setting = json.load(config_file) if not os.path.exists(config_f_path): with open(config_f_path, "w") as f: f.write("{}") print("设置已初始化,发送help获取帮助") boss_filepath = os.path.join(dirname, "boss3.json") if not os.path.exists(boss_filepath): if is_packaged: default_boss_filepath = os.path.join(sys._MEIPASS, "packedfiles", "default_boss.json") else: default_boss_filepath = os.path.join(os.path.dirname(__file__), "packedfiles", "default_boss.json") shutil.copyfile(default_boss_filepath, boss_filepath) pool_filepath = os.path.join(dirname, "pool3.json") if not os.path.exists(pool_filepath): if is_packaged: default_pool_filepath = os.path.join(sys._MEIPASS, "packedfiles", "default_pool.json") else: default_pool_filepath = os.path.join(os.path.dirname(__file__), "packedfiles", "default_pool.json") shutil.copyfile(default_pool_filepath, pool_filepath) for e in os.environ: if e.startswith("YOBOT_"): k = e[6:].lower() self.glo_setting[k] = os.environ[e] with open(config_f_path, "r", encoding="utf-8-sig") as config_file: cfg = json.load(config_file) for k in self.glo_setting.keys(): if k in cfg: self.glo_setting[k] = cfg[k] if verinfo is None: verinfo = updater.get_version(self.Version, self.Version_id) print(verinfo['ver_name']) # initialize database ybdata.init(os.path.join(dirname, 'yobotdata.db')) # enable gzip if self.glo_setting["web_gzip"] > 0: gzipped_types = { 'text/html', 'text/javascript', 'text/css', 'application/json' } @quart_app.after_request async def gzip_response(response): accept_encoding = request.headers.get('Accept-Encoding', '') if (response.status_code < 200 or response.status_code >= 300 or len(await response.get_data()) < 1024 or 'gzip' not in accept_encoding.lower() or 'Content-Encoding' in response.headers): return response gzip_buffer = BytesIO() gzip_file = gzip.GzipFile( mode='wb', compresslevel=self.glo_setting["web_gzip"], fileobj=gzip_buffer) gzip_file.write(await response.get_data()) gzip_file.close() gzipped_response = gzip_buffer.getvalue() response.set_data(gzipped_response) response.headers['Content-Encoding'] = 'gzip' response.headers['Content-Length'] = len(gzipped_response) return response # initialize web path if not self.glo_setting.get("public_address"): try: res = requests.get("http://api.ipify.org/") ipaddr = res.text except: with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: s.connect(("8.8.8.8", 53)) ipaddr = s.getsockname()[0] self.glo_setting["public_address"] = "http://{}:{}/".format( ipaddr, self.glo_setting["port"], ) if not self.glo_setting["public_address"].endswith("/"): self.glo_setting["public_address"] += "/" if not self.glo_setting["public_basepath"].startswith("/"): self.glo_setting["public_basepath"] = "/" + \ self.glo_setting["public_basepath"] if not self.glo_setting["public_basepath"].endswith("/"): self.glo_setting["public_basepath"] += "/" # initialize update time if self.glo_setting["update-time"] == "random": self.glo_setting["update-time"] = "{:02d}:{:02d}".format( random.randint(2, 4), random.randint(0, 59)) # initialize client salt if self.glo_setting["client_salt"] is None: self.glo_setting["client_salt"] = web_util.rand_string(16) # save initialization with open(config_f_path, "w", encoding="utf-8") as config_file: json.dump(self.glo_setting, config_file, indent=4) # initialize utils templating.Ver = self.Version[2:-1] # generate random secret_key if (quart_app.secret_key is None): quart_app.secret_key = bytes( (random.randint(0, 255) for _ in range(16))) # add mimetype mimetypes.init() mimetypes.add_type('application/javascript', '.js') mimetypes.add_type('image/webp', '.webp') # add route for static files @quart_app.route(urljoin(self.glo_setting["public_basepath"], "assets/<path:filename>"), methods=["GET"]) async def yobot_static(filename): accept_encoding = request.headers.get('Accept-Encoding', '') origin_file = os.path.join(os.path.dirname(__file__), "public", "static", filename) if ('gzip' not in accept_encoding.lower() or self.glo_setting['web_gzip'] == 0): return await send_file(origin_file) gzipped_file = os.path.abspath( os.path.join( os.path.dirname(__file__), "public", "static", filename + "." + self.Version[1:-1] + ".gz", )) if not os.path.exists(gzipped_file): if not os.path.exists(origin_file): return "404 not found", 404 with open(origin_file, 'rb') as of, open(gzipped_file, 'wb') as gf: with gzip.GzipFile( mode='wb', compresslevel=self.glo_setting["web_gzip"], fileobj=gf, ) as gzip_file: gzip_file.write(of.read()) response = await make_response(await send_file(gzipped_file)) response.mimetype = (mimetypes.guess_type( os.path.basename(origin_file))[0] or "application/octet-stream") response.headers['Content-Encoding'] = 'gzip' response.headers['Vary'] = 'Accept-Encoding' return response # add route for output files if not os.path.exists(os.path.join(dirname, "output")): os.mkdir(os.path.join(dirname, "output")) @quart_app.route(urljoin(self.glo_setting["public_basepath"], "output/<path:filename>"), methods=["GET"]) async def yobot_output(filename): return await send_file(os.path.join(dirname, "output", filename)) # openCC self.ccs2t = OpenCC(self.glo_setting.get("zht_out_style", "s2t")) self.cct2s = OpenCC("t2s") # filter self.black_list = set(self.glo_setting["black-list"]) self.black_list_group = set(self.glo_setting["black-list-group"]) self.white_list_group = set(self.glo_setting["white-list-group"]) # update runtime variables self.glo_setting.update({"dirname": dirname, "verinfo": verinfo}) kwargs = { "glo_setting": self.glo_setting, "bot_api": bot_api, "scheduler": scheduler, "app": quart_app, } # load plugins plug_all = [ updater.Updater(**kwargs), switcher.Switcher(**kwargs), yobot_msg.Message(**kwargs), gacha.Gacha(**kwargs), jjc_consult.Consult(**kwargs), push_news.News(**kwargs), calender.Event(**kwargs), homepage.Index(**kwargs), marionette.Marionette(**kwargs), login.Login(**kwargs), settings.Setting(**kwargs), web_util.WebUtil(**kwargs), clan_battle.ClanBattle(**kwargs), ] self.plug_passive = [p for p in plug_all if p.Passive] self.plug_active = [p for p in plug_all if p.Active] for p in plug_all: if p.Request: p.register_routes(quart_app) # load new plugins self.plug_new = [ miner.Miner(**kwargs), group_leave.GroupLeave(**kwargs), custom.Custom(**kwargs), ]