Skip to content

Commit

Permalink
修复多用户文件冲突
Browse files Browse the repository at this point in the history
  • Loading branch information
binary-sky committed Nov 19, 2023
1 parent 74f7030 commit 977f992
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 40 deletions.
26 changes: 18 additions & 8 deletions crazy_functions/对话历史存档.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
from toolbox import CatchException, update_ui, promote_file_to_downloadzone, get_log_folder
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
from toolbox import CatchException, update_ui, promote_file_to_downloadzone, get_log_folder, get_user
import re

f_prefix = 'GPT-Academic对话存档'

def write_chat_to_file(chatbot, history=None, file_name=None):
"""
将对话记录history以Markdown格式写入文件中。如果没有指定文件名,则使用当前时间生成文件名。
"""
import os
import time
if file_name is None:
file_name = 'chatGPT对话历史' + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + '.html'
fp = os.path.join(get_log_folder(), file_name)
file_name = f_prefix + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + '.html'
fp = os.path.join(get_log_folder(get_user(chatbot), plugin_name='chat_history'), file_name)
with open(fp, 'w', encoding='utf8') as f:
from themes.theme import advanced_css
f.write(f'<!DOCTYPE html><head><meta charset="utf-8"><title>对话历史</title><style>{advanced_css}</style></head>')
Expand Down Expand Up @@ -80,7 +81,7 @@ def 对话历史存档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_
"""

chatbot.append(("保存当前对话",
f"[Local Message] {write_chat_to_file(chatbot, history)}您可以调用“载入对话历史存档”还原当下的对话\n警告!被保存的对话历史可以被使用该系统的任何人查阅。"))
f"[Local Message] {write_chat_to_file(chatbot, history)}您可以调用下拉菜单中的“载入对话历史存档”还原当下的对话。"))
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新

def hide_cwd(str):
Expand All @@ -106,7 +107,12 @@ def 载入对话历史存档(txt, llm_kwargs, plugin_kwargs, chatbot, history, s
if not success:
if txt == "": txt = '空空如也的输入栏'
import glob
local_history = "<br/>".join(["`"+hide_cwd(f)+f" ({gen_file_preview(f)})"+"`" for f in glob.glob(f'{get_log_folder()}/**/chatGPT对话历史*.html', recursive=True)])
local_history = "<br/>".join([
"`"+hide_cwd(f)+f" ({gen_file_preview(f)})"+"`"
for f in glob.glob(
f'{get_log_folder(get_user(chatbot), plugin_name="chat_history")}/**/{f_prefix}*.html',
recursive=True
)])
chatbot.append([f"正在查找对话历史文件(html格式): {txt}", f"找不到任何html文件: {txt}。但本地存储了以下历史文件,您可以将任意一个文件路径粘贴到输入区,然后重试:<br/>{local_history}"])
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
return
Expand All @@ -132,8 +138,12 @@ def 删除所有本地对话历史记录(txt, llm_kwargs, plugin_kwargs, chatbot
"""

import glob, os
local_history = "<br/>".join(["`"+hide_cwd(f)+"`" for f in glob.glob(f'{get_log_folder()}/**/chatGPT对话历史*.html', recursive=True)])
for f in glob.glob(f'{get_log_folder()}/**/chatGPT对话历史*.html', recursive=True):
local_history = "<br/>".join([
"`"+hide_cwd(f)+"`"
for f in glob.glob(
f'{get_log_folder(get_user(chatbot), plugin_name="chat_history")}/**/{f_prefix}*.html', recursive=True
)])
for f in glob.glob(f'{get_log_folder(get_user(chatbot), plugin_name="chat_history")}/**/{f_prefix}*.html', recursive=True):
os.remove(f)
chatbot.append([f"删除所有历史对话文件", f"已删除<br/>{local_history}"])
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
Expand Down
22 changes: 17 additions & 5 deletions crazy_functions/辅助功能.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
# @Time : 2023/4/19
# @Author : Spike
# @Descr :
from toolbox import update_ui, get_conf
from toolbox import update_ui, get_conf, get_user
from toolbox import CatchException
from toolbox import default_user_name
from crazy_functions.crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
import shutil
import os


