insight Keldos commited on
Commit
b9dc38b
1 Parent(s): b6c84da

feat: 增加多用户显示与多用户历史文件夹 (#489)

Browse files

* 功能添加: 对每个用户添加独立history文件夹

* 修改: 无用户名时的兼容性 Fix Username

* UI美化

---------

Co-authored-by: Keldos <i@keldos.me>

Files changed (4) hide show
  1. ChuanhuChatbot.py +17 -6
  2. assets/custom.css +13 -0
  3. modules/presets.py +2 -1
  4. modules/utils.py +20 -19
ChuanhuChatbot.py CHANGED
@@ -19,6 +19,7 @@ with open("assets/custom.css", "r", encoding="utf-8") as f:
19
  customCSS = f.read()
20
 
21
  with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
 
22
  history = gr.State([])
23
  token_count = gr.State([])
24
  promptTemplates = gr.State(load_template(get_template_names(plain=True)[0], mode=2))
@@ -29,8 +30,18 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
29
 
30
  with gr.Row():
31
  gr.HTML(title)
 
32
  status_display = gr.Markdown(get_geoip(), elem_id="status_display")
33
 
 
 
 
 
 
 
 
 
 
34
  with gr.Row().style(equal_height=True):
35
  with gr.Column(scale=5):
36
  with gr.Row():
@@ -323,27 +334,27 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
323
  # S&L
324
  saveHistoryBtn.click(
325
  save_chat_history,
326
- [saveFileName, systemPromptTxt, history, chatbot],
327
  downloadFile,
328
  show_progress=True,
329
  )
330
- saveHistoryBtn.click(get_history_names, None, [historyFileSelectDropdown])
331
  exportMarkdownBtn.click(
332
  export_markdown,
333
- [saveFileName, systemPromptTxt, history, chatbot],
334
  downloadFile,
335
  show_progress=True,
336
  )
337
- historyRefreshBtn.click(get_history_names, None, [historyFileSelectDropdown])
338
  historyFileSelectDropdown.change(
339
  load_chat_history,
340
- [historyFileSelectDropdown, systemPromptTxt, history, chatbot],
341
  [saveFileName, systemPromptTxt, history, chatbot],
342
  show_progress=True,
343
  )
344
  downloadFile.change(
345
  load_chat_history,
346
- [downloadFile, systemPromptTxt, history, chatbot],
347
  [saveFileName, systemPromptTxt, history, chatbot],
348
  )
349
 
 
19
  customCSS = f.read()
20
 
21
  with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
22
+ user_name = gr.State("")
23
  history = gr.State([])
24
  token_count = gr.State([])
25
  promptTemplates = gr.State(load_template(get_template_names(plain=True)[0], mode=2))
 
30
 
31
  with gr.Row():
32
  gr.HTML(title)
33
+ user_ip = gr.Markdown(value="", elem_id="user_ip")
34
  status_display = gr.Markdown(get_geoip(), elem_id="status_display")
35
 
36
+ # https://github.com/gradio-app/gradio/pull/3296
37
+ def create_greeting(request: gr.Request):
38
+ if hasattr(request, "username") and request.username: # is not None or is not ""
39
+ logging.info(f"Get User Name: {request.username}")
40
+ return gr.Markdown.update(value=f"User: {request.username}"), request.username
41
+ else:
42
+ return gr.Markdown.update(value=f"User: 管理员"), ""
43
+ demo.load(create_greeting, inputs=None, outputs=[user_ip, user_name])
44
+
45
  with gr.Row().style(equal_height=True):
46
  with gr.Column(scale=5):
47
  with gr.Row():
 
334
  # S&L
335
  saveHistoryBtn.click(
336
  save_chat_history,
337
+ [saveFileName, systemPromptTxt, history, chatbot, user_name],
338
  downloadFile,
339
  show_progress=True,
340
  )
341
+ saveHistoryBtn.click(get_history_names, [gr.State(False), user_name], [historyFileSelectDropdown])
342
  exportMarkdownBtn.click(
343
  export_markdown,
344
+ [saveFileName, systemPromptTxt, history, chatbot, user_name],
345
  downloadFile,
346
  show_progress=True,
347
  )
348
+ historyRefreshBtn.click(get_history_names, [gr.State(False), user_name], [historyFileSelectDropdown])
349
  historyFileSelectDropdown.change(
350
  load_chat_history,
351
+ [historyFileSelectDropdown, systemPromptTxt, history, chatbot, user_name],
352
  [saveFileName, systemPromptTxt, history, chatbot],
353
  show_progress=True,
354
  )
355
  downloadFile.change(
356
  load_chat_history,
357
+ [downloadFile, systemPromptTxt, history, chatbot, user_name],
358
  [saveFileName, systemPromptTxt, history, chatbot],
359
  )
360
 
assets/custom.css CHANGED
@@ -18,6 +18,19 @@ footer {
18
  opacity: 0.85;
19
  }
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  /* status_display */
22
  #status_display {
23
  display: flex;
 
18
  opacity: 0.85;
19
  }
