Spaces:
Sleeping
Sleeping
with gr.Tab("老師|作業列表") as assignment_list_tab:
Browse files- app.py +29 -6
- assignment_service.py +38 -4
- assignment_ui.py +180 -0
- submission_service.py +14 -2
app.py
CHANGED
@@ -15,7 +15,11 @@ import urllib.parse
|
|
15 |
import pandas as pd
|
16 |
import re
|
17 |
|
|
|
18 |
from storage_service import GoogleCloudStorage
|
|
|
|
|
|
|
19 |
|
20 |
is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
|
21 |
print(f"is_env_local: {is_env_local}")
|
@@ -1353,6 +1357,9 @@ def init_params(request: gr.Request):
|
|
1353 |
admin_group = gr.update(visible=False)
|
1354 |
english_group = gr.update(visible=True)
|
1355 |
chinese_group = gr.update(visible=True)
|
|
|
|
|
|
|
1356 |
|
1357 |
# check if origin is from junyiacademy
|
1358 |
query_params = dict(request.query_params)
|
@@ -1372,19 +1379,27 @@ def init_params(request: gr.Request):
|
|
1372 |
# admin_group visible in local
|
1373 |
if is_env_local:
|
1374 |
admin_group = gr.update(visible=True)
|
|
|
1375 |
|
1376 |
# session timestamp 用 2024-01-01-12-00-00 格式, 要用 UTC+8 時間
|
1377 |
session_timestamp = datetime.now(pytz.utc).astimezone(pytz.timezone('Asia/Taipei')).strftime("%Y-%m-%d-%H-%M-%S")
|
1378 |
|
1379 |
-
if "language" in query_params:
|
1380 |
-
if query_params["language"] == "english":
|
1381 |
print(f"language: english")
|
1382 |
english_group = gr.update(visible=True)
|
1383 |
chinese_group = gr.update(visible=False)
|
1384 |
-
|
|
|
|
|
1385 |
print(f"language: chinese")
|
1386 |
english_group = gr.update(visible=False)
|
1387 |
chinese_group = gr.update(visible=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
1388 |
|
1389 |
assignment_id_value = None
|
1390 |
assignment_json_value = None
|
@@ -1417,10 +1432,11 @@ def init_params(request: gr.Request):
|
|
1417 |
assignment_id_input = gr.update(value=None)
|
1418 |
assignment_json = gr.update(value=None)
|
1419 |
|
1420 |
-
return
|
|
|
1421 |
assignment_id_input, assignment_json, \
|
1422 |
chinese_assignment_row, chinese_assignment_grade, chinese_assignment_topic, chinese_assignment_introduction, chinese_assignment_description, \
|
1423 |
-
english_group, chinese_group
|
1424 |
|
1425 |
CSS = """
|
1426 |
.accordion-prompts {
|
@@ -3343,10 +3359,16 @@ with gr.Blocks(theme=THEME, css=CSS) as demo:
|
|
3343 |
outputs=chinese_essay_idea_output
|
3344 |
)
|
3345 |
|
|
|
|
|
|
|
|
|
|
|
3346 |
demo.load(
|
3347 |
init_params,
|
3348 |
inputs =[],
|
3349 |
outputs = [
|
|
|
3350 |
admin_group,
|
3351 |
session_timestamp,
|
3352 |
request_origin,
|
@@ -3358,7 +3380,8 @@ with gr.Blocks(theme=THEME, css=CSS) as demo:
|
|
3358 |
chinese_assignment_introduction,
|
3359 |
chinese_assignment_description,
|
3360 |
english_group,
|
3361 |
-
chinese_group
|
|
|
3362 |
]
|
3363 |
)
|
3364 |
|
|
|
15 |
import pandas as pd
|
16 |
import re
|
17 |
|
18 |
+
# From other files
|
19 |
from storage_service import GoogleCloudStorage
|
20 |
+
from assignment_ui import create_assignment_ui
|
21 |
+
from assignment_service import AssignmentService
|
22 |
+
from submission_service import SubmissionService
|
23 |
|
24 |
is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
|
25 |
print(f"is_env_local: {is_env_local}")
|
|
|
1357 |
admin_group = gr.update(visible=False)
|
1358 |
english_group = gr.update(visible=True)
|
1359 |
chinese_group = gr.update(visible=True)
|
1360 |
+
assignment_tab = gr.update(visible=False)
|
1361 |
+
|
1362 |
+
user_data = gr.update(value="")
|
1363 |
|
1364 |
# check if origin is from junyiacademy
|
1365 |
query_params = dict(request.query_params)
|
|
|
1379 |
# admin_group visible in local
|
1380 |
if is_env_local:
|
1381 |
admin_group = gr.update(visible=True)
|
1382 |
+
user_data = gr.update(value="aa")
|
1383 |
|
1384 |
# session timestamp 用 2024-01-01-12-00-00 格式, 要用 UTC+8 時間
|
1385 |
session_timestamp = datetime.now(pytz.utc).astimezone(pytz.timezone('Asia/Taipei')).strftime("%Y-%m-%d-%H-%M-%S")
|
1386 |
|
1387 |
+
if "language" in query_params and query_params["language"] == "english":
|
|
|
1388 |
print(f"language: english")
|
1389 |
english_group = gr.update(visible=True)
|
1390 |
chinese_group = gr.update(visible=False)
|
1391 |
+
assignment_tab = gr.update(visible=False)
|
1392 |
+
|
1393 |
+
if "language" in query_params and query_params["language"] == "chinese":
|
1394 |
print(f"language: chinese")
|
1395 |
english_group = gr.update(visible=False)
|
1396 |
chinese_group = gr.update(visible=True)
|
1397 |
+
assignment_tab = gr.update(visible=False)
|
1398 |
+
|
1399 |
+
if "assignment_mode" in query_params and query_params["assignment_mode"] == "true":
|
1400 |
+
english_group = gr.update(visible=False)
|
1401 |
+
chinese_group = gr.update(visible=False)
|
1402 |
+
assignment_tab = gr.update(visible=True)
|
1403 |
|
1404 |
assignment_id_value = None
|
1405 |
assignment_json_value = None
|
|
|
1432 |
assignment_id_input = gr.update(value=None)
|
1433 |
assignment_json = gr.update(value=None)
|
1434 |
|
1435 |
+
return user_data, \
|
1436 |
+
admin_group, session_timestamp, request_origin, \
|
1437 |
assignment_id_input, assignment_json, \
|
1438 |
chinese_assignment_row, chinese_assignment_grade, chinese_assignment_topic, chinese_assignment_introduction, chinese_assignment_description, \
|
1439 |
+
english_group, chinese_group, assignment_tab
|
1440 |
|
1441 |
CSS = """
|
1442 |
.accordion-prompts {
|
|
|
3359 |
outputs=chinese_essay_idea_output
|
3360 |
)
|
3361 |
|
3362 |
+
with gr.Tab("作業管理") as assignment_tab:
|
3363 |
+
assignment_service = AssignmentService(GCS_SERVICE)
|
3364 |
+
submission_service = SubmissionService(GCS_SERVICE)
|
3365 |
+
assignment_interface = create_assignment_ui(user_data, assignment_service, submission_service)
|
3366 |
+
|
3367 |
demo.load(
|
3368 |
init_params,
|
3369 |
inputs =[],
|
3370 |
outputs = [
|
3371 |
+
user_data,
|
3372 |
admin_group,
|
3373 |
session_timestamp,
|
3374 |
request_origin,
|
|
|
3380 |
chinese_assignment_introduction,
|
3381 |
chinese_assignment_description,
|
3382 |
english_group,
|
3383 |
+
chinese_group,
|
3384 |
+
assignment_tab
|
3385 |
]
|
3386 |
)
|
3387 |
|
assignment_service.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1 |
import uuid
|
2 |
import json
|
3 |
-
import datetime
|
4 |
import gradio as gr
|
5 |
from datetime import datetime
|
6 |
|
@@ -16,6 +15,21 @@ class AssignmentService:
|
|
16 |
file_name = f"assignments/{assignment_id}.json"
|
17 |
if not self.gcs_service.check_file_exists(self.bucket_name, file_name):
|
18 |
return assignment_id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
def create_assignment(self, user_data, assignment_type, metadata):
|
21 |
assignment_id = self.create_assignment_id()
|
@@ -55,6 +69,10 @@ class AssignmentService:
|
|
55 |
print(f"Error: {e}")
|
56 |
return "無效的作業 ID"
|
57 |
return assignment_data
|
|
|
|
|
|
|
|
|
58 |
|
59 |
def get_user_assignments(self, user_id):
|
60 |
try:
|
@@ -68,10 +86,26 @@ class AssignmentService:
|
|
68 |
def update_assignment_list(self, assigner_data):
|
69 |
choices = []
|
70 |
user_assignments = self.get_user_assignments(assigner_data)
|
71 |
-
for assignment_id in user_assignments.
|
72 |
assignment_data = self.get_assignment(assignment_id)
|
73 |
metadata = assignment_data.get("metadata", {})
|
74 |
-
topic = metadata.get("topic", "
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
choices.append(choice)
|
|
|
|
|
|
|
|
|
77 |
return gr.update(choices=choices)
|
|
|
|
|
|
|
|
|
|
1 |
import uuid
|
2 |
import json
|
|
|
3 |
import gradio as gr
|
4 |
from datetime import datetime
|
5 |
|
|
|
15 |
file_name = f"assignments/{assignment_id}.json"
|
16 |
if not self.gcs_service.check_file_exists(self.bucket_name, file_name):
|
17 |
return assignment_id
|
18 |
+
|
19 |
+
def create_assignment_metadata(self, assignment_type, grade, topic, introduction, description, url, attach_materials, submission_deadline):
|
20 |
+
if assignment_type == "中文寫作 AI 批改":
|
21 |
+
metadata = {
|
22 |
+
"assignment_type": assignment_type,
|
23 |
+
"grade": grade,
|
24 |
+
"topic": topic,
|
25 |
+
"introduction": introduction,
|
26 |
+
"description": description,
|
27 |
+
"url": url,
|
28 |
+
"attach_materials": attach_materials,
|
29 |
+
"submission_deadline": submission_deadline
|
30 |
+
}
|
31 |
+
|
32 |
+
return metadata
|
33 |
|
34 |
def create_assignment(self, user_data, assignment_type, metadata):
|
35 |
assignment_id = self.create_assignment_id()
|
|
|
69 |
print(f"Error: {e}")
|
70 |
return "無效的作業 ID"
|
71 |
return assignment_data
|
72 |
+
|
73 |
+
def get_assignment_submissions(self, assignment_id):
|
74 |
+
assignment_data = self.get_assignment(assignment_id)
|
75 |
+
return assignment_data["submission_ids"]
|
76 |
|
77 |
def get_user_assignments(self, user_id):
|
78 |
try:
|
|
|
86 |
def update_assignment_list(self, assigner_data):
|
87 |
choices = []
|
88 |
user_assignments = self.get_user_assignments(assigner_data)
|
89 |
+
for assignment_id, assignment_info in user_assignments.items():
|
90 |
assignment_data = self.get_assignment(assignment_id)
|
91 |
metadata = assignment_data.get("metadata", {})
|
92 |
+
topic = metadata.get("topic", "未命名作業")
|
93 |
+
assignment_type = assignment_data.get("assignment_type", "未知類型")
|
94 |
+
timestamp = assignment_data.get("timestamp", "未知日期")
|
95 |
+
|
96 |
+
# 格式化日期
|
97 |
+
date = datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d")
|
98 |
+
|
99 |
+
# 創建格式化的選項
|
100 |
+
formatted_choice = f"{date}|{assignment_type}|{topic}"
|
101 |
+
choice = (formatted_choice, assignment_id)
|
102 |
choices.append(choice)
|
103 |
+
|
104 |
+
# 按日期降序排序
|
105 |
+
choices.sort(key=lambda x: x[0].split("|")[0], reverse=True)
|
106 |
+
|
107 |
return gr.update(choices=choices)
|
108 |
+
|
109 |
+
|
110 |
+
|
111 |
+
|
assignment_ui.py
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
|
3 |
+
def create_assignment_ui(user_data, assignment_service, submission_service):
|
4 |
+
with gr.Blocks() as assignment_interface:
|
5 |
+
with gr.Tab("老師|建立作業"):
|
6 |
+
with gr.Row():
|
7 |
+
with gr.Column():
|
8 |
+
assignment_type_list = [
|
9 |
+
"中文寫作 AI 批改",
|
10 |
+
"英文寫作 AI 批改"
|
11 |
+
]
|
12 |
+
assignment_type = gr.Radio(choices=assignment_type_list, label="選擇類型")
|
13 |
+
grade = gr.Radio(["一年級", "二年級", "三年級", "四年級", "五年級", "六年級"], label="選擇年級")
|
14 |
+
topic = gr.Textbox(label="題目")
|
15 |
+
introduction = gr.Textbox(label="寫作引文(非必填)")
|
16 |
+
description = gr.Textbox(label="作業說明")
|
17 |
+
url = gr.Textbox(label="作業链接")
|
18 |
+
attach_materials = gr.Textbox(label="附加材料 (JSON 格式)", placeholder='[{"type": "video", "url": "link1", "description": "描述"}]')
|
19 |
+
submission_deadline = gr.Textbox(label="提交截止日期", placeholder="2024-09-01T23:59:59Z")
|
20 |
+
create_button = gr.Button("建立作業")
|
21 |
+
assignment_id_display_teacher = gr.Textbox(label="作業 ID", interactive=False)
|
22 |
+
assignment_metadata = gr.JSON(label="作業元數據")
|
23 |
+
|
24 |
+
create_button.click(
|
25 |
+
assignment_service.create_assignment_metadata,
|
26 |
+
inputs=[assignment_type, grade, topic, introduction, description, url, attach_materials, submission_deadline],
|
27 |
+
outputs=[assignment_metadata]
|
28 |
+
).then(
|
29 |
+
assignment_service.create_assignment,
|
30 |
+
inputs=[user_data, assignment_type, assignment_metadata],
|
31 |
+
outputs=[assignment_id_display_teacher]
|
32 |
+
)
|
33 |
+
|
34 |
+
with gr.Tab("老師|作業列表") as assignment_list_tab:
|
35 |
+
with gr.Row():
|
36 |
+
with gr.Column(scale=1):
|
37 |
+
get_all_assignments_button = gr.Button("獲取所有作業")
|
38 |
+
assignment_list = gr.Radio([], label="作業列表", interactive=True)
|
39 |
+
with gr.Column(scale=2):
|
40 |
+
assignment_data = gr.JSON(label="作業內容", visible=False)
|
41 |
+
assignment_data_markdown = gr.Markdown(label="作業內容", show_label=True)
|
42 |
+
with gr.Row():
|
43 |
+
with gr.Column(scale=1):
|
44 |
+
submissions_list_json = gr.JSON(visible=False)
|
45 |
+
submissions_list_radio = gr.Radio([], label="已提交的作業學生", interactive=True)
|
46 |
+
with gr.Column(scale=2):
|
47 |
+
submission_data_json = gr.JSON(label="提交內容", visible=False)
|
48 |
+
submission_data_markdown = gr.Markdown(label="提交內容")
|
49 |
+
|
50 |
+
def init_assignment_list_data(assignment_list_value=None):
|
51 |
+
assignment_list = gr.update(value=assignment_list_value)
|
52 |
+
assignment_data = gr.update(value=None)
|
53 |
+
assignment_data_markdown = gr.update(value=None)
|
54 |
+
submissions_list_json = gr.update(value=None)
|
55 |
+
submissions_list_radio = gr.update(choices=[], value=None)
|
56 |
+
submission_data_json = gr.update(value=None)
|
57 |
+
submission_data_markdown = gr.update(value=None)
|
58 |
+
return assignment_list, assignment_data, assignment_data_markdown, submissions_list_json, submissions_list_radio, submission_data_json, submission_data_markdown
|
59 |
+
|
60 |
+
def update_assignment_data_markdown(assignment_data):
|
61 |
+
markdown_value = f"""
|
62 |
+
### 作業類型: {assignment_data['assignment_type']}
|
63 |
+
### 作業年級: {assignment_data['metadata']['grade']}
|
64 |
+
### 作業題目: {assignment_data['metadata']['topic']}
|
65 |
+
### 日期: {assignment_data['timestamp']}
|
66 |
+
### 作業引文
|
67 |
+
{assignment_data['metadata']['introduction']}
|
68 |
+
### 作業說明:
|
69 |
+
{assignment_data['metadata']['description']}
|
70 |
+
### 作業連結: {assignment_data['metadata']['url']}
|
71 |
+
### 附加材料:
|
72 |
+
{assignment_data['metadata']['attach_materials']}
|
73 |
+
"""
|
74 |
+
return gr.update(value=markdown_value)
|
75 |
+
|
76 |
+
def update_submissions_list_radio(submission_ids):
|
77 |
+
choices = []
|
78 |
+
for submission_id in submission_ids:
|
79 |
+
submission_data = submission_service.get_submission_from_gcs(submission_id)
|
80 |
+
choice_text = f"{submission_data['student_name']}"
|
81 |
+
choice = (choice_text, submission_id)
|
82 |
+
choices.append(choice)
|
83 |
+
return gr.update(choices=choices)
|
84 |
+
|
85 |
+
def update_submission_data_markdown(submission_json):
|
86 |
+
markdown_value = f"""
|
87 |
+
### 提交內容
|
88 |
+
{submission_json['submission_data']['content']}
|
89 |
+
### 提交日期
|
90 |
+
{submission_json['timestamp']}
|
91 |
+
"""
|
92 |
+
return gr.update(value=markdown_value)
|
93 |
+
|
94 |
+
get_all_assignments_button.click(
|
95 |
+
assignment_service.update_assignment_list,
|
96 |
+
inputs=[user_data],
|
97 |
+
outputs=assignment_list
|
98 |
+
).then(
|
99 |
+
fn=init_assignment_list_data,
|
100 |
+
inputs=[],
|
101 |
+
outputs=[assignment_list, assignment_data, assignment_data_markdown, submissions_list_json, submissions_list_radio, submission_data_json, submission_data_markdown]
|
102 |
+
)
|
103 |
+
|
104 |
+
assignment_list.select(
|
105 |
+
fn=init_assignment_list_data,
|
106 |
+
inputs=[assignment_list],
|
107 |
+
outputs=[assignment_list, assignment_data, assignment_data_markdown, submissions_list_json, submissions_list_radio, submission_data_json, submission_data_markdown]
|
108 |
+
).then(
|
109 |
+
assignment_service.get_assignment,
|
110 |
+
inputs=[assignment_list],
|
111 |
+
outputs=[assignment_data]
|
112 |
+
).then(
|
113 |
+
fn=update_assignment_data_markdown,
|
114 |
+
inputs=[assignment_data],
|
115 |
+
outputs=[assignment_data_markdown]
|
116 |
+
).then(
|
117 |
+
assignment_service.get_assignment_submissions,
|
118 |
+
inputs=[assignment_list],
|
119 |
+
outputs=[submissions_list_json]
|
120 |
+
).then(
|
121 |
+
fn=update_submissions_list_radio,
|
122 |
+
inputs=[submissions_list_json],
|
123 |
+
outputs=[submissions_list_radio]
|
124 |
+
)
|
125 |
+
|
126 |
+
submissions_list_radio.select(
|
127 |
+
submission_service.get_submission_from_gcs,
|
128 |
+
inputs=[submissions_list_radio],
|
129 |
+
outputs=submission_data_json
|
130 |
+
).then(
|
131 |
+
fn=update_submission_data_markdown,
|
132 |
+
inputs=[submission_data_json],
|
133 |
+
outputs=[submission_data_markdown]
|
134 |
+
)
|
135 |
+
|
136 |
+
with gr.Tab("學生"):
|
137 |
+
with gr.Row():
|
138 |
+
with gr.Column():
|
139 |
+
assignment_id_input_student = gr.Textbox(label="作業 ID")
|
140 |
+
get_assignment_button = gr.Button("獲取作業")
|
141 |
+
assignment_display = gr.JSON(label="作業內容")
|
142 |
+
|
143 |
+
get_assignment_button.click(
|
144 |
+
assignment_service.get_assignment,
|
145 |
+
inputs=[assignment_id_input_student],
|
146 |
+
outputs=assignment_display
|
147 |
+
)
|
148 |
+
|
149 |
+
with gr.Row():
|
150 |
+
with gr.Column():
|
151 |
+
student_name_input = gr.Textbox(label="學生姓名")
|
152 |
+
submission_input = gr.Textbox(label="文字輸入")
|
153 |
+
submit_button = gr.Button("繳交作業")
|
154 |
+
submission_status = gr.Textbox(label="繳交狀態", interactive=False)
|
155 |
+
|
156 |
+
submit_button.click(
|
157 |
+
submission_service.submit_assignment,
|
158 |
+
inputs=[assignment_id_input_student, user_data, student_name_input, submission_input],
|
159 |
+
outputs=submission_status
|
160 |
+
)
|
161 |
+
|
162 |
+
with gr.Row():
|
163 |
+
with gr.Column():
|
164 |
+
load_submissions_button = gr.Button("獲取提交的作業")
|
165 |
+
submissions_radio = gr.Radio([], label="提交的作業", interactive=True)
|
166 |
+
submission_display = gr.JSON(label="作業內容")
|
167 |
+
|
168 |
+
load_submissions_button.click(
|
169 |
+
submission_service.update_submission_list,
|
170 |
+
inputs=[user_data],
|
171 |
+
outputs=submissions_radio
|
172 |
+
)
|
173 |
+
|
174 |
+
submissions_radio.select(
|
175 |
+
submission_service.get_submission_from_gcs,
|
176 |
+
inputs=[submissions_radio],
|
177 |
+
outputs=submission_display
|
178 |
+
)
|
179 |
+
|
180 |
+
return assignment_interface
|
submission_service.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1 |
import uuid
|
2 |
import json
|
3 |
-
import datetime
|
4 |
import gradio as gr
|
5 |
from datetime import datetime
|
6 |
|
@@ -36,8 +35,21 @@ class SubmissionService:
|
|
36 |
|
37 |
self.save_submission_to_gcs(submission_data)
|
38 |
self.save_user_submissions_to_gcs(student_id, submission_data)
|
|
|
39 |
|
40 |
return f"作業已收到,學生ID:{student_id}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
def get_assignment_data(self, assignment_id):
|
43 |
try:
|
@@ -111,7 +123,7 @@ class SubmissionService:
|
|
111 |
choices.append(choice)
|
112 |
return gr.update(choices=choices)
|
113 |
|
114 |
-
def
|
115 |
submission_ids = self.list_submissions()
|
116 |
for submission_id in submission_ids:
|
117 |
submission_data = self.get_submission_from_gcs(submission_id)
|
|
|
1 |
import uuid
|
2 |
import json
|
|
|
3 |
import gradio as gr
|
4 |
from datetime import datetime
|
5 |
|
|
|
35 |
|
36 |
self.save_submission_to_gcs(submission_data)
|
37 |
self.save_user_submissions_to_gcs(student_id, submission_data)
|
38 |
+
self.update_assignment_submission_ids(assignment_id, submission_id)
|
39 |
|
40 |
return f"作業已收到,學生ID:{student_id}"
|
41 |
+
|
42 |
+
def update_assignment_submission_ids(self, assignment_id, submission_id):
|
43 |
+
try:
|
44 |
+
assignment_data = self.get_assignment_data(assignment_id)
|
45 |
+
if assignment_data:
|
46 |
+
if "submission_ids" not in assignment_data:
|
47 |
+
assignment_data["submission_ids"] = []
|
48 |
+
assignment_data["submission_ids"].append(submission_id)
|
49 |
+
file_name = f"assignments/{assignment_id}.json"
|
50 |
+
self.gcs_service.upload_json_string(self.bucket_name, file_name, json.dumps(assignment_data))
|
51 |
+
except Exception as e:
|
52 |
+
print(f"更新作業提交ID時出錯:{e}")
|
53 |
|
54 |
def get_assignment_data(self, assignment_id):
|
55 |
try:
|
|
|
123 |
choices.append(choice)
|
124 |
return gr.update(choices=choices)
|
125 |
|
126 |
+
def get_student_submissions(self, student_id):
|
127 |
submission_ids = self.list_submissions()
|
128 |
for submission_id in submission_ids:
|
129 |
submission_data = self.get_submission_from_gcs(submission_id)
|