Skip to content

Commit ec7622f

Browse files
authored
Merge pull request #196 from sudoleg/develop
minor improvements
2 parents 8f96d1d + 7d8d328 commit ec7622f

File tree

6 files changed

+108
-72
lines changed

6 files changed

+108
-72
lines changed

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ YouTubeGPT lets you **summarize and chat (Q&A)** with YouTube videos. Its featur
1010

1111
- **provide a custom prompt for summaries** :writing_hand: [**VIEW DEMO**](https://youtu.be/rJqx3qvebws)
1212
- you can tailor the summary to your needs by providing a custom prompt or just use the default summarization
13-
- **automatically save summaries** :open_file_folder:
14-
- the summaries can be automatically saved in the directory where you run the app. The summaries will be available under `<YT-channel-name>/<video-title>.md`
1513
- **get answers to questions about the video content** :question: [**VIEW DEMO**](https://youtu.be/rI8NogvHplE)
1614
- part of the application is designed and optimized specifically for question answering tasks (Q&A)
17-
- **create your own knowledge base** :floppy_disk:
18-
- once a video is processed, you can chat with it at any time!
15+
- **create your own library/knowledge base** :open_file_folder:
16+
- the summaries and answers can be saved to a library accessible at a separate page!
17+
- additionally, summaries can be automatically saved in the directory where you run the app. The summaries will be available under `<YT-channel-name>/<video-title>.md`
1918
- **choose from different OpenAI models** :robot:
2019
- currently available: gpt-3.5-turbo, gpt-4 (turbo), gpt-4o (mini)
2120
- by choosing a different model, you can summarize even longer videos and potentially get better responses

modules/persistance.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,9 @@ def save_library_entry(
117117

118118
def delete_library_entry(lib_entry: LibraryEntry):
119119
"""Deletes a library entry."""
120-
LibraryEntry.delete_by_id(lib_entry)
121-
logging.info("Deleted library entry for video '%s'", lib_entry.video.title)
120+
try:
121+
LibraryEntry.delete_by_id(lib_entry)
122+
except Exception as e:
123+
logging.error("An error occured during the deletion of a library entry: %s", e)
124+
else:
125+
logging.info("Deleted library entry for video '%s'", lib_entry.video.title)

modules/youtube.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from .helpers import (
1414
extract_youtube_video_id,
1515
get_preffered_languages,
16-
save_response_as_file,
1716
)
1817

1918
OEMBED_PROVIDER = "https://noembed.com/embed"
@@ -56,12 +55,6 @@ def get_video_metadata(url: str):
5655
return None
5756
else:
5857
json_response = json.loads(response.text)
59-
save_response_as_file(
60-
dir_name="./video_meta",
61-
filename=f"{json_response['title']}",
62-
file_content=json_response,
63-
content_type="json",
64-
)
6558
return {
6659
"name": json_response["title"],
6760
"channel": json_response["author_name"],

pages/chat.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
is_environment_prod,
1818
num_tokens_from_string,
1919
read_file,
20-
save_response_as_file,
2120
)
2221
from modules.persistance import (
2322
SQL_DB,
@@ -286,11 +285,6 @@ def save_response_to_lib():
286285
download_folder_path="data/audio",
287286
)
288287
whisper_transcript = generate_transcript(file_path=download)
289-
save_response_as_file(
290-
dir_name="data/transcripts",
291-
filename=saved_video.title,
292-
file_content=whisper_transcript,
293-
)
294288
transcript_excerpts = split_text_recursively(
295289
transcript_text=whisper_transcript,
296290
chunk_size=chunk_size,

pages/library.py

Lines changed: 81 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import streamlit as st
22

3-
from modules.persistance import SQL_DB, LibraryEntry, delete_library_entry
3+
from modules.persistance import SQL_DB, LibraryEntry, delete_library_entry, Video
44
from modules.ui import display_nav_menu
55

66

@@ -13,12 +13,8 @@
1313
SQL_DB.create_tables([LibraryEntry], safe=True)
1414
# --- end ---
1515

16-
saved_lib_entries_summaries = (
17-
LibraryEntry.select().where(LibraryEntry.entry_type == "S").execute()
18-
)
19-
saved_lib_entries_answers = (
20-
LibraryEntry.select().where(LibraryEntry.entry_type == "A").execute()
21-
)
16+
tab_summaries, tab_answers = st.tabs(["Summaries", "Answers"])
17+
saved_videos = Video.select()
2218

2319

2420
def execute_entry_deletion(entry: LibraryEntry):
@@ -27,32 +23,81 @@ def execute_entry_deletion(entry: LibraryEntry):
2723
st.rerun()
2824

2925

30-
if saved_lib_entries_summaries:
31-
st.header("Saved summaries")
32-
for i, entry in enumerate(saved_lib_entries_summaries, 0):
33-
st.caption(f"{entry.video.title} - {entry.video.channel}")
34-
with st.expander("Show"):
35-
st.write(entry.text)
36-
if st.button(
37-
label="Delete entry",
38-
key=f"delete_summary_{i}",
39-
):
40-
execute_entry_deletion(entry)
41-
st.divider()
42-
else:
43-
st.info("You don't have any saved summaries yet!")
44-
45-
if saved_lib_entries_answers:
46-
st.header("Saved answers")
47-
for j, entry in enumerate(saved_lib_entries_answers, 0):
48-
st.subheader(entry.question)
49-
with st.expander("Show"):
50-
st.write(entry.text)
51-
if st.button(
52-
label="Delete entry",
53-
key=f"delete_answer_{j}",
54-
):
55-
execute_entry_deletion(entry)
56-
st.divider()
57-
else:
58-
st.info("You don't have any saved answers yet!")
26+
with tab_summaries:
27+
selected_channel = st.selectbox(
28+
label="Filter by channel",
29+
placeholder="choose a channel or start typing",
30+
# only videos with an associated transcript can be selected
31+
options={video.channel for video in saved_videos},
32+
index=None,
33+
key="selected_channel",
34+
)
35+
36+
if selected_channel:
37+
saved_lib_entries_summaries = (
38+
LibraryEntry.select()
39+
.join(Video)
40+
.where(LibraryEntry.entry_type == "S", Video.channel == selected_channel)
41+
.execute()
42+
)
43+
else:
44+
saved_lib_entries_summaries = (
45+
LibraryEntry.select().where(LibraryEntry.entry_type == "S").execute()
46+
)
47+
48+
if saved_lib_entries_summaries:
49+
st.header("Saved summaries")
50+
for i, entry in enumerate(saved_lib_entries_summaries, 0):
51+
st.caption(f"{entry.video.title} - {entry.video.channel}")
52+
with st.expander("Show"):
53+
st.write(entry.text)
54+
if st.button(
55+
label="Delete entry",
56+
key=f"delete_summary_{i}",
57+
):
58+
execute_entry_deletion(entry)
59+
st.divider()
60+
else:
61+
st.info("You don't have any saved summaries yet!")
62+
63+
with tab_answers:
64+
selected_video_title = st.selectbox(
65+
label="Filter by video",
66+
placeholder="choose a video or start typing",
67+
# only videos with an associated transcript can be selected
68+
options=[
69+
video.title for video in saved_videos if video.transcripts.count() != 0
70+
],
71+
index=None,
72+
key="selected_video",
73+
)
74+
75+
if selected_video_title:
76+
saved_lib_entries_answers = (
77+
LibraryEntry.select()
78+
.join(Video)
79+
.where(
80+
LibraryEntry.entry_type == "A",
81+
Video.title == st.session_state.selected_video,
82+
)
83+
.execute()
84+
)
85+
else:
86+
saved_lib_entries_answers = (
87+
LibraryEntry.select().where(LibraryEntry.entry_type == "A").execute()
88+
)
89+
90+
if saved_lib_entries_answers:
91+
st.header("Saved answers")
92+
for j, entry in enumerate(saved_lib_entries_answers, 0):
93+
st.subheader(entry.question)
94+
with st.expander("Show"):
95+
st.write(entry.text)
96+
if st.button(
97+
label="Delete entry",
98+
key=f"delete_answer_{j}",
99+
):
100+
execute_entry_deletion(entry)
101+
st.divider()
102+
else:
103+
st.info("You don't have any saved answers yet!")

pages/summary.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,22 @@
4545
display_link_to_repo("summary")
4646
# --- end ---
4747

48-
# variable for holding the Video object
49-
saved_video: None | Video = None
48+
49+
@st.dialog(title="Transcript too long", width="large")
50+
def display_dialog(message: str):
51+
st.warning(message)
5052

5153

5254
def save_summary_to_lib():
5355
"""Wrapper func for saving summaries to the library."""
5456
try:
57+
saved_video = Video.create(
58+
yt_video_id=extract_youtube_video_id(url_input),
59+
link=url_input,
60+
title=vid_metadata["name"],
61+
channel=vid_metadata["channel"],
62+
saved_on=dt.now(),
63+
)
5564
save_library_entry(
5665
entry_type="S",
5766
question_text=None,
@@ -65,12 +74,7 @@ def save_summary_to_lib():
6574
st.success("Saved summary to library successfully!")
6675

6776

68-
@st.dialog(title="Transcript too long", width="large")
69-
def display_dialog(message: str):
70-
st.warning(message)
71-
72-
73-
if is_api_key_set and is_api_key_valid(st.session_state.openai_api_key):
77+
if is_api_key_set() and is_api_key_valid(st.session_state.openai_api_key):
7478

7579
# --- rest of the sidebar, which requires an api key to be set ---
7680
display_model_settings_sidebar()
@@ -113,13 +117,6 @@ def display_dialog(message: str):
113117
with col2:
114118
if summarize_button:
115119
try:
116-
saved_video = Video.create(
117-
yt_video_id=extract_youtube_video_id(url_input),
118-
link=url_input,
119-
title=vid_metadata["name"],
120-
channel=vid_metadata["channel"],
121-
saved_on=dt.now(),
122-
)
123120
transcript = fetch_youtube_transcript(url_input)
124121
cb = OpenAICallbackHandler()
125122
llm = ChatOpenAI(
@@ -133,10 +130,14 @@ def display_dialog(message: str):
133130
with st.spinner("Summarizing video :gear: Hang on..."):
134131
if custom_prompt:
135132
resp = get_transcript_summary(
136-
transcript, llm, custom_prompt=custom_prompt
133+
transcript_text=transcript,
134+
llm=llm,
135+
custom_prompt=custom_prompt,
137136
)
138137
else:
139-
resp = get_transcript_summary(transcript, llm)
138+
resp = get_transcript_summary(
139+
transcript_text=transcript, llm=llm
140+
)
140141
st.session_state.summary = resp
141142
st.markdown(st.session_state.summary)
142143

0 commit comments

Comments
 (0)