youngtsai commited on
Commit
5c4cdd1
·
1 Parent(s): 991d9ac

gr.Markdown("# 📚 歷程回顧")

Browse files
Files changed (2) hide show
  1. app.py +150 -86
  2. storage_service.py +59 -0
app.py CHANGED
@@ -5,11 +5,15 @@ from openai import OpenAI
5
 
6
  import random
7
  import uuid
 
 
8
 
9
 
10
  import json
11
  import tempfile
12
- import pandas as pd
 
 
13
 
14
 
15
  is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
@@ -21,11 +25,17 @@ if is_env_local:
21
  config = json.load(f)
22
  IS_ENV_PROD = "False"
23
  OPEN_AI_KEY = config["OPEN_AI_KEY"]
 
24
  else:
25
  OPEN_AI_KEY = os.getenv("OPEN_AI_KEY")
 
26
 
27
  OPEN_AI_CLIENT = OpenAI(api_key=OPEN_AI_KEY)
28
 
 
 
 
 
29
  def update_scenario_input(scenario_radio):
30
  return scenario_radio
31
 
@@ -182,8 +192,6 @@ def generate_points(model, max_tokens, sys_content, scenario, eng_level, topic,
182
  def update_points_input(points):
183
  return points
184
 
185
-
186
-
187
  def generate_topic_sentences(model, max_tokens, sys_content, scenario, eng_level, topic, points, user_generate_topic_sentences_prompt):
188
  """
189
  根据系统提示和用户输入的情境及要点,调用OpenAI API生成相关的主题句及其合理性解释。
@@ -405,7 +413,6 @@ def generate_paragraph_evaluate(model, sys_content, paragraph, user_generate_par
405
 
406
  return gr_update
407
 
408
-
409
  def generate_correct_grammatical_spelling_errors(model, sys_content, eng_level, paragraph, user_correct_grammatical_spelling_errors_prompt):
410
  """
411
  根据用户输入的段落,调用OpenAI API生成相关的文法和拼字错误修正。
@@ -511,20 +518,47 @@ def generate_refine_paragraph(model, sys_content, eng_level, paragraph, user_ref
511
  def update_paragraph_refine_input(text):
512
  return text
513
 
514
- def generate_paragraph_history(scenario_input,
515
- topic_output,
516
- points_output,
517
- topic_sentence_input,
518
- supporting_sentences_input,
519
- conclusion_sentence_input,
520
- paragraph_output,
521
- paragraph_evaluate_output,
522
- correct_grammatical_spelling_errors_output_table,
523
- refine_output_table,
524
- refine_output):
 
 
 
 
 
525
  """
526
  生成段落歷史紀錄
527
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
 
529
  return scenario_input, \
530
  topic_output, \
@@ -537,7 +571,6 @@ def generate_paragraph_history(scenario_input,
537
  correct_grammatical_spelling_errors_output_table, \
538
  refine_output_table, \
539
  refine_output
540
-
541
 
542
  def paragraph_save_and_tts(paragraph_text):
543
  """
@@ -569,7 +602,37 @@ def update_history_accordion():
569
  history_accordion_gr_update = gr.update(open=True)
570
  return history_accordion_gr_update
571
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
572
 
 
 
573
  def generate_chinese_evaluation_table(model, sys_content, user_prompt, text):
574
  # https://www.ceec.edu.tw/files/file_pool/1/0j052575870800204600/1216%E5%9C%8B%E6%96%87%E4%BD%9C%E6%96%87%E5%88%86%E9%A0%85%E5%BC%8F%E8%A9%95%E5%88%86%E6%8C%87%E6%A8%99.pdf
575
 
@@ -693,6 +756,14 @@ def init_params(request: gr.Request):
693
  else:
694
  raise gr.Error("Invalid origin")
695
 
 
 
 
 
 
 
 
 
696
  if "language" in query_params:
697
  if query_params["language"] == "english":
698
  print(f"language: english")
@@ -703,39 +774,7 @@ def init_params(request: gr.Request):
703
  english_group = gr.update(visible=False)
704
  chinese_group = gr.update(visible=True)
705
 
706
- return request_origin, english_group, chinese_group
707
-
708
- def update_english_grapragh_practice_rows(selected_tab):
709
- if selected_tab == "📝 英文段落寫作練習":
710
- gr_update_english_grapragh_practice_row = gr.update(visible=True)
711
- gr_update_english_grapragh_evaluate_row = gr.update(visible=False)
712
- gr_update_english_exam_practice_row = gr.update(visible=False)
713
- gr_update_english_grapragh_practice_button = gr.update(variant="primary")
714
- gr_update_english_grapragh_evaluate_button = gr.update(variant="secondary")
715
- gr_update_english_exam_practice_tab_button = gr.update(variant="secondary")
716
-
717
- elif selected_tab == "📊 英文段落寫作評分":
718
- gr_update_english_grapragh_practice_row = gr.update(visible=False)
719
- gr_update_english_grapragh_evaluate_row = gr.update(visible=True)
720
- gr_update_english_exam_practice_row = gr.update(visible=False)
721
- gr_update_english_grapragh_practice_button = gr.update(variant="secondary")
722
- gr_update_english_grapragh_evaluate_button = gr.update(variant="primary")
723
- gr_update_english_exam_practice_tab_button = gr.update(variant="secondary")
724
-
725
- elif selected_tab == "🎯 英文考古題寫作練習":
726
- gr_update_english_grapragh_practice_row = gr.update(visible=False)
727
- gr_update_english_grapragh_evaluate_row = gr.update(visible=False)
728
- gr_update_english_exam_practice_row = gr.update(visible=True)
729
- gr_update_english_grapragh_practice_button = gr.update(variant="secondary")
730
- gr_update_english_grapragh_evaluate_button = gr.update(variant="secondary")
731
- gr_update_english_exam_practice_tab_button = gr.update(variant="primary")
732
-
733
- return gr_update_english_grapragh_practice_row, \
734
- gr_update_english_grapragh_evaluate_row, \
735
- gr_update_english_exam_practice_row, \
736
- gr_update_english_grapragh_practice_button, \
737
- gr_update_english_grapragh_evaluate_button, \
738
- gr_update_english_exam_practice_tab_button
739
 
740
  CSS = """
741
  .accordion-prompts {
@@ -748,9 +787,11 @@ english_grapragh_practice_button_js = """
748
  document.getElementById("english_grapragh_practice_row").style.display = "block";
749
  document.getElementById("english_grapragh_evaluate_row").style.display = "none";
750
  document.getElementById("english_exam_practice_row").style.display = "none";
 
751
  document.getElementById("english_grapragh_practice_button").classList.add("primary");
752
  document.getElementById("english_grapragh_evaluate_button").classList.remove("primary");
753
  document.getElementById("english_exam_practice_tab_button").classList.remove("primary");
 
754
 
755
  return true;
756
  }
@@ -761,9 +802,11 @@ english_grapragh_evaluate_button_js = """
761
  document.getElementById("english_grapragh_practice_row").style.display = "none";
762
  document.getElementById("english_grapragh_evaluate_row").style.display = "block";
763
  document.getElementById("english_exam_practice_row").style.display = "none";
 
764
  document.getElementById("english_grapragh_practice_button").classList.remove("primary");
765
  document.getElementById("english_grapragh_evaluate_button").classList.add("primary");
766
  document.getElementById("english_exam_practice_tab_button").classList.remove("primary");
 
767
 
768
  return true;
769
  }
@@ -774,9 +817,26 @@ english_exam_practice_tab_button_js = """
774
  document.getElementById("english_grapragh_practice_row").style.display = "none";
775
  document.getElementById("english_grapragh_evaluate_row").style.display = "none";
776
  document.getElementById("english_exam_practice_row").style.display = "block";
 
777
  document.getElementById("english_grapragh_practice_button").classList.remove("primary");
778
  document.getElementById("english_grapragh_evaluate_button").classList.remove("primary");
779
  document.getElementById("english_exam_practice_tab_button").classList.add("primary");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
780
 
781
  return true;
782
  }
