Harshal Vhatkar commited on
Commit
7e06d5a
·
2 Parent(s): b771940 2e0de0f

Merge branch 'main' of https://huggingface.co/spaces/SPJIMR-Internship/SPJIMR_FlipClassroom_RCopilot_ResearchInternship

Browse files
Files changed (5) hide show
  1. app.py +346 -276
  2. create_course.py +55 -2
  3. live_polls.py +6 -4
  4. poll_db_operations.py +4 -2
  5. session_page.py +8 -5
app.py CHANGED
@@ -17,7 +17,7 @@ from werkzeug.security import generate_password_hash, check_password_hash
17
  import os
18
  from openai import OpenAI
19
  from dotenv import load_dotenv
20
- from create_course2 import create_course, courses_collection, generate_perplexity_response, generate_session_resources, PERPLEXITY_API_KEY, validate_course_plan
21
  import json
22
  from bson import ObjectId
23
  client = OpenAI(api_key=os.getenv("OPENAI_KEY"))
@@ -234,35 +234,110 @@ def create_session(new_session, course_id):
234
  return False
235
 
236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  def create_session_form(course_id):
238
  """Display form to create a new session and perform the creation operation"""
239
  st.title("Create New Session")
240
 
241
- if 'session_time' not in st.session_state:
242
  st.session_state.session_time = datetime.now().time()
243
- if 'show_create_session_form' not in st.session_state:
 
244
  st.session_state.show_create_session_form = False
245
 
 
 
 
246
  with st.form("create_session_form"):
247
  session_title = st.text_input("Session Title")
248
  session_date = st.date_input("Session Date", date.today(), key="session_date")
