Spaces:
Sleeping
Sleeping
gr.Markdown("# 📚 歷程回顧")
Browse files- app.py +150 -86
- 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 |
-
|
|
|
|
|
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(
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
|
|
|
|
|
|
|
|
|
|
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 |
-
#
|
1926 |
-
|
1927 |
-
|
1928 |
-
|
1929 |
-
|
1930 |
-
|
1931 |
-
|
1932 |
-
|
1933 |
-
|
1934 |
-
|
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]
|