diff --git a/main.py b/main.py
index 53fb68894..578dd7ca0 100644
--- a/main.py
+++ b/main.py
@@ -1,6 +1,17 @@
import os; os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
-import pickle
-import base64
+
+help_menu_description = \
+"""Github源代码开源和更新[地址🚀](https://github.com/binary-husky/gpt_academic),
+感谢热情的[开发者们❤️](https://github.com/binary-husky/gpt_academic/graphs/contributors).
+常见问题请查阅[项目Wiki](https://github.com/binary-husky/gpt_academic/wiki),
+如遇到Bug请前往[Bug反馈](https://github.com/binary-husky/gpt_academic/issues).
+普通对话使用说明: 1. 输入问题; 2. 点击提交
+基础功能区使用说明: 1. 输入文本; 2. 点击任意基础功能区按钮
+函数插件区使用说明: 1. 输入路径/问题, 或者上传文件; 2. 点击任意函数插件区按钮
+虚空终端使用说明: 点击虚空终端, 然后根据提示输入指令, 再次点击虚空终端
+如何保存对话: 点击保存当前的对话按钮
+如何语音对话: 请阅读Wiki
+如何临时更换API_KEY: 在输入区输入临时API_KEY后提交(网页刷新后失效)"""
def main():
import gradio as gr
@@ -8,7 +19,7 @@ def main():
raise ModuleNotFoundError("使用项目内置Gradio获取最优体验! 请运行 `pip install -r requirements.txt` 指令安装内置Gradio及其他依赖, 详情信息见requirements.txt.")
from request_llms.bridge_all import predict
from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf, ArgsGeneralWrapper, load_chat_cookies, DummyWith
- # 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到
+ # 建议您复制一个config_private.py放自己的秘密, 如API和代理网址
proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION = get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION')
CHATBOT_HEIGHT, LAYOUT, AVAIL_LLM_MODELS, AUTO_CLEAR_TXT = get_conf('CHATBOT_HEIGHT', 'LAYOUT', 'AVAIL_LLM_MODELS', 'AUTO_CLEAR_TXT')
ENABLE_AUDIO, AUTO_CLEAR_TXT, PATH_LOGGING, AVAIL_THEMES, THEME = get_conf('ENABLE_AUDIO', 'AUTO_CLEAR_TXT', 'PATH_LOGGING', 'AVAIL_THEMES', 'THEME')
@@ -18,21 +29,11 @@ def main():
# 如果WEB_PORT是-1, 则随机选取WEB端口
PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
from check_proxy import get_current_version
- from themes.theme import adjust_theme, advanced_css, theme_declaration, load_dynamic_theme
-
+ from themes.theme import adjust_theme, advanced_css, theme_declaration
+ from themes.theme import js_code_for_css_changing, js_code_for_darkmode_init, js_code_for_toggle_darkmode, js_code_for_persistent_cookie_init
+ from themes.theme import load_dynamic_theme, to_cookie_str, from_cookie_str, init_cookie
title_html = f"
GPT 学术优化 {get_current_version()}
{theme_declaration}"
- description = "Github源代码开源和更新[地址🚀](https://github.com/binary-husky/gpt_academic), "
- description += "感谢热情的[开发者们❤️](https://github.com/binary-husky/gpt_academic/graphs/contributors)."
- description += "常见问题请查阅[项目Wiki](https://github.com/binary-husky/gpt_academic/wiki), "
- description += "如遇到Bug请前往[Bug反馈](https://github.com/binary-husky/gpt_academic/issues)."
- description += "普通对话使用说明: 1. 输入问题; 2. 点击提交"
- description += "基础功能区使用说明: 1. 输入文本; 2. 点击任意基础功能区按钮"
- description += "函数插件区使用说明: 1. 输入路径/问题, 或者上传文件; 2. 点击任意函数插件区按钮"
- description += "虚空终端使用说明: 点击虚空终端, 然后根据提示输入指令, 再次点击虚空终端"
- description += "如何保存对话: 点击保存当前的对话按钮"
- description += "如何语音对话: 请阅读Wiki"
- description += "如何临时更换API_KEY: 在输入区输入临时API_KEY后提交(网页刷新后失效)"
-
+
# 问询记录, python 版本建议3.9+(越新越好)
import logging, uuid
os.makedirs(PATH_LOGGING, exist_ok=True)
@@ -162,16 +163,10 @@ def main():
checkboxes_2 = gr.CheckboxGroup(["自定义菜单"],
value=[], label="显示/隐藏自定义菜单", elem_id='cbs').style(container=False)
dark_mode_btn = gr.Button("切换界面明暗 ☀", variant="secondary").style(size="sm")
- dark_mode_btn.click(None, None, None, _js="""() => {
- if (document.querySelectorAll('.dark').length) {
- document.querySelectorAll('.dark').forEach(el => el.classList.remove('dark'));
- } else {
- document.querySelector('body').classList.add('dark');
- }
- }""",
+ dark_mode_btn.click(None, None, None, _js=js_code_for_toggle_darkmode,
)
with gr.Tab("帮助", elem_id="interact-panel"):
- gr.Markdown(description)
+ gr.Markdown(help_menu_description)
with gr.Floating(init_x="20%", init_y="50%", visible=False, width="40%", drag="top") as area_input_secondary:
with gr.Accordion("浮动输入区", open=True, elem_id="input-panel2"):
@@ -186,16 +181,6 @@ def main():
stopBtn2 = gr.Button("停止", variant="secondary"); stopBtn2.style(size="sm")
clearBtn2 = gr.Button("清除", variant="secondary", visible=False); clearBtn2.style(size="sm")
- def to_cookie_str(d):
- # Pickle the dictionary and encode it as a string
- pickled_dict = pickle.dumps(d)
- cookie_value = base64.b64encode(pickled_dict).decode('utf-8')
- return cookie_value
-
- def from_cookie_str(c):
- # Decode the base64-encoded string and unpickle it into a dictionary
- pickled_dict = base64.b64decode(c.encode('utf-8'))
- return pickle.loads(pickled_dict)
with gr.Floating(init_x="20%", init_y="50%", visible=False, width="40%", drag="top") as area_customize:
with gr.Accordion("自定义菜单", open=True, elem_id="edit-panel"):
@@ -227,11 +212,11 @@ def assign_btn(persistent_cookie_, cookies_, basic_btn_dropdown_, basic_fn_title
else:
ret.update({predefined_btns[basic_btn_dropdown_]: gr.update(visible=True, value=basic_fn_title)})
ret.update({cookies: cookies_})
- try: persistent_cookie_ = from_cookie_str(persistent_cookie_) # persistent cookie to dict
+ try: persistent_cookie_ = from_cookie_str(persistent_cookie_) # persistent cookie to dict
except: persistent_cookie_ = {}
- persistent_cookie_["custom_bnt"] = customize_fn_overwrite_ # dict update new value
- persistent_cookie_ = to_cookie_str(persistent_cookie_) # persistent cookie to dict
- ret.update({persistent_cookie: persistent_cookie_}) # write persistent cookie
+ persistent_cookie_["custom_bnt"] = customize_fn_overwrite_ # dict update new value
+ persistent_cookie_ = to_cookie_str(persistent_cookie_) # persistent cookie to dict
+ ret.update({persistent_cookie: persistent_cookie_}) # write persistent cookie
return ret
def reflesh_btn(persistent_cookie_, cookies_):
@@ -252,10 +237,11 @@ def reflesh_btn(persistent_cookie_, cookies_):
else: ret.update({predefined_btns[k]: gr.update(visible=True, value=v['Title'])})
return ret
- basic_fn_load.click(reflesh_btn, [persistent_cookie, cookies],[cookies, *customize_btns.values(), *predefined_btns.values()])
+ basic_fn_load.click(reflesh_btn, [persistent_cookie, cookies], [cookies, *customize_btns.values(), *predefined_btns.values()])
h = basic_fn_confirm.click(assign_btn, [persistent_cookie, cookies, basic_btn_dropdown, basic_fn_title, basic_fn_prefix, basic_fn_suffix],
[persistent_cookie, cookies, *customize_btns.values(), *predefined_btns.values()])
- h.then(None, [persistent_cookie], None, _js="""(persistent_cookie)=>{setCookie("persistent_cookie", persistent_cookie, 5);}""") # save persistent cookie
+ # save persistent cookie
+ h.then(None, [persistent_cookie], None, _js="""(persistent_cookie)=>{setCookie("persistent_cookie", persistent_cookie, 5);}""")
# 功能区显示开关与功能区的互动
def fn_area_visibility(a):
@@ -342,18 +328,7 @@ def on_theme_dropdown_changed(theme, secret_css):
None,
[secret_css],
None,
- _js="""(css) => {
- var existingStyles = document.querySelectorAll("style[data-loaded-css]");
- for (var i = 0; i < existingStyles.length; i++) {
- var style = existingStyles[i];
- style.parentNode.removeChild(style);
- }
- var styleElement = document.createElement('style');
- styleElement.setAttribute('data-loaded-css', css);
- styleElement.innerHTML = css;
- document.head.appendChild(styleElement);
- }
- """
+ _js=js_code_for_css_changing
)
# 随变按钮的回调函数注册
def route(request: gr.Request, k, *args, **kwargs):
@@ -385,27 +360,10 @@ def deal_audio(audio, cookies):
rad.feed(cookies['uuid'].hex, audio)
audio_mic.stream(deal_audio, inputs=[audio_mic, cookies])
- def init_cookie(cookies, chatbot):
- # 为每一位访问的用户赋予一个独一无二的uuid编码
- cookies.update({'uuid': uuid.uuid4()})
- return cookies
+
demo.load(init_cookie, inputs=[cookies, chatbot], outputs=[cookies])
- darkmode_js = """(dark) => {
- dark = dark == "True";
- if (document.querySelectorAll('.dark').length) {
- if (!dark){
- document.querySelectorAll('.dark').forEach(el => el.classList.remove('dark'));
- }
- } else {
- if (dark){
- document.querySelector('body').classList.add('dark');
- }
- }
- }"""
- load_cookie_js = """(persistent_cookie) => {
- return getCookie("persistent_cookie");
- }"""
- demo.load(None, inputs=None, outputs=[persistent_cookie], _js=load_cookie_js)
+ darkmode_js = js_code_for_darkmode_init
+ demo.load(None, inputs=None, outputs=[persistent_cookie], _js=js_code_for_persistent_cookie_init)
demo.load(None, inputs=[dark_mode], outputs=None, _js=darkmode_js) # 配置暗色主题或亮色主题
demo.load(None, inputs=[gr.Textbox(LAYOUT, visible=False)], outputs=None, _js='(LAYOUT)=>{GptAcademicJavaScriptInit(LAYOUT);}')
@@ -418,7 +376,7 @@ def run_delayed_tasks():
def auto_updates(): time.sleep(0); auto_update()
def open_browser(): time.sleep(2); webbrowser.open_new_tab(f"http://localhost:{PORT}")
- def warm_up_mods(): time.sleep(4); warm_up_modules()
+ def warm_up_mods(): time.sleep(6); warm_up_modules()
threading.Thread(target=auto_updates, name="self-upgrade", daemon=True).start() # 查看自动更新
threading.Thread(target=open_browser, name="open-browser", daemon=True).start() # 打开浏览器页面
diff --git a/themes/cookies.py b/themes/cookies.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/themes/theme.py b/themes/theme.py
index f59db9f83..ca6ab3a17 100644
--- a/themes/theme.py
+++ b/themes/theme.py
@@ -1,6 +1,14 @@
-import gradio as gr
+import pickle
+import base64
+import uuid
from toolbox import get_conf
-THEME = get_conf('THEME')
+
+"""
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+第 1 部分
+加载主题相关的工具函数
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+"""
def load_dynamic_theme(THEME):
adjust_dynamic_theme = None
@@ -20,4 +28,86 @@ def load_dynamic_theme(THEME):
theme_declaration = ""
return adjust_theme, advanced_css, theme_declaration, adjust_dynamic_theme
-adjust_theme, advanced_css, theme_declaration, _ = load_dynamic_theme(THEME)
\ No newline at end of file
+adjust_theme, advanced_css, theme_declaration, _ = load_dynamic_theme(get_conf('THEME'))
+
+
+
+
+
+
+"""
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+第 2 部分
+cookie相关工具函数
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+"""
+
+def init_cookie(cookies, chatbot):
+ # 为每一位访问的用户赋予一个独一无二的uuid编码
+ cookies.update({'uuid': uuid.uuid4()})
+ return cookies
+
+def to_cookie_str(d):
+ # Pickle the dictionary and encode it as a string
+ pickled_dict = pickle.dumps(d)
+ cookie_value = base64.b64encode(pickled_dict).decode('utf-8')
+ return cookie_value
+
+def from_cookie_str(c):
+ # Decode the base64-encoded string and unpickle it into a dictionary
+ pickled_dict = base64.b64decode(c.encode('utf-8'))
+ return pickle.loads(pickled_dict)
+
+
+
+
+
+"""
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+第 3 部分
+内嵌的javascript代码
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+"""
+
+js_code_for_css_changing = """(css) => {
+ var existingStyles = document.querySelectorAll("style[data-loaded-css]");
+ for (var i = 0; i < existingStyles.length; i++) {
+ var style = existingStyles[i];
+ style.parentNode.removeChild(style);
+ }
+ var styleElement = document.createElement('style');
+ styleElement.setAttribute('data-loaded-css', css);
+ styleElement.innerHTML = css;
+ document.head.appendChild(styleElement);
+}
+"""
+
+js_code_for_darkmode_init = """(dark) => {
+ dark = dark == "True";
+ if (document.querySelectorAll('.dark').length) {
+ if (!dark){
+ document.querySelectorAll('.dark').forEach(el => el.classList.remove('dark'));
+ }
+ } else {
+ if (dark){
+ document.querySelector('body').classList.add('dark');
+ }
+ }
+}
+"""
+
+js_code_for_toggle_darkmode = """() => {
+ if (document.querySelectorAll('.dark').length) {
+ document.querySelectorAll('.dark').forEach(el => el.classList.remove('dark'));
+ } else {
+ document.querySelector('body').classList.add('dark');
+ }
+}"""
+
+
+js_code_for_persistent_cookie_init = """(persistent_cookie) => {
+ return getCookie("persistent_cookie");
+}
+"""
+
+