Add logging (#142)

* Configure logger

* Add logging at various points

* Add logging to window verify_if_image_can_be_used
This commit is contained in:
imbev 2024-07-17 21:49:55 -05:00 committed by GitHub
parent c8ace20e60
commit 92f1b62f8c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 66 additions and 10 deletions

View File

@ -1,6 +1,10 @@
# local_instance.py # local_instance.py
import subprocess, os, threading import subprocess, os, threading
from time import sleep from time import sleep
from logging import getLogger
logger = getLogger(__name__)
instance = None instance = None
port = 11435 port = 11435
@ -13,19 +17,22 @@ def start():
params["OLLAMA_HOST"] = f"127.0.0.1:{port}" # You can't change this directly sorry :3 params["OLLAMA_HOST"] = f"127.0.0.1:{port}" # You can't change this directly sorry :3
params["HOME"] = data_dir params["HOME"] = data_dir
instance = subprocess.Popen(["/app/bin/ollama", "serve"], env={**os.environ, **params}, stderr=subprocess.PIPE, text=True) instance = subprocess.Popen(["/app/bin/ollama", "serve"], env={**os.environ, **params}, stderr=subprocess.PIPE, text=True)
print("Starting Alpaca's Ollama instance...") logger.info("Starting Alpaca's Ollama instance...")
logger.debug(params)
sleep(1) sleep(1)
print("Started Alpaca's Ollama instance") logger.info("Started Alpaca's Ollama instance")
def stop(): def stop():
logger.info("Stopping Alpaca's Ollama instance")
global instance global instance
if instance: if instance:
instance.terminate() instance.terminate()
instance.wait() instance.wait()
instance = None instance = None
print("Stopped Alpaca's Ollama instance") logger.info("Stopped Alpaca's Ollama instance")
def reset(): def reset():
logger.info("Resetting Alpaca's Ollama instance")
stop() stop()
sleep(1) sleep(1)
start() start()

View File

@ -18,6 +18,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import sys import sys
import logging
import gi import gi
gi.require_version('Gtk', '4.0') gi.require_version('Gtk', '4.0')
@ -26,6 +27,10 @@ gi.require_version('Adw', '1')
from gi.repository import Gtk, Gio, Adw, GLib from gi.repository import Gtk, Gio, Adw, GLib
from .window import AlpacaWindow from .window import AlpacaWindow
logger = logging.getLogger(__name__)
class AlpacaApplication(Adw.Application): class AlpacaApplication(Adw.Application):
"""The main application singleton class.""" """The main application singleton class."""
@ -35,6 +40,7 @@ class AlpacaApplication(Adw.Application):
self.create_action('quit', lambda *_: self.quit(), ['<primary>q']) self.create_action('quit', lambda *_: self.quit(), ['<primary>q'])
self.create_action('preferences', lambda *_: AlpacaWindow.show_preferences_dialog(self.props.active_window), ['<primary>p']) self.create_action('preferences', lambda *_: AlpacaWindow.show_preferences_dialog(self.props.active_window), ['<primary>p'])
self.create_action('about', self.on_about_action) self.create_action('about', self.on_about_action)
self.version = '0.9.6.1'
def do_activate(self): def do_activate(self):
win = self.props.active_window win = self.props.active_window
@ -47,7 +53,7 @@ class AlpacaApplication(Adw.Application):
application_name='Alpaca', application_name='Alpaca',
application_icon='com.jeffser.Alpaca', application_icon='com.jeffser.Alpaca',
developer_name='Jeffry Samuel Eduarte Rojas', developer_name='Jeffry Samuel Eduarte Rojas',
version='0.9.6.1', version=self.version,
developers=['Jeffser https://jeffser.com'], developers=['Jeffser https://jeffser.com'],
designers=['Jeffser https://jeffser.com', 'Tobias Bernard (App Icon) https://tobiasbernard.com/'], designers=['Jeffser https://jeffser.com', 'Tobias Bernard (App Icon) https://tobiasbernard.com/'],
translator_credits='Alex K (Russian) https://github.com/alexkdeveloper\nJeffser (Spanish) https://jeffser.com\nDaimar Stein (Brazilian Portuguese) https://github.com/not-a-dev-stein\nLouis Chauvet-Villaret (French) https://github.com/loulou64490\nCounterFlow64 (Norwegian) https://github.com/CounterFlow64', translator_credits='Alex K (Russian) https://github.com/alexkdeveloper\nJeffser (Spanish) https://jeffser.com\nDaimar Stein (Brazilian Portuguese) https://github.com/not-a-dev-stein\nLouis Chauvet-Villaret (French) https://github.com/loulou64490\nCounterFlow64 (Norwegian) https://github.com/CounterFlow64',
@ -64,5 +70,10 @@ class AlpacaApplication(Adw.Application):
def main(version): def main(version):
logging.basicConfig(
format="%(levelname)s\t[%(filename)s | %(funcName)s] %(message)s",
level=logging.INFO
)
app = AlpacaApplication() app = AlpacaApplication()
logger.info(f"Alpaca version: {app.version}")
return app.run(sys.argv) return app.run(sys.argv)

View File

@ -29,6 +29,10 @@ from pypdf import PdfReader
from datetime import datetime from datetime import datetime
from . import dialogs, local_instance, connection_handler, available_models_descriptions from . import dialogs, local_instance, connection_handler, available_models_descriptions
logger = logging.getLogger(__name__)
@Gtk.Template(resource_path='/com/jeffser/Alpaca/window.ui') @Gtk.Template(resource_path='/com/jeffser/Alpaca/window.ui')
class AlpacaWindow(Adw.ApplicationWindow): class AlpacaWindow(Adw.ApplicationWindow):
config_dir = os.getenv("XDG_CONFIG_HOME") config_dir = os.getenv("XDG_CONFIG_HOME")
@ -45,10 +49,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
gettext.textdomain('com.jeffser.Alpaca') gettext.textdomain('com.jeffser.Alpaca')
_ = gettext.gettext _ = gettext.gettext
logger = logging.getLogger(__name__)
logging.basicConfig(format="%(levelname)s\t[%(filename)s | %(funcName)s] %(message)s")
logger.setLevel(logging.ERROR)
#Variables #Variables
editing_message = None editing_message = None
available_models = None available_models = None
@ -133,6 +133,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
@Gtk.Template.Callback() @Gtk.Template.Callback()
def verify_if_image_can_be_used(self, pspec=None, user_data=None): def verify_if_image_can_be_used(self, pspec=None, user_data=None):
logger.debug("Verifying if image can be used")
if self.model_drop_down.get_selected_item() == None: return True if self.model_drop_down.get_selected_item() == None: return True
selected = self.model_drop_down.get_selected_item().get_string().split(" (")[0].lower() selected = self.model_drop_down.get_selected_item().get_string().split(" (")[0].lower()
if selected in [key for key, value in self.available_models.items() if value["image"]]: if selected in [key for key, value in self.available_models.items() if value["image"]]:
@ -246,11 +247,13 @@ class AlpacaWindow(Adw.ApplicationWindow):
@Gtk.Template.Callback() @Gtk.Template.Callback()
def manage_models_button_activate(self, button=None): def manage_models_button_activate(self, button=None):
logger.debug(f"Managing models")
self.update_list_local_models() self.update_list_local_models()
self.manage_models_dialog.present(self) self.manage_models_dialog.present(self)
@Gtk.Template.Callback() @Gtk.Template.Callback()
def welcome_carousel_page_changed(self, carousel, index): def welcome_carousel_page_changed(self, carousel, index):
logger.debug("Showing welcome carousel")
if index == 0: self.welcome_previous_button.set_sensitive(False) if index == 0: self.welcome_previous_button.set_sensitive(False)
else: self.welcome_previous_button.set_sensitive(True) else: self.welcome_previous_button.set_sensitive(True)
if index == carousel.get_n_pages()-1: if index == carousel.get_n_pages()-1:
@ -274,6 +277,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
@Gtk.Template.Callback() @Gtk.Template.Callback()
def chat_changed(self, listbox, row): def chat_changed(self, listbox, row):
logger.debug("Changing selected chat")
if row and row.get_child().get_name() != self.chats["selected_chat"]: if row and row.get_child().get_name() != self.chats["selected_chat"]:
self.chats["selected_chat"] = row.get_child().get_name() self.chats["selected_chat"] = row.get_child().get_name()
self.load_history_into_chat() self.load_history_into_chat()
@ -287,6 +291,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
@Gtk.Template.Callback() @Gtk.Template.Callback()
def change_remote_url(self, entry): def change_remote_url(self, entry):
self.remote_url = entry.get_text() self.remote_url = entry.get_text()
logger.debug(f"Changing remote url: {self.remote_url}")
if self.run_remote: if self.run_remote:
connection_handler.url = self.remote_url connection_handler.url = self.remote_url
if self.verify_connection() == False: if self.verify_connection() == False:
@ -319,9 +324,9 @@ class AlpacaWindow(Adw.ApplicationWindow):
@Gtk.Template.Callback() @Gtk.Template.Callback()
def closing_app(self, user_data): def closing_app(self, user_data):
if self.get_hide_on_close(): if self.get_hide_on_close():
print("Hiding app...") logger.info("Hiding app...")
else: else:
print("Closing app...") logger.info("Closing app...")
local_instance.stop() local_instance.stop()
@Gtk.Template.Callback() @Gtk.Template.Callback()
@ -441,6 +446,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
def show_toast(self, message:str, overlay): def show_toast(self, message:str, overlay):
logger.info(message)
toast = Adw.Toast( toast = Adw.Toast(
title=message, title=message,
timeout=2 timeout=2
@ -449,12 +455,14 @@ class AlpacaWindow(Adw.ApplicationWindow):
def show_notification(self, title:str, body:str, icon:Gio.ThemedIcon=None): def show_notification(self, title:str, body:str, icon:Gio.ThemedIcon=None):
if not self.is_active(): if not self.is_active():
logger.info(f"{title}, {body}")
notification = Gio.Notification.new(title) notification = Gio.Notification.new(title)
notification.set_body(body) notification.set_body(body)
if icon: notification.set_icon(icon) if icon: notification.set_icon(icon)
self.get_application().send_notification(None, notification) self.get_application().send_notification(None, notification)
def delete_message(self, message_element): def delete_message(self, message_element):
logger.debug("Deleting message")
id = message_element.get_name() id = message_element.get_name()
del self.chats["chats"][self.chats["selected_chat"]]["messages"][id] del self.chats["chats"][self.chats["selected_chat"]]["messages"][id]
self.chat_container.remove(message_element) self.chat_container.remove(message_element)
@ -463,12 +471,14 @@ class AlpacaWindow(Adw.ApplicationWindow):
self.save_history() self.save_history()
def copy_message(self, message_element): def copy_message(self, message_element):
logger.debug("Copying message")
id = message_element.get_name() id = message_element.get_name()
clipboard = Gdk.Display().get_default().get_clipboard() clipboard = Gdk.Display().get_default().get_clipboard()
clipboard.set(self.chats["chats"][self.chats["selected_chat"]]["messages"][id]["content"]) clipboard.set(self.chats["chats"][self.chats["selected_chat"]]["messages"][id]["content"])
self.show_toast(_("Message copied to the clipboard"), self.main_overlay) self.show_toast(_("Message copied to the clipboard"), self.main_overlay)
def edit_message(self, message_element, text_view, button_container): def edit_message(self, message_element, text_view, button_container):
logger.debug("Editing message")
if self.editing_message: self.send_message() if self.editing_message: self.send_message()
button_container.set_visible(False) button_container.set_visible(False)
@ -489,6 +499,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
self.editing_message = {"text_view": text_view, "id": id, "button_container": button_container, "footer": footer} self.editing_message = {"text_view": text_view, "id": id, "button_container": button_container, "footer": footer}
def preview_file(self, file_path, file_type, presend_name): def preview_file(self, file_path, file_type, presend_name):
logger.debug(f"Previewing file: {file_path}")
file_path = file_path.replace("{selected_chat}", self.chats["selected_chat"]) file_path = file_path.replace("{selected_chat}", self.chats["selected_chat"])
content = self.get_content_of_file(file_path, file_type) content = self.get_content_of_file(file_path, file_type)
if presend_name: if presend_name:
@ -548,6 +559,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
return messages return messages
def generate_chat_title(self, message, label_element): def generate_chat_title(self, message, label_element):
logger.debug("Generating chat title")
prompt = f""" prompt = f"""
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
@ -728,6 +740,7 @@ Generate a title following these rules:
self.bot_message_button_container = button_container self.bot_message_button_container = button_container
def update_list_local_models(self): def update_list_local_models(self):
logger.debug("Updating list of local models")
self.local_models = [] self.local_models = []
response = connection_handler.simple_get(f"{connection_handler.url}/api/tags") response = connection_handler.simple_get(f"{connection_handler.url}/api/tags")
for i in range(self.model_string_list.get_n_items() -1, -1, -1): for i in range(self.model_string_list.get_n_items() -1, -1, -1):
@ -874,6 +887,7 @@ Generate a title following these rules:
self.bot_message_box = None self.bot_message_box = None
def on_theme_changed(self, manager, dark, buffer): def on_theme_changed(self, manager, dark, buffer):
logger.debug("Theme changed")
if manager.get_dark(): if manager.get_dark():
source_style = GtkSource.StyleSchemeManager.get_default().get_scheme('Adwaita-dark') source_style = GtkSource.StyleSchemeManager.get_default().get_scheme('Adwaita-dark')
else: else:
@ -881,6 +895,7 @@ Generate a title following these rules:
buffer.set_style_scheme(source_style) buffer.set_style_scheme(source_style)
def on_copy_code_clicked(self, btn, text_buffer): def on_copy_code_clicked(self, btn, text_buffer):
logger.debug("Copying code")
clipboard = Gdk.Display().get_default().get_clipboard() clipboard = Gdk.Display().get_default().get_clipboard()
start = text_buffer.get_start_iter() start = text_buffer.get_start_iter()
end = text_buffer.get_end_iter() end = text_buffer.get_end_iter()
@ -933,6 +948,7 @@ Generate a title following these rules:
self.send_button.set_visible(not self.send_button.get_visible()) self.send_button.set_visible(not self.send_button.get_visible())
def run_message(self, messages, model, id): def run_message(self, messages, model, id):
logger.debug("Running message")
self.bot_message_button_container.set_visible(False) self.bot_message_button_container.set_visible(False)
response = connection_handler.stream_post(f"{connection_handler.url}/api/chat", data=json.dumps({"model": model, "messages": messages}), callback=lambda data, id=id: self.update_bot_message(data, id)) response = connection_handler.stream_post(f"{connection_handler.url}/api/chat", data=json.dumps({"model": model, "messages": messages}), callback=lambda data, id=id: self.update_bot_message(data, id))
GLib.idle_add(self.add_code_blocks) GLib.idle_add(self.add_code_blocks)
@ -980,6 +996,7 @@ Generate a title following these rules:
GLib.idle_add(self.pulling_model_list_box.set_visible, False) GLib.idle_add(self.pulling_model_list_box.set_visible, False)
def pull_model(self, model): def pull_model(self, model):
logger.info("Pulling model")
if model in list(self.pulling_models.keys()) or model in self.local_models: if model in list(self.pulling_models.keys()) or model in self.local_models:
return return
self.pulling_model_list_box.set_visible(True) self.pulling_model_list_box.set_visible(True)
@ -1013,11 +1030,13 @@ Generate a title following these rules:
thread.start() thread.start()
def confirm_pull_model(self, model_name): def confirm_pull_model(self, model_name):
logger.debug("Confirming pull model")
self.navigation_view_manage_models.pop() self.navigation_view_manage_models.pop()
self.model_tag_list_box.unselect_all() self.model_tag_list_box.unselect_all()
self.pull_model(model_name) self.pull_model(model_name)
def list_available_model_tags(self, model_name): def list_available_model_tags(self, model_name):
logger.debug("Listing available model tags")
self.navigation_view_manage_models.push_by_tag('model_tags_page') self.navigation_view_manage_models.push_by_tag('model_tags_page')
self.navigation_view_manage_models.find_page('model_tags_page').set_title(model_name.capitalize()) self.navigation_view_manage_models.find_page('model_tags_page').set_title(model_name.capitalize())
self.model_link_button.set_name(self.available_models[model_name]['url']) self.model_link_button.set_name(self.available_models[model_name]['url'])
@ -1037,6 +1056,7 @@ Generate a title following these rules:
self.model_tag_list_box.append(tag_row) self.model_tag_list_box.append(tag_row)
def update_list_available_models(self): def update_list_available_models(self):
logger.debug("Updating list of available models")
self.available_model_list_box.connect('row_selected', lambda list_box, row: self.list_available_model_tags(row.get_name()) if row else None) self.available_model_list_box.connect('row_selected', lambda list_box, row: self.list_available_model_tags(row.get_name()) if row else None)
self.available_model_list_box.remove_all() self.available_model_list_box.remove_all()
for name, model_info in self.available_models.items(): for name, model_info in self.available_models.items():
@ -1055,6 +1075,7 @@ Generate a title following these rules:
self.available_model_list_box.append(model) self.available_model_list_box.append(model)
def save_history(self): def save_history(self):
logger.debug("Saving history")
with open(os.path.join(self.data_dir, "chats", "chats.json"), "w+") as f: with open(os.path.join(self.data_dir, "chats", "chats.json"), "w+") as f:
json.dump(self.chats, f, indent=4) json.dump(self.chats, f, indent=4)
@ -1071,6 +1092,7 @@ Generate a title following these rules:
self.bot_message = None self.bot_message = None
def load_history(self): def load_history(self):
logger.debug("Loading history")
if os.path.exists(os.path.join(self.data_dir, "chats", "chats.json")): if os.path.exists(os.path.join(self.data_dir, "chats", "chats.json")):
try: try:
with open(os.path.join(self.data_dir, "chats", "chats.json"), "r") as f: with open(os.path.join(self.data_dir, "chats", "chats.json"), "r") as f:
@ -1108,11 +1130,13 @@ Generate a title following these rules:
return f"{datetime.today().strftime('%Y%m%d%H%M%S%f')}{uuid.uuid4().hex}" return f"{datetime.today().strftime('%Y%m%d%H%M%S%f')}{uuid.uuid4().hex}"
def clear_chat(self): def clear_chat(self):
logger.info("Clearing chat")
for widget in list(self.chat_container): self.chat_container.remove(widget) for widget in list(self.chat_container): self.chat_container.remove(widget)
self.chats["chats"][self.chats["selected_chat"]]["messages"] = [] self.chats["chats"][self.chats["selected_chat"]]["messages"] = []
self.save_history() self.save_history()
def delete_chat(self, chat_name): def delete_chat(self, chat_name):
logger.info("Deleting chat")
del self.chats['chats'][chat_name] del self.chats['chats'][chat_name]
self.chats['order'].remove(chat_name) self.chats['order'].remove(chat_name)
if os.path.exists(os.path.join(self.data_dir, "chats", chat_name)): if os.path.exists(os.path.join(self.data_dir, "chats", chat_name)):
@ -1125,6 +1149,7 @@ Generate a title following these rules:
self.chat_list_box.select_row(self.chat_list_box.get_row_at_index(0)) self.chat_list_box.select_row(self.chat_list_box.get_row_at_index(0))
def rename_chat(self, old_chat_name, new_chat_name, label_element): def rename_chat(self, old_chat_name, new_chat_name, label_element):
logger.info(f"Renaming chat \"{old_chat_name}\" -> \"{new_chat_name}\"")
new_chat_name = self.generate_numbered_name(new_chat_name, self.chats["chats"].keys()) new_chat_name = self.generate_numbered_name(new_chat_name, self.chats["chats"].keys())
if self.chats["selected_chat"] == old_chat_name: self.chats["selected_chat"] = new_chat_name if self.chats["selected_chat"] == old_chat_name: self.chats["selected_chat"] = new_chat_name
self.chats["chats"][new_chat_name] = self.chats["chats"][old_chat_name] self.chats["chats"][new_chat_name] = self.chats["chats"][old_chat_name]
@ -1145,10 +1170,12 @@ Generate a title following these rules:
self.new_chat_element(chat_name, True, False) self.new_chat_element(chat_name, True, False)
def stop_pull_model(self, model_name): def stop_pull_model(self, model_name):
logger.debug("Stopping model pull")
self.pulling_models[model_name]['overlay'].get_parent().get_parent().remove(self.pulling_models[model_name]['overlay'].get_parent()) self.pulling_models[model_name]['overlay'].get_parent().get_parent().remove(self.pulling_models[model_name]['overlay'].get_parent())
del self.pulling_models[model_name] del self.pulling_models[model_name]
def delete_model(self, model_name): def delete_model(self, model_name):
logger.debug("Deleting model")
response = connection_handler.simple_delete(f"{connection_handler.url}/api/delete", data={"name": model_name}) response = connection_handler.simple_delete(f"{connection_handler.url}/api/delete", data={"name": model_name})
self.update_list_local_models() self.update_list_local_models()
if response.status_code == 200: if response.status_code == 200:
@ -1205,15 +1232,18 @@ Generate a title following these rules:
self.new_chat_element(name, self.chats["selected_chat"] == name, True) self.new_chat_element(name, self.chats["selected_chat"] == name, True)
def show_preferences_dialog(self): def show_preferences_dialog(self):
logger.debug("Showing preferences dialog")
self.preferences_dialog.present(self) self.preferences_dialog.present(self)
def connect_remote(self, url): def connect_remote(self, url):
logger.debug(f"Connecting to remote: {url}")
connection_handler.url = url connection_handler.url = url
self.remote_url = connection_handler.url self.remote_url = connection_handler.url
self.remote_connection_entry.set_text(self.remote_url) self.remote_connection_entry.set_text(self.remote_url)
if self.verify_connection() == False: self.connection_error() if self.verify_connection() == False: self.connection_error()
def connect_local(self): def connect_local(self):
logger.debug("Connecting to Alpaca's Ollama instance")
self.run_remote = False self.run_remote = False
connection_handler.bearer_token = None connection_handler.bearer_token = None
connection_handler.url = f"http://127.0.0.1:{local_instance.port}" connection_handler.url = f"http://127.0.0.1:{local_instance.port}"
@ -1222,6 +1252,7 @@ Generate a title following these rules:
else: self.remote_connection_switch.set_active(False) else: self.remote_connection_switch.set_active(False)
def connection_error(self): def connection_error(self):
logger.error("Connection error")
if self.run_remote: if self.run_remote:
dialogs.reconnect_remote(self, connection_handler.url) dialogs.reconnect_remote(self, connection_handler.url)
else: else:
@ -1229,6 +1260,7 @@ Generate a title following these rules:
self.show_toast(_("There was an error with the local Ollama instance, so it has been reset"), self.main_overlay) self.show_toast(_("There was an error with the local Ollama instance, so it has been reset"), self.main_overlay)
def connection_switched(self): def connection_switched(self):
logger.debug("Connection switched")
new_value = self.remote_connection_switch.get_active() new_value = self.remote_connection_switch.get_active()
if new_value != self.run_remote: if new_value != self.run_remote:
self.run_remote = new_value self.run_remote = new_value
@ -1277,6 +1309,7 @@ Generate a title following these rules:
) )
def export_chat(self, chat_name): def export_chat(self, chat_name):
logger.info("Exporting chat")
file_dialog = Gtk.FileDialog(initial_name=f"{chat_name}.tar") file_dialog = Gtk.FileDialog(initial_name=f"{chat_name}.tar")
file_dialog.save(parent=self, cancellable=None, callback=lambda file_dialog, result, chat_name=chat_name: self.on_export_chat(file_dialog, result, chat_name)) file_dialog.save(parent=self, cancellable=None, callback=lambda file_dialog, result, chat_name=chat_name: self.on_export_chat(file_dialog, result, chat_name))
@ -1316,10 +1349,12 @@ Generate a title following these rules:
self.show_toast(_("Chat imported successfully"), self.main_overlay) self.show_toast(_("Chat imported successfully"), self.main_overlay)
def import_chat(self): def import_chat(self):
logger.info("Importing chat")
file_dialog = Gtk.FileDialog(default_filter=self.file_filter_tar) file_dialog = Gtk.FileDialog(default_filter=self.file_filter_tar)
file_dialog.open(self, None, self.on_chat_imported) file_dialog.open(self, None, self.on_chat_imported)
def switch_run_on_background(self): def switch_run_on_background(self):
logger.debug("Switching run on background")
self.run_on_background = self.background_switch.get_active() self.run_on_background = self.background_switch.get_active()
self.set_hide_on_close(self.run_on_background) self.set_hide_on_close(self.run_on_background)
self.verify_connection() self.verify_connection()
@ -1357,12 +1392,14 @@ Generate a title following these rules:
return text return text
def remove_attached_file(self, name): def remove_attached_file(self, name):
logger.debug("Removing attached file")
button = self.attachments[name]['button'] button = self.attachments[name]['button']
button.get_parent().remove(button) button.get_parent().remove(button)
del self.attachments[name] del self.attachments[name]
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):
logger.debug(f"Attaching file: {file_path}")
file_name = self.generate_numbered_name(os.path.basename(file_path), self.attachments.keys()) file_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:
@ -1446,6 +1483,7 @@ Generate a title following these rules:
except Exception as e: 'huh' except Exception as e: 'huh'
def on_clipboard_paste(self, textview): def on_clipboard_paste(self, textview):
logger.debug("Pasting from clipboard")
clipboard = Gdk.Display.get_default().get_clipboard() clipboard = Gdk.Display.get_default().get_clipboard()
clipboard.read_text_async(None, self.cb_text_received) clipboard.read_text_async(None, self.cb_text_received)
clipboard.read_texture_async(None, self.cb_image_received) clipboard.read_texture_async(None, self.cb_image_received)