Harshal Vhatkar
commited on
Commit
·
b771940
1
Parent(s):
5d1504a
fix youtube video issue and some minor fixes
Browse files- app.py +70 -0
- live_chat_feature.py +4 -4
- session_page.py +195 -79
- subjective_test_evaluation.py +1 -1
app.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import re
|
|
|
2 |
import streamlit as st
|
3 |
from datetime import datetime, date, time, timedelta
|
4 |
from pathlib import Path
|
@@ -334,6 +335,63 @@ def create_session_form(course_id):
|
|
334 |
# else:
|
335 |
|
336 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
337 |
def get_new_student_id():
|
338 |
"""Generate a new student ID by incrementing the last student ID"""
|
339 |
last_student = students_collection.find_one(sort=[("SID", -1)])
|
@@ -1372,6 +1430,10 @@ def main_dashboard():
|
|
1372 |
use_container_width=True,
|
1373 |
):
|
1374 |
st.session_state.show_create_session_form = True
|
|
|
|
|
|
|
|
|
1375 |
|
1376 |
if st.button("Logout", use_container_width=True):
|
1377 |
for key in st.session_state.keys():
|
@@ -1386,6 +1448,14 @@ def main_dashboard():
|
|
1386 |
create_session_form(selected_course_id)
|
1387 |
elif st.session_state.get("show_enroll_course_page"):
|
1388 |
show_available_courses(st.session_state.username, st.session_state.user_type, st.session_state.user_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1389 |
else:
|
1390 |
# Main content
|
1391 |
if "selected_session" in st.session_state:
|
|
|
1 |
import re
|
2 |
+
from pymongo import MongoClient
|
3 |
import streamlit as st
|
4 |
from datetime import datetime, date, time, timedelta
|
5 |
from pathlib import Path
|
|
|
335 |
# else:
|
336 |
|
337 |
|
338 |
+
load_dotenv()
|
339 |
+
MONGO_URI = os.getenv('MONGO_URI')
|
340 |
+
client = MongoClient(MONGO_URI)
|
341 |
+
db = client["novascholar_db"]
|
342 |
+
subjective_tests_collection = db["subjective_tests"]
|
343 |
+
resources_collection = db['resources']
|
344 |
+
quizzes_collection = db['quizzes']
|
345 |
+
chat_history_collection = db['chat_history']
|
346 |
+
polls_collection = db['polls']
|
347 |
+
|
348 |
+
|
349 |
+
|
350 |
+
def delete_session(course_id: str, session_id: str) -> bool:
|
351 |
+
"""Delete a session and all its associated data"""
|
352 |
+
try:
|
353 |
+
# Delete all resources for this session
|
354 |
+
resources_collection.delete_many({
|
355 |
+
"course_id": course_id,
|
356 |
+
"session_id": session_id
|
357 |
+
})
|
358 |
+
|
359 |
+
# Delete all quizzes for this session
|
360 |
+
quizzes_collection.delete_many({
|
361 |
+
"course_id": course_id,
|
362 |
+
"session_id": session_id
|
363 |
+
})
|
364 |
+
|
365 |
+
# Delete all subjective tests
|
366 |
+
subjective_tests_collection.delete_many({
|
367 |
+
"course_id": course_id,
|
368 |
+
"session_id": session_id
|
369 |
+
})
|
370 |
+
|
371 |
+
# Delete chat history
|
372 |
+
chat_history_collection.delete_many({
|
373 |
+
"course_id": course_id,
|
374 |
+
"session_id": session_id
|
375 |
+
})
|
376 |
+
|
377 |
+
# Delete session polls
|
378 |
+
polls_collection.delete_many({
|
379 |
+
"course_id": course_id,
|
380 |
+
"session_id": session_id
|
381 |
+
})
|
382 |
+
|
383 |
+
# Finally remove session from course
|
384 |
+
result = courses_collection.update_one(
|
385 |
+
{"course_id": course_id},
|
386 |
+
{"$pull": {"sessions": {"session_id": session_id}}}
|
387 |
+
)
|
388 |
+
|
389 |
+
return result.modified_count > 0
|
390 |
+
|
391 |
+
except Exception as e:
|
392 |
+
print(f"Error deleting session: {e}")
|
393 |
+
return False
|
394 |
+
|
395 |
def get_new_student_id():
|
396 |
"""Generate a new student ID by incrementing the last student ID"""
|
397 |
last_student = students_collection.find_one(sort=[("SID", -1)])
|
|
|
1430 |
use_container_width=True,
|
1431 |
):
|
1432 |
st.session_state.show_create_session_form = True
|
1433 |
+
|
1434 |
+
if st.button("Delete a Session", key="delete_session", use_container_width=True):
|
1435 |
+
# session_id = st.text_input("Enter the Session ID to delete")
|
1436 |
+
st.session_state.show_delete_session_form = True
|
1437 |
|
1438 |
if st.button("Logout", use_container_width=True):
|
1439 |
for key in st.session_state.keys():
|
|
|
1448 |
create_session_form(selected_course_id)
|
1449 |
elif st.session_state.get("show_enroll_course_page"):
|
1450 |
show_available_courses(st.session_state.username, st.session_state.user_type, st.session_state.user_id)
|
1451 |
+
elif st.session_state.get("show_delete_session_form"):
|
1452 |
+
session_options = [f"{session['title']} (ID: {session['session_id']})" for session in sessions]
|
1453 |
+
session_id = st.selectbox("Select Session to Delete", session_options)
|
1454 |
+
session_id = session_id.split(" (ID: ")[-1][:-1]
|
1455 |
+
if st.button("Delete Session"):
|
1456 |
+
if delete_session(selected_course_id, session_id):
|
1457 |
+
st.success(f"Session {session_id} deleted successfully!")
|
1458 |
+
st.rerun()
|
1459 |
else:
|
1460 |
# Main content
|
1461 |
if "selected_session" in st.session_state:
|
live_chat_feature.py
CHANGED
@@ -20,7 +20,7 @@ model = genai.GenerativeModel("gemini-1.5-flash")
|
|
20 |
def display_live_chat_interface(session, user_id, course_id):
|
21 |
"""Main interface for live chat sessions - handles both faculty and student views"""
|
22 |
st.markdown("<div style='margin-top: 20px;'></div>", unsafe_allow_html=True)
|
23 |
-
st.markdown("####
|
24 |
|
25 |
# Initialize session states
|
26 |
if 'chat_active' not in st.session_state:
|
@@ -229,14 +229,14 @@ def display_faculty_controls(session, faculty_id, course_id):
|
|
229 |
|
230 |
# Show scheduled sessions
|
231 |
st.markdown("<div style='margin-top: 20px;'></div>", unsafe_allow_html=True)
|
232 |
-
st.markdown("##### 📅 Scheduled
|
233 |
scheduled_sessions = list(live_chat_sessions_collection.find({
|
234 |
"session_id": session['session_id'],
|
235 |
"status": "scheduled"
|
236 |
}))
|
237 |
|
238 |
# Schedule new session
|
239 |
-
with st.expander("➕ Schedule New
|
240 |
col1, col2, col3 = st.columns([2, 2, 1])
|
241 |
with col1:
|
242 |
session_date = st.date_input("📅 Date", min_value=datetime.now().date())
|
@@ -279,7 +279,7 @@ def display_faculty_controls(session, faculty_id, course_id):
|
|
279 |
# Start immediate session
|
280 |
if not st.session_state.get('chat_active', False):
|
281 |
st.markdown("<div style='margin-top: 20px;'></div>", unsafe_allow_html=True)
|
282 |
-
st.markdown("##### 🎯 Start Immediate Session")
|
283 |
col1, col2 = st.columns([3, 1])
|
284 |
with col1:
|
285 |
immediate_duration = st.selectbox(
|
|
|
20 |
def display_live_chat_interface(session, user_id, course_id):
|
21 |
"""Main interface for live chat sessions - handles both faculty and student views"""
|
22 |
st.markdown("<div style='margin-top: 20px;'></div>", unsafe_allow_html=True)
|
23 |
+
st.markdown("#### In-class Chatbot Session")
|
24 |
|
25 |
# Initialize session states
|
26 |
if 'chat_active' not in st.session_state:
|
|
|
229 |
|
230 |
# Show scheduled sessions
|
231 |
st.markdown("<div style='margin-top: 20px;'></div>", unsafe_allow_html=True)
|
232 |
+
st.markdown("##### 📅 Scheduled Chatbot Sessions")
|
233 |
scheduled_sessions = list(live_chat_sessions_collection.find({
|
234 |
"session_id": session['session_id'],
|
235 |
"status": "scheduled"
|
236 |
}))
|
237 |
|
238 |
# Schedule new session
|
239 |
+
with st.expander("➕ Schedule New Chatbot Session"):
|
240 |
col1, col2, col3 = st.columns([2, 2, 1])
|
241 |
with col1:
|
242 |
session_date = st.date_input("📅 Date", min_value=datetime.now().date())
|
|
|
279 |
# Start immediate session
|
280 |
if not st.session_state.get('chat_active', False):
|
281 |
st.markdown("<div style='margin-top: 20px;'></div>", unsafe_allow_html=True)
|
282 |
+
st.markdown("##### 🎯 Start an Immediate Session")
|
283 |
col1, col2 = st.columns([3, 1])
|
284 |
with col1:
|
285 |
immediate_duration = st.selectbox(
|
session_page.py
CHANGED
@@ -5,6 +5,7 @@ import requests
|
|
5 |
import streamlit as st
|
6 |
from datetime import datetime, timedelta
|
7 |
from youtube_transcript_api import YouTubeTranscriptApi
|
|
|
8 |
from session_page_alt import display_pre_test_results, pre_generate_questions, pre_save_subjective_test, submit_pre_subjective_test
|
9 |
from utils.helpers import display_progress_bar, create_notification, format_datetime
|
10 |
from file_upload_vectorize import upload_resource, extract_text_from_file, create_vector_store, resources_collection, model, assignment_submit
|
@@ -1139,7 +1140,7 @@ def fetch_youtube_video_title(video_url):
|
|
1139 |
st.write("Please try again or choose a different video.")
|
1140 |
return None
|
1141 |
|
1142 |
-
def upload_video_source(course_id, session_id, video_url):
|
1143 |
"""
|
1144 |
Upload video source and its transcript with comprehensive error handling
|
1145 |
"""
|
@@ -1151,6 +1152,7 @@ def upload_video_source(course_id, session_id, video_url):
|
|
1151 |
# Display processing message
|
1152 |
# with st.spinner("Processing your YouTube video..."):
|
1153 |
# Validate video URL
|
|
|
1154 |
video_id = extract_youtube_id(video_url)
|
1155 |
if not video_id:
|
1156 |
return None
|
@@ -1161,10 +1163,16 @@ def upload_video_source(course_id, session_id, video_url):
|
|
1161 |
return None
|
1162 |
|
1163 |
# Extract transcript
|
1164 |
-
transcript = extract_youtube_transcript(video_url)
|
1165 |
-
if not transcript:
|
1166 |
-
|
1167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1168 |
# Create resource document
|
1169 |
resource_data = {
|
1170 |
"_id": ObjectId(),
|
@@ -1172,7 +1180,7 @@ def upload_video_source(course_id, session_id, video_url):
|
|
1172 |
"session_id": session_id,
|
1173 |
"file_name": video_title,
|
1174 |
"file_type": "video",
|
1175 |
-
"text_content":
|
1176 |
"material_type": "video",
|
1177 |
"source_url": video_url,
|
1178 |
"uploaded_at": datetime.utcnow(),
|
@@ -1229,7 +1237,7 @@ def upload_video_source(course_id, session_id, video_url):
|
|
1229 |
# Create vector store for the transcript
|
1230 |
# create_vector_store(transcript, resource_id)
|
1231 |
# Create vector store for the transcript
|
1232 |
-
vector_store_result = create_vector_store(
|
1233 |
if not vector_store_result:
|
1234 |
st.error("⚠️ Failed to create vector store for the transcript.")
|
1235 |
# Rollback insertions
|
@@ -1258,14 +1266,83 @@ def upload_video_source(course_id, session_id, video_url):
|
|
1258 |
3. Contact support if the issue persists
|
1259 |
""")
|
1260 |
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1261 |
|
1262 |
-
def upload_preclass_materials(session_id, course_id, student_id):
|
1263 |
"""Upload pre-class materials and manage external resources for a session"""
|
1264 |
st.subheader("Pre-class Materials Management")
|
1265 |
|
1266 |
# Create tabs for different functionalities
|
1267 |
-
upload_tab, videos_tab, web_resources
|
1268 |
|
|
|
|
|
1269 |
with upload_tab:
|
1270 |
# Original file upload functionality
|
1271 |
uploaded_file = st.file_uploader("Upload Material", type=['txt', 'pdf', 'docx'])
|
@@ -1298,12 +1375,52 @@ def upload_preclass_materials(session_id, course_id, student_id):
|
|
1298 |
with videos_tab:
|
1299 |
# Upload video sources
|
1300 |
st.info("Upload video sources for this session.")
|
1301 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1302 |
if st.button("Upload Video"):
|
1303 |
-
|
1304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1305 |
# if video_resource_id:
|
1306 |
# st.success("Video source uploaded successfully!")
|
|
|
|
|
1307 |
|
1308 |
with web_resources:
|
1309 |
st.markdown("##### Upload Web Resource Links")
|
@@ -1324,8 +1441,8 @@ def upload_preclass_materials(session_id, course_id, student_id):
|
|
1324 |
placeholder="https://colab.research.google.com/... or other web resource")
|
1325 |
resource_type = st.selectbox("Resource Type",
|
1326 |
["Jupyter Notebook", "Presentation", "Documentation", "Tutorial", "Other"])
|
1327 |
-
|
1328 |
-
placeholder="Brief
|
1329 |
|
1330 |
submit_resource = st.form_submit_button("Add Resource")
|
1331 |
|
@@ -1343,12 +1460,13 @@ def upload_preclass_materials(session_id, course_id, student_id):
|
|
1343 |
"file_type": "web_resource",
|
1344 |
"material_type": resource_type,
|
1345 |
"source_url": resource_url,
|
1346 |
-
"
|
1347 |
"uploaded_at": datetime.utcnow()
|
1348 |
}
|
1349 |
|
1350 |
# Check if resource already exists
|
1351 |
existing_resource = resources_collection.find_one({
|
|
|
1352 |
"session_id": session_id,
|
1353 |
"source_url": resource_url
|
1354 |
})
|
@@ -1374,67 +1492,65 @@ def upload_preclass_materials(session_id, course_id, student_id):
|
|
1374 |
except Exception as e:
|
1375 |
st.error(f"Error adding resource: {str(e)}")
|
1376 |
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
{"sessions.$": 1}
|
1384 |
-
)
|
1385 |
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
|
1434 |
with pre_class_tab:
|
1435 |
if st.session_state.user_type == "faculty":
|
1436 |
faculty_id = st.session_state.user_id
|
1437 |
-
st.
|
1438 |
|
1439 |
# Create a form for test generation
|
1440 |
with st.form("pre_create_subjective_test_form"):
|
@@ -2172,8 +2288,8 @@ def display_session_outline(session, outline, course_id):
|
|
2172 |
# st.markdown("**Materials Needed:**")
|
2173 |
# for material in activity["materials_needed"]:
|
2174 |
# st.markdown(f"- {material}")
|
2175 |
-
st.markdown("#### 📋
|
2176 |
-
with st.expander("View
|
2177 |
# Opening Activities Section
|
2178 |
# st.markdown('<div class="session-section">', unsafe_allow_html=True)
|
2179 |
st.markdown("<div style='margin-top: 10px;'></div>", unsafe_allow_html=True)
|
@@ -2310,7 +2426,7 @@ def display_in_class_content(session, user_type, course_id, user_id):
|
|
2310 |
# st.write("Found existing session outline")
|
2311 |
st.session_state.session_outline = stored_outline
|
2312 |
else:
|
2313 |
-
|
2314 |
st.session_state.session_outline = None
|
2315 |
|
2316 |
except Exception as e:
|
@@ -2320,9 +2436,9 @@ def display_in_class_content(session, user_type, course_id, user_id):
|
|
2320 |
if user_type == 'faculty':
|
2321 |
# st.markdown("<div style='margin-top: 10px;'></div>", unsafe_allow_html=True)
|
2322 |
if not st.session_state.session_outline:
|
2323 |
-
st.markdown("####
|
2324 |
-
if st.button("Generate a
|
2325 |
-
with st.spinner("Generating
|
2326 |
outline = generate_session_outline(session['session_id'], course_id)
|
2327 |
if outline:
|
2328 |
display_session_outline(session, outline, course_id)
|
@@ -3038,15 +3154,15 @@ def get_response_from_llm(raw_data):
|
|
3038 |
return None
|
3039 |
|
3040 |
import typing_extensions as typing
|
3041 |
-
from typing import Union, List, Dict
|
3042 |
|
3043 |
# class Topics(typing.TypedDict):
|
3044 |
# overarching_theme: List[Dict[str, Union[str, List[Dict[str, Union[str, List[str]]]]]]]
|
3045 |
# indirect_topics: List[Dict[str, str]]
|
3046 |
|
3047 |
-
def extract_topics_from_materials(session):
|
3048 |
"""Extract topics from pre-class materials"""
|
3049 |
-
materials = resources_collection.find({"session_id": session['session_id']})
|
3050 |
texts = ""
|
3051 |
if materials:
|
3052 |
for material in materials:
|
@@ -3224,7 +3340,7 @@ def get_preclass_analytics(session, course_id):
|
|
3224 |
print("Total chat histories collected:", len(all_chat_histories))
|
3225 |
|
3226 |
# Extract topics with debug print
|
3227 |
-
topics = extract_topics_from_materials(session)
|
3228 |
# Debug print 5: Check topics
|
3229 |
print("Extracted topics:", topics)
|
3230 |
|
@@ -3914,7 +4030,7 @@ def display_session_content(student_id, course_id, session, username, user_type)
|
|
3914 |
"Evaluate Subjective Tests"
|
3915 |
])
|
3916 |
with tabs[0]:
|
3917 |
-
upload_preclass_materials(session['session_id'], course_id, student_id)
|
3918 |
with tabs[1]:
|
3919 |
display_in_class_content(session, user_type, course_id, user_type)
|
3920 |
with tabs[2]:
|
|
|
5 |
import streamlit as st
|
6 |
from datetime import datetime, timedelta
|
7 |
from youtube_transcript_api import YouTubeTranscriptApi
|
8 |
+
# from process_yt_videos import process_youtube_video
|
9 |
from session_page_alt import display_pre_test_results, pre_generate_questions, pre_save_subjective_test, submit_pre_subjective_test
|
10 |
from utils.helpers import display_progress_bar, create_notification, format_datetime
|
11 |
from file_upload_vectorize import upload_resource, extract_text_from_file, create_vector_store, resources_collection, model, assignment_submit
|
|
|
1140 |
st.write("Please try again or choose a different video.")
|
1141 |
return None
|
1142 |
|
1143 |
+
def upload_video_source(course_id, session_id, video_url, video_transcript):
|
1144 |
"""
|
1145 |
Upload video source and its transcript with comprehensive error handling
|
1146 |
"""
|
|
|
1152 |
# Display processing message
|
1153 |
# with st.spinner("Processing your YouTube video..."):
|
1154 |
# Validate video URL
|
1155 |
+
|
1156 |
video_id = extract_youtube_id(video_url)
|
1157 |
if not video_id:
|
1158 |
return None
|
|
|
1163 |
return None
|
1164 |
|
1165 |
# Extract transcript
|
1166 |
+
# transcript = extract_youtube_transcript(video_url)
|
1167 |
+
# if not transcript:
|
1168 |
+
# return None
|
1169 |
+
# transcript_data = extract_youtube_transcript2(video_url)
|
1170 |
+
# if not transcript_data:
|
1171 |
+
# return None
|
1172 |
+
# print(transcript_data)
|
1173 |
+
# transcript = transcript_data['full_text']
|
1174 |
+
# print(transcript)
|
1175 |
+
|
1176 |
# Create resource document
|
1177 |
resource_data = {
|
1178 |
"_id": ObjectId(),
|
|
|
1180 |
"session_id": session_id,
|
1181 |
"file_name": video_title,
|
1182 |
"file_type": "video",
|
1183 |
+
"text_content": video_transcript,
|
1184 |
"material_type": "video",
|
1185 |
"source_url": video_url,
|
1186 |
"uploaded_at": datetime.utcnow(),
|
|
|
1237 |
# Create vector store for the transcript
|
1238 |
# create_vector_store(transcript, resource_id)
|
1239 |
# Create vector store for the transcript
|
1240 |
+
vector_store_result = create_vector_store(video_transcript, resource_id)
|
1241 |
if not vector_store_result:
|
1242 |
st.error("⚠️ Failed to create vector store for the transcript.")
|
1243 |
# Rollback insertions
|
|
|
1266 |
3. Contact support if the issue persists
|
1267 |
""")
|
1268 |
return None
|
1269 |
+
|
1270 |
+
|
1271 |
+
# def upload_video_source(course_id: str, session_id: str, video_url: str):
|
1272 |
+
# """Upload video source with transcript."""
|
1273 |
+
# if not video_url:
|
1274 |
+
# st.error("Please provide a YouTube URL")
|
1275 |
+
# return None
|
1276 |
+
|
1277 |
+
# with st.spinner("Processing video..."):
|
1278 |
+
# resource_data = process_youtube_video(video_url, course_id, session_id)
|
1279 |
+
|
1280 |
+
# if resource_data:
|
1281 |
+
# try:
|
1282 |
+
# # Insert into your database
|
1283 |
+
# result = resources_collection.insert_one(resource_data)
|
1284 |
+
|
1285 |
+
# # Update course document
|
1286 |
+
# courses_collection.update_one(
|
1287 |
+
# {
|
1288 |
+
# "course_id": course_id,
|
1289 |
+
# "sessions.session_id": session_id
|
1290 |
+
# },
|
1291 |
+
# {
|
1292 |
+
# "$push": {"sessions.$.pre_class.resources": result.inserted_id}
|
1293 |
+
# }
|
1294 |
+
# )
|
1295 |
+
|
1296 |
+
# st.success(f"✅ Successfully added: {resource_data['file_name']}")
|
1297 |
+
# return result.inserted_id
|
1298 |
+
|
1299 |
+
# except Exception as e:
|
1300 |
+
# st.error(f"Error saving to database: {str(e)}")
|
1301 |
+
# return None
|
1302 |
+
|
1303 |
+
# return None
|
1304 |
+
# def upload_video_source(course_id: str, session_id: str, video_url: str, video_transcript: str):
|
1305 |
+
# """Upload video source with transcript."""
|
1306 |
+
# if not video_url:
|
1307 |
+
# st.error("Please provide a YouTube URL")
|
1308 |
+
# return None
|
1309 |
+
|
1310 |
+
# with st.spinner("Processing video..."):
|
1311 |
+
# # resource_data = process_youtube_video(video_url, course_id, session_id)
|
1312 |
+
# # if resource_data:
|
1313 |
+
# try:
|
1314 |
+
# # Insert into your database
|
1315 |
+
# result = resources_collection.insert_one(resource_data)
|
1316 |
+
|
1317 |
+
# # Update course document
|
1318 |
+
# courses_collection.update_one(
|
1319 |
+
# {
|
1320 |
+
# "course_id": course_id,
|
1321 |
+
# "sessions.session_id": session_id
|
1322 |
+
# },
|
1323 |
+
# {
|
1324 |
+
# "$push": {"sessions.$.pre_class.resources": result.inserted_id}
|
1325 |
+
# }
|
1326 |
+
# )
|
1327 |
+
|
1328 |
+
# st.success(f"✅ Successfully added: {resource_data['file_name']}")
|
1329 |
+
# return result.inserted_id
|
1330 |
+
|
1331 |
+
# except Exception as e:
|
1332 |
+
# st.error(f"Error saving to database: {str(e)}")
|
1333 |
+
# return None
|
1334 |
+
|
1335 |
+
# return None
|
1336 |
|
1337 |
+
def upload_preclass_materials(session, session_id, course_id, student_id):
|
1338 |
"""Upload pre-class materials and manage external resources for a session"""
|
1339 |
st.subheader("Pre-class Materials Management")
|
1340 |
|
1341 |
# Create tabs for different functionalities
|
1342 |
+
# upload_tab, videos_tab, web_resources, pre_class_tab, pre_class_evaluate, pre_class_quiz = st.tabs(["Upload Materials","Upload Video Sources","Web Resources", "Pre-class Questions", "Pre-class Evaluation", "Pre-class Quiz"])
|
1343 |
|
1344 |
+
pre_class_quiz, pre_class_tab, pre_class_evaluate, upload_tab, videos_tab, web_resources = st.tabs(["Pre-class Quiz", "Pre-class Subjective Questions", "Subjective Questions Evaluation", "Upload Materials", "Upload Video Sources", "Web Resources"])
|
1345 |
+
|
1346 |
with upload_tab:
|
1347 |
# Original file upload functionality
|
1348 |
uploaded_file = st.file_uploader("Upload Material", type=['txt', 'pdf', 'docx'])
|
|
|
1375 |
with videos_tab:
|
1376 |
# Upload video sources
|
1377 |
st.info("Upload video sources for this session.")
|
1378 |
+
|
1379 |
+
# Add URL input and transcript guide
|
1380 |
+
col1, col2 = st.columns([1,1])
|
1381 |
+
|
1382 |
+
with col1:
|
1383 |
+
video_url = st.text_input("Enter a YouTube Video URL")
|
1384 |
+
|
1385 |
+
with col2:
|
1386 |
+
st.markdown("##### How to Get Video Transcript")
|
1387 |
+
st.markdown("""
|
1388 |
+
1. Visit [tactiq.io Transcript Tool](https://tactiq.io/tools/youtube-transcript)
|
1389 |
+
2. In the input field, paste your YouTube video URL
|
1390 |
+
3. Click on "Get Video Transcript" button
|
1391 |
+
4. When transcript appears, click "Copy" button
|
1392 |
+
5. Return here and paste the transcript below
|
1393 |
+
""")
|
1394 |
+
|
1395 |
+
# Add transcript input with clear instructions
|
1396 |
+
st.markdown("##### Paste Video Transcript")
|
1397 |
+
st.info("For the chatbot context, please provide the video transcript")
|
1398 |
+
video_transcript = st.text_area(
|
1399 |
+
"Video Transcript",
|
1400 |
+
height=200,
|
1401 |
+
placeholder="Paste the copied transcript from tactiq.io here..."
|
1402 |
+
)
|
1403 |
+
|
1404 |
+
# Add upload button
|
1405 |
if st.button("Upload Video"):
|
1406 |
+
if not video_url:
|
1407 |
+
st.error("Please provide a YouTube video URL")
|
1408 |
+
else:
|
1409 |
+
with st.spinner("Processing video source..."):
|
1410 |
+
video_resource_id = upload_video_source(course_id, session_id, video_url, video_transcript)
|
1411 |
+
|
1412 |
+
# with videos_tab:
|
1413 |
+
# # Upload video sources
|
1414 |
+
# st.info("Upload video sources for this session.")
|
1415 |
+
# video_url = st.text_input("Enter a Youtube Video URL")
|
1416 |
+
# video_transcript = st.text_area("Please paste the Youtube Video Transcript", height=200)
|
1417 |
+
# if st.button("Upload Video"):
|
1418 |
+
# with st.spinner("Processing video source..."):
|
1419 |
+
# video_resource_id = upload_video_source(course_id, session_id, video_url)
|
1420 |
# if video_resource_id:
|
1421 |
# st.success("Video source uploaded successfully!")
|
1422 |
+
|
1423 |
+
|
1424 |
|
1425 |
with web_resources:
|
1426 |
st.markdown("##### Upload Web Resource Links")
|
|
|
1441 |
placeholder="https://colab.research.google.com/... or other web resource")
|
1442 |
resource_type = st.selectbox("Resource Type",
|
1443 |
["Jupyter Notebook", "Presentation", "Documentation", "Tutorial", "Other"])
|
1444 |
+
text_content = st.text_area("Text Content (for Chatbot)",
|
1445 |
+
placeholder="Brief text content for the resource")
|
1446 |
|
1447 |
submit_resource = st.form_submit_button("Add Resource")
|
1448 |
|
|
|
1460 |
"file_type": "web_resource",
|
1461 |
"material_type": resource_type,
|
1462 |
"source_url": resource_url,
|
1463 |
+
"text_content": text_content,
|
1464 |
"uploaded_at": datetime.utcnow()
|
1465 |
}
|
1466 |
|
1467 |
# Check if resource already exists
|
1468 |
existing_resource = resources_collection.find_one({
|
1469 |
+
"course_id": course_id,
|
1470 |
"session_id": session_id,
|
1471 |
"source_url": resource_url
|
1472 |
})
|
|
|
1492 |
except Exception as e:
|
1493 |
st.error(f"Error adding resource: {str(e)}")
|
1494 |
|
1495 |
+
# with external_tab:
|
1496 |
+
# # Fetch and display external resources
|
1497 |
+
# session_data = courses_collection.find_one(
|
1498 |
+
# {"course_id": course_id, "sessions.session_id": session_id},
|
1499 |
+
# {"sessions.$": 1}
|
1500 |
+
# )
|
|
|
|
|
1501 |
|
1502 |
+
# if session_data and session_data.get('sessions'):
|
1503 |
+
# session = session_data['sessions'][0]
|
1504 |
+
# external = session.get('external_resources', {})
|
1505 |
|
1506 |
+
# # Display web articles
|
1507 |
+
# if 'readings' in external:
|
1508 |
+
# st.subheader("Web Articles and Videos")
|
1509 |
+
# for reading in external['readings']:
|
1510 |
+
# col1, col2 = st.columns([3, 1])
|
1511 |
+
# with col1:
|
1512 |
+
# st.markdown(f"**{reading['title']}**")
|
1513 |
+
# st.markdown(f"Type: {reading['type']} | Est. time: {reading['estimated_read_time']}")
|
1514 |
+
# st.markdown(f"URL: [{reading['url']}]({reading['url']})")
|
1515 |
+
# with col2:
|
1516 |
+
# if st.button("Extract Content", key=f"extract_{reading['url']}"):
|
1517 |
+
# with st.spinner("Extracting content..."):
|
1518 |
+
# content = extract_external_content(reading['url'], reading['type'])
|
1519 |
+
# if content:
|
1520 |
+
# resource_id = upload_external_resource(
|
1521 |
+
# course_id,
|
1522 |
+
# session_id,
|
1523 |
+
# reading['title'],
|
1524 |
+
# content,
|
1525 |
+
# reading['type'].lower(),
|
1526 |
+
# reading['url']
|
1527 |
+
# )
|
1528 |
+
# st.success("Content extracted and stored successfully!")
|
1529 |
|
1530 |
+
# # Display books
|
1531 |
+
# if 'books' in external:
|
1532 |
+
# st.subheader("Recommended Books")
|
1533 |
+
# for book in external['books']:
|
1534 |
+
# st.markdown(f"""
|
1535 |
+
# **{book['title']}** by {book['author']}
|
1536 |
+
# - ISBN: {book['isbn']}
|
1537 |
+
# - Chapters: {book['chapters']}
|
1538 |
+
# """)
|
1539 |
|
1540 |
+
# # Display additional resources
|
1541 |
+
# if 'additional_resources' in external:
|
1542 |
+
# st.subheader("Additional Resources")
|
1543 |
+
# for resource in external['additional_resources']:
|
1544 |
+
# st.markdown(f"""
|
1545 |
+
# **{resource['title']}** ({resource['type']})
|
1546 |
+
# - {resource['description']}
|
1547 |
+
# - URL: [{resource['url']}]({resource['url']})
|
1548 |
+
# """)
|
1549 |
|
1550 |
with pre_class_tab:
|
1551 |
if st.session_state.user_type == "faculty":
|
1552 |
faculty_id = st.session_state.user_id
|
1553 |
+
st.markdown("#### Create Pre-class Subjective Questions")
|
1554 |
|
1555 |
# Create a form for test generation
|
1556 |
with st.form("pre_create_subjective_test_form"):
|
|
|
2288 |
# st.markdown("**Materials Needed:**")
|
2289 |
# for material in activity["materials_needed"]:
|
2290 |
# st.markdown(f"- {material}")
|
2291 |
+
st.markdown("#### 📋 Teaching Strategy")
|
2292 |
+
with st.expander("View Teaching Strategy"):
|
2293 |
# Opening Activities Section
|
2294 |
# st.markdown('<div class="session-section">', unsafe_allow_html=True)
|
2295 |
st.markdown("<div style='margin-top: 10px;'></div>", unsafe_allow_html=True)
|
|
|
2426 |
# st.write("Found existing session outline")
|
2427 |
st.session_state.session_outline = stored_outline
|
2428 |
else:
|
2429 |
+
print("No existing session outline found")
|
2430 |
st.session_state.session_outline = None
|
2431 |
|
2432 |
except Exception as e:
|
|
|
2436 |
if user_type == 'faculty':
|
2437 |
# st.markdown("<div style='margin-top: 10px;'></div>", unsafe_allow_html=True)
|
2438 |
if not st.session_state.session_outline:
|
2439 |
+
st.markdown("#### 📋 Teaching Strategy")
|
2440 |
+
if st.button("Generate a Teaching Strategy"):
|
2441 |
+
with st.spinner("Generating the Teaching Strategy..."):
|
2442 |
outline = generate_session_outline(session['session_id'], course_id)
|
2443 |
if outline:
|
2444 |
display_session_outline(session, outline, course_id)
|
|
|
3154 |
return None
|
3155 |
|
3156 |
import typing_extensions as typing
|
3157 |
+
from typing import Optional, Union, List, Dict
|
3158 |
|
3159 |
# class Topics(typing.TypedDict):
|
3160 |
# overarching_theme: List[Dict[str, Union[str, List[Dict[str, Union[str, List[str]]]]]]]
|
3161 |
# indirect_topics: List[Dict[str, str]]
|
3162 |
|
3163 |
+
def extract_topics_from_materials(course_id, session):
|
3164 |
"""Extract topics from pre-class materials"""
|
3165 |
+
materials = resources_collection.find({"session_id": session['session_id'], "course_id": course_id})
|
3166 |
texts = ""
|
3167 |
if materials:
|
3168 |
for material in materials:
|
|
|
3340 |
print("Total chat histories collected:", len(all_chat_histories))
|
3341 |
|
3342 |
# Extract topics with debug print
|
3343 |
+
topics = extract_topics_from_materials(course_id, session)
|
3344 |
# Debug print 5: Check topics
|
3345 |
print("Extracted topics:", topics)
|
3346 |
|
|
|
4030 |
"Evaluate Subjective Tests"
|
4031 |
])
|
4032 |
with tabs[0]:
|
4033 |
+
upload_preclass_materials(session, session['session_id'], course_id, student_id)
|
4034 |
with tabs[1]:
|
4035 |
display_in_class_content(session, user_type, course_id, user_type)
|
4036 |
with tabs[2]:
|
subjective_test_evaluation.py
CHANGED
@@ -659,7 +659,7 @@ def pre_display_evaluation_to_faculty(session_id, student_id, course_id):
|
|
659 |
"""
|
660 |
Display interface for faculty to generate and view evaluations
|
661 |
"""
|
662 |
-
st.
|
663 |
|
664 |
try:
|
665 |
# Fetch available tests
|
|
|
659 |
"""
|
660 |
Display interface for faculty to generate and view evaluations
|
661 |
"""
|
662 |
+
st.markdown("#### Evaluate Pre-class Subjective Questions")
|
663 |
|
664 |
try:
|
665 |
# Fetch available tests
|