New big feature: Attach website (experimental)
This commit is contained in:
parent
2c2a1ac2bc
commit
2ded3c72fd
@ -99,6 +99,20 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "python3-html2text",
|
||||||
|
"buildsystem": "simple",
|
||||||
|
"build-commands": [
|
||||||
|
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"html2text\" --no-build-isolation"
|
||||||
|
],
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"url": "https://files.pythonhosted.org/packages/1a/43/e1d53588561e533212117750ee79ad0ba02a41f52a08c1df3396bd466c05/html2text-2024.2.26.tar.gz",
|
||||||
|
"sha256": "05f8e367d15aaabc96415376776cdd11afd5127a77fce6e36afc60c563ca2c32"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ollama",
|
"name": "ollama",
|
||||||
"buildsystem": "simple",
|
"buildsystem": "simple",
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
from gi.repository import Adw, Gtk, Gdk, GLib, GtkSource, Gio, GdkPixbuf
|
from gi.repository import Adw, Gtk, Gdk, GLib, GtkSource, Gio, GdkPixbuf
|
||||||
import os
|
import os
|
||||||
from pytube import YouTube
|
from pytube import YouTube
|
||||||
|
from html2text import html2text
|
||||||
|
from . import connection_handler
|
||||||
|
|
||||||
# CLEAR CHAT | WORKS
|
# CLEAR CHAT | WORKS
|
||||||
|
|
||||||
@ -312,3 +314,35 @@ def youtube_caption(self, video_url):
|
|||||||
callback = lambda dialog, task, video_url = video_url, caption_drop_down = caption_drop_down: youtube_caption_response(self, dialog, task, video_url, caption_drop_down)
|
callback = lambda dialog, task, video_url = video_url, caption_drop_down = caption_drop_down: youtube_caption_response(self, dialog, task, video_url, caption_drop_down)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Website extraction |
|
||||||
|
|
||||||
|
def attach_website_response(self, dialog, task, url):
|
||||||
|
if dialog.choose_finish(task) == "accept":
|
||||||
|
html = connection_handler.simple_get(url)['text']
|
||||||
|
md = html2text(html)
|
||||||
|
buffer = self.message_text_view.get_buffer()
|
||||||
|
textview_text = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), False).replace(url, "")
|
||||||
|
buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
|
||||||
|
buffer.insert(buffer.get_start_iter(), textview_text, len(textview_text))
|
||||||
|
if not os.path.exists('/tmp/alpaca/websites/'):
|
||||||
|
os.makedirs('/tmp/alpaca/websites/')
|
||||||
|
md_name = self.generate_numbered_name('website.md', os.listdir('/tmp/alpaca/websites'))
|
||||||
|
file_path = os.path.join('/tmp/alpaca/websites/', md_name)
|
||||||
|
with open(file_path, 'w+') as f:
|
||||||
|
f.write('{}\n\n{}'.format(url, md))
|
||||||
|
self.attach_file(file_path, 'website')
|
||||||
|
|
||||||
|
def attach_website(self, url):
|
||||||
|
dialog = Adw.AlertDialog(
|
||||||
|
heading=_("Attach Website (Experimental)"),
|
||||||
|
body=_("Are you sure you want to attach\n'{}'?").format(url),
|
||||||
|
close_response="cancel"
|
||||||
|
)
|
||||||
|
dialog.add_response("cancel", _("Cancel"))
|
||||||
|
dialog.add_response("accept", _("Accept"))
|
||||||
|
dialog.set_response_appearance("accept", Adw.ResponseAppearance.SUGGESTED)
|
||||||
|
dialog.choose(
|
||||||
|
parent = self,
|
||||||
|
cancellable = None,
|
||||||
|
callback = lambda dialog, task, url=url: attach_website_response(self, dialog, task, url)
|
||||||
|
)
|
||||||
|
@ -196,7 +196,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
self.save_history()
|
self.save_history()
|
||||||
self.show_toast("info", 6, self.main_overlay)
|
self.show_toast("info", 6, self.main_overlay)
|
||||||
|
|
||||||
if self.bot_message: return
|
if self.bot_message or self.get_focus() not in (self.message_text_view, self.send_button): return
|
||||||
if not self.message_text_view.get_buffer().get_text(self.message_text_view.get_buffer().get_start_iter(), self.message_text_view.get_buffer().get_end_iter(), False): return
|
if not self.message_text_view.get_buffer().get_text(self.message_text_view.get_buffer().get_start_iter(), self.message_text_view.get_buffer().get_end_iter(), False): return
|
||||||
current_chat_row = self.chat_list_box.get_selected_row()
|
current_chat_row = self.chat_list_box.get_selected_row()
|
||||||
self.chat_list_box.unselect_all()
|
self.chat_list_box.unselect_all()
|
||||||
@ -514,6 +514,8 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
if file_type == 'youtube':
|
if file_type == 'youtube':
|
||||||
self.file_preview_dialog.set_title(content.split('\n')[0])
|
self.file_preview_dialog.set_title(content.split('\n')[0])
|
||||||
self.file_preview_open_button.set_name(content.split('\n')[2])
|
self.file_preview_open_button.set_name(content.split('\n')[2])
|
||||||
|
elif file_type == 'website':
|
||||||
|
self.file_preview_open_button.set_name(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_open_button.set_name(file_path)
|
self.file_preview_open_button.set_name(file_path)
|
||||||
@ -545,7 +547,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
|||||||
Generate a title following these rules:
|
Generate a title following these rules:
|
||||||
- The title should be based on the prompt at the end
|
- The title should be based on the prompt at the end
|
||||||
- Keep it in the same language as the prompt
|
- Keep it in the same language as the prompt
|
||||||
- The title needs to be less than 4 words
|
- The title needs to be less than 30 characters
|
||||||
- Use only alphanumeric characters and spaces
|
- Use only alphanumeric characters and spaces
|
||||||
- Just write the title, NOTHING ELSE
|
- Just write the title, NOTHING ELSE
|
||||||
|
|
||||||
@ -558,6 +560,7 @@ Generate a title following these rules:
|
|||||||
if 'images' in message: data["images"] = message['images']
|
if 'images' in message: data["images"] = message['images']
|
||||||
response = connection_handler.simple_post(f"{connection_handler.url}/api/generate", data=json.dumps(data))
|
response = connection_handler.simple_post(f"{connection_handler.url}/api/generate", data=json.dumps(data))
|
||||||
new_chat_name = json.loads(response['text'])["response"].lstrip().rstrip().replace('"', '').replace("'", "").title()
|
new_chat_name = json.loads(response['text'])["response"].lstrip().rstrip().replace('"', '').replace("'", "").title()
|
||||||
|
new_chat_name = new_chat_name[:30] + (new_chat_name[30:] and '...')
|
||||||
self.rename_chat(label_element.get_name(), new_chat_name, label_element)
|
self.rename_chat(label_element.get_name(), new_chat_name, label_element)
|
||||||
|
|
||||||
def show_message(self, msg:str, bot:bool, footer:str=None, images:list=None, files:dict=None, id:str=None):
|
def show_message(self, msg:str, bot:bool, footer:str=None, images:list=None, files:dict=None, id:str=None):
|
||||||
@ -660,7 +663,12 @@ Generate a title following these rules:
|
|||||||
for name, file_type in files.items():
|
for name, file_type in files.items():
|
||||||
button_content = Adw.ButtonContent(
|
button_content = Adw.ButtonContent(
|
||||||
label=name,
|
label=name,
|
||||||
icon_name="play-symbolic" if file_type=='youtube' else "document-text-symbolic"
|
icon_name={
|
||||||
|
"plain_text": "document-text-symbolic",
|
||||||
|
"pdf": "document-text-symbolic",
|
||||||
|
"youtube": "play-symbolic",
|
||||||
|
"website": "globe-symbolic"
|
||||||
|
}[file_type]
|
||||||
)
|
)
|
||||||
button = Gtk.Button(
|
button = Gtk.Button(
|
||||||
vexpand=False,
|
vexpand=False,
|
||||||
@ -671,7 +679,6 @@ Generate a title following these rules:
|
|||||||
child=button_content
|
child=button_content
|
||||||
)
|
)
|
||||||
file_path = os.path.join(self.data_dir, "chats", "{selected_chat}", id, name)
|
file_path = os.path.join(self.data_dir, "chats", "{selected_chat}", id, name)
|
||||||
print(file_path)
|
|
||||||
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)
|
||||||
@ -1308,7 +1315,7 @@ Generate a title following these rules:
|
|||||||
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' or file_type == 'youtube':
|
elif file_type == 'plain_text' or file_type == 'youtube' or file_type == 'website':
|
||||||
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':
|
||||||
@ -1334,7 +1341,8 @@ Generate a title following these rules:
|
|||||||
"image": "image-x-generic-symbolic",
|
"image": "image-x-generic-symbolic",
|
||||||
"plain_text": "document-text-symbolic",
|
"plain_text": "document-text-symbolic",
|
||||||
"pdf": "document-text-symbolic",
|
"pdf": "document-text-symbolic",
|
||||||
"youtube": "play-symbolic"
|
"youtube": "play-symbolic",
|
||||||
|
"website": "globe-symbolic"
|
||||||
}[file_type]
|
}[file_type]
|
||||||
)
|
)
|
||||||
button = Gtk.Button(
|
button = Gtk.Button(
|
||||||
@ -1372,11 +1380,20 @@ Generate a title following these rules:
|
|||||||
youtube_regex = re.compile(
|
youtube_regex = re.compile(
|
||||||
r'(https?://)?(www\.)?(youtube|youtu|youtube-nocookie)\.(com|be)/'
|
r'(https?://)?(www\.)?(youtube|youtu|youtube-nocookie)\.(com|be)/'
|
||||||
r'(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})')
|
r'(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})')
|
||||||
|
url_regex = re.compile(
|
||||||
|
r'http[s]?://'
|
||||||
|
r'(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|'
|
||||||
|
r'(?:%[0-9a-fA-F][0-9a-fA-F]))+'
|
||||||
|
r'(?:\\:[0-9]{1,5})?'
|
||||||
|
r'(?:/[^\\s]*)?'
|
||||||
|
)
|
||||||
if youtube_regex.match(text):
|
if youtube_regex.match(text):
|
||||||
try:
|
try:
|
||||||
dialogs.youtube_caption(self, text)
|
dialogs.youtube_caption(self, text)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.show_toast("error", 10, self.main_overlay)
|
self.show_toast("error", 10, self.main_overlay)
|
||||||
|
elif url_regex.match(text):
|
||||||
|
dialogs.attach_website(self, text)
|
||||||
except Exception as e: 'huh'
|
except Exception as e: 'huh'
|
||||||
|
|
||||||
def cb_image_received(self, clipboard, result):
|
def cb_image_received(self, clipboard, result):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user