Spaces:
Sleeping
Sleeping
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() | |