File size: 7,011 Bytes
309c78e
 
 
 
d270452
2f705b4
309c78e
 
 
 
 
 
 
 
 
 
 
 
 
e9e2b32
96c172b
f455cf9
 
 
 
 
f1b30c1
 
 
 
 
 
 
 
 
e9e2b32
 
309c78e
 
 
2f705b4
96c172b
 
e751703
96c172b
 
 
 
 
309c78e
 
 
 
 
96c172b
309c78e
 
 
 
 
96c172b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309c78e
 
 
 
 
 
 
 
 
 
 
 
 
4d3170d
d270452
309c78e
 
 
 
 
 
 
 
 
 
e9e2b32
 
 
 
309c78e
 
 
d270452
 
309c78e
 
 
 
 
 
 
 
 
e9e2b32
309c78e
 
e9e2b32
 
 
 
 
 
 
 
 
 
309c78e
e9e2b32
 
 
 
309c78e
e9e2b32
 
f455cf9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e9e2b32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import uuid
import json
import gradio as gr
from datetime import datetime
import urllib.parse
import pytz


class AssignmentService:
    def __init__(self, gcs_service):
        self.bucket_name = "ai_assignment_submission"
        self.gcs_service = gcs_service

    def create_assignment_id(self):
        while True:
            assignment_id = "assign_" + str(uuid.uuid4())
            file_name = f"assignments/{assignment_id}.json"
            if not self.gcs_service.check_file_exists(self.bucket_name, file_name):
                return assignment_id
            
    def create_assignment_metadata(self, assignment_type, grade, topic, introduction, description, attach_materials, submission_deadline):
        # submission_deadline is Unix timestamp (seconds)
        # convert to ISO format with timezone, example: 2024-06-01T00:00:00+08:00
        taipei_tz = pytz.timezone('Asia/Taipei')
        submission_deadline = datetime.fromtimestamp(submission_deadline, tz=taipei_tz).isoformat()
        
        metadata = {
            "assignment_type": assignment_type,
            "grade": grade,
            "topic": topic,
            "introduction": introduction,
            "description": description,
            "attach_materials": attach_materials,
            "submission_deadline": submission_deadline
        }
        
        return metadata

    def create_assignment(self, user_data, assignment_type, metadata):
        assignment_id = self.create_assignment_id()
        timestamp_now = datetime.now(pytz.utc).astimezone(pytz.timezone('Asia/Taipei')).strftime("%Y-%m-%d %H:%M:%S")
        host_url = "https://www.junyiacademy.org/event/jutor_write_2024/?__theme=light"
        language_mapping = {
            "中文寫作 AI 批改": "chinese",
            "英文寫作 AI 批改": "english"
        }
        language = language_mapping.get(assignment_type, "")

        assignment_url = f"{host_url}&language={language}&assignment={assignment_id}"
        new_assignment = {
            "assignment_id": assignment_id,
            "assigner_data": user_data,
            "assignment_type": assignment_type,
            "metadata": metadata,
            "assignment_url": assignment_url,
            "submission_ids": [],
            "timestamp": timestamp_now
        }
        self.save_assignment_to_gcs(new_assignment)
        self.save_user_assignment_to_gcs(user_data, assignment_id)
        return new_assignment
    
    def get_assignment_url(self, assignment_id):
        assignment_data = self.get_assignment(assignment_id)
        if isinstance(assignment_data, str):
            print(f"错误:无法获取作业数据。返回的数据:{assignment_data}")
            return None
        
        assignment_url = assignment_data.get("assignment_url")
        if not assignment_url:
            print(f"警告:作业 {assignment_id} 没有 URL")
            return None

        return assignment_url
    
    def update_assignment(self, assignment_id, assignment_data):
        self.gcs_service.upload_json_string(self.bucket_name, f"assignments/{assignment_id}.json", json.dumps(assignment_data))

    def save_assignment_to_gcs(self, assignment):
        file_name = f"assignments/{assignment['assignment_id']}.json"
        self.gcs_service.upload_json_string(self.bucket_name, file_name, json.dumps(assignment))

    def save_user_assignment_to_gcs(self, user_id, assignment_id):
        user_assignments = self.get_user_assignments(user_id)
        assignment_data = self.get_assignment(assignment_id)
        user_assignments[assignment_id] = {
            "assignment_name": assignment_data["metadata"]["topic"],
            "assignment_type": assignment_data["assignment_type"],
            "timestamp": assignment_data["timestamp"]
        }
        encoded_user_id_url = urllib.parse.quote(user_id, safe='')
        self.gcs_service.upload_json_string(self.bucket_name, f"users/{encoded_user_id_url}/assignments.json", json.dumps(user_assignments))

    def get_assignment(self, assignment_id):
        try:
            file_name = f"assignments/{assignment_id}.json"
            assignment_json = self.gcs_service.download_as_string(self.bucket_name, file_name)
            assignment_data = json.loads(assignment_json)
        except Exception as e:
            print(f"Error: {e}")
            return "無效的作業 ID"
        return assignment_data
    
    def get_assignment_submissions(self, assignment_id):
        assignment_data = self.get_assignment(assignment_id)
        return assignment_data["submission_ids"]

    def get_user_assignments(self, user_id):
        try:
            encoded_user_id_url = urllib.parse.quote(user_id, safe='')
            user_assignments_json = self.gcs_service.download_as_string(self.bucket_name, f"users/{encoded_user_id_url}/assignments.json")
            user_assignments = json.loads(user_assignments_json)
        except Exception as e:
            print(f"Error: {e}")
            user_assignments = {}
        return user_assignments

    def update_assignment_list(self, assigner_data):
        choices = []
        user_assignments = self.get_user_assignments(assigner_data)
        for assignment_id, assignment_info in user_assignments.items():
            assignment_data = self.get_assignment(assignment_id)
            metadata = assignment_data.get("metadata", {})
            topic = metadata.get("topic", "未命名作業")
            assignment_type = assignment_data.get("assignment_type", "未知類型")
            timestamp = assignment_data.get("timestamp", "未知日期")
            
            # 格式化日期
            date = datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d")
            
            # 創建格式化的選項
            formatted_choice = f"{date}|{assignment_type}|{topic}"
            choice = (formatted_choice, assignment_id)
            choices.append(choice)
        
        # 按日期降序排序
        choices.sort(key=lambda x: x[0].split("|")[0], reverse=True)
        
        return gr.update(choices=choices)
    

    def delete_assignment(self, assignment_id, user_data):
        try:
            # 刪除作業文件
            file_name = f"assignments/{assignment_id}.json"
            if not self.gcs_service.delete_file(self.bucket_name, file_name):
                raise Exception("Failed to delete assignment file")

            # 從用戶的作業列表中刪除
            user_assignments = self.get_user_assignments(user_data)
            if assignment_id in user_assignments:
                del user_assignments[assignment_id]
                encoded_user_id_url = urllib.parse.quote(user_data, safe='')
                self.gcs_service.upload_json_string(self.bucket_name, f"users/{encoded_user_id_url}/assignments.json", json.dumps(user_assignments))

            return True
        except Exception as e:
            print(f"Error deleting assignment: {e}")
            return False