import gi gi.require_version('Gtk', '4.0') from gi.repository import Gtk, GLib import numpy from PIL import Image import requests import io import threading import time import logging import src.utils as utils logger = logging.getLogger(__name__) class CoverEntry(Gtk.Box): def __init__(self, parent_window, resources, filename=None): Gtk.Box.__init__(self) self._parent_window = parent_window self._image = Image.open(filename or f'{resources}/blank-cover.png') self._picture = Gtk.Picture.new_for_pixbuf(utils.image_to_pixbuf(self._image)) self.append(self._picture) gesture_click = Gtk.GestureClick() gesture_click.connect('released', self._on_open_dialog) self._picture.add_controller(gesture_click) def get_image(self): return self._image def _on_open_dialog(self, gesture, n_press, x, y): self._dialog = Gtk.Window() utils.configure_dialog(self._dialog, self._parent_window, 'Couverture', height=None) self._dialog_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=20) self._dialog.set_child(self._dialog_box) utils.set_margin(self._dialog_box, 20) self._error_message = None self._dialog_box.append(utils.label('URL')) self._url_entry = Gtk.Entry() self._dialog_box.append(self._url_entry) self._append_download_button() self._dialog.present() def _on_download_cover(self): if(self._url_entry.get_text()): thread = threading.Thread(target=self._download_cover_daemon) thread.daemon = True thread.start() self._dialog_spinner = Gtk.Spinner() self._dialog_spinner.start() self._dialog_box.append(self._dialog_spinner) self._dialog_box.remove(self._dialog_button) if self._error_message: self._dialog_box.remove(self._error_message) def _download_cover_daemon(self): try: self._image = download_image(self._url_entry.get_text()) self._picture.set_pixbuf(utils.image_to_pixbuf(self._image)) GLib.idle_add(self._complete_download) except Exception as e: logger.error('Failed downloading cover %s: %s', self._url_entry, e) self._dialog_spinner.stop() self._dialog_box.remove(self._dialog_spinner) self._error_message = utils.label(f'{e}') self._dialog_box.append(self._error_message) self._append_download_button() def _append_download_button(self): self._dialog_button = Gtk.Button(label='Télécharger') self._dialog_button.connect('clicked', lambda _: self._on_download_cover()) self._dialog_box.append(self._dialog_button) def _complete_download(self): self._dialog.close() def download_image(url): response = requests.get(url, headers={ 'User-Agent': 'python-script' }) image = Image.open(io.BytesIO(response.content)) width, height = image.size if width > 400: image = image.resize((400, int(400 * height / width)), Image.LANCZOS) return image