20
 
21
+ /* user_ip */
22
+ #user_ip {
23
+ display: flex;
24
+ min-height: 2.5em;
25
+ align-items: flex-end;
26
+ justify-content: flex-end;
27
+ }
28
+ #user_ip p {
29
+ font-size: .85em;
30
+ font-family: monospace;
31
+ color: var(--body-text-color-subdued);
32
+ }
33
+
34
  /* status_display */
35
  #status_display {
36
  display: flex;
modules/presets.py CHANGED
@@ -1,5 +1,6 @@
1
  # -*- coding:utf-8 -*-
2
  import gradio as gr
 
3
 
4
  # ChatGPT 设置
5
  initial_prompt = "You are a helpful assistant."
@@ -7,7 +8,7 @@ API_HOST = "api.openai.com"
7
  COMPLETION_URL = "https://api.openai.com/v1/chat/completions"
8
  BALANCE_API_URL="https://api.openai.com/dashboard/billing/credit_grants"
9
  USAGE_API_URL="https://api.openai.com/dashboard/billing/usage"
10
- HISTORY_DIR = "history"
11
  TEMPLATES_DIR = "templates"
12
 
13
  # 错误信息
 
1
  # -*- coding:utf-8 -*-
2
  import gradio as gr
3
+ from pathlib import Path
4
 
5
  # ChatGPT 设置
6
  initial_prompt = "You are a helpful assistant."
 
8
  COMPLETION_URL = "https://api.openai.com/v1/chat/completions"
9
  BALANCE_API_URL="https://api.openai.com/dashboard/billing/credit_grants"
10
  USAGE_API_URL="https://api.openai.com/dashboard/billing/usage"
11
+ HISTORY_DIR = Path("history")
12
  TEMPLATES_DIR = "templates"
13
 
14
  # 错误信息
modules/utils.py CHANGED
@@ -190,46 +190,46 @@ def delete_last_conversation(chatbot, history, previous_token_count):
190
  )
191
 
192
 
193
- def save_file(filename, system, history, chatbot):
194
- logging.info("保存对话历史中……")
195
- os.makedirs(HISTORY_DIR, exist_ok=True)
196
  if filename.endswith(".json"):
197
  json_s = {"system": system, "history": history, "chatbot": chatbot}
198
  print(json_s)
199
- with open(os.path.join(HISTORY_DIR, filename), "w") as f:
200
  json.dump(json_s, f)
201
  elif filename.endswith(".md"):
202
  md_s = f"system: \n- {system} \n"
203
  for data in history:
204
  md_s += f"\n{data['role']}: \n- {data['content']} \n"
205
- with open(os.path.join(HISTORY_DIR, filename), "w", encoding="utf8") as f:
206
  f.write(md_s)
207
- logging.info("保存对话历史完毕")
208
- return os.path.join(HISTORY_DIR, filename)
209
 
210
 
211
- def save_chat_history(filename, system, history, chatbot):
212
  if filename == "":
213
  return
214
  if not filename.endswith(".json"):
215
  filename += ".json"
216
- return save_file(filename, system, history, chatbot)
217
 
218
 
219
- def export_markdown(filename, system, history, chatbot):
220
  if filename == "":
221
  return
222
  if not filename.endswith(".md"):
223
  filename += ".md"
224
- return save_file(filename, system, history, chatbot)
225
 
226
 
