Skip to content

Commit 8600030

Browse files
committed
重构GUI
1 parent a824930 commit 8600030

File tree

97 files changed

+39859
-204
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+39859
-204
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ MANIFEST
3131
# Usually these files are written by a python script from a template
3232
# before PyInstaller builds the exe, so as to inject date/other infos into it.
3333
*.manifest
34-
*.spec
3534

3635
# Installer logs
3736
pip-log.txt
@@ -134,3 +133,6 @@ release/
134133
config.json
135134
dumped_pages/
136135
config_multi.json
136+
buffer_file/
137+
测试-功能测试/
138+
notion_backup_terminal.spec

Flask/app.py

+332
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
import os
2+
import sys
3+
import json
4+
import threading
5+
import time
6+
7+
from NotionDump import NotionBackupLogger
8+
from api.configuration import CONFIG_FILE_PATH, Configuration
9+
from api.notion_dump import NotionBackup
10+
11+
from flask import Flask, render_template, send_from_directory, request
12+
from flask_bootstrap import Bootstrap
13+
14+
app = Flask(__name__, template_folder='templates', static_folder='static//')
15+
app.config['SECRET_KEY'] = 'delta1037@qq.com'
16+
app.config['BOOTSTRAP_SERVE_LOCAL'] = True
17+
bootstrap = Bootstrap(app)
18+
19+
SEVER_ABS_PATH = os.path.dirname(sys.argv[0])
20+
LOG_FILE = SEVER_ABS_PATH + "/dump.log"
21+
22+
23+
class NotionBackupGUI(NotionBackupLogger):
24+
def __init__(self):
25+
super().__init__()
26+
self.__notion_backup = None
27+
# 日志文件句柄
28+
self.__log = open(LOG_FILE, "a+", encoding='utf-8')
29+
# 输出备份的时间
30+
self.backup_time = time.strftime('backup_time: %Y-%m-%d %H:%M:%S\n', time.localtime(time.time()))
31+
self.__log.write("\n###################################################\n")
32+
self.__log.write(self.backup_time + "\n")
33+
self.__log.flush()
34+
# 增量输出内容,给前端用的
35+
self.__mutex = threading.Lock()
36+
self.__append_buffer = ""
37+
38+
def log_debug(self, log_str):
39+
self.log_info(log_str)
40+
41+
def log_info(self, message):
42+
self.log("[EXPORT KERNEL] " + str(message))
43+
44+
def log(self, msg):
45+
# 文件输出
46+
self.__log.write(msg + "\n")
47+
self.__log.flush()
48+
49+
# 窗口输出
50+
self.__mutex.acquire()
51+
self.__append_buffer += (str(msg) + "\n")
52+
self.__mutex.release()
53+
54+
def init_process(self, config_handle):
55+
# dump api
56+
self.__notion_backup = NotionBackup(logger=self, config=config_handle)
57+
58+
def start_process(self):
59+
# 转入后台执行
60+
self.log(self.backup_time)
61+
self.__notion_backup.start_dump(force_auto=True)
62+
63+
def get_append_log(self):
64+
self.__mutex.acquire()
65+
ret_str = self.__append_buffer
66+
self.__append_buffer = ""
67+
self.__mutex.release()
68+
# print("//trans", ret_str, "##trans", len(ret_str))
69+
return ret_str
70+
71+
72+
# 初始化控制程序
73+
gui = NotionBackupGUI()
74+
config = Configuration(CONFIG_FILE_PATH, gui)
75+
gui.init_process(config)
76+
77+
78+
@app.route('/', methods=['GET', 'POST'])
79+
def index():
80+
# 默认返回主界面渲染
81+
return render_main()
82+
83+
84+
# 基本设置界面
85+
@app.route('/setting_base', methods=['GET', 'POST'])
86+
def render_setting_base():
87+
backup_type = config.get_key("*backup_type")
88+
return render_template(
89+
'index.html',
90+
main_content=render_template(
91+
'setting_base.html',
92+
backup_root_path=config.get_key("backup_root_path", default=""),
93+
display_rowss=["单页面备份", "多页面备份"],
94+
# 单页面配置
95+
display_rows_choose=("单页面备份" if backup_type == "single" else "多页面备份"),
96+
single_readonly_token=config.get_key("*backup_token", prefix="single"),
97+
single_page_id=config.get_key("*page_id", prefix="single"),
98+
single_page_types=["Page-ID是页面类型的", "Database-ID是数据库页面类型的"],
99+
single_page_type_choose=("Page-ID是页面类型的" if config.get_key("-page_type", prefix="single") == "page" else "Database-ID是数据库页面类型的"),
100+
single_dump_path=config.get_key("-dump_path", prefix="single"),
101+
database_insert_types=["Content-内容嵌入", "Link-链接嵌入"],
102+
database_insert_type_choose=("Content-内容嵌入" if config.get_key("db_insert_type", prefix="single") == "content" else "Link-链接嵌入"),
103+
# 多页面配置
104+
multi_readonly_token=config.get_key("*backup_token", prefix="multi"),
105+
multi_rw_token=config.get_key("*backup_info_token", prefix="multi"),
106+
multi_page_id=config.get_key("*backup_list_id", prefix="multi"),
107+
multi_log_id=config.get_key("*backup_log_id", prefix="multi"),
108+
)
109+
)
110+
111+
112+
# 基本设置 确认请求
113+
@app.route('/setting_base_ack', methods=['GET', 'POST'])
114+
def setting_base_ack():
115+
setting_base_json = json.loads(request.data)
116+
# print(setting_base_json)
117+
config.alt_key("backup_root_path", setting_base_json["backup_root_path"])
118+
if setting_base_json["display_type"] != "多页面备份":
119+
config.alt_key("*backup_type", "single")
120+
config.alt_key("*backup_token", setting_base_json["single_readonly_token"], prefix="single")
121+
config.alt_key("*page_id", setting_base_json["single_page_id"], prefix="single")
122+
if "Page-" in setting_base_json["single_page_type"]:
123+
config.alt_key("-page_type", "page", prefix="single")
124+
else:
125+
config.alt_key("-page_type", "database", prefix="single")
126+
config.alt_key("-dump_path", setting_base_json["single_dump_path"], prefix="single")
127+
if "Content-" in setting_base_json["database_insert_type"]:
128+
config.alt_key("db_insert_type", "content", prefix="single")
129+
else:
130+
config.alt_key("db_insert_type", "link", prefix="single")
131+
else:
132+
config.alt_key("*backup_type", "multi")
133+
config.alt_key("*backup_token", setting_base_json["multi_readonly_token"], prefix="multi")
134+
config.alt_key("*backup_info_token", setting_base_json["multi_rw_token"], prefix="multi")
135+
config.alt_key("*backup_list_id", setting_base_json["multi_page_id"], prefix="multi")
136+
config.alt_key("*backup_log_id", setting_base_json["multi_log_id"], prefix="multi")
137+
return ""
138+
139+
140+
# 基本设置 取消请求
141+
@app.route('/setting_base_cancel', methods=['GET', 'POST'])
142+
def setting_base_cancel():
143+
ret_map = {
144+
"display_type": ("单页面备份" if config.get_key("*backup_type") == "single" else "多页面备份")
145+
}
146+
if ret_map["display_type"] != "多页面备份":
147+
ret_map["single_readonly_token"] = config.get_key("*backup_token", prefix="single")
148+
ret_map["single_page_id"] = config.get_key("*page_id", prefix="single")
149+
ret_map["single_page_type_choose"] = ("Page-ID是页面类型的" if config.get_key("-page_type", prefix="single") == "page" else "Database-ID是数据库页面类型的")
150+
ret_map["single_dump_path"] = config.get_key("-dump_path", prefix="single")
151+
ret_map["database_insert_type_choose"] = ("Content-内容嵌入" if config.get_key("db_insert_type", prefix="single") == "content" else "Link-链接嵌入")
152+
else:
153+
ret_map["multi_readonly_token"] = config.get_key("*backup_token", prefix="multi")
154+
ret_map["multi_rw_token"] = config.get_key("*backup_info_token", prefix="multi")
155+
ret_map["multi_page_id"] = config.get_key("*backup_list_id", prefix="multi")
156+
ret_map["multi_log_id"] = config.get_key("*backup_log_id", prefix="multi")
157+
return ret_map
158+
159+
160+
# 开发设置界面
161+
@app.route('/setting_dev', methods=['GET', 'POST'])
162+
def render_setting_dev():
163+
backup_list_map = config.get_key("backup_list_map", prefix="multi")
164+
backup_log_map = config.get_key("backup_log_map", prefix="multi")
165+
# 主题名称转换
166+
color_theme_type_choose = "自定义"
167+
if config.get_key("color_theme") == "dark":
168+
color_theme_type_choose = "暗黑"
169+
elif config.get_key("color_theme") == "light":
170+
color_theme_type_choose = "明亮"
171+
# 主题文字背景属性
172+
color_map = config.get_key("your_color_theme")
173+
b_types = []
174+
f_types = []
175+
d_types = []
176+
for color_name in color_map:
177+
if color_name.startswith("b_"):
178+
b_types.append({
179+
"name": color_name[color_name.find("_")+1:],
180+
"id_name": color_name,
181+
"color": color_map[color_name]
182+
})
183+
elif color_name.startswith("f_"):
184+
f_types.append({
185+
"name": color_name[color_name.find("_")+1:],
186+
"id_name": color_name,
187+
"color": color_map[color_name]
188+
})
189+
elif color_name.startswith("d_"):
190+
d_types.append({
191+
"name": color_name[color_name.find("_")+1:],
192+
"id_name": color_name,
193+
"color": color_map[color_name]
194+
})
195+
196+
return render_template(
197+
'index.html',
198+
main_content=render_template(
199+
'setting_dev.html',
200+
# checkbox信息
201+
debug=("true" if config.get_key("debug") else "false"),
202+
page_properties=("true" if config.get_key("page_properties") else "false"),
203+
use_buffer=("true" if config.get_key("use_buffer") else "false"),
204+
file_with_link=("true" if config.get_key("file_with_link") else "false"),
205+
# 日期信息
206+
date_formate=config.get_key("date_formate"),
207+
datetime_formate=config.get_key("datetime_formate"),
208+
# 主题选择
209+
color_theme_types=["明亮", "暗黑", "自定义"],
210+
color_theme_type_choose=color_theme_type_choose,
211+
b_types=b_types,
212+
f_types=f_types,
213+
d_types=d_types,
214+
# 多页面配置页面列名映射表
215+
page_id=backup_list_map["page_id"],
216+
page_type=backup_list_map["page_type"],
217+
dump_path=backup_list_map["dump_path"],
218+
db_insert_type=backup_list_map["db_insert_type"],
219+
dump_status=backup_list_map["dump_status"],
220+
title=backup_log_map["title"],
221+
date=backup_log_map["date"],
222+
status=backup_log_map["status"],
223+
log=backup_log_map["log"],
224+
)
225+
)
226+
227+
228+
# 开发设置 确认请求
229+
@app.route('/setting_dev_ack', methods=['GET', 'POST'])
230+
def setting_dev_ack():
231+
setting_dev_json = json.loads(request.data)
232+
# print(setting_dev_json)
233+
234+
# checkbox信息
235+
config.alt_key("debug", setting_dev_json["debug"])
236+
config.alt_key("use_buffer", setting_dev_json["use_buffer"])
237+
config.alt_key("page_properties", setting_dev_json["page_properties"])
238+
config.alt_key("file_with_link", setting_dev_json["file_with_link"])
239+
# 日期格式
240+
config.alt_key("date_formate", setting_dev_json["date_formate"])
241+
config.alt_key("datetime_formate", setting_dev_json["datetime_formate"])
242+
# 主题
243+
if setting_dev_json["theme_type"] == "明亮":
244+
config.alt_key("color_theme", "light")
245+
elif setting_dev_json["theme_type"] == "暗黑":
246+
config.alt_key("color_theme", "dark")
247+
else:
248+
config.alt_key("color_theme", "your_color_theme")
249+
for key in setting_dev_json:
250+
if key.startswith("b_") or key.startswith("f_") or key.startswith("d_"):
251+
config.alt_key(key, setting_dev_json[key], prefix="your_color_theme")
252+
253+
# 备份映射表
254+
backup_list_map = {
255+
"page_id": setting_dev_json["page_id"],
256+
"page_type": setting_dev_json["page_type"],
257+
"dump_path": setting_dev_json["dump_path"],
258+
"dump_status": setting_dev_json["dump_status"],
259+
"db_insert_type": setting_dev_json["db_insert_type"],
260+
}
261+
backup_log_map = {
262+
"title": setting_dev_json["title"],
263+
"date": setting_dev_json["date"],
264+
"status": setting_dev_json["status"],
265+
"log": setting_dev_json["log"],
266+
}
267+
config.alt_key("backup_list_map", backup_list_map, prefix="multi")
268+
config.alt_key("backup_log_map", backup_log_map, prefix="multi")
269+
return ""
270+
271+
272+
@app.route('/donate', methods=['GET', 'POST'])
273+
def render_donate():
274+
return render_template(
275+
'index.html',
276+
main_content=render_template(
277+
'donate.html',
278+
)
279+
)
280+
281+
282+
@app.route('/tutorial', methods=['GET', 'POST'])
283+
def render_tutorial():
284+
return render_template(
285+
'index.html',
286+
main_content=render_template(
287+
'tutorial.html',
288+
)
289+
)
290+
291+
292+
# 主界面
293+
@app.route('/main', methods=['GET', 'POST'])
294+
def render_main():
295+
return render_template(
296+
'index.html',
297+
main_content=render_template(
298+
'backup.html'
299+
)
300+
)
301+
302+
303+
@app.route('/start_export', methods=['GET', 'POST'])
304+
def start_export():
305+
gui.start_process()
306+
return ""
307+
308+
309+
@app.route('/get_msg', methods=['GET', 'POST'])
310+
def get_msg():
311+
return gui.get_append_log()
312+
# return "msg test"
313+
314+
315+
@app.errorhandler(404)
316+
def page_not_found(e):
317+
return render_template("index.html", main_content=render_template("error_404.html")), 404
318+
319+
320+
@app.errorhandler(500)
321+
def page_not_found(e):
322+
return render_template("index.html", main_content=render_template("error_500.html")), 500
323+
324+
325+
@app.route('/favicon.ico')
326+
def favicon():
327+
return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico')
328+
329+
330+
@app.route('/local_static/<path:filename>')
331+
def local_static(filename):
332+
return send_from_directory(os.path.join(app.root_path, 'static'), filename)

0 commit comments

Comments
 (0)