aboutsummaryrefslogtreecommitdiff
path: root/src/ui/cover_entry.py
blob: 8f73a01e205b033a05d799daa92052889f46538f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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