Zheng Qu
commited on
Commit
•
7d70be7
1
Parent(s):
d762a7c
v2 to use tinydb for db.
Browse files- app_utils.py +31 -123
- requirements.txt +1 -0
- student_tab.py +10 -6
app_utils.py
CHANGED
@@ -1,48 +1,24 @@
|
|
1 |
import json
|
2 |
import os
|
3 |
import datetime
|
4 |
-
import sqlite3
|
5 |
from pathlib import Path
|
6 |
from dotenv import load_dotenv
|
7 |
-
from
|
8 |
-
from
|
9 |
-
from
|
10 |
import tempfile
|
11 |
|
12 |
load_dotenv()
|
13 |
SESSION_ID = os.getenv('SESSION_ID')
|
14 |
print(f"Session ID: {SESSION_ID}")
|
15 |
-
|
16 |
ADMIN_PASSWD = os.getenv('ADMIN_PASSWD', 'default_password')
|
17 |
SUBMISSIONS_DIR = 'submissions'
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
db = client['COS501_app']
|
24 |
-
print("Successfully connected to MongoDB Atlas")
|
25 |
-
except Exception as e:
|
26 |
-
print(f"MongoDB connection failed: {str(e)}")
|
27 |
-
USE_MONGO = False
|
28 |
-
sqlite_path = Path('submissions.db')
|
29 |
-
conn = sqlite3.connect(sqlite_path)
|
30 |
-
cursor = conn.cursor()
|
31 |
-
cursor.execute('''
|
32 |
-
CREATE TABLE IF NOT EXISTS submissions (
|
33 |
-
session TEXT,
|
34 |
-
name TEXT,
|
35 |
-
email TEXT,
|
36 |
-
problem_id TEXT,
|
37 |
-
student_code TEXT,
|
38 |
-
hint_requested INTEGER,
|
39 |
-
timestamp TEXT,
|
40 |
-
PRIMARY KEY (session, name, email, problem_id)
|
41 |
-
)
|
42 |
-
''')
|
43 |
-
conn.commit()
|
44 |
-
conn.close()
|
45 |
-
print("Falling back to SQLite database")
|
46 |
|
47 |
def load_problems():
|
48 |
problems = []
|
@@ -56,37 +32,18 @@ def load_problems():
|
|
56 |
return problems
|
57 |
|
58 |
def save_submission(session, name, email, problem_id, code, hint_requested):
|
59 |
-
timestamp = datetime.datetime.now()
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
collection.update_one(
|
72 |
-
{'session': session, 'name': name, 'email': email, 'problem_id': problem_id},
|
73 |
-
{'$set': submission},
|
74 |
-
upsert=True
|
75 |
-
)
|
76 |
-
else:
|
77 |
-
conn = sqlite3.connect('submissions.db')
|
78 |
-
cursor = conn.cursor()
|
79 |
-
cursor.execute('''
|
80 |
-
INSERT OR REPLACE INTO submissions
|
81 |
-
(session, name, email, problem_id, student_code, hint_requested, timestamp)
|
82 |
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
83 |
-
''', (
|
84 |
-
session, name, email, problem_id, code,
|
85 |
-
1 if hint_requested else 0,
|
86 |
-
timestamp.isoformat()
|
87 |
-
))
|
88 |
-
conn.commit()
|
89 |
-
conn.close()
|
90 |
|
91 |
def save_all_submissions(name, email, codes_dict, hints_dict):
|
92 |
try:
|
@@ -101,57 +58,19 @@ def check_password(password):
|
|
101 |
return password == ADMIN_PASSWD
|
102 |
|
103 |
def get_all_students():
|
104 |
-
|
105 |
-
return list(db.submissions.distinct("name"))
|
106 |
-
else:
|
107 |
-
conn = sqlite3.connect('submissions.db')
|
108 |
-
cursor = conn.cursor()
|
109 |
-
cursor.execute('SELECT DISTINCT name FROM submissions')
|
110 |
-
students = [row[0] for row in cursor.fetchall()]
|
111 |
-
conn.close()
|
112 |
-
return students
|
113 |
|
114 |
def get_student_submissions(name):
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
).sort("timestamp", -1))
|
120 |
-
return submissions
|
121 |
-
else:
|
122 |
-
conn = sqlite3.connect('submissions.db')
|
123 |
-
cursor = conn.cursor()
|
124 |
-
cursor.execute('''
|
125 |
-
SELECT session, name, email, problem_id, student_code, hint_requested, timestamp
|
126 |
-
FROM submissions WHERE name = ?
|
127 |
-
ORDER BY timestamp DESC
|
128 |
-
''', (name,))
|
129 |
-
columns = ['session', 'name', 'email', 'problem_id', 'student_code', 'hint_requested', 'timestamp']
|
130 |
-
submissions = []
|
131 |
-
for row in cursor.fetchall():
|
132 |
-
submission = dict(zip(columns, row))
|
133 |
-
submission['hint_requested'] = bool(submission['hint_requested'])
|
134 |
-
submissions.append(submission)
|
135 |
-
conn.close()
|
136 |
-
return submissions
|
137 |
|
138 |
def export_submissions():
|
139 |
try:
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
else:
|
144 |
-
conn = sqlite3.connect('submissions.db')
|
145 |
-
cursor = conn.cursor()
|
146 |
-
cursor.execute('SELECT * FROM submissions ORDER BY timestamp DESC')
|
147 |
-
columns = ['session', 'name', 'email', 'problem_id', 'student_code', 'hint_requested', 'timestamp']
|
148 |
-
submissions = []
|
149 |
-
for row in cursor.fetchall():
|
150 |
-
submission = dict(zip(columns, row))
|
151 |
-
submission['hint_requested'] = bool(submission['hint_requested'])
|
152 |
-
submissions.append(submission)
|
153 |
-
conn.close()
|
154 |
-
data = json.dumps(submissions, indent=2)
|
155 |
|
156 |
# Create a temporary file and write the data to it
|
157 |
temp_file = tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.json')
|
@@ -163,17 +82,6 @@ def export_submissions():
|
|
163 |
return None
|
164 |
|
165 |
def refresh_submissions():
|
166 |
-
|
167 |
-
|
168 |
-
else:
|
169 |
-
conn = sqlite3.connect('submissions.db')
|
170 |
-
cursor = conn.cursor()
|
171 |
-
cursor.execute('SELECT * FROM submissions ORDER BY timestamp DESC')
|
172 |
-
columns = ['session', 'name', 'email', 'problem_id', 'student_code', 'hint_requested', 'timestamp']
|
173 |
-
submissions = []
|
174 |
-
for row in cursor.fetchall():
|
175 |
-
submission = dict(zip(columns, row))
|
176 |
-
submission['hint_requested'] = bool(submission['hint_requested'])
|
177 |
-
submissions.append(submission)
|
178 |
-
conn.close()
|
179 |
return submissions
|
|
|
1 |
import json
|
2 |
import os
|
3 |
import datetime
|
|
|
4 |
from pathlib import Path
|
5 |
from dotenv import load_dotenv
|
6 |
+
from tinydb import TinyDB, Query
|
7 |
+
from tinydb.storages import JSONStorage
|
8 |
+
from tinydb.middlewares import CachingMiddleware
|
9 |
import tempfile
|
10 |
|
11 |
load_dotenv()
|
12 |
SESSION_ID = os.getenv('SESSION_ID')
|
13 |
print(f"Session ID: {SESSION_ID}")
|
14 |
+
DB_PATH = 'submissions.json'
|
15 |
ADMIN_PASSWD = os.getenv('ADMIN_PASSWD', 'default_password')
|
16 |
SUBMISSIONS_DIR = 'submissions'
|
17 |
+
|
18 |
+
# TinyDB connection setup
|
19 |
+
db = TinyDB(DB_PATH, storage=CachingMiddleware(JSONStorage))
|
20 |
+
submissions_table = db.table('submissions')
|
21 |
+
print("Using TinyDB for data storage")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
def load_problems():
|
24 |
problems = []
|
|
|
32 |
return problems
|
33 |
|
34 |
def save_submission(session, name, email, problem_id, code, hint_requested):
|
35 |
+
timestamp = datetime.datetime.now().isoformat()
|
36 |
+
submission = {
|
37 |
+
'session': session,
|
38 |
+
'name': name,
|
39 |
+
'email': email,
|
40 |
+
'problem_id': problem_id,
|
41 |
+
'student_code': code,
|
42 |
+
'hint_requested': hint_requested,
|
43 |
+
'timestamp': timestamp
|
44 |
+
}
|
45 |
+
query = Query()
|
46 |
+
submissions_table.upsert(submission, (query.session == session) & (query.name == name) & (query.email == email) & (query.problem_id == problem_id))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
def save_all_submissions(name, email, codes_dict, hints_dict):
|
49 |
try:
|
|
|
58 |
return password == ADMIN_PASSWD
|
59 |
|
60 |
def get_all_students():
|
61 |
+
return list(set([submission['name'] for submission in submissions_table.all()]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
def get_student_submissions(name):
|
64 |
+
query = Query()
|
65 |
+
submissions = submissions_table.search(query.name == name)
|
66 |
+
submissions.sort(key=lambda x: x['timestamp'], reverse=True)
|
67 |
+
return submissions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
def export_submissions():
|
70 |
try:
|
71 |
+
submissions = submissions_table.all()
|
72 |
+
submissions.sort(key=lambda x: x['timestamp'], reverse=True)
|
73 |
+
data = json.dumps(submissions, indent=2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
|
75 |
# Create a temporary file and write the data to it
|
76 |
temp_file = tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.json')
|
|
|
82 |
return None
|
83 |
|
84 |
def refresh_submissions():
|
85 |
+
submissions = submissions_table.all()
|
86 |
+
submissions.sort(key=lambda x: x['timestamp'], reverse=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
return submissions
|
requirements.txt
CHANGED
@@ -2,6 +2,7 @@ pymongo==4.10.1
|
|
2 |
python-dotenv==1.0.1
|
3 |
huggingface_hub==0.25.2
|
4 |
gradio==4.44.1
|
|
|
5 |
|
6 |
#google-auth==2.35.0
|
7 |
#google-auth-httplib2==0.2.0
|
|
|
2 |
python-dotenv==1.0.1
|
3 |
huggingface_hub==0.25.2
|
4 |
gradio==4.44.1
|
5 |
+
tinydb==4.8.2
|
6 |
|
7 |
#google-auth==2.35.0
|
8 |
#google-auth-httplib2==0.2.0
|
student_tab.py
CHANGED
@@ -87,18 +87,22 @@ def create_student_tab(problems):
|
|
87 |
submit_all = gr.Button("Submit All")
|
88 |
submit_status = gr.Markdown()
|
89 |
|
90 |
-
def submit_all_problems(
|
|
|
91 |
if not name or not email:
|
92 |
return "Please enter your name and email before submitting."
|
93 |
|
94 |
-
|
|
|
95 |
hints = {prob_id: hint_state.value for prob_id, hint_state in hint_states.items()}
|
96 |
|
97 |
return save_all_submissions(name, email, codes, hints)
|
98 |
|
|
|
|
|
|
|
99 |
submit_all.click(
|
100 |
-
submit_all_problems,
|
101 |
-
|
102 |
-
submit_status
|
103 |
)
|
104 |
-
|
|
|
87 |
submit_all = gr.Button("Submit All")
|
88 |
submit_status = gr.Markdown()
|
89 |
|
90 |
+
def submit_all_problems(values):
|
91 |
+
name, email, *code_values = values
|
92 |
if not name or not email:
|
93 |
return "Please enter your name and email before submitting."
|
94 |
|
95 |
+
# Create dictionary of latest code values
|
96 |
+
codes = {prob_id: code for prob_id, code in zip(code_boxes.keys(), code_values)}
|
97 |
hints = {prob_id: hint_state.value for prob_id, hint_state in hint_states.items()}
|
98 |
|
99 |
return save_all_submissions(name, email, codes, hints)
|
100 |
|
101 |
+
# Create list of all inputs in correct order
|
102 |
+
all_inputs = [name, email] + list(code_boxes.values())
|
103 |
+
|
104 |
submit_all.click(
|
105 |
+
fn=lambda *args: submit_all_problems(args),
|
106 |
+
inputs=all_inputs,
|
107 |
+
outputs=submit_status
|
108 |
)
|
|