Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import os | |
| from models import Model | |
| from prompt import Prompt | |
| from config import Config | |
| from content_generator import generate_notes, generate_quiz | |
| import yt_dlp | |
| import logging | |
| from openai import OpenAI | |
| # Configure logging | |
| logging.basicConfig(level=logging.INFO) | |
| # Initialize OpenAI client | |
| def init_openai_client(): | |
| return OpenAI(api_key=Config.get_openai_api_key()) | |
| client = init_openai_client() | |
| def download_audio(url): | |
| ydl_opts = { | |
| 'format': 'bestaudio/best', | |
| 'postprocessors': [{ | |
| 'key': 'FFmpegExtractAudio', | |
| 'preferredcodec': 'mp3', | |
| 'preferredquality': '192', | |
| }], | |
| 'outtmpl': '%(id)s.%(ext)s', | |
| } | |
| with yt_dlp.YoutubeDL(ydl_opts) as ydl: | |
| info = ydl.extract_info(url, download=True) | |
| return f"{info['id']}.mp3" | |
| def get_transcript_from_file(uploaded_file): | |
| if uploaded_file is not None: | |
| with st.spinner("Transcribing... This may take a few minutes."): | |
| transcript = client.audio.transcriptions.create( | |
| model="whisper-1", | |
| file=uploaded_file | |
| ) | |
| return transcript.text.strip() | |
| return None | |
| def get_transcript_from_url(url): | |
| try: | |
| if url != '': | |
| with st.spinner("Downloading audio..."): | |
| mp3_file = download_audio(url) | |
| file_stats = os.stat(mp3_file) | |
| logging.info(f'Size of audio file in Bytes: {file_stats.st_size}') | |
| if file_stats.st_size <= 25000000: # OpenAI has a 25MB limit | |
| with st.spinner("Transcribing... This may take a few minutes."): | |
| with open(mp3_file, "rb") as audio_file: | |
| try: | |
| transcript = client.audio.transcriptions.create( | |
| model="whisper-1", | |
| file=audio_file | |
| ) | |
| result = transcript.text.strip() | |
| except Exception as api_error: | |
| logging.error(f"API Error: {str(api_error)}") | |
| result = f"API Error: {str(api_error)}" | |
| # Clean up the downloaded file | |
| os.remove(mp3_file) | |
| return result | |
| else: | |
| os.remove(mp3_file) | |
| return "Error: The audio file is too large. Please choose a shorter video (up to ~25MB audio file size)." | |
| except Exception as e: | |
| logging.error(f"An error occurred: {str(e)}") | |
| return f"An error occurred: {str(e)}" | |
| def display_quiz(quiz_content): | |
| st.subheader("Quiz") | |
| with st.form(key='quiz_form'): | |
| user_answers = {} | |
| for i, q in enumerate(quiz_content, 1): | |
| st.write(f"{i}. {q['question']}") | |
| user_answers[i] = st.radio(f"Question {i}", q['options'], key=f"q{i}") | |
| st.write("") | |
| submit_button = st.form_submit_button(label='Submit Quiz') | |
| if submit_button: | |
| score = calculate_score(quiz_content, user_answers) | |
| st.success(f"Your score: {score}/{len(quiz_content)}") | |
| st.session_state.quiz_submitted = True | |
| st.session_state.user_answers = user_answers | |
| st.rerun() # Rerun to update the display | |
| def calculate_score(quiz_content, user_answers): | |
| score = 0 | |
| for i, q in enumerate(quiz_content, 1): | |
| if user_answers[i] == q['correct_answer']: | |
| score += 1 | |
| return score | |
| def show_quiz_results(quiz_content, user_answers): | |
| st.subheader("Quiz Results") | |
| for i, q in enumerate(quiz_content, 1): | |
| st.write(f"{i}. {q['question']}") | |
| user_choice = user_answers.get(i, "Not answered") | |
| correct_answer = q['correct_answer'] | |
| if user_choice == correct_answer: | |
| st.success(f"Your answer: {user_choice} (Correct)") | |
| else: | |
| st.error(f"Your answer: {user_choice}") | |
| st.success(f"Correct answer: {correct_answer}") | |
| st.write("") # Add some space between questions | |
| def main(): | |
| st.title("AI-Powered Teaching Assistant") | |
| # Initialize session state variables | |
| if 'transcript' not in st.session_state: | |
| st.session_state.transcript = None | |
| if 'notes' not in st.session_state: | |
| st.session_state.notes = None | |
| if 'quiz' not in st.session_state: | |
| st.session_state.quiz = None | |
| if 'quiz_submitted' not in st.session_state: | |
| st.session_state.quiz_submitted = False | |
| if 'user_answers' not in st.session_state: | |
| st.session_state.user_answers = None | |
| if 'input_method' not in st.session_state: | |
| st.session_state.input_method = "Upload File" | |
| # Display input method selection | |
| if not st.session_state.quiz_submitted: | |
| st.session_state.input_method = st.radio("Choose input method:", ("Upload File", "YouTube URL")) | |
| else: | |
| st.info("Quiz submitted. Refresh the page to change the input method.") | |
| st.radio("Input method (disabled):", ("Upload File", "YouTube URL"), disabled=True, index=0 if st.session_state.input_method == "Upload File" else 1) | |
| # Handle file upload or YouTube URL input | |
| if st.session_state.input_method == "Upload File": | |
| uploaded_file = st.file_uploader("Choose a file", type=Config.ALLOWED_EXTENSIONS, help="Limit 25MB per file • MP3, MP4, M4A, WAV, WEBM, MPEG, MPGA, MPG, MPEG4") | |
| if uploaded_file is not None: | |
| file_details = {"FileName": uploaded_file.name, "FileType": uploaded_file.type, "FileSize": uploaded_file.size} | |
| st.write(file_details) | |
| if uploaded_file.size <= 25000000: # 25 MB in bytes | |
| if st.button("Process Video"): | |
| st.session_state.transcript = get_transcript_from_file(uploaded_file) | |
| st.rerun() | |
| else: | |
| st.error("File size exceeds 25 MB limit. Please upload a smaller file.") | |
| else: | |
| url = st.text_input("Enter YouTube URL:") | |
| if url: | |
| if st.button("Process Video"): | |
| st.session_state.transcript = get_transcript_from_url(url) | |
| st.rerun() | |
| if st.session_state.transcript: | |
| st.subheader("Transcript") | |
| st.text_area("Generated Transcript", st.session_state.transcript, height=200) | |
| if st.button("Generate Notes and Quiz") or (st.session_state.notes and st.session_state.quiz): | |
| if not st.session_state.notes: | |
| with st.spinner("Generating notes..."): | |
| st.session_state.notes = generate_notes(st.session_state.transcript) | |
| if not st.session_state.quiz: | |
| with st.spinner("Generating quiz..."): | |
| st.session_state.quiz = generate_quiz(st.session_state.transcript) | |
| st.subheader("Generated Notes") | |
| st.markdown(st.session_state.notes) | |
| if not st.session_state.quiz_submitted: | |
| display_quiz(st.session_state.quiz) | |
| else: | |
| show_quiz_results(st.session_state.quiz, st.session_state.user_answers) | |
| st.info("Quiz already submitted. Refresh the page to take the quiz again.") | |
| if __name__ == "__main__": | |
| main() |