@@ -786,6 +846,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue=gr.themes.colors.blue, secondary
786
 
787
  with gr.Row(visible=False) as admin_group:
788
  user_data = gr.Textbox(label="User Data", value="", elem_id="jutor_user_data_input")
 
789
  request_origin = gr.Textbox(label="Request Domain", value="")
790
 
791
  with gr.Row(visible=False) as english_group:
@@ -808,6 +869,8 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue=gr.themes.colors.blue, secondary
808
  english_grapragh_evaluate_button = gr.Button("📊 英文段落寫作評分", variant="", elem_id="english_grapragh_evaluate_button")
809
  with gr.Column():
810
  english_exam_practice_tab_button = gr.Button("🎯 英文考古題寫作練習", variant="", elem_id="english_exam_practice_tab_button")
 
 
811
  # ===== 英文段落寫作練習 =====
812
  with gr.Row(visible=True, elem_id="english_grapragh_practice_row") as english_grapragh_practice_row:
813
  with gr.Column():
@@ -1662,6 +1725,9 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue=gr.themes.colors.blue, secondary
1662
  paragraph_save_button.click(
1663
  fn=generate_paragraph_history,
1664
  inputs=[
 
 
 
1665
  scenario_input,
1666
  topic_input,
1667
  points_input,
@@ -1922,61 +1988,57 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue=gr.themes.colors.blue, secondary
1922
  outputs=past_exam_refine_output_diff
1923
  )
1924
 
1925
- # english_grapragh_practice_button.click(
1926
- # fn=update_english_grapragh_practice_rows,
1927
- # inputs=[english_grapragh_practice_button],
1928
- # outputs=[
1929
- # english_grapragh_practice_row,
1930
- # english_grapragh_evaluate_row,
1931
- # english_exam_practice_row,
1932
- # english_grapragh_practice_button,
1933
- # english_grapragh_evaluate_button,
1934
- # english_exam_practice_tab_button
1935
- # ]
1936
- # )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1937
  english_grapragh_practice_button.click(
1938
  None,
1939
  None,
1940
  None,
1941
  js=english_grapragh_practice_button_js
1942
  )
1943
-
1944
- # english_grapragh_evaluate_button.click(
1945
- # fn=update_english_grapragh_practice_rows,
1946
- # inputs=[english_grapragh_evaluate_button],
1947
- # outputs=[
1948
- # english_grapragh_practice_row,
1949
- # english_grapragh_evaluate_row,
1950
- # english_exam_practice_row,
1951
- # english_grapragh_practice_button,
1952
- # english_grapragh_evaluate_button,
1953
- # english_exam_practice_tab_button
1954
- # ]
1955
- # )
1956
  english_grapragh_evaluate_button.click(
1957
  None,
1958
  None,
1959
  None,
1960
  js=english_grapragh_evaluate_button_js
1961
  )
1962
- # english_exam_practice_tab_button.click(
1963
- # fn=update_english_grapragh_practice_rows,
1964
- # inputs=[english_exam_practice_tab_button],
1965
- # outputs=[
1966
- # english_grapragh_practice_row,
1967
- # english_grapragh_evaluate_row,
1968
- # english_exam_practice_row,
1969
- # english_grapragh_practice_button,
1970
- # english_grapragh_evaluate_button,
1971
- # english_exam_practice_tab_button
1972
- # ]
1973
- # )
1974
  english_exam_practice_tab_button.click(
1975
  None,
1976
  None,
1977
  None,
1978
  js=english_exam_practice_tab_button_js
1979
  )
 
 
 
 
 
 
1980
 
1981
 
1982
  with gr.Row(visible=False) as chinese_group:
@@ -2158,6 +2220,8 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue=gr.themes.colors.blue, secondary
2158
  init_params,
2159
  inputs =[],
2160
  outputs = [
 
 
2161
  request_origin,
2162
  english_group,
2163
  chinese_group
 
5
 
6
  import random
7
  import uuid
8
+ import json
9
+ from datetime import datetime
10
 
11
 
12
  import json
13
  import tempfile
14
+
15
+ from storage_service import GoogleCloudStorage
16
+
17
 
18
 
19
  is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
 
25
  config = json.load(f)
26
  IS_ENV_PROD = "False"
27
  OPEN_AI_KEY = config["OPEN_AI_KEY"]
28
+ GCS_KEY = json.dumps(config["GOOGLE_APPLICATION_CREDENTIALS_JSON"])
29
  else:
30
  OPEN_AI_KEY = os.getenv("OPEN_AI_KEY")
31
+ GCS_KEY = os.getenv("GOOGLE_APPLICATION_CREDENTIALS_JSON")
32
 
33
  OPEN_AI_CLIENT = OpenAI(api_key=OPEN_AI_KEY)
34
 
35
+ # 设置 Google Cloud Storage 客户端
36
+ GCS_SERVICE = GoogleCloudStorage(GCS_KEY)
37
+ GCS_CLIENT = GCS_SERVICE.client
38
+
39
  def update_scenario_input(scenario_radio):
40
  return scenario_radio
41
 
 
192
  def update_points_input(points):
193
  return points
194
 
 
 
195
  def generate_topic_sentences(model, max_tokens, sys_content, scenario, eng_level, topic, points, user_generate_topic_sentences_prompt):
196
  """
197
  根据系统提示和用户输入的情境及要点,调用OpenAI API生成相关的主题句及其合理性解释。
 
413
 
414
  return gr_update
415
 
 
416
  def generate_correct_grammatical_spelling_errors(model, sys_content, eng_level, paragraph, user_correct_grammatical_spelling_errors_prompt):
417
  """
418
  根据用户输入的段落,调用OpenAI API生成相关的文法和拼字错误修正。
 
518
  def update_paragraph_refine_input(text):
519
  return text
520
 
521
+ def generate_paragraph_history(
522
+ user_data,
523
+ session_timestamp,
524
+ request_origin,
525
+ scenario_input,
526
+ topic_output,
527
+ points_output,
528
+ topic_sentence_input,
529
+ supporting_sentences_input,
530
+ conclusion_sentence_input,
531
+ paragraph_output,
532
+ paragraph_evaluate_output,
533
+ correct_grammatical_spelling_errors_output_table,
534
+ refine_output_table,
535
+ refine_output
536
+ ):
537
  """
538
  生成段落歷史紀錄
539
  """
540
+ if user_data:
541
+ file_name = f"{user_data}/jutor_write_paragraph/{session_timestamp}.json"
542
+ content = {
543
+ "session_timestamp": session_timestamp,
544
+ "request_origin": request_origin,
545
+ "scenario_input": scenario_input,
546
+ "topic_output": topic_output,
547
+ "points_output": points_output,
548
+ "topic_sentence_input": topic_sentence_input,
549
+ "supporting_sentences_input": supporting_sentences_input,
550
+ "conclusion_sentence_input": conclusion_sentence_input,
551
+ "paragraph_output": paragraph_output,
552
+ "paragraph_evaluate_output": paragraph_evaluate_output.to_dict(orient='records'),
553
+ "correct_grammatical_spelling_errors_output_table": correct_grammatical_spelling_errors_output_table.to_dict(orient='records'),
554
+ "refine_output_table": refine_output_table.to_dict(orient='records'),
555
+ "refine_output": refine_output
556
+ }
557
+ print(file_name)
558
+ print(content)
559
+ GCS_SERVICE.upload_json_string("jutor_logs", file_name, json.dumps(content))
560
+ else:
561
+ pass
562
 
563
  return scenario_input, \
564
  topic_output, \
 
571
  correct_grammatical_spelling_errors_output_table, \
572
  refine_output_table, \
573
  refine_output
 
574
 
575
  def paragraph_save_and_tts(paragraph_text):
576
  """
 
602
  history_accordion_gr_update = gr.update(open=True)
603
  return history_accordion_gr_update
604
 
605
+ def get_logs_sessions(user_data, log_type):
606
+ if user_data and log_type:
607
+ file_name_prefix = f"{user_data}/{log_type}"
608
+ print(f"file_name_prefix: {file_name_prefix}")
609
+ file_names = GCS_SERVICE.list_files("jutor_logs", file_name_prefix)
610
+ print(f"file_names: {file_names}")
611
+ else:
612
+ file_names = []
613
+
614
+
615
+ # (name, value) name 取 最後 ../ {}.json
616
+ choices = [
617
+ (file_name.split("/")[-1].split(".")[0], file_name) for file_name in file_names
618
+ ]
619
+
620
+ paragraph_logs_session_list = gr.update(choices=choices, interactive=True, visible=True)
621
+
622
+ return paragraph_logs_session_list
623
+
624
+ def get_log_session_content(file_name):
625
+ if file_name:
626
+ content = GCS_SERVICE.download_as_string("jutor_logs", file_name)
627
+ print(f"content: {content}")
628
+ content_json = json.loads(content)
629
+ else:
630
+ content_json = None
631
+
632
+ return content_json
633
 
634
+
635
+ # === Chinese ===
636
  def generate_chinese_evaluation_table(model, sys_content, user_prompt, text):
637
  # https://www.ceec.edu.tw/files/file_pool/1/0j052575870800204600/1216%E5%9C%8B%E6%96%87%E4%BD%9C%E6%96%87%E5%88%86%E9%A0%85%E5%BC%8F%E8%A9%95%E5%88%86%E6%8C%87%E6%A8%99.pdf
638
 
 
756
  else:
757
  raise gr.Error("Invalid origin")
758
 
759
+ # admin_group visible in local
760
+ if is_env_local:
761
+ admin_group = gr.update(visible=True)
762
+
763
+ # session timestamp 用 2024-01-01-12-00-00 格式
764
+ session_timestamp = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
765
+
766
+
767
  if "language" in query_params:
768
  if query_params["language"] == "english":
769
  print(f"language: english")
 
774
  english_group = gr.update(visible=False)
775
  chinese_group = gr.update(visible=True)
776
 
777
+ return admin_group, session_timestamp, request_origin, english_group, chinese_group
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
778
 
779
  CSS = """
780
  .accordion-prompts {
 
787
  document.getElementById("english_grapragh_practice_row").style.display = "block";
788
  document.getElementById("english_grapragh_evaluate_row").style.display = "none";
789
  document.getElementById("english_exam_practice_row").style.display = "none";
790
+ document.getElementById("english_logs_row").style.display = "none";
791
  document.getElementById("english_grapragh_practice_button").classList.add("primary");
792
  document.getElementById("english_grapragh_evaluate_button").classList.remove("primary");
793
  document.getElementById("english_exam_practice_tab_button").classList.remove("primary");
794
+ document.getElementById("english_logs_tab_button").classList.remove("primary");
795
 
796
  return true;
797
  }
 
802
  document.getElementById("english_grapragh_practice_row").style.display = "none";
803
  document.getElementById("english_grapragh_evaluate_row").style.display = "block";
804
  document.getElementById("english_exam_practice_row").style.display = "none";
805
+ document.getElementById("english_logs_row").style.display = "none";
806
  document.getElementById("english_grapragh_practice_button").classList.remove("primary");
807
  document.getElementById("english_grapragh_evaluate_button").classList.add("primary");
808
  document.getElementById("english_exam_practice_tab_button").classList.remove("primary");
809
+ document.getElementById("english_logs_tab_button").classList.remove("primary");
810
 
811
  return true;
812
  }
 
817
  document.getElementById("english_grapragh_practice_row").style.display = "none";
818
  document.getElementById("english_grapragh_evaluate_row").style.display = "none";
819
  document.getElementById("english_exam_practice_row").style.display = "block";
820
+ document.getElementById("english_logs_row").style.display = "none";
821
  document.getElementById("english_grapragh_practice_button").classList.remove("primary");
822
  document.getElementById("english_grapragh_evaluate_button").classList.remove("primary");
823
  document.getElementById("english_exam_practice_tab_button").classList.add("primary");
824
+ document.getElementById("english_logs_tab_button").classList.remove("primary");
825
+
826
+ return true;
827
+ }
828
+ """
829
+
830
+ english_logs_tab_button_js = """
831
+ function english_logs_tab_button_click() {
832
+ document.getElementById("english_grapragh_practice_row").style.display = "none";
833
+ document.getElementById("english_grapragh_evaluate_row").style.display = "none";
834
+ document.getElementById("english_exam_practice_row").style.display = "none";
835
+ document.getElementById("english_logs_row").style.display = "block";
836
+ document.getElementById("english_grapragh_practice_button").classList.remove("primary");
837
+ document.getElementById("english_grapragh_evaluate_button").classList.remove("primary");
838
+ document.getElementById("english_exam_practice_tab_button").classList.remove("primary");
839
+ document.getElementById("english_logs_tab_button").classList.add("primary");
840
 
841
  return true;
842
  }
 
