class VIP: def __init__(self, bot): self.bot = bot self.sessions = {} conf = Config("config.ini") self.DB = PostgreSQL(**conf.get("Database")) trans_conf = conf.get("Translation") i18n.set("locale", trans_conf['default_locale']) i18n.set("file_type", "json") i18n.load_path.append(trans_conf['path']) def __unload(self): self.DB.close() async def on_ready(self): print(f" [VIP] Successfully loaded.") @command('ν¬μΈνΈ', pass_context=True) async def vip_point(self, ctx): _, data = self.DB.rnf(f"SELECT uuid.point FROM uuid INNER JOIN discord ON (discord.uuid = uuid.uuid) WHERE discord.discord_id='{ctx.message.author.id}';") if not data: await ctx.bot.reply(t("messages.register_request")) else: await ctx.bot.reply(t("messages.vip_point").format(point=data[0][0]))
async def confirm_number_for_reservation(message:Message): if message.contact is not None: psql = PostgreSQL() psql.insert( ( 'first_name', 'last_name', 'month_of_reservation', 'day_of_reservation', 'time_of_reservation', 'phone_number', ), ( message.from_user.first_name, message.from_user.last_name, reservation_list[0], reservation_list[1], reservation_list[2], message.contact.phone_number ), 'reservations' ) psql.connection.close() await BotStates.show_main_menu_buttons.set() return await bot.send_message( chat_id=message.from_user.id, text = '*Столик успешно забронирован 😅*', reply_markup=btns.main_buttons() )
async def feedbacks(message: Message): psql = PostgreSQL() if message.text == 'Оставить отзыв ✍': await BotStates.get_feedback.set() return await message.answer( text='*Пожалуйста отправьте мне ваш отзыв!*', parse_mode=types.ParseMode.MARKDOWN) elif message.text == 'Прочитать отзывы 👍': feedbacks = psql.select(( 'author_first_name', 'author_last_name', 'feedback_text', 'date_created', ), 'feedbacks') for feedback in feedbacks: date_time = dt.strftime(feedback[-1], '%Y-%m-%d %H:%M') await bot.send_message( chat_id=message.from_user.id, text= f'*{feedback[0]} {feedback[1]}*\n\n{feedback[2]}\n\n_{date_time}_', parse_mode=types.ParseMode.MARKDOWN, ) else: await BotStates.show_main_menu_buttons.set() await bot.send_message( chat_id=message.from_user.id, text='Для выхода в главное меню нажмите ⏩ *Назад в меню*', parse_mode=types.ParseMode.MARKDOWN, reply_markup=btns.back_to_menu()) psql.connection.close() else: await BotStates.feedback_menu.set() return await bot.send_message(chat_id=message.from_user.id, text="Выберите опцию:", reply_markup=btns.feedback_buttons())
async def confirm_location_for_order(message: Message): if message.location is not None: psql = PostgreSQL() psql.insert( ( 'first_name', 'last_name', 'meal_name', 'meal_type', 'phone_number', 'location', ), ( message.from_user.first_name, message.from_user.last_name, order_list[0].split(' ')[1], order_list[0].split(' ')[0], order_list[1], f'{message.location.latitude} {message.location.longitude}' ), 'orders' ) await BotStates.check_clicked_button.set() psql.connection.close() return await bot.send_message( chat_id = message.from_user.id, text = 'Ваш заказ успешно сохранен' )
async def confirm_number_for_feedback(message:Message): if message.contact is not None: psql = PostgreSQL() psql.insert( ( 'author_id', 'author_first_name', 'author_last_name', 'author_phone_number', 'feedback_text', ), ( feedback_message.from_user.id, feedback_message.from_user.first_name, feedback_message.from_user.last_name, message.contact.phone_number, feedback_message.text, ), 'feedbacks' ) psql.connection.close() await BotStates.feedback_menu.set() return await bot.send_message( chat_id=message.from_user.id, text = '*Ваш отзыв успешно сохранён 😅*', reply_markup=btns.feedback_buttons() )
def __init__(self): if 'BLAST_IMAGE_DB_SERVICE_HOST' in os.environ: self._db = PostgreSQL(os.environ['POSTGRESQL_USER'], \ os.environ['POSTGRESQL_PASSWORD'], \ os.environ['BLAST_IMAGE_DB_SERVICE_HOST'], \ os.environ['BLAST_IMAGE_DB_SERVICE_PORT']) else: self._db = PostgreSQL('user', 'password', 'localhost', '5432')
def __init__(self): if 'IMAGE_DB_SERVICE_HOST' in os.environ: self.db = PostgreSQL(os.getenv('POSTGRESQL_USER'), \ os.getenv('POSTGRESQL_PASSWORD'), \ os.getenv('IMAGE_DB_SERVICE_HOST'), \ os.getenv('IMAGE_DB_SERVICE_PORT')) else: self.db = PostgreSQL('user', 'password', 'localhost', '5432')
def __init__(self, bot): self.bot = bot self.sessions = {} conf = Config("config.ini") self.DB = PostgreSQL(**conf.get("Database")) trans_conf = conf.get("Translation") i18n.set("locale", trans_conf['default_locale']) i18n.set("file_type", "json") i18n.load_path.append(trans_conf['path'])
def generate(self, **kwargs): conf = kwargs["conf"] # todo: 为测试方便,强制使用json conf["db_type"] = "json" if conf["db_type"] == "postgresql": PostgreSQL.set_conf(conf) return PostgreSQL elif conf["db_type"] == "json": JSON.set_conf(conf) return JSON
class Attendance: def __init__(self, bot): self.bot = bot self.session = {} conf = Config("config.ini") trans_conf = conf.get("Translation") i18n.set("locale", trans_conf['default_locale']) i18n.set("file_type", "json") i18n.load_path.append(trans_conf['path']) DB = PostgreSQL(**Config("config.ini").get("Database")) def __unload(self): self.DB.close() async def on_ready(self): print(" [ATd] Successfully loaded.") @checks.is_user(DB) @command("출석", pass_context=True) async def add_attendance(self, ctx): _, uuid = users.get_uuid(self.DB, ctx.message.author.id) if uuid is None: await ctx.bot.reply(t("messages.register_request")) return _, data = self.DB.rnf( f"SELECT date FROM attendance WHERE uuid='{uuid}' and date >= current_date;" ) if data: await ctx.bot.reply(t("messages.attendance_already")) return _, data = self.DB.rnf( f"INSERT INTO attendance (uuid) VALUES ('{uuid}') RETURNING date;") if data: await ctx.bot.reply( t("messages.attendance_success").format(time=data[0][0])) return await ctx.bot.reply(t("messages.error_call_admin")) @add_attendance.error async def error_add_attendance(self, error, ctx): if isinstance(error, CheckFailure): await ctx.bot.reply(t("messages.register_request")) print(error)
async def show_menu(callback: CallbackQuery): psql = PostgreSQL() if callback.data == 'breakfast': for breakfast_object in psql.select( ('name', 'meal_type', 'image_path', 'price'), 'meal', {"meal_type": 2}): resized_image = resize_image(breakfast_object[2]) await bot.send_photo( chat_id=callback.from_user.id, photo=open(resized_image, 'rb'), caption= f'_**Resto Завтраки:**_\nНазвание блюда: *{breakfast_object[0]}*\nЦена: *{breakfast_object[3]} сом*', parse_mode=types.ParseMode.MARKDOWN) else: psql.connection.close() elif callback.data == 'send_feedback': return await bot.send_message(chat_id=callback.from_user.id, text='*Пожалуйста оставьте отзыв:*', parse_mode=types.ParseMode.MARKDOWN)
class BlastImage(Resource): def __init__(self): if 'BLAST_IMAGE_DB_SERVICE_HOST' in os.environ: self._db = PostgreSQL(os.environ['POSTGRESQL_USER'], \ os.environ['POSTGRESQL_PASSWORD'], \ os.environ['BLAST_IMAGE_DB_SERVICE_HOST'], \ os.environ['BLAST_IMAGE_DB_SERVICE_PORT']) else: self._db = PostgreSQL('user', 'password', 'localhost', '5432') def get(self, tag): items = [] for obj in self._db.get(tag): items.append({'tag': obj['tag'], 'image': obj['image']}) return items
class BlastImage(Resource): def __init__(self): if 'IMAGE_DB_SERVICE_HOST' in os.environ: self.db = PostgreSQL(os.getenv('POSTGRESQL_USER'), \ os.getenv('POSTGRESQL_PASSWORD'), \ os.getenv('IMAGE_DB_SERVICE_HOST'), \ os.getenv('IMAGE_DB_SERVICE_PORT')) else: self.db = PostgreSQL('user', 'password', 'localhost', '5432') def get(self, tag): items = [] try: for obj in self.db.get(tag): items.append({'tag': obj['tag'], 'image': obj['image']}) except Exception as e: print(e, file=sys.stderr) return items
def run(): config = ConfigParser() config.read("config.ini") keys = ConfigParser() keys.read("keys.ini") db = PostgreSQL(user=keys.get("DB", "DB_USER"), password=keys.get("DB", "DB_PASSWORD"), host=keys.get("DB", "HOST"), port=keys.get("DB", "PORT"), database=keys.get("DB", "DB_NAME")) stargazerBot = StargazerBot(db=db, name=config.get("BOT", "NAME"), owner_id=int(keys.get("BOT", "OWNER_ID")), ext_path=config.get("BOT", "EXTENTION_PATH"), output_path=config.get("BOT", "OUTPUT_PATH"), command_prefix=config.get( "BOT", "COMMAND_PREFIX")) stargazerBot.run(keys.get("BOT", "TOKEN"))
class Administration: def __init__(self, bot): self.bot = bot self.session = {} conf = Config("config.ini") trans_conf = conf.get("Translation") i18n.set("locale", trans_conf['default_locale']) i18n.set("file_type", "json") i18n.load_path.append(trans_conf['path']) DB = PostgreSQL(**Config("config.ini").get("Database")) def __unload(self): self.DB.close() async def on_ready(self): print(" [ADm] Successfully loaded.") @command('종료', pass_context=True) async def ad_shutdown(self, ctx): Y = t('emojis.t') N = t('emojis.f') async def callback(): await self.bot.close() exit(1) await interact.interact_with_reaction(self.bot, ctx.message.author, t('admin.shutdown_really'), callback, emojis=[Y, N]) @group('관리', invoke_without_command=True) @checks.is_crescendo() async def administration(self, *_): pass @administration.group('유저', invoke_without_command=True) @checks.is_crescendo() async def ad_user(self, *_): pass @ad_user.command("조회", pass_context=True) @checks.is_crescendo() async def ad_view(self, ctx, *args): if not args: user = ctx.message.author.id else: user, *remains = args user = users.parse_mention(user) user, uuid = users.get_uuid(self.DB, user) if uuid is None: await ctx.bot.reply(t("admin.no_uuid_found")) return point = users.get_point(self.DB, uuid) _fake_ctx = Context(prefix="\0", message=Message(reactions=[], author={"id": user})) valid = checks.is_valid(self.DB, False)(_fake_ctx) await ctx.bot.reply(t("admin.view_point") \ .format( _target=user, _dsid=user, _uuid=uuid, _active=valid, _point=point ) ) @ad_user.command("가입", pass_context=True) @checks.is_crescendo() async def ad_member(self, ctx, *args): bot = ctx.bot if not args: return user, *_ = args user = users.parse_mention(user) if not len(user) == 18: await bot.reply(t('admin.invalid_discord_id')) return _, uuid = users.get_uuid(self.DB, user) if uuid: await bot.reply(t("admin.remote_register_already")) return _, data = self.DB.rnf( f"INSERT INTO uuid (point) VALUES (0) RETURNING uuid;") uuid = data[0][0] _, data = self.DB.rnf( f"INSERT INTO discord (uuid, discord_id) VALUES ('{uuid}', '{user}') RETURNING uuid;" ) if data: await bot.reply( t('admin.remote_register_success').format(_discord=user, _uuid=uuid)) else: await bot.reply(t('admin.remote_register_failed')) @ad_user.command("탈퇴", pass_context=True) @checks.is_crescendo() async def ad_unregister(self, ctx, *args): bot = ctx.bot if not args: await bot.reply(t("admin.remote_unregister_require_specification")) return user, *args = args user = users.parse_mention(user) _, uuid = users.get_uuid(self.DB, user) if not uuid: await bot.reply(t('admin.remote_unregister_not_user')) return Y = t("emojis.t") N = t("emojis.f") if not len(user) == 18: await bot.reply(t('admin.invalid_discord_id')) return await self.ad_view.callback(self, ctx, user) async def callback(): self.DB.run(f"DELETE FROM attendance WHERE uuid='{uuid}';") self.DB.run(f"DELETE FROM discord WHERE uuid='{uuid}';") self.DB.run(f"DELETE FROM uuid WHERE uuid='{uuid}';") await bot.reply(t('admin.remote_unregister_success')) await interact.interact_with_reaction( ctx.bot, ctx.message.author, t("admin.remote_unregister_really"), callback, emojis=[Y, N]) @administration.error @ad_user.error @ad_view.error async def perm_error(self, error, ctx): if isinstance(error, CheckFailure): await ctx.bot.reply(t("messages.less_permission")) ctx.bot.send_message( ctx.bot.get_channel("459291184146153482"), t("error_remote_report").format(_server=ctx.message.server, _channel=ctx.message.channel.id, _error=repr(error)))
def __init__(self, engine, path="./pages/sso"): self.engine = engine self.db = PostgreSQL(**Config().get("Database")) self.parent = SingleWebPage(name="/sso", url_prefix="/sso", description="SSO (OAuth2소셜로그인)", template_folder=path) self.mobile_platform = ['android', 'iphone', 'blackberry'] def render_template(template_name, **kwargs): return render_template_string( open( f"{realpath(self.parent.bp.template_folder)}/{template_name}", "r", encoding="UTF-8").read(), google_analystics=open( f"{realpath(self.parent.bp.template_folder)}/../global/gtag.html", "r", encoding="UTF-8").read(), **kwargs) def send_raw(folder, fname): return send_from_directory( f"{realpath(self.parent.bp.template_folder)}", f"{folder}/{fname}") @self.parent.bp.route('/twitch/') @cross_origin( ["http://enakbot.return0927.xyz", "http://sso.return0927.xyz"]) def twitch(*args, **kwargs): token = request.args.get("access_token") if token: resp = get("https://api.twitch.tv/kraken/user", headers={ "Accept": "application/vnd.twitchtv.v5+json", "Client-ID": Config().get("Cresentials")['twitch-cid'], "Authorization": f"OAuth {token}" }).json() _name = resp['display_name'] _uid = resp['name'] _tid = resp['_id'] _email = resp.get('email') _first_join, _uuid = self.db.add_user("twitch", email=_email, name=_name, uid=_uid, tid=_tid, now=session.get("uuid")) session['uuid'] = _uuid if not isinstance(session.get('li_platform'), dict): session['li_platform'] = {} session['li_platform']['twitch'] = {"name": _name} return render_template("ok.html") else: return render_template("index.html") @self.parent.bp.route("/discord/") @cross_origin( ["http://enakbot.return0927.xyz", "http://sso.return0927.xyz"]) def discord(*args, **kwargs): if "sso.return0927.xyz" in request.url: return render_template("index.html") token = request.args.get("access_token") if token: resp = get("https://discordapp.com/api/users/@me", headers={ "Authorization": f"Bearer {token}" }).json() _email = resp['email'] _name = resp['username'] _id = resp['id'] _first_join, _uuid = self.db.add_user("discord", email=_email, name=_name, uid=_id, now=session.get("uuid")) session['uuid'] = _uuid if not isinstance(session.get('li_platform'), dict): session['li_platform'] = {} session['li_platform']['discord'] = {"name": _name} return render_template("ok.html") else: return "." @self.parent.bp.route( "/<any(css, img, js, media):folder>/<path:filename>") def statics(folder, filename): return send_raw(folder, filename)
class Member: def __init__(self, bot): self.bot = bot self.session = {} conf = Config("config.ini") trans_conf = conf.get("Translation") i18n.set("locale", trans_conf['default_locale']) i18n.set("file_type", "json") i18n.load_path.append(trans_conf['path']) DB = PostgreSQL(**Config("config.ini").get("Database")) def __unload(self): self.DB.close() async def on_ready(self): print(" [Mmb] Successfully loaded.") @command("가입", pass_context=True) @checks.is_not_user(DB) async def register(self, ctx): bot = ctx.bot if not checks.is_valid(self.DB, False)(ctx): await bot.reply(t("messages.register_inavailable")) return Y = t("emojis.t") N = t("emojis.f") o = await bot.reply(t("messages.agreements")) await bot.add_reaction(o, Y) await bot.add_reaction(o, N) r = await bot.wait_for_reaction(emoji=[Y, N], timeout=60, message=o, user=ctx.message.author) await bot.delete_message(o) if r and str(r.reaction.emoji) == Y: _, data = self.DB.rnf( f"INSERT INTO uuid (point) VALUES (0) RETURNING uuid;") _, data = self.DB.rnf( f"INSERT INTO discord (uuid, discord_id) VALUES ('{data[0][0]}', '{ctx.message.author.id}') RETURNING uuid;" ) if data: await bot.reply(t('messages.register_success')) else: await bot.reply(t('messages.error_call_admin')) @command("탈퇴", pass_context=True) @checks.is_user(DB) @checks.is_valid(DB) async def unregister(self, ctx): bot = ctx.bot Y = t("emojis.t") N = t("emojis.f") o = await bot.reply(t("messages.unregister_really")) await bot.add_reaction(o, Y) await bot.add_reaction(o, N) r = await bot.wait_for_reaction(emoji=[Y, N], timeout=60, message=o, user=ctx.message.author) await bot.delete_message(o) if r and str(r.reaction.emoji) == Y: _, uuid = users.get_uuid(self.DB, ctx.message.author.id) self.DB.run(f"DELETE FROM attendance WHERE uuid='{uuid}';") _, data = self.DB.rnf( f"UPDATE uuid SET valid=false WHERE uuid='{uuid}' RETURNING uuid;" ) if data: await bot.reply(t('messages.unregister_success')) else: await bot.reply(t('messages.error_call_admin')) @register.error async def register_error(self, error, ctx): if isinstance(error, CheckFailure): await ctx.bot.reply(t('messages.register_already')) @unregister.error async def unregister_error(self, error, ctx): if isinstance(error, CheckFailure): await ctx.bot.reply(t('messages.unregister_inavailable'))
async def show_menu(callback: CallbackQuery): """Функция которая выводит список блюд по категориям. Всё зависит от нажатой inline-кнопки.""" psql = PostgreSQL() await BotStates.user_confirmation.set() if callback.data == 'breakfast': for breakfast in psql.select( ( 'name', 'image_path', 'price', 'meal_type' ), 'meal', {"meal_type": 2} ): image = resize_image(breakfast[1]) await bot.send_photo( chat_id=callback.from_user.id, photo=open(image, 'rb'), caption=f'_Название:_ *{breakfast[0]}*\n_Цена:_ *{breakfast[2]} сом*', parse_mode=types.ParseMode.MARKDOWN, reply_markup=ibtns.make_order((breakfast[-1], breakfast[0])) ) else: return await bot.send_message( chat_id=callback.from_user.id, text='Нажмите "Назад" чтобы вернуться в Главное Меню!', reply_markup=btns.back_to_menu() ) elif callback.data == 'lunch': for lunch in psql.select( ( 'name', 'image_path', 'price', 'meal_type' ), 'meal', {"meal_type": 3} ): image = resize_image(lunch[1]) await bot.send_photo( chat_id=callback.from_user.id, photo=open(image, 'rb'), caption=f'_Название:_ *{lunch[0]}*\n_Цена:_ *{lunch[2]} сом*', parse_mode=types.ParseMode.MARKDOWN, reply_markup=ibtns.make_order((lunch[-1], lunch[0])) ) else: return await bot.send_message( chat_id=callback.from_user.id, text='Нажмите "Назад" чтобы вернуться в Главное Меню!', reply_markup=btns.back_to_menu() ) elif callback.data == 'dinner': for dinner in psql.select( ( 'name', 'image_path', 'price', 'meal_type' ), 'meal', {"meal_type": 4} ): image = resize_image(dinner[1]) await bot.send_photo( chat_id=callback.from_user.id, photo=open(image, 'rb'), caption=f'_Название:_ *{dinner[0]}*\n_Цена:_ *{dinner[2]} сом*', parse_mode=types.ParseMode.MARKDOWN, reply_markup=ibtns.make_order((dinner[-1], dinner[0])) ) else: return await bot.send_message( chat_id=callback.from_user.id, text='Нажмите "Назад" чтобы вернуться в Главное Меню!', reply_markup=btns.back_to_menu() ) elif callback.data == 'primary_meal': for primary_meal in psql.select( ( 'name', 'image_path', 'price', 'meal_type' ), 'meal', {"meal_type": 1} ): image = resize_image(primary_meal[1]) await bot.send_photo( chat_id=callback.from_user.id, photo=open(image, 'rb'), caption=f'_Название:_ *{primary_meal[0]}*\n_Цена:_ *{primary_meal[2]} сом*', parse_mode=types.ParseMode.MARKDOWN, reply_markup=ibtns.make_order((primary_meal[-1], primary_meal[0])) ) else: return await bot.send_message( chat_id=callback.from_user.id, text='Нажмите "Назад в меню" чтобы вернуться в Главное Меню!', reply_markup=btns.back_to_menu() )
def __init__(self, engine, path="./pages/rank"): self.engine = engine self.db = PostgreSQL(**Config().get("AppDatabase")) self.web_db = PostgreSQL(**Config().get("Database")) self.parent = SingleWebPage(name="/ranks", url_prefix="/ranks", description="Rank (랭킹)", template_folder=path) self.mobile_platform = ['android', 'iphone', 'blackberry'] def render_template(template_name, **kwargs): return render_template_string( open( f"{realpath(self.parent.bp.template_folder)}/{template_name}", "r", encoding="UTF-8").read(), google_analystics=open( f"{realpath(self.parent.bp.template_folder)}/../global/gtag.html", "r", encoding="UTF-8").read(), **kwargs) def send_raw(folder, fname): return send_from_directory( f"{realpath(self.parent.bp.template_folder)}", f"{folder}/{fname}") @self.parent.bp.route("/") def root(*args, **kwargs): return """<script>location.href='/';</script>""" @self.parent.bp.route('/<path:channel>') def ranks(channel, **kwargs): channels = [ *{ *[ x[0] for x in self.db.execute( "SELECT channel FROM points;").fetchall() ] } ] if not channel in channels: return """<script>alert('올바르지 않은 채널명입니다.');location.href='/';</script>""" sel = request.args.get("view", "") if sel == "my": _logged_in_platforms = session.get("li_platform") if not (_logged_in_platforms and "twitch" in _logged_in_platforms): return redirect(f"/login/?redirect={request.url}") # return repr(session['uuid']) tid = self.web_db.execute( f"SELECT twitch FROM users WHERE uuid='{session['uuid']}';" ).fetchall()[0][0] uid = self.web_db.execute( f"SELECT uid FROM twitch WHERE tid='{tid}';").fetchall( )[0][0] data = self.db.execute( f"SELECT channel, point FROM points WHERE \"user\"='{uid}' ORDER BY channel DESC;" ).fetchall() _out = [] for c, p in data: _channel_data = self.db.execute( f"SELECT \"user\", point, RANK() OVER(ORDER BY point DESC) FROM points WHERE channel='{c}' ORDER BY point DESC;" ).fetchall() _out.append( [c, p, [u for u, _, _ in _channel_data].index(uid)]) return render_template( "my.html", debugstring=f"?{time()}" if self.is_debugging() else "", session=session, user=_logged_in_platforms['twitch']['name'], channel=channel, data=_out) elif sel == "": data = self.db.execute( f"SELECT \"user\", point, RANK() OVER(ORDER BY point DESC) FROM points WHERE channel='{channel}' ORDER BY point DESC;" ).fetchall() if session.get("li_platform") and "twitch" in session.get( "li_platform"): tid = self.web_db.execute( f"SELECT twitch FROM users WHERE uuid='{session['uuid']}';" ).fetchall()[0][0] uid = self.web_db.execute( f"SELECT uid FROM twitch WHERE tid='{tid}';").fetchall( )[0][0] data = [[u[:2] + ("*" * (len(u) - 2)), v, r, u == uid] for u, v, r in data] data.sort(key=lambda x: x[3]) me = data[-1] data = [me] + data[:-1] else: data = [[u[:2] + ("*" * (len(u) - 2)), v, r, False] for u, v, r in data] p = [p for u, p, r, me in data] top_5 = sum(p[:5]) / sum(p) * 100 top_10 = sum(p[:10]) / sum(p) * 100 return render_template( "index.html", debugstring=f"?{time()}" if self.is_debugging() else "", session=session, channel=channel, data=data[:100], perc_10=top_10, perc_5=top_5, sel=sel) else: return """<script>alert('없는 페이지입니다.');history.go(-1);</script>""" @self.parent.bp.route( "/<any(css, img, js, media):folder>/<path:filename>") def statics(folder, filename): return send_raw(folder, filename)