from typing import List, Tuple import streamlit as st import os from openai import OpenAI from groq import Groq import openai import os from pytube import YouTube from pathlib import Path import time import fitz # PyMuPDF import moviepy.editor as mp from langchain.chains import RetrievalQA from langchain.chat_models import ChatOpenAI import os import os import queue import re import tempfile import threading import streamlit as st from embedchain import App from embedchain.config import BaseLlmConfig from embedchain.helpers.callbacks import (StreamingStdOutCallbackHandlerYield, generate) st.set_page_config(page_title="Notes Maker", page_icon="📚", layout="wide") client = Groq(api_key="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") client_openai = OpenAI(api_key="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") # Define a function for the login system def login_user(username, password): # Placeholder for actual authentication logic if username == "admin" and password == "qrE8x24sktyUKT": return True else: return False # Function to show the dropdown menu and handle the selection def show_dropdown(user_logged_in): if user_logged_in: options = ["Select Page", "🎥 Notes Maker from Video and Audio", "📚 Notes Generator from PDF"] choice = st.sidebar.selectbox("Choose an option:", options) # Check if a selection has been made and display content accordingly if choice == "🎥 Notes Maker from Video and Audio": youtube_to_notes() elif choice == "📚 Notes Generator from PDF": st.header("Notes Generator from PDF") notes_maker() else: # Message to be displayed if the user is not logged in st.info("Please login to see the options.") # Main app def main(): # Creating a sidebar for login st.sidebar.title("Login") username = st.sidebar.text_input("Username") password = st.sidebar.text_input("Password", type="password") # This session state variable will keep track of whether the user is logged in if 'user_logged_in' not in st.session_state: st.session_state['user_logged_in'] = False if st.sidebar.button("Login"): if login_user(username, password): st.session_state['user_logged_in'] = True st.success(f"You are logged in as {username}") else: st.sidebar.error("Incorrect Username/Password") show_dropdown(st.session_state['user_logged_in']) def youtube_to_notes(): client = openai.Client(api_key="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") # Set your OpenAI Assistant ID here def download_video(url, output_directory): yt = YouTube(url) ys = yt.streams.filter(only_audio=False).first() video_output_path = os.path.join(output_directory, "video.mp4") ys.download(output_path=output_directory, filename="video.mp4") return video_output_path def video_to_mp3(video_path, mp3_path): audio_clip = mp.AudioFileClip(video_path) audio_clip.write_audiofile(mp3_path) # Streamlit UI st.title('Video/Audio to MP3 Converter, Transcriber, and Notes Generator') # Sidebar option for users to upload their own files # Language selection language_options = { "English": "English", "German": "German", "Spanish": "Spanish", "Japanese": "Japanese", "French": "French", "Hindi": "Hindi", "Chinese": "Chinese", # Add other languages and their codes here } language = st.selectbox('Select target Language', options=list(language_options.keys())) input_type = st.radio('Choose input type:', ('YouTube URL', 'Upload Video File', 'Upload Audio File')) if input_type == 'YouTube URL': youtube_url = st.text_input('Enter YouTube Video URL') action = st.button('Download and Convert Video') elif input_type in ['Upload Video File', 'Upload Audio File']: uploaded_file = st.file_uploader("Choose a file", type=['mp4', 'mp3'] if input_type == 'Upload Video File' else ['mp3']) action = st.button('Convert Uploaded File') if action: with st.spinner('Processing...'): output_directory = "downloads" os.makedirs(output_directory, exist_ok=True) if input_type == 'YouTube URL' and youtube_url: video_output_path = download_video(youtube_url, output_directory) elif input_type == 'Upload Video File' and uploaded_file: video_output_path = os.path.join(output_directory, uploaded_file.name) with open(video_output_path, "wb") as f: f.write(uploaded_file.getvalue()) else: st.error("Please enter a YouTube URL or upload a video.") st.stop() mp3_output_path = os.path.join(output_directory, "audio.mp3") video_to_mp3(video_output_path, mp3_output_path) st.success(f"Video converted to MP3: {mp3_output_path}") with open(mp3_output_path, "rb") as audio_file: transcript = client.audio.translations.create( model="whisper-1", prompt="preserve he timestamps and the speaker names if present in the video", file=audio_file, # Use the selected language code ) transcript_text1 = transcript.text transcript_text = transcript.text[:4096] # Adjust according to actual response structure speech_file_path = Path(output_directory) / "speech.mp3" response = client.audio.speech.create( model="tts-1", voice="alloy", # Note: You may need to select the voice based on language input=transcript_text, # Use the selected language code ) response.stream_to_file(str(speech_file_path)) st.audio(str(speech_file_path)) if input_type == 'YouTube URL': st.video(youtube_url) # Download transcript button st.download_button(label="Download Transcript", data=transcript_text1, file_name="transcript.txt", mime='text/plain') # Make the API call within the if block that checks for the button press response = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Make very detailed notes containing all topics mentioned in the video along with important timestamps ut please check teh timestamps and see if by mistake they are longer than the vide itself and if so correct them, and make notes for me about the video also add the necessary mathematical formulas using correct symbols for ex. derivatives, integrals, summations etc. if needed also if teh contentent is about organic chemistry tehn only please give include links to teh 3d molecules along with its name for teh molecules/structures mentioned in teh videoin eth note also if the organic reactions are explained in the video then give all the reaction inthe notes along with if some extra resources are available with the link of them for molecular 3d structure dirctly use this format, the links can be generated for example like: https://embed.molview.org/v1/?mode=balls&cid=124527813 and by just changing teh cid num,ber with teh cid number of teh particular molecule also teh 2d structures can be linked via:https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/benzene/PNG again by chaniging teh name whwnvwer you give links make sure they are clicable for user so formate it coerrctlya also if the video is about the pragraming and computer science weite the codes in the code blocks while writing the notes also in elecrronics buildind a circuit if the codes are given write in block codefor chemical reaqction please format them correctly using all teh necessary correct notationa and it should look like a chemical reaction notation with arrows structural formulas, diagrams , etc, transcript is: " + transcript_text1+ "write the notes in "+ language_options[language] + "Language"}, ] ) notes = response.choices[0].message.content response = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": "this is the notes you made now please check them once agin and confirm it make modification if necessary and please remove any unnecessary non useful part"+notes}, ] ) # Corrected to access the 'content' correctly st.download_button(label="Download Notes", data=notes, file_name="notes.txt", mime='text/plain') st.download_button(label="Download Notes mkd", data=notes, file_name="notes.md", mime='text/plain') def notes_maker(): def _parse_highlight(annot: fitz.Annot, wordlist: List[Tuple[float, float, float, float, str, int, int, int]]) -> str: points = annot.vertices quad_count = int(len(points) / 4) sentences = [] for i in range(quad_count): r = fitz.Quad(points[i * 4: i * 4 + 4]).rect words = [w for w in wordlist if fitz.Rect(w[:4]).intersects(r)] sentences.append(" ".join(w[4] for w in words)) sentence = " ".join(sentences) return sentence def handle_page(page): wordlist = page.get_text("words") wordlist.sort(key=lambda w: (w[3], w[0])) highlights = [] annot = page.first_annot while annot: if annot.type[0] == 8: # Highlight annotation type highlights.append(_parse_highlight(annot, wordlist)) annot = annot.next return highlights, page.get_text("text") def extract_highlights_and_full_text(filepath: str) -> Tuple[List, str]: doc = fitz.open(filepath) highlights = [] full_text = "" for page in doc: page_highlights, page_text = handle_page(page) highlights += page_highlights full_text += page_text + "\n" return highlights, full_text.strip() def generate_notes(text_for_notes, include_problem_solving): base_prompt = "Make properly formatted notes for the text. If there are problem-solving parts, provide schemas and explanations." problem_solving_prompt = " Include detailed problem-solving schemas and explanations for any issues or examples presented." prompt = base_prompt + (problem_solving_prompt if include_problem_solving else "") completion = client.chat.completions.create( model="mixtral-8x7b-32768", messages=[ { "role": "system", "content" : "You are a note makeing assistant make teh notes elaborative, do not keep them very short, also include molecular represantations, chemical equations, mathematical equations or physics notations or codeblocks with code and formatted correctly wherever needed depening on teh content", "role": "user", "content": prompt + " Text: " + text_for_notes, } ], temperature=0.5, max_tokens=1324, top_p=1, stream=False, stop=None, ) notes = completion.choices[0].message.content completion1 = client.chat.completions.create( model="mixtral-8x7b-32768", messages=[ { "role": "user", "content": "these are the notes from step 1 expand them in detiled appropriately and always maintain teh topic structure from teh orginal text if available: " + notes, } ], temperature=0.5, max_tokens=1324, top_p=1, stream=False, stop=None, ) notes = completion1.choices[0].message.content return completion.choices[0].message.content def main(): st.title("PDF Highlight Extractor and Notes Generator with Problem-Solving Schemas") uploaded_file = st.file_uploader("Choose a PDF file", type="pdf") include_problem_solving = st.checkbox("Include problem-solving schemas in the notes", value=False) if uploaded_file is not None and st.button('Generate Notes'): with st.spinner("Processing..."): with open(uploaded_file.name, "wb") as f: f.write(uploaded_file.getbuffer()) highlights, full_text = extract_highlights_and_full_text(uploaded_file.name) os.remove(uploaded_file.name) if highlights: text_for_notes = "\n".join(highlights) else: text_for_notes = full_text # Use full text if no highlights notes = generate_notes(text_for_notes, include_problem_solving) st.download_button(label="Download Notes", data=notes, file_name="notes.txt", mime='text/plain') st.success("Notes generated successfully!") st.text_area("Generated Notes", notes, height=250) if __name__ == "__main__": main() if __name__ == "__main__": main()