Darsh Tulsiyan
commited on
Commit
·
2e0de0f
1
Parent(s):
5d1504a
manual course form
Browse files- app.py +346 -276
- create_course.py +55 -2
- live_polls.py +6 -4
- poll_db_operations.py +4 -2
- session_page.py +8 -5
app.py
CHANGED
@@ -16,7 +16,7 @@ from werkzeug.security import generate_password_hash, check_password_hash
|
|
16 |
import os
|
17 |
from openai import OpenAI
|
18 |
from dotenv import load_dotenv
|
19 |
-
from
|
20 |
import json
|
21 |
from bson import ObjectId
|
22 |
client = OpenAI(api_key=os.getenv("OPENAI_KEY"))
|
@@ -233,35 +233,110 @@ def create_session(new_session, course_id):
|
|
233 |
return False
|
234 |
|
235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
def create_session_form(course_id):
|
237 |
"""Display form to create a new session and perform the creation operation"""
|
238 |
st.title("Create New Session")
|
239 |
|
240 |
-
if
|
241 |
st.session_state.session_time = datetime.now().time()
|
242 |
-
|
|
|
243 |
st.session_state.show_create_session_form = False
|
244 |
|
|
|
|
|
|
|
245 |
with st.form("create_session_form"):
|
246 |
session_title = st.text_input("Session Title")
|
247 |
session_date = st.date_input("Session Date", date.today(), key="session_date")
|
248 |
-
session_time = st.time_input(
|
249 |
-
|
250 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
|
252 |
-
new_session_id = None
|
253 |
# Generate new session ID
|
|
|
254 |
course = courses_collection.find_one({"course_id": course_id})
|
255 |
if course and "sessions" in course and course["sessions"]:
|
256 |
-
last_session_id = max(
|
257 |
-
int(session["session_id"][1:]) for session in course["sessions"]
|
258 |
-
)
|
259 |
new_session_id = last_session_id + 1
|
260 |
else:
|
261 |
new_session_id = 1
|
262 |
|
|
|
263 |
if st.form_submit_button("Create Session"):
|
264 |
-
clicked = True
|
265 |
new_session = {
|
266 |
"session_id": f"S{new_session_id}",
|
267 |
"course_id": course_id,
|
@@ -269,24 +344,23 @@ def create_session_form(course_id):
|
|
269 |
"date": datetime.combine(session_date, session_time),
|
270 |
"status": "upcoming",
|
271 |
"created_at": datetime.utcnow(),
|
272 |
-
"pre_class": {
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
},
|
284 |
}
|
285 |
-
courses_collection.update_one(
|
286 |
-
{"course_id": course_id}, {"$push": {"sessions": new_session}}
|
287 |
-
)
|
288 |
st.success("Session created successfully!")
|
|
|
289 |
st.session_state.show_create_session_form = False
|
|
|
290 |
|
291 |
# new_session_id = None
|
292 |
# creation_success = False
|
@@ -866,282 +940,278 @@ def create_course_form(faculty_name, faculty_id):
|
|
866 |
with col2:
|
867 |
duration_weeks = st.number_input("Duration (weeks)", min_value=1, max_value=16, value=12)
|
868 |
start_date = st.date_input("Start Date")
|
|
|
|
|
869 |
|
870 |
generate_button = st.form_submit_button("Generate Course Structure", use_container_width=True)
|
871 |
|
872 |
if generate_button and course_name:
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
|
|
|
|
|
|
|
|
892 |
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
|
922 |
-
# Display and Edit Generated Course Content
|
923 |
-
if st.session_state.course_plan:
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
|
954 |
-
|
955 |
-
|
956 |
|
957 |
-
|
958 |
-
|
959 |
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
|
1045 |
-
|
1046 |
-
|
1047 |
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
|
1096 |
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
if st.button("Save Course", type="primary", use_container_width=True):
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
|
1120 |
-
|
1121 |
-
|
1122 |
-
{"_id": st.session_state.user_id},
|
1123 |
-
{
|
1124 |
-
"$push": {
|
1125 |
-
"courses_taught": {
|
1126 |
-
"course_id": new_course_id,
|
1127 |
-
"title": course_title,
|
1128 |
-
}
|
1129 |
-
}
|
1130 |
-
}
|
1131 |
-
)
|
1132 |
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
|
1143 |
-
|
1144 |
-
|
1145 |
|
1146 |
|
1147 |
|
|
|
16 |
import os
|
17 |
from openai import OpenAI
|
18 |
from dotenv import load_dotenv
|
19 |
+
from create_course import create_course, courses_collection, generate_perplexity_response #, generate_session_resources, PERPLEXITY_API_KEY, validate_course_plan
|
20 |
import json
|
21 |
from bson import ObjectId
|
22 |
client = OpenAI(api_key=os.getenv("OPENAI_KEY"))
|
|
|
233 |
return False
|
234 |
|
235 |
|
236 |
+
# def create_session_form(course_id):
|
237 |
+
# """Display form to create a new session and perform the creation operation"""
|
238 |
+
# st.title("Create New Session")
|
239 |
+
|
240 |
+
# if 'session_time' not in st.session_state:
|
241 |
+
# st.session_state.session_time = datetime.now().time()
|
242 |
+
# if 'show_create_session_form' not in st.session_state:
|
243 |
+
# st.session_state.show_create_session_form = False
|
244 |
+
|
245 |
+
# with st.form("create_session_form"):
|
246 |
+
# session_title = st.text_input("Session Title")
|
247 |
+
# session_date = st.date_input("Session Date", date.today(), key="session_date")
|
248 |
+
# session_time = st.time_input(
|
249 |
+
# "Session Time", st.session_state.session_time, key="session_time"
|
250 |
+
# )
|
251 |
+
|
252 |
+
# new_session_id = None
|
253 |
+
# # Generate new session ID
|
254 |
+
# course = courses_collection.find_one({"course_id": course_id})
|
255 |
+
# if course and "sessions" in course and course["sessions"]:
|
256 |
+
# last_session_id = max(
|
257 |
+
# int(session["session_id"][1:]) for session in course["sessions"]
|
258 |
+
# )
|
259 |
+
# new_session_id = last_session_id + 1
|
260 |
+
# else:
|
261 |
+
# new_session_id = 1
|
262 |
+
|
263 |
+
# if st.form_submit_button("Create Session"):
|
264 |
+
# clicked = True
|
265 |
+
# new_session = {
|
266 |
+
# "session_id": f"S{new_session_id}",
|
267 |
+
# "course_id": course_id,
|
268 |
+
# "title": session_title,
|
269 |
+
# "date": datetime.combine(session_date, session_time),
|
270 |
+
# "status": "upcoming",
|
271 |
+
# "created_at": datetime.utcnow(),
|
272 |
+
# "pre_class": {
|
273 |
+
# "resources": [],
|
274 |
+
# "completetion_required": True,
|
275 |
+
# },
|
276 |
+
# "in_class": {
|
277 |
+
# "topics": [],
|
278 |
+
# "quiz": {"title": "", "questions": 0, "duration": 0},
|
279 |
+
# "polls": [],
|
280 |
+
# },
|
281 |
+
# "post_class": {
|
282 |
+
# "assignments": [],
|
283 |
+
# },
|
284 |
+
# }
|
285 |
+
# courses_collection.update_one(
|
286 |
+
# {"course_id": course_id}, {"$push": {"sessions": new_session}}
|
287 |
+
# )
|
288 |
+
# st.success("Session created successfully!")
|
289 |
+
# st.session_state.show_create_session_form = False
|
290 |
+
|
291 |
+
|
292 |
def create_session_form(course_id):
|
293 |
"""Display form to create a new session and perform the creation operation"""
|
294 |
st.title("Create New Session")
|
295 |
|
296 |
+
if "session_time" not in st.session_state:
|
297 |
st.session_state.session_time = datetime.now().time()
|
298 |
+
|
299 |
+
if "show_create_session_form" not in st.session_state:
|
300 |
st.session_state.show_create_session_form = False
|
301 |
|
302 |
+
if "outcomes" not in st.session_state:
|
303 |
+
st.session_state.outcomes = [] # List to store outcomes dynamically
|
304 |
+
|
305 |
with st.form("create_session_form"):
|
306 |
session_title = st.text_input("Session Title")
|
307 |
session_date = st.date_input("Session Date", date.today(), key="session_date")
|
308 |
+
session_time = st.time_input("Session Time", st.session_state.session_time, key="session_time")
|
309 |
+
|
310 |
+
st.subheader("Session Learning Outcomes")
|
311 |
+
|
312 |
+
# Display all outcomes dynamically
|
313 |
+
for idx, outcome in enumerate(st.session_state.outcomes):
|
314 |
+
st.text_input(f"Outcome {idx + 1} Description", key=f"outcome_desc_{idx}")
|
315 |
+
st.selectbox(
|
316 |
+
f"Bloom's Taxonomy Level {idx + 1}",
|
317 |
+
["Remember", "Understand", "Apply", "Analyze", "Evaluate", "Create"],
|
318 |
+
key=f"bloom_level_{idx}"
|
319 |
+
)
|
320 |
+
|
321 |
+
# Button to add new outcome fields
|
322 |
+
if st.form_submit_button("Add Outcome"):
|
323 |
+
new_index = len(st.session_state.outcomes)
|
324 |
+
st.session_state.outcomes.append(
|
325 |
+
{"outcome_number": new_index + 1, "outcome_description": "", "bloom_taxanomy_level": ""}
|
326 |
+
)
|
327 |
+
st.rerun() # Refresh the form to display new fields
|
328 |
|
|
|
329 |
# Generate new session ID
|
330 |
+
new_session_id = None
|
331 |
course = courses_collection.find_one({"course_id": course_id})
|
332 |
if course and "sessions" in course and course["sessions"]:
|
333 |
+
last_session_id = max(int(session["session_id"][1:]) for session in course["sessions"])
|
|
|
|
|
334 |
new_session_id = last_session_id + 1
|
335 |
else:
|
336 |
new_session_id = 1
|
337 |
|
338 |
+
# Submit session
|
339 |
if st.form_submit_button("Create Session"):
|
|
|
340 |
new_session = {
|
341 |
"session_id": f"S{new_session_id}",
|
342 |
"course_id": course_id,
|
|
|
344 |
"date": datetime.combine(session_date, session_time),
|
345 |
"status": "upcoming",
|
346 |
"created_at": datetime.utcnow(),
|
347 |
+
"pre_class": {"resources": [], "completetion_required": True},
|
348 |
+
"in_class": {"topics": [], "quiz": {"title": "", "questions": 0, "duration": 0}, "polls": []},
|
349 |
+
"post_class": {"assignments": []},
|
350 |
+
"session_learning_outcomes": [
|
351 |
+
{
|
352 |
+
"outcome_number": idx + 1,
|
353 |
+
"outcome_description": st.session_state[f"outcome_desc_{idx}"],
|
354 |
+
"bloom_taxanomy_level": st.session_state[f"bloom_level_{idx}"]
|
355 |
+
}
|
356 |
+
for idx in range(len(st.session_state.outcomes))
|
357 |
+
]
|
|
|
358 |
}
|
359 |
+
courses_collection.update_one({"course_id": course_id}, {"$push": {"sessions": new_session}})
|
|
|
|
|
360 |
st.success("Session created successfully!")
|
361 |
+
st.session_state.outcomes = [] # Clear outcomes after submission
|
362 |
st.session_state.show_create_session_form = False
|
363 |
+
st.rerun()
|
364 |
|
365 |
# new_session_id = None
|
366 |
# creation_success = False
|
|
|
940 |
with col2:
|
941 |
duration_weeks = st.number_input("Duration (weeks)", min_value=1, max_value=16, value=12)
|
942 |
start_date = st.date_input("Start Date")
|
943 |
+
course_description = st.text_area("Course Description", placeholder="Enter a brief course description here")
|
944 |
+
|
945 |
|
946 |
generate_button = st.form_submit_button("Generate Course Structure", use_container_width=True)
|
947 |
|
948 |
if generate_button and course_name:
|
949 |
+
create_course(course_name, duration_weeks, faculty_name, sessions_per_week, start_date, course_description, faculty_id)
|
950 |
+
|
951 |
+
#update faculty list of courses
|
952 |
+
|
953 |
+
# with st.spinner("Generating course structure and resources..."):
|
954 |
+
# try:
|
955 |
+
# # Generate course plan with resources
|
956 |
+
# course_plan = generate_perplexity_response(
|
957 |
+
# PERPLEXITY_API_KEY,
|
958 |
+
# course_name,
|
959 |
+
# duration_weeks,
|
960 |
+
# sessions_per_week
|
961 |
+
# )
|
962 |
+
# try:
|
963 |
+
# course_plan_json = json.loads(course_plan)
|
964 |
+
# validate_course_plan(course_plan_json)
|
965 |
+
# st.session_state.course_plan = course_plan_json
|
966 |
+
# except (json.JSONDecodeError, ValueError) as e:
|
967 |
+
# st.error(f"Error in course plan structure: {e}")
|
968 |
+
# return
|
969 |
+
# st.session_state.start_date = start_date
|
970 |
+
# st.session_state.duration_weeks = duration_weeks
|
971 |
+
# st.session_state.sessions_per_week = sessions_per_week
|
972 |
|
973 |
+
# # Generate resources for all sessions
|
974 |
+
# session_titles = []
|
975 |
+
# for module in st.session_state.course_plan['modules']:
|
976 |
+
# for sub_module in module['sub_modules']:
|
977 |
+
# for topic in sub_module['topics']:
|
978 |
+
# # session_titles.append(topic['title'])
|
979 |
+
# # session_titles.append(topic)
|
980 |
+
# if isinstance(topic, dict):
|
981 |
+
# session_titles.append(topic['title'])
|
982 |
+
# else:
|
983 |
+
# session_titles.append(topic)
|
984 |
+
# # In generate_session_resources function, add validation:
|
985 |
+
# if not session_titles:
|
986 |
+
# return json.dumps({"session_resources": []})
|
987 |
+
# resources_response = generate_session_resources(PERPLEXITY_API_KEY, session_titles)
|
988 |
+
# without_backticks = remove_json_backticks(resources_response)
|
989 |
+
# resources = json.loads(without_backticks)
|
990 |
+
# st.session_state.resources_map = {
|
991 |
+
# resource['session_title']: resource['resources']
|
992 |
+
# for resource in resources['session_resources']
|
993 |
+
# }
|
994 |
+
# # Add error handling for the resources map
|
995 |
+
# # if st.session_state.resources_map is None:
|
996 |
+
# # st.session_state.resources_map = {}
|
997 |
+
|
998 |
+
# st.rerun()
|
999 |
+
# except Exception as e:
|
1000 |
+
# st.error(f"Error generating course structure: {e}")
|
1001 |
|
1002 |
+
# # Display and Edit Generated Course Content
|
1003 |
+
# if st.session_state.course_plan:
|
1004 |
+
# with st.expander("Course Overview", expanded=True):
|
1005 |
+
# if not st.session_state.edit_mode:
|
1006 |
+
# st.subheader(st.session_state.course_plan['course_title'])
|
1007 |
+
# st.write(st.session_state.course_plan['course_description'])
|
1008 |
+
# col1, col2, col3 = st.columns(3)
|
1009 |
+
# with col1:
|
1010 |
+
# st.write(f"**Start Date:** {st.session_state.start_date}")
|
1011 |
+
# with col2:
|
1012 |
+
# st.write(f"**Duration (weeks):** {st.session_state.duration_weeks}")
|
1013 |
+
# with col3:
|
1014 |
+
# st.write(f"**Sessions Per Week:** {st.session_state.sessions_per_week}")
|
1015 |
+
|
1016 |
+
# edit_button = st.button("Edit Course Details", use_container_width=True)
|
1017 |
+
# if edit_button:
|
1018 |
+
# st.session_state.edit_mode = True
|
1019 |
+
# st.rerun()
|
1020 |
+
# else:
|
1021 |
+
# with st.form("edit_course_details"):
|
1022 |
+
# st.session_state.course_plan['course_title'] = st.text_input(
|
1023 |
+
# "Course Title",
|
1024 |
+
# value=st.session_state.course_plan['course_title']
|
1025 |
+
# )
|
1026 |
+
# st.session_state.course_plan['course_description'] = st.text_area(
|
1027 |
+
# "Course Description",
|
1028 |
+
# value=st.session_state.course_plan['course_description']
|
1029 |
+
# )
|
1030 |
+
# if st.form_submit_button("Save Course Details"):
|
1031 |
+
# st.session_state.edit_mode = False
|
1032 |
+
# st.rerun()
|
1033 |
|
1034 |
+
# # Display Modules and Sessions
|
1035 |
+
# st.subheader("Course Modules and Sessions")
|
1036 |
|
1037 |
+
# start_date = st.session_state.start_date
|
1038 |
+
# current_date = start_date
|
1039 |
|
1040 |
+
# all_sessions = []
|
1041 |
+
# for module_idx, module in enumerate(st.session_state.course_plan['modules']):
|
1042 |
+
# with st.expander(f"📚 Module {module_idx + 1}: {module['module_title']}", expanded=True):
|
1043 |
+
# # Edit module title
|
1044 |
+
# new_module_title = st.text_input(
|
1045 |
+
# f"Edit Module Title",
|
1046 |
+
# value=module['module_title'],
|
1047 |
+
# key=f"module_{module_idx}"
|
1048 |
+
# )
|
1049 |
+
# module['module_title'] = new_module_title
|
1050 |
|
1051 |
+
# for sub_idx, sub_module in enumerate(module['sub_modules']):
|
1052 |
+
# st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
|
1053 |
+
# # st.markdown(f"### 📖 {sub_module['title']}")
|
1054 |
+
# st.markdown(f'<h3 style="font-size: 1.25rem;">📖 Chapter {sub_idx + 1}: {sub_module["title"]}</h3>', unsafe_allow_html=True)
|
1055 |
+
# # Possible fix:
|
1056 |
+
# # Inside the loop where topics are being processed:
|
1057 |
+
|
1058 |
+
# for topic_idx, topic in enumerate(sub_module['topics']):
|
1059 |
+
# st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
|
1060 |
+
# session_key = f"session_{module_idx}_{sub_idx}_{topic_idx}"
|
1061 |
|
1062 |
+
# # Get topic title based on type
|
1063 |
+
# if isinstance(topic, dict):
|
1064 |
+
# current_topic_title = topic.get('title', '')
|
1065 |
+
# current_topic_display = current_topic_title
|
1066 |
+
# else:
|
1067 |
+
# current_topic_title = str(topic)
|
1068 |
+
# current_topic_display = current_topic_title
|
1069 |
+
|
1070 |
+
# with st.container():
|
1071 |
+
# # Session Details
|
1072 |
+
# col1, col2, col3 = st.columns([3, 2, 1])
|
1073 |
+
# with col1:
|
1074 |
+
# new_topic = st.text_input(
|
1075 |
+
# f"Session {topic_idx + 1} Title",
|
1076 |
+
# value=current_topic_display,
|
1077 |
+
# key=f"{session_key}_topic"
|
1078 |
+
# )
|
1079 |
+
# # Update the topic in the data structure
|
1080 |
+
# if isinstance(topic, dict):
|
1081 |
+
# topic['title'] = new_topic
|
1082 |
+
# else:
|
1083 |
+
# sub_module['topics'][topic_idx] = new_topic
|
1084 |
|
1085 |
+
# with col2:
|
1086 |
+
# session_date = st.date_input(
|
1087 |
+
# "Session Date",
|
1088 |
+
# value=current_date,
|
1089 |
+
# key=f"{session_key}_date"
|
1090 |
+
# )
|
1091 |
|
1092 |
+
# with col3:
|
1093 |
+
# session_status = st.selectbox(
|
1094 |
+
# "Status",
|
1095 |
+
# options=["upcoming", "in-progress", "completed"],
|
1096 |
+
# key=f"{session_key}_status"
|
1097 |
+
# )
|
1098 |
|
1099 |
+
# # Display Resources
|
1100 |
+
# if st.session_state.resources_map:
|
1101 |
+
# # Try both the full topic title and the display title
|
1102 |
+
# resources = None
|
1103 |
+
# if isinstance(topic, dict) and topic.get('title') in st.session_state.resources_map:
|
1104 |
+
# resources = st.session_state.resources_map[topic['title']]
|
1105 |
+
# elif current_topic_title in st.session_state.resources_map:
|
1106 |
+
# resources = st.session_state.resources_map[current_topic_title]
|
1107 |
|
1108 |
+
# if resources:
|
1109 |
+
# with st.container():
|
1110 |
+
# # st.markdown("#### 📚 Session Resources")
|
1111 |
+
# st.markdown(f'<h4 style="font-size: 1.25rem;">📚 Session Resources</h4>', unsafe_allow_html=True)
|
1112 |
+
# # Readings Tab
|
1113 |
+
# if resources.get('readings'):
|
1114 |
+
# st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📖 External Resources</h5>', unsafe_allow_html=True)
|
1115 |
+
# col1, col2 = st.columns(2)
|
1116 |
+
# for idx, reading in enumerate(resources['readings']):
|
1117 |
+
# with col1 if idx % 2 == 0 else col2:
|
1118 |
+
# st.markdown(f"""
|
1119 |
+
# - **{reading['title']}**
|
1120 |
+
# - Type: {reading['type']}
|
1121 |
+
# - Estimated reading time: {reading['estimated_read_time']}
|
1122 |
+
# - [Access Resource]({reading['url']})
|
1123 |
+
# """)
|
1124 |
|
1125 |
+
# # Books Tab and Additional Resources Tab side-by-side
|
1126 |
+
# col1, col2 = st.columns(2)
|
1127 |
|
1128 |
+
# with col1:
|
1129 |
+
# if resources.get('books'):
|
1130 |
+
# st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📚 Reference Books</h5>', unsafe_allow_html=True)
|
1131 |
+
# for book in resources['books']:
|
1132 |
+
# with st.container():
|
1133 |
+
# st.markdown(f"""
|
1134 |
+
# - **{book['title']}**
|
1135 |
+
# - Author: {book['author']}
|
1136 |
+
# - ISBN: {book['isbn']}
|
1137 |
+
# - Chapters: {book['chapters']}
|
1138 |
+
# """)
|
1139 |
|
1140 |
+
# with col2:
|
1141 |
+
# if resources.get('additional_resources'):
|
1142 |
+
# st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">🔗 Additional Study Resources</h5>', unsafe_allow_html=True)
|
1143 |
+
# for resource in resources['additional_resources']:
|
1144 |
+
# with st.container():
|
1145 |
+
# st.markdown(f"""
|
1146 |
+
# - **{resource['title']}**
|
1147 |
+
# - Type: {resource['type']}
|
1148 |
+
# - Description: {resource['description']}
|
1149 |
+
# - [Access Resource]({resource['url']})
|
1150 |
+
# """)
|
1151 |
|
1152 |
+
# # Create session object
|
1153 |
+
# session = {
|
1154 |
+
# "session_id": str(ObjectId()),
|
1155 |
+
# "title": new_topic,
|
1156 |
+
# "date": datetime.combine(session_date, datetime.min.time()),
|
1157 |
+
# "status": session_status,
|
1158 |
+
# "module_name": module['module_title'],
|
1159 |
+
# "created_at": datetime.utcnow(),
|
1160 |
+
# "pre_class": {
|
1161 |
+
# "resources": [],
|
1162 |
+
# "completion_required": True
|
1163 |
+
# },
|
1164 |
+
# "in_class": {
|
1165 |
+
# "quiz": [],
|
1166 |
+
# "polls": []
|
1167 |
+
# },
|
1168 |
+
# "post_class": {
|
1169 |
+
# "assignments": []
|
1170 |
+
# },
|
1171 |
+
# "external_resources": st.session_state.resources_map.get(current_topic_title, {})
|
1172 |
+
# }
|
1173 |
+
# all_sessions.append(session)
|
1174 |
+
# current_date = session_date + timedelta(days=7)
|
1175 |
|
1176 |
|
1177 |
+
# new_course_id = get_new_course_id()
|
1178 |
+
# course_title = st.session_state.course_plan['course_title']
|
1179 |
+
|
1180 |
+
# # Final Save Button
|
1181 |
+
# if st.button("Save Course", type="primary", use_container_width=True):
|
1182 |
+
# try:
|
1183 |
+
# course_doc = {
|
1184 |
+
# "course_id": new_course_id,
|
1185 |
+
# "title": course_title,
|
1186 |
+
# "description": st.session_state.course_plan['course_description'],
|
1187 |
+
# "faculty": faculty_name,
|
1188 |
+
# "faculty_id": faculty_id,
|
1189 |
+
# "duration": f"{st.session_state.duration_weeks} weeks",
|
1190 |
+
# "sessions_per_week": st.session_state.sessions_per_week,
|
1191 |
+
# "start_date": datetime.combine(st.session_state.start_date, datetime.min.time()),
|
1192 |
+
# "created_at": datetime.utcnow(),
|
1193 |
+
# "sessions": all_sessions
|
1194 |
+
# }
|
1195 |
|
1196 |
+
# # Insert into database
|
1197 |
+
# courses_collection.insert_one(course_doc)
|
1198 |
+
# st.success("Course successfully created!")
|
1199 |
|
1200 |
+
# # Update faculty collection
|
1201 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1202 |
|
1203 |
+
# # Clear session state
|
1204 |
+
# st.session_state.course_plan = None
|
1205 |
+
# st.session_state.edit_mode = False
|
1206 |
+
# st.session_state.resources_map = {}
|
1207 |
|
1208 |
+
# # Optional: Add a button to view the created course
|
1209 |
+
# if st.button("View Course"):
|
1210 |
+
# # Add navigation logic here
|
1211 |
+
# pass
|
1212 |
|
1213 |
+
# except Exception as e:
|
1214 |
+
# st.error(f"Error saving course: {e}")
|
1215 |
|
1216 |
|
1217 |
|
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
|
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
@@ -154,7 +154,8 @@ def display_preclass_content(session, student_id, course_id):
|
|
154 |
"""Display pre-class materials for a session including external resources"""
|
155 |
st.subheader("Pre-class Materials")
|
156 |
print("Session ID is: ", session['session_id'])
|
157 |
-
|
|
|
158 |
# Display uploaded materials
|
159 |
materials = resources_collection.find({"session_id": session['session_id']})
|
160 |
|
@@ -724,6 +725,7 @@ def display_preclass_content(session, student_id, course_id):
|
|
724 |
if not quiz:
|
725 |
st.info("No practice quizzes created.")
|
726 |
else:
|
|
|
727 |
with st.expander(f"📝 Practice Quiz", expanded=True):
|
728 |
existing_score = get_student_quiz_score(quiz['_id'], student_id)
|
729 |
|
@@ -1282,7 +1284,7 @@ def upload_preclass_materials(session_id, course_id, student_id):
|
|
1282 |
# Display pre-class materials
|
1283 |
# Group resources by their types
|
1284 |
grouped_resources = defaultdict(list)
|
1285 |
-
materials = resources_collection.find({"session_id": session_id})
|
1286 |
for material in materials:
|
1287 |
grouped_resources[material['material_type']].append(material)
|
1288 |
|
@@ -2441,13 +2443,13 @@ def display_in_class_content(session, user_type, course_id, user_id):
|
|
2441 |
|
2442 |
# Display appropriate interface based on user role
|
2443 |
if user_type == 'faculty':
|
2444 |
-
live_polls.display_faculty_interface(session['session_id'])
|
2445 |
else:
|
2446 |
-
live_polls.display_student_interface(session['session_id'])
|
2447 |
|
2448 |
display_live_chat_interface(session, user_id, course_id=course_id)
|
2449 |
|
2450 |
-
# Live Presentation
|
2451 |
display_live_presentation(session, user_type, course_id)
|
2452 |
|
2453 |
def get_current_context(session):
|
@@ -3737,6 +3739,7 @@ def display_quiz_tab(student_id, course_id, session_id):
|
|
3737 |
# "quiz_type": {"$ne": "pre_class"}
|
3738 |
# })
|
3739 |
quizzes = list(quizzes_collection.find({
|
|
|
3740 |
"course_id": course_id,
|
3741 |
"session_id": session_id,
|
3742 |
"status": "active",
|
|
|
154 |
"""Display pre-class materials for a session including external resources"""
|
155 |
st.subheader("Pre-class Materials")
|
156 |
print("Session ID is: ", session['session_id'])
|
157 |
+
print(course_id)
|
158 |
+
|
159 |
# Display uploaded materials
|
160 |
materials = resources_collection.find({"session_id": session['session_id']})
|
161 |
|
|
|
725 |
if not quiz:
|
726 |
st.info("No practice quizzes created.")
|
727 |
else:
|
728 |
+
display_quiz_tab(student_id, course_id, session['session_id'])
|
729 |
with st.expander(f"📝 Practice Quiz", expanded=True):
|
730 |
existing_score = get_student_quiz_score(quiz['_id'], student_id)
|
731 |
|
|
|
1284 |
# Display pre-class materials
|
1285 |
# Group resources by their types
|
1286 |
grouped_resources = defaultdict(list)
|
1287 |
+
materials = resources_collection.find({"session_id": session_id, "course_id": course_id})
|
1288 |
for material in materials:
|
1289 |
grouped_resources[material['material_type']].append(material)
|
1290 |
|
|
|
2443 |
|
2444 |
# Display appropriate interface based on user role
|
2445 |
if user_type == 'faculty':
|
2446 |
+
live_polls.display_faculty_interface(session['session_id'], course_id)
|
2447 |
else:
|
2448 |
+
live_polls.display_student_interface(session['session_id'], course_id)
|
2449 |
|
2450 |
display_live_chat_interface(session, user_id, course_id=course_id)
|
2451 |
|
2452 |
+
# Live Presentation Featurer
|
2453 |
display_live_presentation(session, user_type, course_id)
|
2454 |
|
2455 |
def get_current_context(session):
|
|
|
3739 |
# "quiz_type": {"$ne": "pre_class"}
|
3740 |
# })
|
3741 |
quizzes = list(quizzes_collection.find({
|
3742 |
+
"user_id": ObjectId(student_id),
|
3743 |
"course_id": course_id,
|
3744 |
"session_id": session_id,
|
3745 |
"status": "active",
|