From f3f38973452e1246e7ee0a3eb6589e37b1908f37 Mon Sep 17 00:00:00 2001 From: SkyEye_FAST Date: Sat, 27 Jan 2024 20:03:53 +0800 Subject: [PATCH] Use WTForms and Flask-WTF --- .flaskenv | 2 + .gitignore | 1 + app.py | 98 ++++++++++++++------------------------------ base.py | 87 +++++++++++++++++++++++++++++++++++++++ configuration.toml | 5 +++ requirements.txt | 7 +++- templates/index.html | 6 +-- wsgi.py | 12 ++++++ 8 files changed, 146 insertions(+), 72 deletions(-) create mode 100644 .flaskenv create mode 100644 base.py create mode 100644 configuration.toml create mode 100644 wsgi.py diff --git a/.flaskenv b/.flaskenv new file mode 100644 index 0000000..dc5dc0f --- /dev/null +++ b/.flaskenv @@ -0,0 +1,2 @@ +FLASK_DEBUG = 1 +BABEL_DEFAULT_LOCALE = zh \ No newline at end of file diff --git a/.gitignore b/.gitignore index ef4206f..8d6f8d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__/ .idea .vercel +.env \ No newline at end of file diff --git a/app.py b/app.py index a69c3d6..b9b9c4f 100644 --- a/app.py +++ b/app.py @@ -1,91 +1,52 @@ # -*- encoding: utf-8 -*- """Minecraft中文标准译名查询网页,使用Flask编写的后端框架""" -import json -import re -from pathlib import Path +from os import getenv from datetime import date -from flask import Flask, render_template, request, send_from_directory -LANG_DIR = Path(__file__).resolve().parent / "lang" - -# 读取语言文件 -print("开始读取语言文件。") -file_list = [ - "en_us.json", - "zh_cn.json", - "zh_hk.json", - "zh_tw.json", - "lzh.json", -] -data = {} -for file in file_list: - with open(LANG_DIR / file, "r", encoding="utf-8") as f: - data[file.split(".", maxsplit=1)[0]] = json.load(f) - -# 读取补充字符串 -with open(LANG_DIR / "supplements.json", "r", encoding="utf-8") as f: - supplements = json.load(f) -for lang in ["zh_cn", "zh_hk", "zh_tw", "lzh"]: - data[lang].update(supplements[lang]) -print(f"已补充{len(supplements['zh_cn'])}条字符串。") +from flask import Flask, render_template, request, send_from_directory +from flask_wtf import FlaskForm +from wtforms import StringField, SubmitField +from base import data, is_valid_key, get_translation flask_app = Flask(__name__) +flask_app.config["SECRET_KEY"] = getenv("SECRET_KEY", "dev") +page_lang = { + "zh_cn": { + "lang_name": "简体中文(中国大陆)", + "query_input_label": "查询的源字符串内容:", + "translation_key_select_label": "选择本地化键名:", + "query_button": "查询", + }, + "en_us": { + "lang_name": "English (United States)", + "query_input_label": "Source string content to be queried: ", + "translation_key_select_label": "Select translation key:", + "query_button": "QUERY", + }, +} -def is_valid_key(translation_key: str): - """判断是否为有效键名""" - - prefixes = ( - "block.", - "item.minecraft.", - "entity.minecraft.", - "biome.", - "effect.minecraft.", - "enchantment.minecraft.", - "trim_pattern.", - "upgrade.", - ) - - if ( - translation_key.startswith(prefixes) - and not re.match( - r"(block\.minecraft\.|item\.minecraft\.|entity\.minecraft\.)[^.]*\.", - translation_key, - ) - and translation_key - not in ["block.minecraft.set_spawn", "entity.minecraft.falling_block_type"] - and "pottery_shard" not in translation_key - ): - return True - - # 匹配进度键名 - if re.match(r"advancements\.(.*)\.title", translation_key): - return True - return False +class QueryForm(FlaskForm): + """查询表单""" - -def get_translation(query_str: str): - """在语言文件中匹配含有输入内容的源字符串""" - translation = {} - for k, v in data["en_us"].items(): - if query_str.lower() in v.lower(): - element = {lang: content.get(k, "?") for lang, content in data.items()} - translation[k] = element - return translation + source_string = StringField("查询的源字符串内容:") + submit = SubmitField("查询") @flask_app.route("/", methods=["GET", "POST"]) def index(): """主页面""" + form = QueryForm() + + query_str = form.source_string.data selected_option = request.form.get("options", "") - query_str = request.form.get("query-input", "") if not query_str: selected_option = "" # 清空下拉列表选择项 - if request.method == "POST": + if form.validate_on_submit(): translation = get_translation(query_str) keys = [k for k in translation if is_valid_key(k)] selected_translation = translation.get(selected_option, {}) @@ -97,6 +58,7 @@ def index(): return render_template( "index.html", + form=form, source=source_str, key=selected_option, input_value=query_str, @@ -114,4 +76,4 @@ def favicon(): if __name__ == "__main__": - flask_app.run(debug=True) + flask_app.run() diff --git a/base.py b/base.py new file mode 100644 index 0000000..0f8ea2d --- /dev/null +++ b/base.py @@ -0,0 +1,87 @@ +# -*- encoding: utf-8 -*- +"""基础文件""" + +import re +import json +import sys +import tomllib as tl +from pathlib import Path + +# 当前绝对路径 +P = Path(__file__).resolve().parent + +# 加载配置 +CONFIG_DIR = P / "configuration.toml" +if not CONFIG_DIR.exists(): + print("\n无法找到配置文件,请将配置文件放置在与此脚本同级的目录下。") + sys.exit() +with open(CONFIG_DIR, "rb") as f: + config = tl.load(f) + +LANG_DIR = P / config["language_folder"] +IGNORE_SUPPLEMENTS = config["ignore_supplements"] + +# 读取语言文件 +print("开始读取语言文件。") +file_list = [ + "en_us.json", + "zh_cn.json", + "zh_hk.json", + "zh_tw.json", + "lzh.json", +] +data = {} +for file in file_list: + with open(LANG_DIR / file, "r", encoding="utf-8") as f: + data[file.split(".", maxsplit=1)[0]] = json.load(f) + +# 读取补充字符串 +if not IGNORE_SUPPLEMENTS: + with open(LANG_DIR / "supplements.json", "r", encoding="utf-8") as f: + supplements = json.load(f) + for lang in ["zh_cn", "zh_hk", "zh_tw", "lzh"]: + data[lang].update(supplements[lang]) + print(f"已补充{len(supplements['zh_cn'])}条字符串。") + + +def is_valid_key(translation_key: str): + """判断是否为有效键名""" + + prefixes = ( + "block.", + "item.minecraft.", + "entity.minecraft.", + "biome.", + "effect.minecraft.", + "enchantment.minecraft.", + "trim_pattern.", + "upgrade.", + ) + + if ( + translation_key.startswith(prefixes) + and not re.match( + r"(block\.minecraft\.|item\.minecraft\.|entity\.minecraft\.)[^.]*\.", + translation_key, + ) + and translation_key + not in ["block.minecraft.set_spawn", "entity.minecraft.falling_block_type"] + and "pottery_shard" not in translation_key + ): + return True + + # 匹配进度键名 + if re.match(r"advancements\.(.*)\.title", translation_key): + return True + + return False + + +def get_translation(query_str: str): + """在语言文件中匹配含有输入内容的源字符串""" + translation = {} + for k, v in data["en_us"].items(): + if query_str.lower() in v.lower(): + element = {lang: content.get(k, "?") for lang, content in data.items()} + translation[k] = element + return translation diff --git a/configuration.toml b/configuration.toml new file mode 100644 index 0000000..3ed31b3 --- /dev/null +++ b/configuration.toml @@ -0,0 +1,5 @@ +# 语言文件文件夹 +language_folder = "lang" + +# 是否忽略补充字符串 +ignore_supplements = true diff --git a/requirements.txt b/requirements.txt index c204bef..8980d9e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,6 @@ -Flask==3.0.0 \ No newline at end of file +Flask==3.0.1 +flask_wtf==1.2.1 +fonttools==4.47.2 +python-dotenv==1.0.1 +Requests==2.31.0 +WTForms==3.1.2 diff --git a/templates/index.html b/templates/index.html index 66044ff..64f7997 100644 --- a/templates/index.html +++ b/templates/index.html @@ -17,8 +17,8 @@
- - + {{ form.hidden_tag() }} + {{ form.source_string.label }}{{ form.source_string(autocomplete="off") }} {% if input_value %} {% endif %}
- + {{ form.submit(class="submit") }}
{% if translation %} diff --git a/wsgi.py b/wsgi.py new file mode 100644 index 0000000..97eb104 --- /dev/null +++ b/wsgi.py @@ -0,0 +1,12 @@ +# -*- encoding: utf-8 -*- +"""手动设置环境变量并导入程序实例""" + +from pathlib import Path +from dotenv import load_dotenv +from app import flask_app + +dotenv_path = Path(__file__).resolve().parent / ".env" +if dotenv_path.exists(): + load_dotenv(dotenv_path) + +app = flask_app