249
- session_time = st.time_input(
250
- "Session Time", st.session_state.session_time, key="session_time"
251
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
- new_session_id = None
254
  # Generate new session ID
 
255
  course = courses_collection.find_one({"course_id": course_id})
256
  if course and "sessions" in course and course["sessions"]:
257
- last_session_id = max(
258
- int(session["session_id"][1:]) for session in course["sessions"]
259
- )
260
  new_session_id = last_session_id + 1
261
  else:
262
  new_session_id = 1
263
 
 
264
  if st.form_submit_button("Create Session"):
265
- clicked = True
266
  new_session = {
267
  "session_id": f"S{new_session_id}",
268
  "course_id": course_id,
@@ -270,24 +345,23 @@ def create_session_form(course_id):
270
  "date": datetime.combine(session_date, session_time),
271
  "status": "upcoming",
272
  "created_at": datetime.utcnow(),
273
- "pre_class": {
274
- "resources": [],
275
- "completetion_required": True,
276
- },
277
- "in_class": {
278
- "topics": [],
279
- "quiz": {"title": "", "questions": 0, "duration": 0},
280
- "polls": [],
281
- },
282
- "post_class": {
283
- "assignments": [],
284
- },
285
  }
286
- courses_collection.update_one(
287
- {"course_id": course_id}, {"$push": {"sessions": new_session}}
288
- )
289
  st.success("Session created successfully!")
 
290
  st.session_state.show_create_session_form = False
 
291
 
292
  # new_session_id = None
293
  # creation_success = False
@@ -924,282 +998,278 @@ def create_course_form(faculty_name, faculty_id):
924
  with col2:
925
  duration_weeks = st.number_input("Duration (weeks)", min_value=1, max_value=16, value=12)
926
  start_date = st.date_input("Start Date")
 
 
927
 
928
  generate_button = st.form_submit_button("Generate Course Structure", use_container_width=True)
929
 
930
  if generate_button and course_name:
931
- with st.spinner("Generating course structure and resources..."):
932
- try:
933
- # Generate course plan with resources
934
- course_plan = generate_perplexity_response(
935
- PERPLEXITY_API_KEY,
936
- course_name,
937
- duration_weeks,
938
- sessions_per_week
939
- )
940
- try:
941
- course_plan_json = json.loads(course_plan)
942
- validate_course_plan(course_plan_json)
943
- st.session_state.course_plan = course_plan_json
944
- except (json.JSONDecodeError, ValueError) as e:
945
- st.error(f"Error in course plan structure: {e}")
946
- return
947
- st.session_state.start_date = start_date
948
- st.session_state.duration_weeks = duration_weeks
949
- st.session_state.sessions_per_week = sessions_per_week
 
 
 
 
950
 
951
- # Generate resources for all sessions
952
- session_titles = []
953
- for module in st.session_state.course_plan['modules']:
954
- for sub_module in module['sub_modules']:
955
- for topic in sub_module['topics']:
956
- # session_titles.append(topic['title'])
957
- # session_titles.append(topic)
958
- if isinstance(topic, dict):
959
- session_titles.append(topic['title'])
960
- else:
961
- session_titles.append(topic)
962
- # In generate_session_resources function, add validation:
963
- if not session_titles:
964
- return json.dumps({"session_resources": []})
965
- resources_response = generate_session_resources(PERPLEXITY_API_KEY, session_titles)
966
- without_backticks = remove_json_backticks(resources_response)
967
- resources = json.loads(without_backticks)
968
- st.session_state.resources_map = {
969
- resource['session_title']: resource['resources']
970
- for resource in resources['session_resources']
971
- }
972
- # Add error handling for the resources map
973
- # if st.session_state.resources_map is None:
974
- # st.session_state.resources_map = {}
975
-
976
- st.rerun()
977
- except Exception as e:
978
- st.error(f"Error generating course structure: {e}")
979
 
980
- # Display and Edit Generated Course Content
981
- if st.session_state.course_plan:
982
- with st.expander("Course Overview", expanded=True):
983
- if not st.session_state.edit_mode:
984
- st.subheader(st.session_state.course_plan['course_title'])
985
- st.write(st.session_state.course_plan['course_description'])
986
- col1, col2, col3 = st.columns(3)
987
- with col1:
988
- st.write(f"**Start Date:** {st.session_state.start_date}")
989
- with col2:
990
- st.write(f"**Duration (weeks):** {st.session_state.duration_weeks}")
991
- with col3:
992
- st.write(f"**Sessions Per Week:** {st.session_state.sessions_per_week}")
993
-
994
- edit_button = st.button("Edit Course Details", use_container_width=True)
995
- if edit_button:
996
- st.session_state.edit_mode = True
997
- st.rerun()
998
- else:
999
- with st.form("edit_course_details"):
1000
- st.session_state.course_plan['course_title'] = st.text_input(
1001
- "Course Title",
1002
- value=st.session_state.course_plan['course_title']
1003
- )
1004
- st.session_state.course_plan['course_description'] = st.text_area(
1005
- "Course Description",
1006
- value=st.session_state.course_plan['course_description']
1007
- )
1008
- if st.form_submit_button("Save Course Details"):
1009
- st.session_state.edit_mode = False
1010
- st.rerun()
1011
 
1012
- # Display Modules and Sessions
1013
- st.subheader("Course Modules and Sessions")
1014
 
1015
- start_date = st.session_state.start_date
1016
- current_date = start_date
1017
 
1018
- all_sessions = []
1019
- for module_idx, module in enumerate(st.session_state.course_plan['modules']):
1020
- with st.expander(f"📚 Module {module_idx + 1}: {module['module_title']}", expanded=True):
1021
- # Edit module title
1022
- new_module_title = st.text_input(
1023
- f"Edit Module Title",
1024
- value=module['module_title'],
1025
- key=f"module_{module_idx}"
1026
- )
1027
- module['module_title'] = new_module_title
1028
 
1029
- for sub_idx, sub_module in enumerate(module['sub_modules']):
1030
- st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
1031
- # st.markdown(f"### 📖 {sub_module['title']}")
1032
- st.markdown(f'<h3 style="font-size: 1.25rem;">📖 Chapter {sub_idx + 1}: {sub_module["title"]}</h3>', unsafe_allow_html=True)
1033
- # Possible fix:
1034
- # Inside the loop where topics are being processed:
1035
-
1036
- for topic_idx, topic in enumerate(sub_module['topics']):
1037
- st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
1038
- session_key = f"session_{module_idx}_{sub_idx}_{topic_idx}"
1039
 
1040
- # Get topic title based on type
1041
- if isinstance(topic, dict):
1042
- current_topic_title = topic.get('title', '')
1043
- current_topic_display = current_topic_title
1044
- else:
1045
- current_topic_title = str(topic)
1046
- current_topic_display = current_topic_title
1047
-
1048
- with st.container():
1049
- # Session Details
1050
- col1, col2, col3 = st.columns([3, 2, 1])
1051
- with col1:
1052
- new_topic = st.text_input(
1053
- f"Session {topic_idx + 1} Title",
1054
- value=current_topic_display,
1055
- key=f"{session_key}_topic"
1056
- )
1057
- # Update the topic in the data structure
1058
- if isinstance(topic, dict):
1059
- topic['title'] = new_topic
1060
- else:
1061
- sub_module['topics'][topic_idx] = new_topic
1062
 
1063
- with col2:
1064
- session_date = st.date_input(
1065
- "Session Date",
1066
- value=current_date,
1067
- key=f"{session_key}_date"
1068
- )
1069
 
1070
- with col3:
1071
- session_status = st.selectbox(
1072
- "Status",
1073
- options=["upcoming", "in-progress", "completed"],
1074
- key=f"{session_key}_status"
1075
- )
1076
 
1077
- # Display Resources
1078
- if st.session_state.resources_map:
1079
- # Try both the full topic title and the display title
1080
- resources = None
1081
- if isinstance(topic, dict) and topic.get('title') in st.session_state.resources_map:
1082
- resources = st.session_state.resources_map[topic['title']]
1083
- elif current_topic_title in st.session_state.resources_map:
1084
- resources = st.session_state.resources_map[current_topic_title]
1085
 
1086
- if resources:
1087
- with st.container():
1088
- # st.markdown("#### 📚 Session Resources")
1089
- st.markdown(f'<h4 style="font-size: 1.25rem;">📚 Session Resources</h4>', unsafe_allow_html=True)
1090
- # Readings Tab
1091
- if resources.get('readings'):
1092
- st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📖 External Resources</h5>', unsafe_allow_html=True)
1093
- col1, col2 = st.columns(2)
1094
- for idx, reading in enumerate(resources['readings']):
1095
- with col1 if idx % 2 == 0 else col2:
1096
- st.markdown(f"""
1097
- - **{reading['title']}**
1098
- - Type: {reading['type']}
1099
- - Estimated reading time: {reading['estimated_read_time']}
1100
- - [Access Resource]({reading['url']})
1101
- """)
1102
 
1103
- # Books Tab and Additional Resources Tab side-by-side
1104
- col1, col2 = st.columns(2)
1105
 
1106
- with col1:
1107
- if resources.get('books'):
1108
- st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📚 Reference Books</h5>', unsafe_allow_html=True)
1109
- for book in resources['books']:
1110
- with st.container():
1111
- st.markdown(f"""
1112
- - **{book['title']}**
1113
- - Author: {book['author']}
1114
- - ISBN: {book['isbn']}
1115
- - Chapters: {book['chapters']}
1116
- """)
1117
 
1118
- with col2:
1119
- if resources.get('additional_resources'):
1120
- st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">🔗 Additional Study Resources</h5>', unsafe_allow_html=True)
1121
- for resource in resources['additional_resources']:
1122
- with st.container():
1123
- st.markdown(f"""
1124
- - **{resource['title']}**
1125
- - Type: {resource['type']}
1126
- - Description: {resource['description']}
1127
- - [Access Resource]({resource['url']})
1128
- """)
1129
 
1130
- # Create session object
1131
- session = {
1132
- "session_id": str(ObjectId()),
1133
- "title": new_topic,
1134
- "date": datetime.combine(session_date, datetime.min.time()),
1135
- "status": session_status,
1136
- "module_name": module['module_title'],
1137
- "created_at": datetime.utcnow(),
1138
- "pre_class": {
1139
- "resources": [],
1140
- "completion_required": True
1141
- },
1142
- "in_class": {
1143
- "quiz": [],
1144
- "polls": []
1145
- },
1146
- "post_class": {
1147
- "assignments": []
1148
- },
1149
- "external_resources": st.session_state.resources_map.get(current_topic_title, {})
1150
- }
1151
- all_sessions.append(session)
1152
- current_date = session_date + timedelta(days=7)
1153
 
1154
 
1155
- new_course_id = get_new_course_id()
1156
- course_title = st.session_state.course_plan['course_title']
1157
-
1158
- # Final Save Button
1159
- if st.button("Save Course", type="primary", use_container_width=True):
1160
- try:
1161
- course_doc = {
1162
- "course_id": new_course_id,
1163
- "title": course_title,
1164
- "description": st.session_state.course_plan['course_description'],
1165
- "faculty": faculty_name,
1166
- "faculty_id": faculty_id,
1167
- "duration": f"{st.session_state.duration_weeks} weeks",
1168
- "sessions_per_week": st.session_state.sessions_per_week,
1169
- "start_date": datetime.combine(st.session_state.start_date, datetime.min.time()),
1170
- "created_at": datetime.utcnow(),
1171
- "sessions": all_sessions
1172
- }
1173
 
1174
- # Insert into database
1175
- courses_collection.insert_one(course_doc)
1176
- st.success("Course successfully created!")
1177
 
1178
- # Update faculty collection
1179
- faculty_collection.update_one(
1180
- {"_id": st.session_state.user_id},
1181
- {
1182
- "$push": {
1183
- "courses_taught": {
1184
- "course_id": new_course_id,
1185
- "title": course_title,
1186
- }
1187
- }
1188
- }
1189
- )
1190
 
1191
- # Clear session state
1192
- st.session_state.course_plan = None
1193
- st.session_state.edit_mode = False
1194
- st.session_state.resources_map = {}
1195
 
1196
- # Optional: Add a button to view the created course
1197
- if st.button("View Course"):
1198
- # Add navigation logic here
1199
- pass
1200
 
1201
- except Exception as e:
1202
- st.error(f"Error saving course: {e}")
1203
 
1204
 
1205
 
 
17
  import os
18
  from openai import OpenAI
19
  from dotenv import load_dotenv
20
+ from create_course import create_course, courses_collection, generate_perplexity_response #, generate_session_resources, PERPLEXITY_API_KEY, validate_course_plan
21
  import json
22
  from bson import ObjectId
23
  client = OpenAI(api_key=os.getenv("OPENAI_KEY"))
 
234
  return False
235
 
236
 
237
+ # def create_session_form(course_id):
238
+ # """Display form to create a new session and perform the creation operation"""
239
+ # st.title("Create New Session")
240
+
241
+ # if 'session_time' not in st.session_state:
242
+ # st.session_state.session_time = datetime.now().time()
243
+ # if 'show_create_session_form' not in st.session_state:
244
+ # st.session_state.show_create_session_form = False
245
+
246
+ # with st.form("create_session_form"):
247
+ # session_title = st.text_input("Session Title")
248
+ # session_date = st.date_input("Session Date", date.today(), key="session_date")
249
+ # session_time = st.time_input(
250
+ # "Session Time", st.session_state.session_time, key="session_time"
251
+ # )
252
+
253
+ # new_session_id = None
254
+ # # Generate new session ID
255
+ # course = courses_collection.find_one({"course_id": course_id})
256
+ # if course and "sessions" in course and course["sessions"]:
257
+ # last_session_id = max(
258
+ # int(session["session_id"][1:]) for session in course["sessions"]
259
+ # )
260
+ # new_session_id = last_session_id + 1
261
+ # else:
262
+ # new_session_id = 1
263
+
264
+ # if st.form_submit_button("Create Session"):
265
+ # clicked = True
266
+ # new_session = {
267
+ # "session_id": f"S{new_session_id}",
268
+ # "course_id": course_id,
269
+ # "title": session_title,
270
+ # "date": datetime.combine(session_date, session_time),
271
+ # "status": "upcoming",
272
+ # "created_at": datetime.utcnow(),
273
+ # "pre_class": {
274
+ # "resources": [],
275
+ # "completetion_required": True,
276
+ # },
277
+ # "in_class": {
278
+ # "topics": [],
279
+ # "quiz": {"title": "", "questions": 0, "duration": 0},
280
+ # "polls": [],
281
+ # },
282
+ # "post_class": {
283
+ # "assignments": [],
284
+ # },
285
+ # }
286
+ # courses_collection.update_one(
287
+ # {"course_id": course_id}, {"$push": {"sessions": new_session}}
288
+ # )
289
+ # st.success("Session created successfully!")
290
+ # st.session_state.show_create_session_form = False
291
+
292
+
293
  def create_session_form(course_id):
294
  """Display form to create a new session and perform the creation operation"""
295
  st.title("Create New Session")
296
 
297
+ if "session_time" not in st.session_state:
298
  st.session_state.session_time = datetime.now().time()
299
+
300
+ if "show_create_session_form" not in st.session_state:
301
  st.session_state.show_create_session_form = False
302
 
303
+ if "outcomes" not in st.session_state:
304
+ st.session_state.outcomes = [] # List to store outcomes dynamically
305
+
306
  with st.form("create_session_form"):
307
  session_title = st.text_input("Session Title")
308
  session_date = st.date_input("Session Date", date.today(), key="session_date")
309
+ session_time = st.time_input("Session Time", st.session_state.session_time, key="session_time")
310
+
311
+ st.subheader("Session Learning Outcomes")
312
+
313
+ # Display all outcomes dynamically
314
+ for idx, outcome in enumerate(st.session_state.outcomes):
315
+ st.text_input(f"Outcome {idx + 1} Description", key=f"outcome_desc_{idx}")
316
+ st.selectbox(
317
+ f"Bloom's Taxonomy Level {idx + 1}",
318
+ ["Remember", "Understand", "Apply", "Analyze", "Evaluate", "Create"],
319
+ key=f"bloom_level_{idx}"
320
+ )
321
+
322
+ # Button to add new outcome fields
323
+ if st.form_submit_button("Add Outcome"):
324
+ new_index = len(st.session_state.outcomes)
325
+ st.session_state.outcomes.append(
326
+ {"outcome_number": new_index + 1, "outcome_description": "", "bloom_taxanomy_level": ""}
327
+ )
328
+ st.rerun() # Refresh the form to display new fields
329
 
 
330
  # Generate new session ID
331
+ new_session_id = None
332
  course = courses_collection.find_one({"course_id": course_id})
333
  if course and "sessions" in course and course["sessions"]:
334
+ last_session_id = max(int(session["session_id"][1:]) for session in course["sessions"])
 
 
335
  new_session_id = last_session_id + 1
336
  else:
337
  new_session_id = 1
338
 
339
+ # Submit session
340
  if st.form_submit_button("Create Session"):
 
341
  new_session = {
342
  "session_id": f"S{new_session_id}",
343
  "course_id": course_id,
 
345
  "date": datetime.combine(session_date, session_time),
346
  "status": "upcoming",
347
  "created_at": datetime.utcnow(),
348
+ "pre_class": {"resources": [], "completetion_required": True},
349
+ "in_class": {"topics": [], "quiz": {"title": "", "questions": 0, "duration": 0}, "polls": []},
350
+ "post_class": {"assignments": []},
351
+ "session_learning_outcomes": [
352
+ {
353
+ "outcome_number": idx + 1,
354
+ "outcome_description": st.session_state[f"outcome_desc_{idx}"],
355
+ "bloom_taxanomy_level": st.session_state[f"bloom_level_{idx}"]
356
+ }
357
+ for idx in range(len(st.session_state.outcomes))
358
+ ]
 
359
  }
360
+ courses_collection.update_one({"course_id": course_id}, {"$push": {"sessions": new_session}})
 
 
361
  st.success("Session created successfully!")
362
+ st.session_state.outcomes = [] # Clear outcomes after submission
363
  st.session_state.show_create_session_form = False
364
+ st.rerun()
365
 
366
  # new_session_id = None
367
  # creation_success = False
 
998
  with col2:
999
  duration_weeks = st.number_input("Duration (weeks)", min_value=1, max_value=16, value=12)
1000
  start_date = st.date_input("Start Date")
1001
+ course_description = st.text_area("Course Description", placeholder="Enter a brief course description here")
1002
+
1003
 
1004
  generate_button = st.form_submit_button("Generate Course Structure", use_container_width=True)
1005
 
1006
  if generate_button and course_name:
1007
+ create_course(course_name, duration_weeks, faculty_name, sessions_per_week, start_date, course_description, faculty_id)
1008
+
1009
+ #update faculty list of courses
1010
+
1011
+ # with st.spinner("Generating course structure and resources..."):
1012
+ # try:
1013
+ # # Generate course plan with resources
1014
+ # course_plan = generate_perplexity_response(
1015
+ # PERPLEXITY_API_KEY,
1016
+ # course_name,
1017
+ # duration_weeks,
1018
+ # sessions_per_week
1019
+ # )
1020
+ # try:
1021
+ # course_plan_json = json.loads(course_plan)
1022
+ # validate_course_plan(course_plan_json)
1023
+ # st.session_state.course_plan = course_plan_json
1024
+ # except (json.JSONDecodeError, ValueError) as e:
1025
+ # st.error(f"Error in course plan structure: {e}")
1026
+ # return
1027
+ # st.session_state.start_date = start_date
1028
+ # st.session_state.duration_weeks = duration_weeks
1029
+ # st.session_state.sessions_per_week = sessions_per_week
1030
 
1031
+ # # Generate resources for all sessions
1032
+ # session_titles = []
1033
+ # for module in st.session_state.course_plan['modules']:
1034
+ # for sub_module in module['sub_modules']:
1035
+ # for topic in sub_module['topics']:
1036
+ # # session_titles.append(topic['title'])
1037
+ # # session_titles.append(topic)
1038
+ # if isinstance(topic, dict):
1039
+ # session_titles.append(topic['title'])
1040
+ # else:
1041
+ # session_titles.append(topic)
1042
+ # # In generate_session_resources function, add validation:
1043
+ # if not session_titles:
1044
+ # return json.dumps({"session_resources": []})
1045
+ # resources_response = generate_session_resources(PERPLEXITY_API_KEY, session_titles)
1046
+ # without_backticks = remove_json_backticks(resources_response)
1047
+ # resources = json.loads(without_backticks)
1048
+ # st.session_state.resources_map = {
1049
+ # resource['session_title']: resource['resources']
1050
+ # for resource in resources['session_resources']
1051
+ # }
1052
+ # # Add error handling for the resources map
1053
+ # # if st.session_state.resources_map is None:
1054
+ # # st.session_state.resources_map = {}
1055
+
1056
+ # st.rerun()
1057
+ # except Exception as e:
1058
+ # st.error(f"Error generating course structure: {e}")
1059
 
1060
+ # # Display and Edit Generated Course Content
1061
+ # if st.session_state.course_plan:
1062
+ # with st.expander("Course Overview", expanded=True):
1063
+ # if not st.session_state.edit_mode:
1064
+ # st.subheader(st.session_state.course_plan['course_title'])
1065
+ # st.write(st.session_state.course_plan['course_description'])
1066
+ # col1, col2, col3 = st.columns(3)
1067
+ # with col1:
1068
+ # st.write(f"**Start Date:** {st.session_state.start_date}")
1069
+ # with col2:
1070
+ # st.write(f"**Duration (weeks):** {st.session_state.duration_weeks}")
1071
+ # with col3:
1072
+ # st.write(f"**Sessions Per Week:** {st.session_state.sessions_per_week}")
1073
+
1074
+ # edit_button = st.button("Edit Course Details", use_container_width=True)
1075
+ # if edit_button:
1076
+ # st.session_state.edit_mode = True
1077
+ # st.rerun()
1078
+ # else:
1079
+ # with st.form("edit_course_details"):
1080
+ # st.session_state.course_plan['course_title'] = st.text_input(
1081
+ # "Course Title",
1082
+ # value=st.session_state.course_plan['course_title']
1083
+ # )
1084
+ # st.session_state.course_plan['course_description'] = st.text_area(
1085
+ # "Course Description",
1086
+ # value=st.session_state.course_plan['course_description']
1087
+ # )
1088
+ # if st.form_submit_button("Save Course Details"):
1089
+ # st.session_state.edit_mode = False
1090
+ # st.rerun()
1091
 
1092
+ # # Display Modules and Sessions
1093
+ # st.subheader("Course Modules and Sessions")
1094
 
1095
+ # start_date = st.session_state.start_date
1096
+ # current_date = start_date
1097
 
1098
+ # all_sessions = []
1099
+ # for module_idx, module in enumerate(st.session_state.course_plan['modules']):
1100
+ # with st.expander(f"📚 Module {module_idx + 1}: {module['module_title']}", expanded=True):
1101
+ # # Edit module title
1102
+ # new_module_title = st.text_input(
1103
+ # f"Edit Module Title",
1104
+ # value=module['module_title'],
1105
+ # key=f"module_{module_idx}"
1106
+ # )
1107
+ # module['module_title'] = new_module_title
1108
 
1109
+ # for sub_idx, sub_module in enumerate(module['sub_modules']):
1110
+ # st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
1111
+ # # st.markdown(f"### 📖 {sub_module['title']}")
1112
+ # st.markdown(f'<h3 style="font-size: 1.25rem;">📖 Chapter {sub_idx + 1}: {sub_module["title"]}</h3>', unsafe_allow_html=True)
1113
+ # # Possible fix:
1114
+ # # Inside the loop where topics are being processed:
1115
+
1116
+ # for topic_idx, topic in enumerate(sub_module['topics']):
1117
+ # st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
1118
+ # session_key = f"session_{module_idx}_{sub_idx}_{topic_idx}"
1119
 
1120
+ # # Get topic title based on type
1121
+ # if isinstance(topic, dict):
1122
+ # current_topic_title = topic.get('title', '')
1123
+ # current_topic_display = current_topic_title
1124
+ # else:
1125
+ # current_topic_title = str(topic)
1126
+ # current_topic_display = current_topic_title
1127
+
1128
+ # with st.container():
1129
+ # # Session Details
1130
+ # col1, col2, col3 = st.columns([3, 2, 1])
1131
+ # with col1:
1132
+ # new_topic = st.text_input(
1133
+ # f"Session {topic_idx + 1} Title",
1134
+ # value=current_topic_display,
1135
+ # key=f"{session_key}_topic"
1136
+ # )
1137
+ # # Update the topic in the data structure
1138
+ # if isinstance(topic, dict):
1139
+ # topic['title'] = new_topic
1140
+ # else:
1141
+ # sub_module['topics'][topic_idx] = new_topic
1142
 
1143
+ # with col2:
1144
+ # session_date = st.date_input(
1145
+ # "Session Date",
1146
+ # value=current_date,
1147
+ # key=f"{session_key}_date"
1148
+ # )
1149
 
1150
+ # with col3:
1151
+ # session_status = st.selectbox(
1152
+ # "Status",
1153
+ # options=["upcoming", "in-progress", "completed"],
1154
+ # key=f"{session_key}_status"
1155
+ # )
1156
 
1157
+ # # Display Resources
1158
+ # if st.session_state.resources_map:
1159
+ # # Try both the full topic title and the display title
1160
+ # resources = None
1161
+ # if isinstance(topic, dict) and topic.get('title') in st.session_state.resources_map:
1162
+ # resources = st.session_state.resources_map[topic['title']]
1163
+ # elif current_topic_title in st.session_state.resources_map:
1164
+ # resources = st.session_state.resources_map[current_topic_title]
1165
 
1166
+ # if resources:
1167
+ # with st.container():
1168
+ # # st.markdown("#### 📚 Session Resources")
1169
+ # st.markdown(f'<h4 style="font-size: 1.25rem;">📚 Session Resources</h4>', unsafe_allow_html=True)
1170
+ # # Readings Tab
1171
+ # if resources.get('readings'):
1172
+ # st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📖 External Resources</h5>', unsafe_allow_html=True)
1173
+ # col1, col2 = st.columns(2)
1174
+ # for idx, reading in enumerate(resources['readings']):
1175
+ # with col1 if idx % 2 == 0 else col2:
1176
+ # st.markdown(f"""
1177
+ # - **{reading['title']}**
1178
+ # - Type: {reading['type']}
1179
+ # - Estimated reading time: {reading['estimated_read_time']}
1180
+ # - [Access Resource]({reading['url']})
1181
+ # """)
1182
 
1183
+ # # Books Tab and Additional Resources Tab side-by-side
1184
+ # col1, col2 = st.columns(2)
1185
 
1186
+ # with col1:
1187
+ # if resources.get('books'):
1188
+ # st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📚 Reference Books</h5>', unsafe_allow_html=True)
1189
+ # for book in resources['books']:
1190
+ # with st.container():
1191
+ # st.markdown(f"""
1192
+ # - **{book['title']}**
1193
+ # - Author: {book['author']}
1194
+ # - ISBN: {book['isbn']}
1195
+ # - Chapters: {book['chapters']}
1196
+ # """)
1197
 
1198
+ # with col2:
1199
+ # if resources.get('additional_resources'):
1200
+ # st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">🔗 Additional Study Resources</h5>', unsafe_allow_html=True)
1201
+ # for resource in resources['additional_resources']:
1202
+ # with st.container():
1203
+ # st.markdown(f"""
1204
+ # - **{resource['title']}**
1205
+ # - Type: {resource['type']}
1206
+ # - Description: {resource['description']}
1207
+ # - [Access Resource]({resource['url']})
1208
+ # """)
1209
 
1210
+ # # Create session object
1211
+ # session = {
1212
+ # "session_id": str(ObjectId()),
1213
+ # "title": new_topic,
1214
+ # "date": datetime.combine(session_date, datetime.min.time()),
1215
+ # "status": session_status,
1216
+ # "module_name": module['module_title'],
1217
+ # "created_at": datetime.utcnow(),
1218
+ # "pre_class": {
1219
+ # "resources": [],
1220
+ # "completion_required": True
1221
+ # },
1222
+ # "in_class": {
1223
+ # "quiz": [],
1224
+ # "polls": []
1225
+ # },
1226
+ # "post_class": {
1227
+ # "assignments": []
1228
+ # },
1229
+ # "external_resources": st.session_state.resources_map.get(current_topic_title, {})
1230
+ # }
1231
+ # all_sessions.append(session)
1232
+ # current_date = session_date + timedelta(days=7)
1233
 
1234
 
1235
+ # new_course_id = get_new_course_id()
1236
+ # course_title = st.session_state.course_plan['course_title']
1237
+
1238
+ # # Final Save Button
1239
+ # if st.button("Save Course", type="primary", use_container_width=True):
1240
+ # try:
1241
+ # course_doc = {
1242
+ # "course_id": new_course_id,
1243
+ # "title": course_title,
1244
+ # "description": st.session_state.course_plan['course_description'],
1245
+ # "faculty": faculty_name,
1246
+ # "faculty_id": faculty_id,
1247
+ # "duration": f"{st.session_state.duration_weeks} weeks",
1248
+ # "sessions_per_week": st.session_state.sessions_per_week,
1249
+ # "start_date": datetime.combine(st.session_state.start_date, datetime.min.time()),
1250
+ # "created_at": datetime.utcnow(),
1251
+ # "sessions": all_sessions
1252
+ # }
1253
 
1254
+ # # Insert into database
1255
+ # courses_collection.insert_one(course_doc)
1256
+ # st.success("Course successfully created!")
1257
 
1258
+ # # Update faculty collection
1259
+
 
 
 
 
 
 
 
 
 
 
1260
 
1261
+ # # Clear session state
1262
+ # st.session_state.course_plan = None
1263
+ # st.session_state.edit_mode = False
1264
+ # st.session_state.resources_map = {}
1265
 
1266
+ # # Optional: Add a button to view the created course
1267
+ # if st.button("View Course"):
1268
+ # # Add navigation logic here
1269
+ # pass
1270
 
1271
+ # except Exception as e:
1272
+ # st.error(f"Error saving course: {e}")
1273
 
1274
 
1275
 
create_course.py CHANGED
@@ -1,4 +1,4 @@
1
- from datetime import datetime, timedelta
2
  import os
3
  from typing import Dict, List, Any
4
  from pymongo import MongoClient
@@ -19,6 +19,7 @@ OPENAI_API_KEY = os.getenv("OPENAI_KEY")
19
  client = MongoClient(MONGODB_URI)
20
  db = client['novascholar_db']
21
  courses_collection = db['courses']
 
22
 
23
  def generate_perplexity_response(api_key, course_name):
24
  headers = {
@@ -118,7 +119,7 @@ def get_new_course_id():
118
  return new_course_id
119
 
120
 
121
- def create_course(course_name, start_date, duration_weeks):
122
  # Generate course overview
123
  # overview_prompt = f"""Generate an overview for the undergraduate course {course_name}
124
  # Include all relevant concepts and key topics covered in a typical curriculum.
@@ -246,6 +247,58 @@ def create_course(course_name, start_date, duration_weeks):
246
 
247
  # print(course_plan)
248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  def create_session(title: str, date: datetime, module_name: str):
250
  """Create a session document with pre-class, in-class, and post-class components."""
251
  return {
 
1
+ from datetime import datetime, timedelta, date
2
  import os
3
  from typing import Dict, List, Any
4
  from pymongo import MongoClient
 
19
  client = MongoClient(MONGODB_URI)
20
  db = client['novascholar_db']
21
  courses_collection = db['courses']
22
+ faculty_collection = db['faculty']
23
 
24
  def generate_perplexity_response(api_key, course_name):
25
  headers = {
 
119
  return new_course_id
120
 
121
 
122
+ def create_course_perplexity(course_name, start_date, duration_weeks):
123
  # Generate course overview
124
  # overview_prompt = f"""Generate an overview for the undergraduate course {course_name}
125
  # Include all relevant concepts and key topics covered in a typical curriculum.
 
247
 
248
  # print(course_plan)
249
 
250
+
251
+ def create_course(course_name, duration_weeks, faculty_name, sessions_per_week, start_date: date, course_description, faculty_id):
252
+ """
253
+ Create a course document in the desired JSON format and insert it into MongoDB.
254
+ """
255
+ try:
256
+ # Count sessions
257
+ # st.write("Number of sessions:", len(all_sessions)
258
+
259
+ # Generate a new course ID
260
+ course_id = get_new_course_id()
261
+
262
+ if isinstance(start_date, date):
263
+ start_date = datetime.combine(start_date, datetime.min.time())
264
+
265
+ # Create the course document
266
+ course_doc = {
267
+ "_id": ObjectId(),
268
+ "course_id": course_id, # Assumes there's a helper function in your code
269
+ "title": course_name,
270
+ "description": course_description,
271
+ "faculty": faculty_name,
272
+ "faculty_id": faculty_id,
273
+ "duration": f"{duration_weeks} weeks",
274
+ "sessions_per_week": sessions_per_week,
275
+ "start_date": start_date,
276
+ "created_at": datetime.utcnow(),
277
+ }
278
+
279
+ # Insert into MongoDB
280
+ courses_collection.insert_one(course_doc)
281
+
282
+ faculty_collection.update_one(
283
+ {"_id": st.session_state.user_id},
284
+ {
285
+ "$push": {
286
+ "courses_taught": {
287
+ "course_id": course_id,
288
+ "title": course_name,
289
+ }
290
+ }
291
+ }
292
+ )
293
+
294
+ st.success("Course created successfully!")
295
+ # st.json(course_doc)
296
+ return course_doc
297
+ except Exception as e:
298
+ st.error(f"Failed to insert course data into the database: {e}")
299
+ return None
300
+
301
+
302
  def create_session(title: str, date: datetime, module_name: str):
303
  """Create a session document with pre-class, in-class, and post-class components."""
304
  return {
live_polls.py CHANGED
@@ -9,7 +9,7 @@ class LivePollFeature:
9
  def __init__(self):
10
  self.db = PollDatabase()
11
 
12
- def display_faculty_interface(self, session_id):
13
  """Display the faculty interface for managing polls"""
14
  st.markdown("#### Live Polls Management")
15
 
@@ -31,6 +31,8 @@ class LivePollFeature:
31
 
32
  if st.button("Create Poll") and question and len(options) >= 2:
33
  self.db.create_poll(
 
 
34
  st.session_state.selected_course,
35
  session_id,
36
  question,
@@ -41,7 +43,7 @@ class LivePollFeature:
41
  st.rerun()
42
 
43
  # Display active polls
44
- active_polls = self.db.get_active_polls(session_id)
45
  if active_polls:
46
  st.subheader("Active Polls")
47
  for poll in active_polls:
@@ -55,11 +57,11 @@ class LivePollFeature:
55
  st.success("Poll closed successfully!")
56
  st.rerun()
57
 
58
- def display_student_interface(self, session_id):
59
  """Display the student interface for participating in polls"""
60
  st.subheader("Live Polls")
61
 
62
- active_polls = self.db.get_active_polls(session_id)
63
  if not active_polls:
64
  st.info("No active polls at the moment.")
65
  return
 
9
  def __init__(self):
10
  self.db = PollDatabase()
11
 
12
+ def display_faculty_interface(self, session_id, course_id):
13
  """Display the faculty interface for managing polls"""
14
  st.markdown("#### Live Polls Management")
15
 
 
31
 
32
  if st.button("Create Poll") and question and len(options) >= 2:
33
  self.db.create_poll(
34
+ course_id,
35
+ # course_id,
36
  st.session_state.selected_course,
37
  session_id,
38
  question,
 
43
  st.rerun()
44
 
45
  # Display active polls
46
+ active_polls = self.db.get_active_polls(session_id, course_id)
47
  if active_polls:
48
  st.subheader("Active Polls")
49
  for poll in active_polls:
 
57
  st.success("Poll closed successfully!")
58
  st.rerun()
59
 
60
+ def display_student_interface(self, session_id, course_id):
61
  """Display the student interface for participating in polls"""
62
  st.subheader("Live Polls")
63
 
64
+ active_polls = self.db.get_active_polls(session_id, course_id)
65
  if not active_polls:
66
  st.info("No active polls at the moment.")
67
  return
poll_db_operations.py CHANGED
@@ -11,10 +11,11 @@ class PollDatabase:
11
  self.client = MongoClient(MONGO_URI)
12
  self.db = self.client["novascholar_db"]
13
 
14
- def create_poll(self, course_id, session_id, question, options, faculty_id):
15
  """Create a new poll"""
16
  poll = {
17
  "course_id": course_id,
 
18
  "session_id": session_id,
19
  "faculty_id": faculty_id,
20
  "question": question,
@@ -25,10 +26,11 @@ class PollDatabase:
25
  }
26
  return self.db.polls.insert_one(poll)
27
 
28
- def get_active_polls(self, session_id):
29
  """Get all active polls for a session"""
30
  return list(self.db.polls.find({
31
  "session_id": session_id,
 
32
  "status": "active"
33
  }))
34
 
 
11
  self.client = MongoClient(MONGO_URI)
12
  self.db = self.client["novascholar_db"]
13
 
14
+ def create_poll(self, course_id, course_name, session_id, question, options, faculty_id):
15
  """Create a new poll"""
16
  poll = {
17
  "course_id": course_id,
18
+ "course_name": course_name,
19
  "session_id": session_id,
20
  "faculty_id": faculty_id,
21
  "question": question,
 
26
  }
27
  return self.db.polls.insert_one(poll)
28
 
29
+ def get_active_polls(self, session_id, course_id):
30
  """Get all active polls for a session"""
31
  return list(self.db.polls.find({
32
  "session_id": session_id,
33
+ "course_id": course_id,
34
  "status": "active"
35
  }))
36
 
session_page.py CHANGED
@@ -155,7 +155,8 @@ def display_preclass_content(session, student_id, course_id):
155
  """Display pre-class materials for a session including external resources"""
156
  st.subheader("Pre-class Materials")
157
  print("Session ID is: ", session['session_id'])
158
-
 
159
  # Display uploaded materials
160
  materials = resources_collection.find({"session_id": session['session_id']})
161
 
@@ -725,6 +726,7 @@ def display_preclass_content(session, student_id, course_id):
725
  if not quiz:
726
  st.info("No practice quizzes created.")
727
  else:
 
728
  with st.expander(f"📝 Practice Quiz", expanded=True):
729
  existing_score = get_student_quiz_score(quiz['_id'], student_id)
730
 
@@ -1359,7 +1361,7 @@ def upload_preclass_materials(session, session_id, course_id, student_id):
1359
  # Display pre-class materials
1360
  # Group resources by their types
1361
  grouped_resources = defaultdict(list)
1362
- materials = resources_collection.find({"session_id": session_id})
1363
  for material in materials:
1364
  grouped_resources[material['material_type']].append(material)
1365
 
@@ -2557,13 +2559,13 @@ def display_in_class_content(session, user_type, course_id, user_id):
2557
 
2558
  # Display appropriate interface based on user role
2559
  if user_type == 'faculty':
2560
- live_polls.display_faculty_interface(session['session_id'])
2561
  else:
2562
- live_polls.display_student_interface(session['session_id'])
2563
 
2564
  display_live_chat_interface(session, user_id, course_id=course_id)
2565
 
2566
- # Live Presentation Feature
2567
  display_live_presentation(session, user_type, course_id)
2568
 
2569
  def get_current_context(session):
@@ -3853,6 +3855,7 @@ def display_quiz_tab(student_id, course_id, session_id):
3853
  # "quiz_type": {"$ne": "pre_class"}
3854
  # })
3855
  quizzes = list(quizzes_collection.find({
 
3856
  "course_id": course_id,
3857
  "session_id": session_id,
3858
  "status": "active",
 
155
  """Display pre-class materials for a session including external resources"""
156
  st.subheader("Pre-class Materials")
157
  print("Session ID is: ", session['session_id'])
158
+ print(course_id)
159
+
160
  # Display uploaded materials
161
  materials = resources_collection.find({"session_id": session['session_id']})
162
 
 
726
  if not quiz:
727
  st.info("No practice quizzes created.")
728
  else:
729
+ display_quiz_tab(student_id, course_id, session['session_id'])
730
  with st.expander(f"📝 Practice Quiz", expanded=True):
731
  existing_score = get_student_quiz_score(quiz['_id'], student_id)
732
 
 
1361
  # Display pre-class materials
1362
  # Group resources by their types
1363
  grouped_resources = defaultdict(list)
1364
+ materials = resources_collection.find({"session_id": session_id, "course_id": course_id})
1365
  for material in materials:
1366
  grouped_resources[material['material_type']].append(material)
1367
 
 
2559
 
2560
  # Display appropriate interface based on user role
2561
  if user_type == 'faculty':
2562
+ live_polls.display_faculty_interface(session['session_id'], course_id)
2563
  else:
2564
+ live_polls.display_student_interface(session['session_id'], course_id)
2565
 
2566
  display_live_chat_interface(session, user_id, course_id=course_id)
2567
 
2568
+ # Live Presentation Featurer
2569
  display_live_presentation(session, user_type, course_id)
2570
 
2571
  def get_current_context(session):
 
3855
  # "quiz_type": {"$ne": "pre_class"}
3856
  # })
3857
  quizzes = list(quizzes_collection.find({
3858
+ "user_id": ObjectId(student_id),
3859
  "course_id": course_id,
3860
  "session_id": session_id,
3861
  "status": "active",