@CatchException
Expand Down Expand Up @@ -33,10 +36,19 @@ def 清除缓存(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt
chatbot.append(['清除本地缓存数据', '执行中. 删除数据'])
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面

import shutil, os
PATH_PRIVATE_UPLOAD, PATH_LOGGING = get_conf('PATH_PRIVATE_UPLOAD', 'PATH_LOGGING')
shutil.rmtree(PATH_LOGGING, ignore_errors=True)
shutil.rmtree(PATH_PRIVATE_UPLOAD, ignore_errors=True)
def _get_log_folder(user=default_user_name):
PATH_LOGGING = get_conf('PATH_LOGGING')
_dir = os.path.join(PATH_LOGGING, user)
if not os.path.exists(_dir): os.makedirs(_dir)
return _dir

def _get_upload_folder(user=default_user_name):
PATH_PRIVATE_UPLOAD = get_conf('PATH_PRIVATE_UPLOAD')
_dir = os.path.join(PATH_PRIVATE_UPLOAD, user)
return _dir

shutil.rmtree(_get_log_folder(get_user(chatbot)), ignore_errors=True)
shutil.rmtree(_get_upload_folder(get_user(chatbot)), ignore_errors=True)

chatbot.append(['清除本地缓存数据', '执行完成'])
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
98 changes: 71 additions & 27 deletions toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from latex2mathml.converter import convert as tex2mathml
from functools import wraps, lru_cache
pj = os.path.join

default_user_name = 'default_user'
"""
========================================================================
第一部分
Expand Down Expand Up @@ -61,11 +61,16 @@ def decorated(request: gradio.Request, cookies, max_length, llm_model, txt, txt2
txt_passon = txt
if txt == "" and txt2 != "": txt_passon = txt2
# 引入一个有cookie的chatbot
if request.username is not None:
user_name = request.username
else:
user_name = default_user_name
cookies.update({
'top_p':top_p,
'api_key': cookies['api_key'],
'llm_model': llm_model,
'temperature':temperature,
'user_name': user_name,
})
llm_kwargs = {
'api_key': cookies['api_key'],
Expand Down Expand Up @@ -537,40 +542,57 @@ def find_recent_files(directory):

return recent_files


def file_already_in_downloadzone(file, user_path):
parent_path = user_path
child_path = file
if os.path.commonpath([parent_path, child_path]) == parent_path:
return True
else:
return False


def promote_file_to_downloadzone(file, rename_file=None, chatbot=None):
# 将文件复制一份到下载区
import shutil
if rename_file is None: rename_file = f'{gen_time_str()}-{os.path.basename(file)}'
new_path = pj(get_log_folder(), rename_file)
# 如果已经存在,先删除
if os.path.exists(new_path) and not os.path.samefile(new_path, file): os.remove(new_path)
# 把文件复制过去
if not os.path.exists(new_path): shutil.copyfile(file, new_path)
# 将文件添加到chatbot cookie中,避免多用户干扰
if chatbot is not None:
user_name = get_user(chatbot)
else:
user_name = default_user_name

user_path = get_log_folder(user_name, plugin_name=None)
if file_already_in_downloadzone(file, user_path):
new_path = file
else:
if rename_file is None: rename_file = f'{gen_time_str()}-{os.path.basename(file)}'
new_path = pj(user_path, rename_file)
# 如果已经存在,先删除
if os.path.exists(new_path) and not os.path.samefile(new_path, file): os.remove(new_path)
# 把文件复制过去
if not os.path.exists(new_path): shutil.copyfile(file, new_path)
# 将文件添加到chatbot cookie中
if chatbot is not None:
if 'files_to_promote' in chatbot._cookies: current = chatbot._cookies['files_to_promote']
else: current = []
chatbot._cookies.update({'files_to_promote': [new_path] + current})
return new_path


def disable_auto_promotion(chatbot):
chatbot._cookies.update({'files_to_promote': []})
return

def is_the_upload_folder(string):
PATH_PRIVATE_UPLOAD = get_conf('PATH_PRIVATE_UPLOAD')
pattern = r'^PATH_PRIVATE_UPLOAD/[A-Za-z0-9_-]+/\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$'
pattern = pattern.replace('PATH_PRIVATE_UPLOAD', PATH_PRIVATE_UPLOAD)
if re.match(pattern, string): return True
else: return False

def del_outdated_uploads(outdate_time_seconds):
PATH_PRIVATE_UPLOAD = get_conf('PATH_PRIVATE_UPLOAD')
def del_outdated_uploads(outdate_time_seconds, target_path_base=None):
if target_path_base is None:
user_upload_dir = get_conf('PATH_PRIVATE_UPLOAD')
else:
user_upload_dir = target_path_base
current_time = time.time()
one_hour_ago = current_time - outdate_time_seconds
# Get a list of all subdirectories in the PATH_PRIVATE_UPLOAD folder
# Get a list of all subdirectories in the user_upload_dir folder
# Remove subdirectories that are older than one hour
for subdirectory in glob.glob(f'{PATH_PRIVATE_UPLOAD}/*/*'):
for subdirectory in glob.glob(f'{user_upload_dir}/*'):
subdirectory_time = os.path.getmtime(subdirectory)
if subdirectory_time < one_hour_ago:
try: shutil.rmtree(subdirectory)
Expand All @@ -583,17 +605,16 @@ def on_file_uploaded(request: gradio.Request, files, chatbot, txt, txt2, checkbo
"""
if len(files) == 0:
return chatbot, txt

# 移除过时的旧文件从而节省空间&保护隐私
outdate_time_seconds = 60
del_outdated_uploads(outdate_time_seconds)

# 创建工作路径
user_name = "default" if not request.username else request.username
user_name = default_user_name if not request.username else request.username
time_tag = gen_time_str()
PATH_PRIVATE_UPLOAD = get_conf('PATH_PRIVATE_UPLOAD')
target_path_base = pj(PATH_PRIVATE_UPLOAD, user_name, time_tag)
target_path_base = get_upload_folder(user_name, tag=time_tag)
os.makedirs(target_path_base, exist_ok=True)

# 移除过时的旧文件从而节省空间&保护隐私
outdate_time_seconds = 3600 # 一小时
del_outdated_uploads(outdate_time_seconds, get_upload_folder(user_name))

# 逐个文件转移到目标路径
upload_msg = ''
Expand Down Expand Up @@ -998,12 +1019,35 @@ def gen_time_str():
import time
return time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())

