From f7ef1668f39c0d4b950728b6668a1c65f620fc03 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 28 Mar 2024 21:27:57 +0100 Subject: [PATCH] fetch data & generate qr code on separate thread makes the app more responsive --- choochoo/deutschlandticket.py | 14 ++++++++++++++ choochoo/home.py | 13 +++++++++++-- choochoo/ticketview.py | 32 ++++++++++++++------------------ 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/choochoo/deutschlandticket.py b/choochoo/deutschlandticket.py index ff2f926..bc4bf82 100644 --- a/choochoo/deutschlandticket.py +++ b/choochoo/deutschlandticket.py @@ -4,6 +4,8 @@ import os import json from choochoo.utils import get_data_dir from typing import Self +import base64 +import treepoem class Ticket(): id: str @@ -89,6 +91,18 @@ class Ticket(): fpath = os.path.join(get_data_dir(), name) return fpath + def generate_code(self): + barcode = self.barcode + + buf = base64.b64decode(barcode) + bin = buf.decode("latin-1") + + img = treepoem.generate_barcode( + barcode_type="azteccode", + data=bin, + options={ "binaryText": True }) + return img.convert("1") + def save(self): fpath = self.get_file_path() handle = open(fpath, "w", encoding="utf-8") diff --git a/choochoo/home.py b/choochoo/home.py index 9edaf70..87d8cd6 100644 --- a/choochoo/home.py +++ b/choochoo/home.py @@ -4,6 +4,7 @@ gi.require_version('Adw', '1') from gi.repository import Gtk, Adw, Gio, GLib from datetime import datetime, timezone from gettext import gettext as _ +import threading from choochoo.widgets.iconbutton import IconButton from choochoo.utils import pass_me, get_data_dir, get_month_name @@ -70,16 +71,24 @@ class HomeScreen(Adw.NavigationPage): # show loading toast GLib.idle_add(self.show_toast, _("Fetching ticket information")) # fetch ticket data + thread = threading.Thread( + target = self.add_ticket_task, + args=[tnumber, tsurname] + ) + thread.daemon = True + thread.start() + def add_ticket_task(self, tnumber, tsurname): tnum = tnumber.get_text() tsur = tsurname.get_text() ticket = Ticket.from_network(tnum, tsur) if ticket is None: GLib.idle_add(self.show_toast, _("Unable to add the ticket.")) return - # save ticket + # got ticket data + # save ticket on disk, for future usage ticket.save() GLib.idle_add(self.show_toast, _("Done")) - self.update() + GLib.idle_add(self.update) def update(self): # show spinner # NOTE: not quite sure if this is ever visible diff --git a/choochoo/ticketview.py b/choochoo/ticketview.py index 24f6fd1..c60b852 100644 --- a/choochoo/ticketview.py +++ b/choochoo/ticketview.py @@ -5,8 +5,7 @@ from gi.repository import Gtk, Adw, Gio, GLib, Gdk from gettext import gettext as _ import os import io -import base64 -import treepoem +import threading from choochoo.widgets.iconbutton import IconButton from choochoo.widgets.daterow import DateRow @@ -64,7 +63,9 @@ class TicketScreen(Adw.NavigationPage): def fetch(self): GLib.idle_add(self.show_toast, _("Fetching ticket information")) - self.task_fetch() + thread = threading.Thread(target = self.task_fetch) + thread.daemon = True + thread.start() def task_fetch(self): tnumber = self.ticket.ticket_number @@ -79,21 +80,11 @@ class TicketScreen(Adw.NavigationPage): GLib.idle_add(self.update) def generate_code(self): - barcode = self.ticket.barcode - - buf = base64.b64decode(barcode) - bin = buf.decode("latin-1") - - img = treepoem.generate_barcode( - barcode_type="azteccode", - data=bin, - options={ "binaryText": True }) - return img.convert("1") - - def show_code(self): - img = self.generate_code() + img = self.ticket.generate_code() f = io.BytesIO() img.save(f, format="png") + GLib.idle_add(self.show_code, f) + def show_code(self, f): buf = GLib.Bytes.new(f.getvalue()) texture = Gdk.Texture.new_from_bytes(buf) pic = Gtk.Picture.new_for_paintable(texture) @@ -120,13 +111,18 @@ class TicketScreen(Adw.NavigationPage): spinner.start() spinner.set_margin_top(12) spinner.set_margin_bottom(12) + spinner.set_margin_start(12) + spinner.set_margin_end(12) cb = Gtk.CenterBox() self.qrbox = Adw.Bin() self.qrbox.add_css_class("card") self.qrbox.set_child(spinner) cb.set_center_widget(self.qrbox) - # TODO: this takes a while, consider starting a separate thread - self.show_code() + # generating the qr code takes a while + # running this on a separate thread makes the app more responsive + thread = threading.Thread(target = self.generate_code) + thread.daemon = True + thread.start() page.append(code_group) page.append(cb) connection_group = Adw.PreferencesGroup() -- 2.38.5