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
|