Zheng Qu commited on
Commit
7d70be7
1 Parent(s): d762a7c

v2 to use tinydb for db.

Browse files
Files changed (3) hide show
  1. app_utils.py +31 -123
  2. requirements.txt +1 -0
  3. 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 pymongo import MongoClient
8
- from pymongo.errors import ServerSelectionTimeoutError
9
- from bson import json_util
10
  import tempfile
11
 
12
  load_dotenv()
13
  SESSION_ID = os.getenv('SESSION_ID')
14
  print(f"Session ID: {SESSION_ID}")
15
- DB_URL = os.getenv('DB_URL')
16
  ADMIN_PASSWD = os.getenv('ADMIN_PASSWD', 'default_password')
17
  SUBMISSIONS_DIR = 'submissions'
18
- # MongoDB connection setup remains the same
19
- try:
20
- client = MongoClient(DB_URL, serverSelectionTimeoutMS=5000)
21
- client.server_info()
22
- USE_MONGO = True
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
- if USE_MONGO:
61
- collection = db.submissions
62
- submission = {
63
- 'session': session,
64
- 'name': name,
65
- 'email': email,
66
- 'problem_id': problem_id,
67
- 'student_code': code,
68
- 'hint_requested': hint_requested,
69
- 'timestamp': timestamp
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
- if USE_MONGO:
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
- if USE_MONGO:
116
- submissions = list(db.submissions.find(
117
- {"name": name},
118
- {"_id": 0}
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
- if USE_MONGO:
141
- submissions = list(db.submissions.find({}, {"_id": 0}).sort("timestamp", -1))
142
- data = json_util.dumps(submissions, indent=2)
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
- if USE_MONGO:
167
- submissions = list(db.submissions.find({}, {"_id": 0}).sort("timestamp", -1))
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(name, email):
 
91
  if not name or not email:
92
  return "Please enter your name and email before submitting."
93
 
94
- codes = {prob_id: code_box.value for prob_id, code_box in code_boxes.items()}
 
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
- [name, email],
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
  )