~fabrixxm/confy

2112b171785a95ee0e315d73615c94ec27a59a16 — fabrixxm 8 months ago dedfaf3
Notify incoming events
2 files changed, 73 insertions(+), 11 deletions(-)

M src/mainwindow.py
M src/models.py
M src/mainwindow.py => src/mainwindow.py +61 -11
@@ 2,6 2,7 @@ from gi.repository import Gio
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Adw
from gi.repository import Notify

from . import local
from . import models


@@ 13,7 14,7 @@ from .widgets import PageHeaderBar
from .pages import PageInfo
from .pages import PageList
from .pages import PageDetails

from .utils import clean_markup

@Gtk.Template(resource_path="/net/kirgroup/confy/mainwindow.ui")
class MainWindow(Adw.ApplicationWindow):


@@ 68,6 69,13 @@ class MainWindow(Adw.ApplicationWindow):
                self.emit("conf-updated")
                self.show_main()

        self.notifications = {}
        # Check if there are notifications to send
        Gio.Application.get_default().connect(
            'tick', self.check_event_notification
        )
        self.check_event_notification()

    def _init_pages(self):
        for p in self.main_stack.get_pages():
            child = p.get_child()


@@ 92,6 100,41 @@ class MainWindow(Adw.ApplicationWindow):
    def _on_fetcher_error(self, fetcher, error):
        self.show_error(error)

    def check_event_notification(self, *args):
        nextup = list(models.Event.nextup(5))
        for e in nextup:
            # fast and stupid clean html
            #cleanr = re.compile('<.*?>|&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-f]{1,6});')
            #title = re.sub(cleanr, '', e.title)
            title = clean_markup(e.title)
            self._send_desktop_notification(
                _("Next up: {}").format(title),
                _("at {} in {}").format(
                    e.start_in_tz().strftime("%H:%M"),
                    e.room
                ),
                f"nextup-{e.id}")
            e.set_notified(True)

    def _send_desktop_notification(self, title, body, nid=None):
        n = Notify.Notification.new(title, body, APP_ID)
        n.set_timeout(Notify.EXPIRES_NEVER)
        n.add_action("view", "View", self.on_notification_action, nid)
        n.show()
        self.notifications[nid] = n

    def on_notification_action(self, notification, action, data):
        print(notification, action, data)
        if action == "view" and data.startswith("nextup-"):
            eventid = int(data.split("-")[1])
            event = models.Event.by_id(eventid)
            # if we are not on "events" subpage, force it as non navigatable,
            # we want to be back to we were
            print(self.subpage_leaflet.get_visible_child(), self.subpage_events)
            can_we_go_back_to_events = self.subpage_leaflet.get_visible_child() == self.subpage_events
            self.show_details(event, can_we_go_back_to_events)


    def show_loader(self):
        self.loader_stack.set_visible_child_name("loader")



@@ 114,13 157,6 @@ class MainWindow(Adw.ApplicationWindow):

    @Gtk.Template.Callback()
    def _on_page_changed(self, *_):
        # Quindi. Quando la pagina cambia su "starred"
        # imposto "subpage_events" come non "navigatable"
        # così quando l'utente sceglie un evento preferito, viene mandato a
        # "subpage_details", e quando naviga indietro torna a "leaflet"
        is_events_navigatable = self.main_stack.get_visible_child_name() != "starred"
        self.subpage_leaflet.get_page(self.subpage_events).set_navigatable(is_events_navigatable)

        self.set_pageheader_title()
        self.show_stack()



@@ 149,6 185,22 @@ class MainWindow(Adw.ApplicationWindow):
    def show_search_all(self):
        self.subpage_leaflet.get_page(self.subpage_events).set_navigatable(False)
        self.subpage_leaflet.get_page(self.subpage_details).set_navigatable(False)

    def show_details(self, event, is_events_navigatable=None):
        # Se sono sulla pagina "starred"
        # imposto "subpage_events" come non "navigatable"
        # così quando l'utente sceglie un evento preferito, viene mandato a
        # "subpage_details", e quando naviga indietro torna a "leaflet".
        #
        # A meno che non ci sia impostato 'is_events_navigatable' come paramentro,
        # nel qual caso, vince lui.
        if is_events_navigatable is None:
            is_events_navigatable = self.main_stack.get_visible_child_name() != "starred"
        self.subpage_leaflet.get_page(self.subpage_events).set_navigatable(is_events_navigatable)

        self.subpage_details.set_obj(event)
        self.show_subpage_details()

    @Gtk.Template.Callback()
    def _on_pagelist_row_activated(self, page):
        self.subpage_events.set_model(page.get_model())


@@ 157,6 209,4 @@ class MainWindow(Adw.ApplicationWindow):

    @Gtk.Template.Callback()
    def _on_event_row_activated(self, page):
        self.subpage_details.set_obj(page.get_value())
        self.show_subpage_details()

        self.show_details(page.get_value())

M src/models.py => src/models.py +12 -0
@@ 25,6 25,11 @@ from . import local
from .settings import Settings
from .fetcher import Fetcher


class ObjectNotFound(Exception):
    pass


## models
def _build_filter(day=None, room=None, track=None, event=None, **kwargs):
        filterdata = []


@@ 398,6 403,13 @@ class Event(GObject.GObject):
            yield cls()._init(row)

    @classmethod
    def by_id(cls, id):
        row = local.getDb().execute("SELECT * FROM events WHERE id = ?", (id,)).fetchone()
        if row is None:
            raise ObjectNotFound("<{} #{}>".format(cls.__name__, id))
        return cls()._init(row)

    @classmethod
    def filter(cls, day:Day = None, room:Room = None, track:Track = None, **kwargs):
        filterdata, wherestm = _build_filter(day=day, room=room, track=track, **kwargs)