Better YouTube integration
This commit is contained in:
parent
f150aa24ab
commit
bd146bdfb3
@ -1,6 +1,8 @@
|
|||||||
# dialogs.py
|
# dialogs.py
|
||||||
|
|
||||||
from gi.repository import Adw, Gtk, Gdk, GLib, GtkSource, Gio, GdkPixbuf
|
from gi.repository import Adw, Gtk, Gdk, GLib, GtkSource, Gio, GdkPixbuf
|
||||||
|
import os
|
||||||
|
from pytube import YouTube
|
||||||
|
|
||||||
# CLEAR CHAT | WORKS
|
# CLEAR CHAT | WORKS
|
||||||
|
|
||||||
@ -269,9 +271,22 @@ def youtube_caption_response(self, dialog, task, video_url, caption_drop_down):
|
|||||||
text = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), False).replace(video_url, "")
|
text = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), False).replace(video_url, "")
|
||||||
buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
|
buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
|
||||||
buffer.insert(buffer.get_start_iter(), text, len(text))
|
buffer.insert(buffer.get_start_iter(), text, len(text))
|
||||||
self.attach_file("{}&caption_lang={}".format(video_url, caption_drop_down.get_selected_item().get_string().split(' | ')[1]), 'youtube')
|
|
||||||
|
|
||||||
def youtube_caption(self, video_title, video_url, captions):
|
yt = YouTube(video_url)
|
||||||
|
text = "{}\n{}\n{}\n\n".format(yt.title, yt.author, yt.watch_url)
|
||||||
|
for event in yt.captions[caption_drop_down.get_selected_item().get_string().split(' | ')[1]].json_captions['events']:
|
||||||
|
text += "{}\n".format(event['segs'][0]['utf8'].replace('\n', '\\n'))
|
||||||
|
if not os.path.exists('/tmp/alpaca/youtube'):
|
||||||
|
os.makedirs('/tmp/alpaca/youtube')
|
||||||
|
file_path = os.path.join('/tmp/alpaca/youtube', self.generate_numbered_name(yt.title, os.listdir('/tmp/alpaca/youtube')))
|
||||||
|
with open(file_path, 'w+') as f:
|
||||||
|
f.write(text)
|
||||||
|
self.attach_file(file_path, 'youtube')
|
||||||
|
|
||||||
|
def youtube_caption(self, video_url):
|
||||||
|
yt = YouTube(video_url)
|
||||||
|
video_title = yt.title
|
||||||
|
captions = yt.captions
|
||||||
if len(captions) == 0:
|
if len(captions) == 0:
|
||||||
self.show_toast("error", 9, self.main_overlay)
|
self.show_toast("error", 9, self.main_overlay)
|
||||||
return
|
return
|
||||||
|
@ -22,7 +22,6 @@ gi.require_version('GtkSource', '5')
|
|||||||
gi.require_version('GdkPixbuf', '2.0')
|
gi.require_version('GdkPixbuf', '2.0')
|
||||||
from gi.repository import Adw, Gtk, Gdk, GLib, GtkSource, Gio, GdkPixbuf
|
from gi.repository import Adw, Gtk, Gdk, GLib, GtkSource, Gio, GdkPixbuf
|
||||||
import json, requests, threading, os, re, base64, sys, gettext, locale, webbrowser, subprocess, uuid, shutil, tarfile, tempfile #, docx
|
import json, requests, threading, os, re, base64, sys, gettext, locale, webbrowser, subprocess, uuid, shutil, tarfile, tempfile #, docx
|
||||||
from pytube import YouTube
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
@ -191,14 +190,10 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
for name, content in self.attachments.items():
|
for name, content in self.attachments.items():
|
||||||
if content["type"] == 'image' and can_use_images: attached_images.append(name)
|
if content["type"] == 'image' and can_use_images: attached_images.append(name)
|
||||||
else:
|
else:
|
||||||
if content["type"] == 'youtube':
|
attached_files[name] = content['type']
|
||||||
attached_files[content['path']] = content['type']
|
|
||||||
else:
|
|
||||||
attached_files[name] = content['type']
|
|
||||||
if not os.path.exists(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id)):
|
if not os.path.exists(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id)):
|
||||||
os.makedirs(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id))
|
os.makedirs(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id))
|
||||||
if content["type"] != 'youtube':
|
shutil.copy(content['path'], os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, name))
|
||||||
shutil.copy(content['path'], os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, name))
|
|
||||||
content["button"].get_parent().remove(content["button"])
|
content["button"].get_parent().remove(content["button"])
|
||||||
self.attachments = {}
|
self.attachments = {}
|
||||||
self.attachment_box.set_visible(False)
|
self.attachment_box.set_visible(False)
|
||||||
@ -438,7 +433,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
|
buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
|
||||||
buffer.insert(buffer.get_start_iter(), content, len(content))
|
buffer.insert(buffer.get_start_iter(), content, len(content))
|
||||||
if file_type == 'youtube':
|
if file_type == 'youtube':
|
||||||
self.file_preview_dialog.set_title(YouTube(file_path).title)
|
self.file_preview_dialog.set_title(content.split('\n')[0])
|
||||||
else:
|
else:
|
||||||
self.file_preview_dialog.set_title(os.path.basename(file_path))
|
self.file_preview_dialog.set_title(os.path.basename(file_path))
|
||||||
self.file_preview_dialog.present(self)
|
self.file_preview_dialog.present(self)
|
||||||
@ -451,10 +446,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
del new_message['files']
|
del new_message['files']
|
||||||
new_message['content'] = ''
|
new_message['content'] = ''
|
||||||
for name, file_type in message['files'].items():
|
for name, file_type in message['files'].items():
|
||||||
if file_type == 'youtube':
|
file_path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, name)
|
||||||
file_path = name
|
|
||||||
else:
|
|
||||||
file_path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, name)
|
|
||||||
file_data = self.get_content_of_file(file_path, file_type)
|
file_data = self.get_content_of_file(file_path, file_type)
|
||||||
if file_data: new_message['content'] += f"```[{name}]\n{file_data}\n```"
|
if file_data: new_message['content'] += f"```[{name}]\n{file_data}\n```"
|
||||||
new_message['content'] += message['content']
|
new_message['content'] += message['content']
|
||||||
@ -554,8 +546,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
)
|
)
|
||||||
for name, file_type in files.items():
|
for name, file_type in files.items():
|
||||||
if file_type == 'youtube':
|
if file_type == 'youtube':
|
||||||
yt = YouTube(name)
|
shown_name=name[:20] + (name[20:] and '..')
|
||||||
shown_name=yt.title[:20] + (yt.title[20:] and '..')
|
|
||||||
else:
|
else:
|
||||||
shown_name='.'.join(name.split(".")[:-1])[:20] + (name[20:] and '..') + f".{name.split('.')[-1]}"
|
shown_name='.'.join(name.split(".")[:-1])[:20] + (name[20:] and '..') + f".{name.split('.')[-1]}"
|
||||||
|
|
||||||
@ -568,13 +559,10 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
valign=3,
|
valign=3,
|
||||||
name=name,
|
name=name,
|
||||||
css_classes=["flat"],
|
css_classes=["flat"],
|
||||||
tooltip_text=name if file_type != 'youtube' else yt.title,
|
tooltip_text=name,
|
||||||
child=button_content
|
child=button_content
|
||||||
)
|
)
|
||||||
if file_type == 'youtube':
|
file_path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, name)
|
||||||
file_path = name
|
|
||||||
else:
|
|
||||||
file_path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, name)
|
|
||||||
button.connect("clicked", lambda button, file_path=file_path, file_type=file_type: self.preview_file(file_path, file_type))
|
button.connect("clicked", lambda button, file_path=file_path, file_type=file_type: self.preview_file(file_path, file_type))
|
||||||
file_container.append(button)
|
file_container.append(button)
|
||||||
message_box.append(file_scroller)
|
message_box.append(file_scroller)
|
||||||
@ -1174,7 +1162,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
self.verify_connection()
|
self.verify_connection()
|
||||||
|
|
||||||
def get_content_of_file(self, file_path, file_type):
|
def get_content_of_file(self, file_path, file_type):
|
||||||
if file_type != 'youtube' and not os.path.exists(file_path): return None
|
if not os.path.exists(file_path): return None
|
||||||
if file_type == 'image':
|
if file_type == 'image':
|
||||||
try:
|
try:
|
||||||
with Image.open(file_path) as img:
|
with Image.open(file_path) as img:
|
||||||
@ -1193,7 +1181,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
return base64.b64encode(image_data).decode("utf-8")
|
return base64.b64encode(image_data).decode("utf-8")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.show_toast("error", 5, self.main_overlay)
|
self.show_toast("error", 5, self.main_overlay)
|
||||||
elif file_type == 'plain_text':
|
elif file_type == 'plain_text' or file_type == 'youtube':
|
||||||
with open(file_path, 'r') as f:
|
with open(file_path, 'r') as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
elif file_type == 'pdf':
|
elif file_type == 'pdf':
|
||||||
@ -1203,12 +1191,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
for i, page in enumerate(reader.pages):
|
for i, page in enumerate(reader.pages):
|
||||||
text += f"\n- Page {i}\n{page.extract_text()}\n"
|
text += f"\n- Page {i}\n{page.extract_text()}\n"
|
||||||
return text
|
return text
|
||||||
elif file_type == 'youtube':
|
|
||||||
yt = YouTube(file_path)
|
|
||||||
text = "{}\n{}\n\n".format(yt.title, yt.author)
|
|
||||||
for event in yt.captions[file_path.split('&caption_lang=')[1]].json_captions['events']:
|
|
||||||
text += "{}\n".format(event['segs'][0]['utf8'].replace('\n', '\\n'))
|
|
||||||
return text
|
|
||||||
#elif file_type == 'docx':
|
#elif file_type == 'docx':
|
||||||
#document = docx.Document(file_path)
|
#document = docx.Document(file_path)
|
||||||
#if len(document.paragraphs) == 0: return None
|
#if len(document.paragraphs) == 0: return None
|
||||||
@ -1223,10 +1205,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
if len(self.attachments) == 0: self.attachment_box.set_visible(False)
|
if len(self.attachments) == 0: self.attachment_box.set_visible(False)
|
||||||
|
|
||||||
def attach_file(self, file_path, file_type):
|
def attach_file(self, file_path, file_type):
|
||||||
if file_type == "youtube":
|
name = self.generate_numbered_name(os.path.basename(file_path), self.attachments.keys())
|
||||||
name = YouTube(file_path).title
|
|
||||||
else:
|
|
||||||
name = self.generate_numbered_name(os.path.basename(file_path), self.attachments.keys())
|
|
||||||
content = self.get_content_of_file(file_path, file_type)
|
content = self.get_content_of_file(file_path, file_type)
|
||||||
if content:
|
if content:
|
||||||
if file_type == "youtube":
|
if file_type == "youtube":
|
||||||
@ -1280,8 +1259,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
r'(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})')
|
r'(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})')
|
||||||
if youtube_regex.match(text):
|
if youtube_regex.match(text):
|
||||||
try:
|
try:
|
||||||
yt = YouTube(text)
|
dialogs.youtube_caption(self, text)
|
||||||
dialogs.youtube_caption(self, yt.title, text, yt.captions)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.show_toast("error", 10, self.main_overlay)
|
self.show_toast("error", 10, self.main_overlay)
|
||||||
|
|
||||||
|
@ -698,8 +698,16 @@
|
|||||||
<property name="margin-bottom">12</property>
|
<property name="margin-bottom">12</property>
|
||||||
<property name="margin-start">12</property>
|
<property name="margin-start">12</property>
|
||||||
<property name="margin-end">12</property>
|
<property name="margin-end">12</property>
|
||||||
|
<style>
|
||||||
|
<class name="card" />
|
||||||
|
<class name="view" />
|
||||||
|
</style>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTextView" id="file_preview_text_view">
|
<object class="GtkTextView" id="file_preview_text_view">
|
||||||
|
<property name="margin-top">12</property>
|
||||||
|
<property name="margin-bottom">12</property>
|
||||||
|
<property name="margin-start">12</property>
|
||||||
|
<property name="margin-end">12</property>
|
||||||
<property name="hexpand">true</property>
|
<property name="hexpand">true</property>
|
||||||
<property name="vexpand">true</property>
|
<property name="vexpand">true</property>
|
||||||
<property name="editable">false</property>
|
<property name="editable">false</property>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user