846
 
847
  with gr.Row(visible=False) as admin_group:
848
  user_data = gr.Textbox(label="User Data", value="", elem_id="jutor_user_data_input")
849
+ session_timestamp = gr.Textbox(label="Session Timestamp", value="", elem_id="jutor_session_timestamp_input")
850
  request_origin = gr.Textbox(label="Request Domain", value="")
851
 
852
  with gr.Row(visible=False) as english_group:
 
869
  english_grapragh_evaluate_button = gr.Button("📊 英文段落寫作評分", variant="", elem_id="english_grapragh_evaluate_button")
870
  with gr.Column():
871
  english_exam_practice_tab_button = gr.Button("🎯 英文考古題寫作練習", variant="", elem_id="english_exam_practice_tab_button")
872
+ with gr.Column():
873
+ english_logs_tab_button = gr.Button("📚 歷程回顧", variant="", elem_id="english_logs_tab_button")
874
  # ===== 英文段落寫作練習 =====
875
  with gr.Row(visible=True, elem_id="english_grapragh_practice_row") as english_grapragh_practice_row:
876
  with gr.Column():
 
1725
  paragraph_save_button.click(
1726
  fn=generate_paragraph_history,
1727
  inputs=[
1728
+ user_data,
1729
+ session_timestamp,
1730
+ request_origin,
1731
  scenario_input,
1732
  topic_input,
1733
  points_input,
 
1988
  outputs=past_exam_refine_output_diff
1989
  )
1990
 
1991
+ # ===== 英文歷程 ====
1992
+ with gr.Row(visible=False, elem_id="english_logs_row") as english_logs_row:
1993
+ with gr.Column():
1994
+ with gr.Row():
1995
+ gr.Markdown("# 📚 歷程回顧")
1996
+ with gr.Row():
1997
+ with gr.Column(scale=1):
1998
+ # 取得英文段落練習 log from GCS
1999
+ paragraph_logs_type = gr.State("jutor_write_paragraph")
2000
+ get_paragraph_logs_button = gr.Button("取得英文段落練習歷程")
2001
+ paragraph_logs_session_list = gr.Radio(label="歷程時間列表")
2002
+ with gr.Column(scale=3):
2003
+ paragraph_logs_session_content = gr.JSON()
2004
+
2005
+ get_paragraph_logs_button.click(
2006
+ fn=get_logs_sessions,
2007
+ inputs=[user_data, paragraph_logs_type],
2008
+ outputs=[paragraph_logs_session_list]
2009
+ )
2010
+
2011
+ paragraph_logs_session_list.select(
2012
+ fn=get_log_session_content,
2013
+ inputs=[paragraph_logs_session_list],
2014
+ outputs=[paragraph_logs_session_content]
2015
+ )
2016
+
2017
+
2018
  english_grapragh_practice_button.click(
2019
  None,
2020
  None,
2021
  None,
2022
  js=english_grapragh_practice_button_js
2023
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
2024
  english_grapragh_evaluate_button.click(
2025
  None,
2026
  None,
2027
  None,
2028
  js=english_grapragh_evaluate_button_js
2029
  )
 
 
 
 
 
 
 
 
 
 
 
 
2030
  english_exam_practice_tab_button.click(
2031
  None,
2032
  None,
2033
  None,
2034
  js=english_exam_practice_tab_button_js
2035
  )
2036
+ english_logs_tab_button.click(
2037
+ None,
2038
+ None,
2039
+ None,
2040
+ js=english_logs_tab_button_js
2041
+ )
2042
 
2043
 
2044
  with gr.Row(visible=False) as chinese_group:
 
2220
  init_params,
2221
  inputs =[],
2222
  outputs = [
2223
+ admin_group,
2224
+ session_timestamp,
2225
  request_origin,
2226
  english_group,
2227
  chinese_group
storage_service.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from google.cloud import storage
3
+ from google.oauth2 import service_account
4
+ from googleapiclient.http import MediaIoBaseDownload
5
+
6
+
7
+ class GoogleCloudStorage:
8
+ def __init__(self, service_account_key_string):
9
+ credentials_dict = json.loads(service_account_key_string)
10
+ credentials = service_account.Credentials.from_service_account_info(credentials_dict)
11
+ self.client = storage.Client(credentials=credentials, project=credentials_dict['project_id'])
12
+
13
+ def check_file_exists(self, bucket_name, file_name):
14
+ blob = self.client.bucket(bucket_name).blob(file_name)
15
+ return blob.exists()
16
+
17
+ def upload_file(self, bucket_name, destination_blob_name, file_path):
18
+ blob = self.client.bucket(bucket_name).blob(destination_blob_name)
19
+ blob.upload_from_filename(file_path)
20
+ print(f"File {file_path} uploaded to {destination_blob_name} in GCS.")
21
+
22
+ def upload_file_as_string(self, bucket_name, destination_blob_name, content):
23
+ blob = self.client.bucket(bucket_name).blob(destination_blob_name)
24
+ blob.upload_from_string(content)
25
+ print(f"String content uploaded to {destination_blob_name} in GCS.")
26
+ return None
27
+
28
+ def upload_json_string(self, bucket_name, destination_blob_name, json_data):
29
+ """Uploads a JSON string to a specified GCS bucket."""
30
+ blob = self.client.bucket(bucket_name).blob(destination_blob_name)
31
+ blob.upload_from_string(json_data, content_type='application/json')
32
+ print(f"JSON string uploaded to {destination_blob_name} in GCS.")
33
+
34
+ def download_as_string(self, bucket_name, source_blob_name):
35
+ blob = self.client.bucket(bucket_name).blob(source_blob_name)
36
+ return blob.download_as_text()
37
+
38
+ def make_blob_public(self, bucket_name, blob_name):
39
+ blob = self.client.bucket(bucket_name).blob(blob_name)
40
+ blob.make_public()
41
+ print(f"Blob {blob_name} is now publicly accessible at {blob.public_url}")
42
+
43
+ def get_public_url(self, bucket_name, blob_name):
44
+ blob = self.client.bucket(bucket_name).blob(blob_name)
45
+ return blob.public_url
46
+
47
+ def upload_image_and_get_public_url(self, bucket_name, file_name, file_path):
48
+ self.upload_file(bucket_name, file_name, file_path)
49
+ self.make_blob_public(bucket_name, file_name)
50
+ return self.get_public_url(bucket_name, file_name)
51
+
52
+ def delete_blob(self, bucket_name, blob_name):
53
+ blob = self.client.bucket(bucket_name).blob(blob_name)
54
+ blob.delete()
55
+ print(f"Blob {blob_name} deleted from {bucket_name}.")
56
+
57
+ def list_files(self, bucket_name, prefix=None):
58
+ blobs = self.client.bucket(bucket_name).list_blobs(prefix=prefix)
59
+ return [blob.name for blob in blobs]