227
- def load_chat_history(filename, system, history, chatbot):
228
- logging.info("加载对话历史中……")
229
  if type(filename) != str:
230
  filename = filename.name
231
  try:
232
- with open(os.path.join(HISTORY_DIR, filename), "r") as f:
233
  json_s = json.load(f)
234
  try:
235
  if type(json_s["history"][0]) == str:
@@ -245,10 +245,10 @@ def load_chat_history(filename, system, history, chatbot):
245
  except:
246
  # 没有对话历史
247
  pass
248
- logging.info("加载对话历史完毕")
249
  return filename, json_s["system"], json_s["history"], json_s["chatbot"]
250
  except FileNotFoundError:
251
- logging.info("没有找到对话历史文件,不执行任何操作")
252
  return filename, system, history, chatbot
253
 
254
 
@@ -267,15 +267,16 @@ def get_file_names(dir, plain=False, filetypes=[".json"]):
267
  files = sorted_by_pinyin(files)
268
  if files == []:
269
  files = [""]
 
270
  if plain:
271
  return files
272
  else:
273
  return gr.Dropdown.update(choices=files)
274
 
275
 
276
- def get_history_names(plain=False):
277
- logging.info("获取历史记录文件名列表")
278
- return get_file_names(HISTORY_DIR, plain)
279
 
280
 
281
  def load_template(filename, mode=0):
 
190
  )
191
 
192
 
193
+ def save_file(filename, system, history, chatbot, user_name):
194
+ logging.info(f"{user_name} 保存对话历史中……")
195
+ os.makedirs(HISTORY_DIR / user_name, exist_ok=True)
196
  if filename.endswith(".json"):
197
  json_s = {"system": system, "history": history, "chatbot": chatbot}
198
  print(json_s)
199
+ with open(os.path.join(HISTORY_DIR / user_name, filename), "w") as f:
200
  json.dump(json_s, f)
201
  elif filename.endswith(".md"):
202
  md_s = f"system: \n- {system} \n"
203
  for data in history:
204
  md_s += f"\n{data['role']}: \n- {data['content']} \n"
205
+ with open(os.path.join(HISTORY_DIR / user_name, filename), "w", encoding="utf8") as f:
206
  f.write(md_s)
207
+ logging.info(f"{user_name} 保存对话历史完毕")
208
+ return os.path.join(HISTORY_DIR / user_name, filename)
209
 
210
 
211
+ def save_chat_history(filename, system, history, chatbot, user_name):
212
  if filename == "":
213
  return
214
  if not filename.endswith(".json"):
215
  filename += ".json"
216
+ return save_file(filename, system, history, chatbot, user_name)
217
 
218
 
219
+ def export_markdown(filename, system, history, chatbot, user_name):
220
  if filename == "":
221
  return
222
  if not filename.endswith(".md"):
223
  filename += ".md"
224
+ return save_file(filename, system, history, chatbot, user_name)
225
 
226
 
227
+ def load_chat_history(filename, system, history, chatbot, user_name):
228
+ logging.info(f"{user_name} 加载对话历史中……")
229
  if type(filename) != str:
230
  filename = filename.name
231
  try:
232
+ with open(os.path.join(HISTORY_DIR / user_name, filename), "r") as f:
233
  json_s = json.load(f)
234
  try:
235
  if type(json_s["history"][0]) == str:
 
245
  except:
246
  # 没有对话历史
247
  pass
248
+ logging.info(f"{user_name} 加载对话历史完毕")
249
  return filename, json_s["system"], json_s["history"], json_s["chatbot"]
250
  except FileNotFoundError:
251
+ logging.info(f"{user_name} 没有找到对话历史文件,不执行任何操作")
252
  return filename, system, history, chatbot
253
 
254
 
 
267
  files = sorted_by_pinyin(files)
268
  if files == []:
269
  files = [""]
270
+ logging.debug(f"files are:{files}")
271
  if plain:
272
  return files
273
  else:
274
  return gr.Dropdown.update(choices=files)
275
 
276
 
277
+ def get_history_names(plain=False, user_name=""):
278
+ logging.info(f"从用户 {user_name} 中获取历史记录文件名列表")
279
+ return get_file_names(HISTORY_DIR / user_name, plain)
280
 
281
 
282
  def load_template(filename, mode=0):