def get_log_folder(user='default', plugin_name='shared'):
def get_log_folder(user=default_user_name, plugin_name='shared'):
if user is None: user = default_user_name
PATH_LOGGING = get_conf('PATH_LOGGING')
_dir = pj(PATH_LOGGING, user, plugin_name)
if plugin_name is None:
_dir = pj(PATH_LOGGING, user)
else:
_dir = pj(PATH_LOGGING, user, plugin_name)
if not os.path.exists(_dir): os.makedirs(_dir)
return _dir

def get_upload_folder(user=default_user_name, tag=None):
PATH_PRIVATE_UPLOAD = get_conf('PATH_PRIVATE_UPLOAD')
if user is None: user = default_user_name
if tag is None or len(tag)==0:
target_path_base = pj(PATH_PRIVATE_UPLOAD, user)
else:
target_path_base = pj(PATH_PRIVATE_UPLOAD, user, tag)
return target_path_base

def is_the_upload_folder(string):
PATH_PRIVATE_UPLOAD = get_conf('PATH_PRIVATE_UPLOAD')
pattern = r'^PATH_PRIVATE_UPLOAD[\\/][A-Za-z0-9_-]+[\\/]\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$'
pattern = pattern.replace('PATH_PRIVATE_UPLOAD', PATH_PRIVATE_UPLOAD)
if re.match(pattern, string): return True
else: return False

def get_user(chatbotwithcookies):
return chatbotwithcookies._cookies.get('user_name', default_user_name)

class ProxyNetworkActivate():
"""
这段代码定义了一个名为TempProxy的空上下文管理器, 用于给一小段代码上代理
Expand Down

0 comments on commit 977f992

Please sign in to comment.