diff -Nru confy-0.5.1/CHANGELOG confy-0.6.1/CHANGELOG --- confy-0.5.1/CHANGELOG 1970-01-01 00:00:00.000000000 +0000 +++ confy-0.6.1/CHANGELOG 2021-09-30 15:03:39.000000000 +0000 @@ -0,0 +1,74 @@ +# CHANGELOG + +## [unreleased] + +## [0.6.1] - 2021-07-18 +### Add +- Support for adaptive filter in Phosh app drawer +### Fixed +- Event progressbar handle events with zero duration (devrtz) (fix ~fabrixxm/confy#18) +### Changed +- Store events datetimes as UTC in db, display in current timezone. + +## [0.6.0] - 2021-06-12 +### Added +- Full-text search in shedule view (fix ~fabrixxm/confy#11) +- Full-text search in starred view (fix ~fabrixxm/confy#12) + +### Fixed +- Add page stack to starred view (fix ~fabrixxm/confy#13) +- Move Search Bar revealer out of overlay (fix ~fabrixxm/confy#10) + +### Changed +- Modify primary menu to better fit GNOME guidelines (seabass) +- Move 'star event' button to end of event widget (seabass) + + +## [0.5.5] - 2020-04-06 +### Added +- Open urls with default application per file type, if possible + +## [0.5.4] - 20201-02-18 +### Fixed +- Use correct file for appstream metadata +- Remove more unsupported markup tags from strings +- Fix "next up" query and notification + +### Changed +- Updated flatpack to GNOME Runtime 3.38 + + +## [0.5.3] - 2021-01-28 +### Added +- Event progress indicator in event list row widget + +### Fixed +- Fix overlapping events query (don't return event ending/starting on same exact time) + + +## [0.5.2] - 2021-01-17 +### Added +- Search in conferences list +- Global shortcuts +- Shortcuts window + +### Changed +- Install python module in python's site-lib dir +- Fix metadata install path +- Fix flatpak manifest: add python deps + + +## [0.5.1] - 2020-12-30 +### Added +- Allow edit user-added conference metadata +- Allow remove user-added conferences +- Show editing dialog after adding a custom url +- Clear cache from preferences dialog + +### Changed +- Set a maximum size for conferece logo in main page + +### Fixed +- Small fixes to UI +- Support "baseurl" property in pentabarf +- Fix XML entities stripping diff -Nru confy-0.5.1/data/meson.build confy-0.6.1/data/meson.build --- confy-0.5.1/data/meson.build 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/data/meson.build 2021-09-30 15:03:39.000000000 +0000 @@ -60,31 +60,23 @@ ) endif -appstream_file = i18n.merge_file( - input: 'net.kirgroup.confy.appdata.xml.in', - output: 'net.kirgroup.confy.appdata.xml', - po_dir: '../po', - install: true, - install_dir: join_paths(get_option('datadir'), 'appdata') +metainfo_file = i18n.merge_file( + input: 'net.kirgroup.confy.metainfo.xml.in', + output: 'net.kirgroup.confy.metainfo.xml', + type: 'xml', + po_dir: join_paths (meson.source_root(), 'po'), + install: true, + install_dir: join_paths (get_option ('datadir'), 'metainfo') ) appstream_cli = find_program('appstream-util', required: false) if appstream_cli.found() test('Validate appstream file', appstream_cli, - args: ['validate', '--nonet', appstream_file] + args: ['validate', '--nonet', metainfo_file] ) endif -metainfo_file = i18n.merge_file( - input: 'net.kirgroup.confy.metainfo.xml', - output: 'net.kirgroup.confy.metainfo.xml', - type: 'xml', - po_dir: join_paths (meson.source_root(), 'po'), - install: true, - install_dir: join_paths (get_option ('datadir'), 'metainfo') -) - install_data('net.kirgroup.confy.gschema.xml', install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas') ) diff -Nru confy-0.5.1/data/net.kirgroup.confy.appdata.xml.in confy-0.6.1/data/net.kirgroup.confy.appdata.xml.in --- confy-0.5.1/data/net.kirgroup.confy.appdata.xml.in 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/data/net.kirgroup.confy.appdata.xml.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ - - - net.kirgroup.confy - Confy - fabrixxm - -

- Confy lets you browse conference schedules. -

-

- Confy lets you organise your visit - select talks to be reminded of (with warnings in case of conflicts). -

-
- Conference schedules viewer - CC-BY-4.0 - GPL-3.0+ - https://confy.kirgroup.net - https://todo.sr.ht/~fabrixxm/confy - GNOME - - https://confy.kirgroup.net/confy1.png - https://confy.kirgroup.net/confy2.png - https://confy.kirgroup.net/confy3.png - - - - - - - - -
- diff -Nru confy-0.5.1/data/net.kirgroup.confy.desktop.in confy-0.6.1/data/net.kirgroup.confy.desktop.in --- confy-0.5.1/data/net.kirgroup.confy.desktop.in 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/data/net.kirgroup.confy.desktop.in 2021-09-30 15:03:39.000000000 +0000 @@ -3,6 +3,8 @@ Exec=confy Terminal=false Type=Application -Categories=GTK; +Categories=Utility;GTK; StartupNotify=true Icon=net.kirgroup.confy +Keywords=Conference;Organize; +X-Purism-FormFactor=Workstation;Mobile; diff -Nru confy-0.5.1/data/net.kirgroup.confy.metainfo.xml confy-0.6.1/data/net.kirgroup.confy.metainfo.xml --- confy-0.5.1/data/net.kirgroup.confy.metainfo.xml 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/data/net.kirgroup.confy.metainfo.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ - - - net.kirgroup.confy - - Confy - Conference schedules viewer - - CC-BY-4.0 - GPL-3.0-or-later - - - pointing - keyboard - touch - - - -

- Confy lets you browse conference schedules. -

-

- Confy lets you organise your visit - select talks to be reminded of (with warnings in case of conflicts). -

-
- - net.kirgroup.confy.desktop - - - https://confy.kirgroup.net/confy1.png - - - https://confy.kirgroup.net/confy2.png - - - https://confy.kirgroup.net/confy3.png - - -
diff -Nru confy-0.5.1/data/net.kirgroup.confy.metainfo.xml.in confy-0.6.1/data/net.kirgroup.confy.metainfo.xml.in --- confy-0.5.1/data/net.kirgroup.confy.metainfo.xml.in 1970-01-01 00:00:00.000000000 +0000 +++ confy-0.6.1/data/net.kirgroup.confy.metainfo.xml.in 2021-09-30 15:03:39.000000000 +0000 @@ -0,0 +1,73 @@ + + + net.kirgroup.confy + Confy + Fabio Comuni + ~fabrixxm/confy-dev@lists.sr.ht + Conference schedules viewer + +

+ Confy lets you browse conference schedules. +

+

+ Browse talks by day, track or room. + Select the talks you are interested in and receive notification when they are about to start. + View when two or more talks you are interested in overlap. +

+
+ net.kirgroup.confy.desktop + CC-BY-4.0 + GPL-3.0-or-later + https://confy.kirgroup.net + https://todo.sr.ht/~fabrixxm/confy + GNOME + + https://confy.kirgroup.net/appdata/confy1.jpg + https://confy.kirgroup.net/appdata/confy2.jpg + https://confy.kirgroup.net/appdata/confy3.jpg + + + + workstation + mobile + + + + +

Fix event progressbar for events with zero duration

+

Display events talks datetimes in current timezone

+

Declare support for mobile devices in metadata

+
+
+ + +

Search talks in schedule and starred view

+

Better page navigation in starred view

+

Varius enhancement to UI to better fit GNOME guidelines

+
+
+ + +

Open urls with default application per file type, if possible.

+
+
+ + +

Fix "next up" query and notification.

+

Fix text rendering issues with unsupported markup tags.

+
+
+ + +

Add event progress indicator.

+

Fix overlapping events definition: exclude events ending/starting on same exact time.

+
+
+ + + + + +
+
+ diff -Nru confy-0.5.1/debian/changelog confy-0.6.1/debian/changelog --- confy-0.5.1/debian/changelog 2021-04-14 12:53:53.000000000 +0000 +++ confy-0.6.1/debian/changelog 2021-10-01 21:42:07.000000000 +0000 @@ -1,3 +1,26 @@ +confy (0.6.1-1) unstable; urgency=medium + + [ Federico Ceratto ] + * Adding myself to uploaders + + [ Evangelos Ribeiro Tzaras ] + * New upstream version 0.6.1 (Closes: #995436) + * d/gbp.conf: Use default upstream-vcs-tag format + * d/README.source: Document update procedure + * Remove upstreamed patches + + -- Federico Ceratto Fri, 01 Oct 2021 22:42:07 +0100 + +confy (0.6.0-1) experimental; urgency=medium + + [ Evangelos Ribeiro Tzaras ] + * New upstream version 0.6.0 + * d/patches: Remove upstreamed patches + * d/patches: Fix non-fatal division by zero error + * d/copyright: appdata.xml.in has been removed + + -- Federico Ceratto Sun, 13 Jun 2021 21:30:01 +0100 + confy (0.5.1-2) experimental; urgency=medium * Add gnome-icon-theme dependency diff -Nru confy-0.5.1/debian/control confy-0.6.1/debian/control --- confy-0.5.1/debian/control 2021-04-14 12:52:41.000000000 +0000 +++ confy-0.6.1/debian/control 2021-10-01 21:42:07.000000000 +0000 @@ -3,6 +3,7 @@ Priority: optional Maintainer: DebianOnMobile Maintainers Uploaders: + Federico Ceratto , Evangelos Ribeiro Tzaras , Build-Depends: appstream-util, @@ -16,7 +17,7 @@ python3-all, python3-icalendar, python3-setuptools, -Standards-Version: 4.5.1 +Standards-Version: 4.6.0 Homepage: https://confy.kirgroup.net/ Vcs-Browser: https://salsa.debian.org/DebianOnMobile-team/confy Vcs-Git: https://salsa.debian.org/DebianOnMobile-team/confy.git diff -Nru confy-0.5.1/debian/copyright confy-0.6.1/debian/copyright --- confy-0.5.1/debian/copyright 2021-04-13 18:39:30.000000000 +0000 +++ confy-0.6.1/debian/copyright 2021-10-01 21:42:07.000000000 +0000 @@ -12,7 +12,6 @@ License: CC-BY-SA-4.0 Files: data/net.kirgroup.confy.metainfo.* - data/net.kirgroup.confy.appdata.* Copyright: 2020 fabrixxm License: CC-BY-4.0 diff -Nru confy-0.5.1/debian/gbp.conf confy-0.6.1/debian/gbp.conf --- confy-0.5.1/debian/gbp.conf 2021-04-13 18:23:29.000000000 +0000 +++ confy-0.6.1/debian/gbp.conf 2021-10-01 21:42:07.000000000 +0000 @@ -1,7 +1,6 @@ [DEFAULT] pristine-tar = True debian-branch = debian/master -upstream-tag = %(version)s [dch] multimaint-merge = True diff -Nru confy-0.5.1/debian/patches/0001-fix-appstream-metadata-location.patch confy-0.6.1/debian/patches/0001-fix-appstream-metadata-location.patch --- confy-0.5.1/debian/patches/0001-fix-appstream-metadata-location.patch 2021-04-13 18:23:29.000000000 +0000 +++ confy-0.6.1/debian/patches/0001-fix-appstream-metadata-location.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -From: Evangelos Ribeiro Tzaras -Subject: Metadata goes into /usr/share/metainfo -Forwarded: https://lists.sr.ht/~fabrixxm/confy-dev/patches/16453 ---- a/data/meson.build -+++ b/data/meson.build -@@ -65,7 +65,7 @@ - output: 'net.kirgroup.confy.appdata.xml', - po_dir: '../po', - install: true, -- install_dir: join_paths(get_option('datadir'), 'appdata') -+ install_dir: join_paths(get_option('datadir'), 'metainfo') - ) - - appstream_cli = find_program('appstream-util', required: false) diff -Nru confy-0.5.1/debian/patches/0002-desktop-file-main-category.patch confy-0.6.1/debian/patches/0002-desktop-file-main-category.patch --- confy-0.5.1/debian/patches/0002-desktop-file-main-category.patch 2021-04-13 18:23:29.000000000 +0000 +++ confy-0.6.1/debian/patches/0002-desktop-file-main-category.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -From: Evangelos Ribeiro Tzaras -Subject: Add Utility main category to desktop file -Forwarded: https://lists.sr.ht/~fabrixxm/confy-dev/patches/16453 ---- a/data/net.kirgroup.confy.desktop.in -+++ b/data/net.kirgroup.confy.desktop.in -@@ -3,6 +3,6 @@ - Exec=confy - Terminal=false - Type=Application --Categories=GTK; -+Categories=Utility;GTK; - StartupNotify=true - Icon=net.kirgroup.confy diff -Nru confy-0.5.1/debian/patches/0003-desktop-add-keywords.patch confy-0.6.1/debian/patches/0003-desktop-add-keywords.patch --- confy-0.5.1/debian/patches/0003-desktop-add-keywords.patch 2021-04-13 18:23:29.000000000 +0000 +++ confy-0.6.1/debian/patches/0003-desktop-add-keywords.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -From: Evangelos Ribeiro Tzaras -Subject: Add keywords to desktop file -Forwarded: https://lists.sr.ht/~fabrixxm/confy-dev/patches/16453 ---- a/data/net.kirgroup.confy.desktop.in -+++ b/data/net.kirgroup.confy.desktop.in -@@ -6,3 +6,4 @@ - Categories=Utility;GTK; - StartupNotify=true - Icon=net.kirgroup.confy -+Keywords=Conference;Organize; diff -Nru confy-0.5.1/debian/patches/0004-fix-python-install-dir.patch confy-0.6.1/debian/patches/0004-fix-python-install-dir.patch --- confy-0.5.1/debian/patches/0004-fix-python-install-dir.patch 2021-04-13 18:23:29.000000000 +0000 +++ confy-0.6.1/debian/patches/0004-fix-python-install-dir.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -From: Evangelos Ribeiro Tzaras -Subject: Install module in correct python directories -Forwarded: https://lists.sr.ht/~fabrixxm/confy-dev/patches/16453 ---- a/src/meson.build -+++ b/src/meson.build -@@ -1,5 +1,4 @@ - pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) --moduledir = join_paths(pkgdatadir, 'confy') - gnome = import('gnome') - - gnome.compile_resources('confy', -@@ -10,12 +9,16 @@ - ) - - python = import('python') -+python3 = python.find_installation('python3') -+pythondir = join_paths(get_option('prefix'), python3.get_path('purelib')) -+moduledir = join_paths(pythondir, 'confy') - - conf = configuration_data() --conf.set('PYTHON', python.find_installation('python3').path()) -+conf.set('PYTHON', python3.path()) - conf.set('VERSION', meson.project_version()) - conf.set('localedir', join_paths(get_option('prefix'), get_option('localedir'))) - conf.set('pkgdatadir', pkgdatadir) -+conf.set('pythondir', pythondir) - - configure_file( - input: 'confy.in', ---- a/src/confy.in -+++ b/src/confy.in -@@ -24,9 +24,10 @@ - - VERSION = '@VERSION@' - pkgdatadir = '@pkgdatadir@' -+pythondir = '@pythondir@' - localedir = '@localedir@' - --sys.path.insert(1, pkgdatadir) -+sys.path.insert(1, pythondir) - signal.signal(signal.SIGINT, signal.SIG_DFL) - gettext.install('confy', localedir) - diff -Nru confy-0.5.1/debian/patches/0005-use-get_install_dir.patch confy-0.6.1/debian/patches/0005-use-get_install_dir.patch --- confy-0.5.1/debian/patches/0005-use-get_install_dir.patch 2021-04-13 18:23:29.000000000 +0000 +++ confy-0.6.1/debian/patches/0005-use-get_install_dir.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -From 6eccf13d916871bace29cfe90e8103024d33f4b1 Mon Sep 17 00:00:00 2001 -From: fabrixxm -Date: Sun, 10 Jan 2021 18:43:43 +0100 -Subject: [PATCH] meson: use `get_install_dir()` instead of - `python3.get_path('purelib')` - -`get_install_dir()` correct path to python's `site-packages` for current -installation and works correctly with flatpak ---- - src/meson.build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/meson.build b/src/meson.build -index a5fa534..fcad25b 100644 ---- a/src/meson.build -+++ b/src/meson.build -@@ -10,7 +10,7 @@ gnome.compile_resources('confy', - - python = import('python') - python3 = python.find_installation('python3') --pythondir = join_paths(get_option('prefix'), python3.get_path('purelib')) -+pythondir = python3.get_install_dir() - moduledir = join_paths(pythondir, 'confy') - - conf = configuration_data() --- -2.26.2 - diff -Nru confy-0.5.1/debian/patches/series confy-0.6.1/debian/patches/series --- confy-0.5.1/debian/patches/series 2021-04-13 18:23:29.000000000 +0000 +++ confy-0.6.1/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -0001-fix-appstream-metadata-location.patch -0002-desktop-file-main-category.patch -0003-desktop-add-keywords.patch -0004-fix-python-install-dir.patch -0005-use-get_install_dir.patch diff -Nru confy-0.5.1/debian/README.source confy-0.6.1/debian/README.source --- confy-0.5.1/debian/README.source 1970-01-01 00:00:00.000000000 +0000 +++ confy-0.6.1/debian/README.source 2021-10-01 21:42:07.000000000 +0000 @@ -0,0 +1,9 @@ +This file documents the update procedure for Confy. + + +It assumes you have the upstream sources https://git.sr.ht/~fabrixxm/confy +added as a remote. + +We are making use of both the upstream sources and the tarball by something like: + +$ gbp import-orig --upstream-vcs-tag=0.6.1 ../confy_0.6.1.orig.tar.gz --debian-branch=rel_0.6.1 --upstream-branch=upstream/latest diff -Nru confy-0.5.1/makeflatpak.sh confy-0.6.1/makeflatpak.sh --- confy-0.5.1/makeflatpak.sh 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/makeflatpak.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -#!/bin/bash -set -x -set -e - -REPOID="net.kirgroup" -APPID="net.kirgroup.confy" -GPGKEY="" -REMOTE="" -BASEDIR="" - -. .makeflatpak.env - -BUILD="$BASEDIR/build" -REPO="$BASEDIR/repo" - -[ -d "$BUILD" ] && rm -fr "$BUILD" - -flatpak-builder -v "$BUILD" "$APPID.devel.json" -flatpak build-export --gpg-sign="$GPGKEY" "$REPO" "$BUILD" -flatpak build-bundle --gpg-sign="$GPGKEY" "$REPO" "$BASEDIR/$APPID.flatpak" $APPID -#flatpak build-update-repo --title="Kirgroup" --comment="Develop packages from kirgroup.net" --icon="https://kirgroup.net/kirblack.png" "$REPO" - -cat > "$BASEDIR/$APPID.flatpakref" < "$BASEDIR/$REPOID.flatpakrepo" <= 0.50.0', default_options: [ 'warning_level=2', ], diff -Nru confy-0.5.1/net.kirgroup.confy.json confy-0.6.1/net.kirgroup.confy.json --- confy-0.5.1/net.kirgroup.confy.json 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/net.kirgroup.confy.json 2021-09-30 15:03:39.000000000 +0000 @@ -1,7 +1,7 @@ { "app-id" : "net.kirgroup.confy", "runtime" : "org.gnome.Platform", - "runtime-version" : "3.36", + "runtime-version" : "3.38", "sdk" : "org.gnome.Sdk", "command" : "confy", "finish-args" : [ @@ -41,10 +41,12 @@ { "type" : "git", "url" : "https://gitlab.gnome.org/GNOME/libhandy.git", - "tag" : "1.0.0" + "tag" : "1.0.3", + "commit" : "7126d2e8da9dcdeb5751e60ff6a74930804f9637" } ] }, + "python3-icalendar.json", { "name" : "confy", "builddir" : true, @@ -55,12 +57,10 @@ "path" : "." } ], - "config-opts" : [ - ] + "config-opts" : [] } ], "build-options" : { - "env" : { - } + "env" : { } } } diff -Nru confy-0.5.1/po/it.po confy-0.6.1/po/it.po --- confy-0.5.1/po/it.po 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/po/it.po 2021-09-30 15:03:39.000000000 +0000 @@ -2,51 +2,92 @@ # Copyright (C) 2020 THE confy'S COPYRIGHT HOLDER # This file is distributed under the same license as the confy package. # Automatically generated, 2020. -# Fabrix Xm , 2020. +# Fabrix Xm , 2020-2021. # msgid "" msgstr "" "Project-Id-Version: confy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-12-30 13:57+0100\n" -"PO-Revision-Date: 2020-12-30 13:58+0100\n" +"POT-Creation-Date: 2021-06-12 21:09+0200\n" +"PO-Revision-Date: 2021-06-12 21:18+0200\n" "Last-Translator: Fabrix Xm \n" -"Language-Team: Italiano <>\n" +"Language-Team: Italian <~fabrixxm/confy-dev@lists.sr.ht>\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Gtranslator 3.38.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Gtranslator 40.0\n" #: data/net.kirgroup.confy.desktop.in:3 -#: data/net.kirgroup.confy.appdata.xml.in:4 -#: data/net.kirgroup.confy.metainfo.xml:5 +#: data/net.kirgroup.confy.metainfo.xml.in:4 msgid "Confy" -msgstr "" +msgstr "Confy" -#: data/net.kirgroup.confy.appdata.xml.in:5 -msgid "fabrixxm" -msgstr "" +#: data/net.kirgroup.confy.desktop.in:10 +msgid "Conference;Organize;" +msgstr "Conferenze;Organizza;" + +#: data/net.kirgroup.confy.metainfo.xml.in:5 +msgid "Fabio Comuni" +msgstr "Fabio Comuni" + +#: data/net.kirgroup.confy.metainfo.xml.in:7 src/window.py:805 +msgid "Conference schedules viewer" +msgstr "Visualizzatore di programmi di conferenze" -#: data/net.kirgroup.confy.appdata.xml.in:7 -#: data/net.kirgroup.confy.metainfo.xml:18 +#: data/net.kirgroup.confy.metainfo.xml.in:9 msgid "Confy lets you browse conference schedules." msgstr "Confy permette di navigare i programmi delle conferenze" -#: data/net.kirgroup.confy.appdata.xml.in:10 -#: data/net.kirgroup.confy.metainfo.xml:21 +#: data/net.kirgroup.confy.metainfo.xml.in:12 msgid "" -"Confy lets you organise your visit - select talks to be reminded of (with " -"warnings in case of conflicts)." +"Browse talks by day, track or room. Select the talks you are interested in " +"and receive notification when they are about to start. View when two or more " +"talks you are interested in overlap." msgstr "" -"Confy ti permette di organizzare la tua visita - seleziona le presentazioni " -"da ricordare (con avvisi in caso di conflitti)" +"Sfoglia i talk per giorno, traccia o stanza. Seleziona i talk che ti " +"interessano e ricevi una notifica quando stanno per iniziare. Visualizza " +"quando due o più talk a cui sei interessato si sovrappongono." -#: data/net.kirgroup.confy.appdata.xml.in:14 -#: data/net.kirgroup.confy.metainfo.xml:6 src/window.py:622 -msgid "Conference schedules viewer" -msgstr "Visualizzatore di programmi di conferenze" +#: data/net.kirgroup.confy.metainfo.xml.in:33 +msgid "Search talks in schedule and starred view" +msgstr "Ricerca talk nelle viste Programma e Preferiti" + +#: data/net.kirgroup.confy.metainfo.xml.in:34 +msgid "Better page navigation in starred view" +msgstr "Navigazione tra pagine migliorata nella vista Preferiti" + +#: data/net.kirgroup.confy.metainfo.xml.in:35 +msgid "Varius enhancement to UI to better fit GNOME guidelines" +msgstr "" +"Varie migliorie all'interfaccia per conformarsi meglio alle linee guida di " +"GNOME" + +#: data/net.kirgroup.confy.metainfo.xml.in:40 +msgid "Open urls with default application per file type, if possible." +msgstr "" +"Apri utl con l'applcazione di default per il tipo di file, se possibile." + +#: data/net.kirgroup.confy.metainfo.xml.in:45 +msgid "Fix \"next up\" query and notification." +msgstr "Sistema query e notifiche \"in arrivo\"" + +#: data/net.kirgroup.confy.metainfo.xml.in:46 +msgid "Fix text rendering issues with unsupported markup tags." +msgstr "Sistema i problemi nel rendere il testo a causa di tag non supportati" + +#: data/net.kirgroup.confy.metainfo.xml.in:51 +msgid "Add event progress indicator." +msgstr "Aggiunge un indicatore di progresso dei talk" + +#: data/net.kirgroup.confy.metainfo.xml.in:52 +msgid "" +"Fix overlapping events definition: exclude events ending/starting on same " +"exact time." +msgstr "" +"Sistema la definizione degli eventi sovrapposti: esclude gli eventi che " +"iniziano/finiscono alla stessa identica ora." #: data/net.kirgroup.confy.gschema.xml:7 src/preferences.py:46 msgid "Events list cache duration" @@ -62,16 +103,20 @@ msgid "Event info cache duration" msgstr "Durata cache informazioni evento" -#: src/window.py:81 +#: src/window.py:91 msgid "No conferences yet." msgstr "Ancora nessuna conferenza." -#: src/window.py:82 +#: src/window.py:92 msgid "Add a conference with the add button in title bar." msgstr "" "Aggiungi una conferenza con il bottone \"Aggiungi\" nella barra del titolo." -#: src/window.py:89 src/window.py:136 src/window.py:194 +#: src/window.py:96 src/pages.py:358 src/pages.py:541 +msgid "No matches found" +msgstr "Nessuna corrispondenza trovata" + +#: src/window.py:120 src/window.py:184 src/window.py:253 msgid "" "Error loading events list:\n" "{}" @@ -79,31 +124,27 @@ "Errore caricando la lista eventi\n" "{}" -#: src/window.py:95 src/window.py:258 -msgid "Preferences" -msgstr "Preferenze" - -#: src/window.py:96 src/window.py:259 -msgid "About {}" -msgstr "Informazioni su {}" - -#: src/window.py:99 src/window.py:262 +#: src/window.py:129 src/window.py:332 msgid "Show window menu" msgstr "Mostra menù finestra" -#: src/window.py:105 +#: src/window.py:135 msgid "Refresh events list" msgstr "Aggiorna lista eventi" -#: src/window.py:111 +#: src/window.py:141 msgid "Add event from URL" msgstr "Aggiungi evento da URL" -#: src/window.py:133 +#: src/window.py:151 +msgid "Find event" +msgstr "Trova evento" + +#: src/window.py:181 msgid "Events list updated" msgstr "Lista eventi aggiornata" -#: src/window.py:163 +#: src/window.py:211 msgid "" "New event:\n" "{}" @@ -111,7 +152,7 @@ "Nuovo evento:\n" "{}" -#: src/window.py:166 src/window.py:182 src/window.py:454 +#: src/window.py:214 src/window.py:230 src/window.py:605 msgid "" "Error:\n" "{}" @@ -119,40 +160,48 @@ "Errore:\n" "{}" -#: src/window.py:200 +#: src/window.py:259 msgid "Past" msgstr "Passate" -#: src/window.py:202 +#: src/window.py:261 msgid "Coming up" msgstr "In arrivo" -#: src/window.py:256 +#: src/window.py:327 msgid "Edit info" msgstr "Modifica informazioni" -#: src/window.py:257 +#: src/window.py:328 msgid "Return to events list" msgstr "Torna alla lista eventi" -#: src/window.py:275 src/window.py:415 +#: src/window.py:345 src/window.py:531 msgid "Error loading event" msgstr "Errore caricando l'evento" +#: src/window.py:375 +msgid "Go back" +msgstr "Vai indietro" + +#: src/window.py:385 +msgid "Find talk" +msgstr "Trova talks" + #. main stack content -#: src/window.py:343 +#: src/window.py:446 msgid "Schedule" msgstr "Programma" -#: src/window.py:348 +#: src/window.py:450 msgid "Starred" msgstr "Preferiti" -#: src/window.py:354 +#: src/window.py:456 msgid "Map" msgstr "Mappa" -#: src/window.py:432 +#: src/window.py:582 msgid "" "Updated event:\n" "{}" @@ -160,7 +209,7 @@ "Evento aggiornato:\n" "{}" -#: src/window.py:435 +#: src/window.py:585 msgid "" "Deleted event:\n" "{}" @@ -168,75 +217,87 @@ "Evento rimosso:\n" "{}" -#: src/window.py:449 +#: src/window.py:600 msgid "Event schedule updated" msgstr "Programma aggiornato" -#: src/window.py:466 +#: src/window.py:621 msgid "Next up: {}" msgstr "Prossimo: {}" -#: src/window.py:467 +#: src/window.py:622 msgid "at {} in {}" msgstr "alle {} in {}" -#: src/pages.py:233 +#: src/window.py:792 +msgid "Preferences" +msgstr "Preferenze" + +#: src/window.py:793 +msgid "Keyboard shortcuts" +msgstr "Scorciatoie da tastiera" + +#: src/window.py:794 +msgid "About {}" +msgstr "Informazioni su {}" + +#: src/pages.py:238 msgid "cache updated" msgstr "cache aggiornata" -#: src/pages.py:242 src/pages.py:514 +#: src/pages.py:247 src/pages.py:584 msgid "Days" msgstr "Giorni" -#: src/pages.py:256 +#: src/pages.py:261 msgid "Talks on {}" msgstr "Presentazioni il {}" -#: src/pages.py:264 src/pages.py:515 +#: src/pages.py:269 src/pages.py:585 msgid "Tracks" msgstr "Temi" -#: src/pages.py:289 +#: src/pages.py:294 msgid "{} Track" msgstr "Tema {}" -#: src/pages.py:298 src/pages.py:516 +#: src/pages.py:303 src/pages.py:586 msgid "Rooms" msgstr "Stanze" -#: src/pages.py:307 +#: src/pages.py:312 msgid "No Room" msgstr "Nessuna Stanza" -#: src/pages.py:309 +#: src/pages.py:314 msgid "Room {}" msgstr "Stanza {}" -#: src/pages.py:400 +#: src/pages.py:427 msgid "Room: {}" msgstr "Stanza: {}" -#: src/pages.py:405 +#: src/pages.py:432 msgid "Track: {}" msgstr "Tema: {}" -#: src/pages.py:421 +#: src/pages.py:448 msgid "Conflicts with" msgstr "In conflitto con" -#: src/pages.py:451 +#: src/pages.py:478 msgid "Links" msgstr "Collegamenti" -#: src/pages.py:485 +#: src/pages.py:534 msgid "Starred Talks" msgstr "Preferiti" -#: src/pages.py:486 +#: src/pages.py:535 msgid "You don't have any starred talk yet." msgstr "Non hai nessun preferito ancora." -#: src/pages.py:487 +#: src/pages.py:536 msgid "" "Click on the star button to add a talk to this list and to be reminded when " "they are about to start." @@ -244,55 +305,55 @@ "Cilcca sul bottone con la stella per aggiungere una presentazione a questa " "lista e ricevere un promemoria quando stanno per iniziare." -#: src/widgets.py:146 +#: src/widgets.py:173 msgid "{}" msgstr "{}" -#: src/widgets.py:167 +#: src/widgets.py:194 msgid "Loading…" msgstr "Caricamento…" -#: src/widgets.py:234 +#: src/widgets.py:261 msgid "Loading…" msgstr "Caricamento…" -#: src/widgets.py:279 +#: src/widgets.py:328 msgid "Cancel" msgstr "Annulla" -#: src/widgets.py:280 +#: src/widgets.py:329 msgid "Ok" msgstr "Ok" -#: src/widgets.py:306 +#: src/widgets.py:355 msgid "Schedule URL" msgstr "URL Programma" -#: src/widgets.py:331 +#: src/widgets.py:380 msgid "Edit Conference" msgstr "Modifica Conferenza" -#: src/widgets.py:403 +#: src/widgets.py:452 msgid "URL" msgstr "URL" -#: src/widgets.py:411 +#: src/widgets.py:460 msgid "Title" msgstr "Titolo" -#: src/widgets.py:419 +#: src/widgets.py:468 msgid "Start" msgstr "Inizio" -#: src/widgets.py:428 +#: src/widgets.py:477 msgid "End" msgstr "Fine" -#: src/widgets.py:435 +#: src/widgets.py:484 msgid "Icon URL" msgstr "URL icona" -#: src/widgets.py:446 +#: src/widgets.py:495 msgid "Delete" msgstr "Rimuovi" @@ -345,14 +406,24 @@ msgid "Confy has {} of cached data" msgstr "Confy ha {} di dati in cache" -#: src/local.py:144 +#: src/local.py:147 msgid "Device disconnected and no cached data available." msgstr "Dispositivo disconnesso e nessun dato locale disponibile." -#: src/local.py:268 +#: src/local.py:273 msgid "Event already in list" msgstr "Evento già in lista" +#~ msgid "Quit" +#~ msgstr "Chiudi" + +#~ msgid "" +#~ "Confy lets you organise your visit - select talks to be reminded of (with " +#~ "warnings in case of conflicts)." +#~ msgstr "" +#~ "Confy ti permette di organizzare la tua visita - seleziona le " +#~ "presentazioni da ricordare (con avvisi in caso di conflitti)" + #, fuzzy #~ msgid "Conference schedule viewer" #~ msgstr "Visualizzatore di programmi di conferenze" diff -Nru confy-0.5.1/po/POTFILES confy-0.6.1/po/POTFILES --- confy-0.5.1/po/POTFILES 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/po/POTFILES 2021-09-30 15:03:39.000000000 +0000 @@ -1,6 +1,5 @@ data/net.kirgroup.confy.desktop.in -data/net.kirgroup.confy.appdata.xml.in -data/net.kirgroup.confy.metainfo.xml +data/net.kirgroup.confy.metainfo.xml.in data/net.kirgroup.confy.gschema.xml src/main.py src/window.py diff -Nru confy-0.5.1/python3-icalendar.json confy-0.6.1/python3-icalendar.json --- confy-0.5.1/python3-icalendar.json 1970-01-01 00:00:00.000000000 +0000 +++ confy-0.6.1/python3-icalendar.json 2021-09-30 15:03:39.000000000 +0000 @@ -0,0 +1,39 @@ +{ + "name": "python3-icalendar", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"icalendar\"" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/aa/d4/0089d680a610c7b5afda26c1ae588eb363b9050ccf5f33a8c2d1164210f3/setuptools-51.1.2-py3-none-any.whl", + "sha256": "67d8af2fc9f33e48f8f4387321700a79b27090a5cff154e5ce1a8c72c2eea54f" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/65/63/39d04c74222770ed1589c0eaba06c05891801219272420b40311cd60c880/wheel-0.36.2-py2.py3-none-any.whl", + "sha256": "78b5b185f0e5763c26ca1e324373aadd49182ca90e825f7853f4b2509215dc0e" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/db/6e/2815f7c8561b088ccedc128681e64daac3d6b2e81a9918b007e244dad8b1/setuptools_scm-5.0.1-py2.py3-none-any.whl", + "sha256": "62fa535edb31ece9fa65dc9dcb3056145b8020c8c26c0ef1018aef33db95c40d" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/be/ed/5bbc91f03fa4c839c4c7360375da77f9659af5f7086b7a7bdda65771c8e0/python-dateutil-2.8.1.tar.gz", + "sha256": "73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/70/44/404ec10dca553032900a65bcded8b8280cf7c64cc3b723324e2181bf93c9/pytz-2020.5.tar.gz", + "sha256": "180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/58/b8/9aa7963f442b2a8bfdfc40eab8bc399c5eaac5711b8919c52122e4903544/icalendar-4.0.7.tar.gz", + "sha256": "0fc18d87f66e0b5da84fa731389496cfe18e4c21304e8f6713556b2e8724a7a4" + } + ] +} diff -Nru confy-0.5.1/README.md confy-0.6.1/README.md --- confy-0.5.1/README.md 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/README.md 2021-09-30 15:03:39.000000000 +0000 @@ -8,9 +8,11 @@ Built with python3, gtk3, libhandy -[https://confy.kirgroup.net](https://confy.kirgroup.net) +- [Home Page](https://confy.kirgroup.net) +- [Project Page](https://sr.ht/~fabrixxm/Confy) +- [Patches and discussions](https://lists.sr.ht/~fabrixxm/confy-dev) +- [Tickets](https://todo.sr.ht/~fabrixxm/confy) -[https://sr.ht/~fabrixxm/confy](https://sr.ht/~fabrixxm/confy) ## Packages diff -Nru confy-0.5.1/src/confy.gresource.xml confy-0.6.1/src/confy.gresource.xml --- confy-0.5.1/src/confy.gresource.xml 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/confy.gresource.xml 2021-09-30 15:03:39.000000000 +0000 @@ -2,5 +2,6 @@ confy.css + shortcuts.ui diff -Nru confy-0.5.1/src/confy.in confy-0.6.1/src/confy.in --- confy-0.5.1/src/confy.in 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/confy.in 2021-09-30 15:03:39.000000000 +0000 @@ -24,9 +24,10 @@ VERSION = '@VERSION@' pkgdatadir = '@pkgdatadir@' +pythondir = '@pythondir@' localedir = '@localedir@' -sys.path.insert(1, pkgdatadir) +sys.path.insert(1, pythondir) signal.signal(signal.SIGINT, signal.SIG_DFL) gettext.install('confy', localedir) diff -Nru confy-0.5.1/src/fetcher.py confy-0.6.1/src/fetcher.py --- confy-0.5.1/src/fetcher.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/fetcher.py 2021-09-30 15:03:39.000000000 +0000 @@ -24,6 +24,10 @@ from gi.repository import GObject +class DownloadCancelled(Exception): + pass + + class Fetcher(GObject.GObject): """ Fetch source to dest, asyncly. @@ -91,7 +95,8 @@ GLib.idle_add(self.notify,"fraction") chunk = fsrc.read(block_size) except Exception as e: - os.unlink(dest) + if os.path.exists(dest): + os.unlink(dest) import traceback; traceback.print_exc() GLib.idle_add(self.emit, "error", str(e)) else: diff -Nru confy-0.5.1/src/local.py confy-0.6.1/src/local.py --- confy-0.5.1/src/local.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/local.py 2021-09-30 15:03:39.000000000 +0000 @@ -40,8 +40,6 @@ class LocalDBNotOpen(Exception): pass -class DownloadCancelled(Exception): - pass dbfile = None db = None @@ -75,6 +73,7 @@ def migrate(): schema = -1 + migrated = False try: c = db.execute("SELECT value FROM meta WHERE key='schema'" ) info = c.fetchone() @@ -95,14 +94,16 @@ print("Migrating to {}".format(f.replace(".py", ""))) import_migration(os.path.join(migrationsdir,f)).up(c) schema = newschema + migrated = True except Exception as e: db.rollback() raise e from None - db.execute("INSERT OR REPLACE INTO meta (key, value) VALUES ('schema', ?)", (schema,)) db.commit() + return migrated + # event database def openconf(conf, is_online=True): @@ -147,13 +148,15 @@ db = sqlite3.connect(dbfilename, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) db.row_factory = sqlite3.Row - migrate() + migrated = migrate() dbfile = dbfilename from .models import Meta - if is_online and (time.time() - Meta().last_update) > Settings.instance().get_event_cache(): + is_time_to_update = (time.time() - Meta().last_update) > Settings.instance().get_event_cache() + + if is_online and (migrated or is_time_to_update): return updatedb(url) return None diff -Nru confy-0.5.1/src/main.py confy-0.6.1/src/main.py --- confy-0.5.1/src/main.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/main.py 2021-09-30 15:03:39.000000000 +0000 @@ -20,7 +20,7 @@ gi.require_version('Gtk', '3.0') gi.require_version('Handy', '1') gi.require_version("Notify", "0.7") -from gi.repository import Gtk, Gdk, Gio, GLib +from gi.repository import Gtk, Gdk, Gio, GLib, GObject from gi.repository import Handy from gi.repository import Notify @@ -32,6 +32,15 @@ class Application(Gtk.Application): + @GObject.Signal + def tick(self): + """Event fired every minute + + Used to check for notifications to send and to update events row background + """ + pass + + def __init__(self): super().__init__(application_id=APP_ID, flags=Gio.ApplicationFlags.FLAGS_NONE) @@ -59,17 +68,38 @@ quit_action = Gio.SimpleAction.new("quit", None) quit_action.connect("activate", lambda *args: self.quit() ) self.add_action(quit_action) - self.add_accelerator("q", "app.quit", None) + self.set_accels_for_action("app.quit", ["q",]) + shortcut_action = Gio.SimpleAction.new("shortcuts") + shortcut_action.connect("activate", self.show_shortcuts) + self.add_action(shortcut_action) + self.set_accels_for_action("app.shortcuts", ["question"]) + + self.set_accels_for_action("win.show-preferences", ["comma",]) + self.set_accels_for_action("win.return-to-events", ["l",]) + self.set_accels_for_action("win.search", ["f",]) + + GLib.timeout_add_seconds(30, self._do_tick) + + def _do_tick(self): + self.emit("tick") + return True def on_activate(self, *_): win = self.props.active_window if not win: win = ConfyWindow(application=self) win.present() - + def on_shutdown(self, *_): local.close() - + + def show_shortcuts(self, *_): + b = Gtk.Builder.new_from_resource("/net/kirgroup/confy/shortcuts.ui") + w = b.get_object("shortcuts-win") + w.set_transient_for(self.props.active_window) + w.props.view_name = None + w.show() + def main(version): diff -Nru confy-0.5.1/src/meson.build confy-0.6.1/src/meson.build --- confy-0.5.1/src/meson.build 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/meson.build 2021-09-30 15:03:39.000000000 +0000 @@ -1,5 +1,4 @@ pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) -moduledir = join_paths(pkgdatadir, 'confy') gnome = import('gnome') gnome.compile_resources('confy', @@ -10,12 +9,16 @@ ) python = import('python') +python3 = python.find_installation('python3') +pythondir = python3.get_install_dir() +moduledir = join_paths(pythondir, 'confy') conf = configuration_data() -conf.set('PYTHON', python.find_installation('python3').path()) +conf.set('PYTHON', python3.path()) conf.set('VERSION', meson.project_version()) conf.set('localedir', join_paths(get_option('prefix'), get_option('localedir'))) conf.set('pkgdatadir', pkgdatadir) +conf.set('pythondir', pythondir) configure_file( input: 'confy.in', diff -Nru confy-0.5.1/src/migrations/001_event_person_unique.py confy-0.6.1/src/migrations/001_event_person_unique.py --- confy-0.5.1/src/migrations/001_event_person_unique.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/migrations/001_event_person_unique.py 2021-09-30 15:03:39.000000000 +0000 @@ -9,4 +9,4 @@ def down(cursor): ... - + diff -Nru confy-0.5.1/src/migrations/002_full_text_search.py confy-0.6.1/src/migrations/002_full_text_search.py --- confy-0.5.1/src/migrations/002_full_text_search.py 1970-01-01 00:00:00.000000000 +0000 +++ confy-0.6.1/src/migrations/002_full_text_search.py 2021-09-30 15:03:39.000000000 +0000 @@ -0,0 +1,7 @@ +def up(cursor): + cursor.execute("""CREATE VIRTUAL TABLE fts_event + USING FTS5 (event_id, text)""") + +def down(cursor): + ... + diff -Nru confy-0.5.1/src/migrations/meson.build confy-0.6.1/src/migrations/meson.build --- confy-0.5.1/src/migrations/meson.build 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/migrations/meson.build 2021-09-30 15:03:39.000000000 +0000 @@ -3,6 +3,7 @@ migrations_sources = [ '000_initial.py', '001_event_person_unique.py', + '002_full_text_search.py', ] install_data(migrations_sources, install_dir: migrationsdir) diff -Nru confy-0.5.1/src/models.py confy-0.6.1/src/models.py --- confy-0.5.1/src/models.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/models.py 2021-09-30 15:03:39.000000000 +0000 @@ -19,8 +19,10 @@ import time from gi.repository import GObject +from dateutil.tz import UTC from . import local +from .settings import Settings from .fetcher import Fetcher ## models @@ -43,7 +45,7 @@ __f("track", track.name) if event is not None: __f("id", event.id) - + for k,v in kwargs.items(): __f(k, v) @@ -57,10 +59,10 @@ self.user = False for k, v in obj.items(): setattr(self, k, v) - + self.start = datetime.date(*[int(s) for s in self.start.split("-")]) self.end = datetime.date(*[int(s) for s in self.end.split("-")]) - + return self def get_map_links(self): @@ -172,13 +174,13 @@ def _init(self, data): self.date = data['date'] return self - + def __repr__(self): return "<{} {!r}>".format(self.__class__.__name__, self.date) - + def __str__(self): return self.date.strftime("%x") - + @classmethod def all(cls): for row in local.getDb().execute("SELECT date FROM events GROUP BY date"): @@ -192,11 +194,11 @@ @classmethod def filter(cls, room=None, track=None, event=None): filterdata, wherestm = _build_filter(room=room, track=track, event=event) - - query = """SELECT date FROM events + + query = """SELECT date FROM events WHERE {} GROUP BY date""".format(" AND ".join(wherestm)) - + for row in local.getDb().execute(query, filterdata): yield cls()._init(row) @@ -212,7 +214,7 @@ def __str__(self): return self.name or "- no room -" - + @classmethod def all(cls): for row in local.getDb().execute("SELECT room FROM events GROUP BY room"): @@ -222,19 +224,19 @@ def count(cls): for row in local.getDb().execute("SELECT count(DISTINCT room) FROM events"): return row[0] - + @classmethod def filter(cls, day=None, track=None, event=None): filterdata, wherestm = _build_filter(day=day, track=track, event=event) - - query = """SELECT room FROM events + + query = """SELECT room FROM events WHERE {} GROUP BY room""".format(" AND ".join(wherestm)) - + for row in local.getDb().execute(query, filterdata): yield cls()._init(row) - + class Track: def _init(self, data): self.name = data['track'] @@ -267,13 +269,13 @@ self.id = data['id'] self.name = data['name'] return self - + def events(self): for row in local.getDb().execute( """SELECT e.* FROM events as e LEFT JOIN event_person AS ep ON e.id = ep.event_id WHERE ep.person_id = ?""", (self.id,)): - yield Event()._init(row) + yield Event()._init(row) def __repr__(self): return "<{} {!r}>".format(self.__class__.__name__, self.name) @@ -285,7 +287,7 @@ def all(cls): for row in local.getDb().execute( "SELECT id, name FROM persons"): - yield cls()._init(row) + yield cls()._init(row) class Link: @@ -307,7 +309,7 @@ __gsignals__ = { 'update': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, ()) } - + def _init(self, data): self.id = data['id'] self.date = data['date'] @@ -324,19 +326,31 @@ self.starred = data['starred'] == 1 self.notified = data['notified'] == 1 return self - + def set_star(self, starred): local.getDb().execute("UPDATE events SET starred=? WHERE id=?",(starred,self.id,)) local.getDb().commit() self.starred = starred self.emit('update') - + def set_notified(self, notified): local.getDb().execute("UPDATE events SET notified=? WHERE id=?",(notified,self.id,)) local.getDb().commit() self.notified = notified self.emit('update') + + def start_in_tz(self): + return self._dt_in_tz(self.start) + + def end_in_tz(self): + return self._dt_in_tz(self.end) + + def _dt_in_tz(self, dt): + dt = dt.replace(tzinfo=UTC) + dt = dt.astimezone(Settings.instance().get_timezone()) + return dt + def persons(self): #print("event", self.id, "persons()") for row in local.getDb().execute( @@ -344,23 +358,23 @@ LEFT JOIN event_person AS ep ON p.id = ep.person_id WHERE ep.event_id = ?""", (self.id,)): yield Person()._init(row) - + def links(self): for row in local.getDb().execute( """SELECT href, name FROM links WHERE event_id=?""", (self.id,)): - yield Link()._init(self, row) - + yield Link()._init(self, row) + def __repr__(self): return "<{} {!r} in {!r} @ {!r}>".format(self.__class__.__name__, self.title, self.room, self.start) def __str__(self): return self.title - + def get_conflicts(self): query = """SELECT * FROM events WHERE starred = 1 AND id != ? AND date = ? - AND end >= ? AND start <= ? + AND end > ? AND start < ? """ for row in local.getDb().execute(query, (self.id, self.date, self.start, self.end)): yield Event()._init(row) @@ -369,12 +383,12 @@ def all(cls): for row in local.getDb().execute("SELECT * FROM events"): yield 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) - - query = """SELECT * FROM events + + query = """SELECT * FROM events WHERE {} ORDER BY start, room""".format(" AND ".join(wherestm)) for row in local.getDb().execute(query, filterdata): @@ -384,7 +398,8 @@ def nextup(cls, minutes): """get events starting in next `minutes`""" minutes = min(int(minutes), 30) # some sanity check - now = "now" + now = datetime.datetime.now(UTC).replace(tzinfo=None).strftime("%Y-%m-%dT%H:%M:%S.000") + # now = "now" # is "now" somehow broken? query = """SELECT * FROM events WHERE starred=1 AND notified=0 AND datetime(start) >= datetime("{1}") @@ -392,3 +407,21 @@ for row in local.getDb().execute(query.format(minutes, now)): yield cls()._init(row) + @classmethod + def search(cls, term, starred=False): + """Search events for 'term'""" + + starfilter = "" + if starred: + starfilter = "events.starred = 1 AND" + + query = """SELECT events.* FROM fts_event + JOIN events ON events.id = fts_event.event_id + WHERE {} fts_event = ? + GROUP BY events.id + ORDER BY rank""".format(starfilter) + + for row in local.getDb().execute(query, (term,)): + yield cls()._init(row) + + diff -Nru confy-0.5.1/src/pages.py confy-0.6.1/src/pages.py --- confy-0.5.1/src/pages.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/pages.py 2021-09-30 15:03:39.000000000 +0000 @@ -18,6 +18,8 @@ import re import html +from dateutil.tz import UTC + from gi.repository import GLib from gi.repository import Gtk from gi.repository import GObject @@ -34,9 +36,13 @@ from . import models + def _clean_markup(text): """remove unsupported markup from text to use in label""" text = text.replace("

", "").replace("

", "\n\n") + text = text.replace("", "").replace("", "") + text = text.replace("", "").replace("", "") + text = text.replace("
", "\n").replace("
", "\n") text = text.replace("

", "").replace("

", "") text = text.replace("

", "").replace("

", "") text = text.replace("

", "").replace("

", "") @@ -68,9 +74,9 @@ self.column = Handy.Clamp( tightening_threshold=500, # dimensione sotto la quale decide di occupare tutto lo spazio maximum_size=640) # dimensione massima allragandosi - + super().add(self.column) - + def add(self, widget): self.column.add(widget) @@ -82,16 +88,16 @@ """Base class for ListBox based pages""" title = "" subtitle = "" - + def __init__(self, title=None, subtitle=None, **kwargs): super().__init__(**kwargs) - + title = title or self.title subtitle = subtitle or self.subtitle box = Gtk.VBox() box.get_style_context().add_class("main-box") - + if title != "" or subtitle != "": titlebox = Gtk.VBox(margin_left=8, margin_right=8) if title != "": @@ -106,41 +112,43 @@ titlebox.pack_start(label, False, False, 0) box.pack_start(titlebox, False, False, 2) - - + + frame = Gtk.Frame(valign=Gtk.Align.START) - + listbox = Gtk.ListBox() listbox.connect('row-activated', self.on_activate) #listbox.get_style_context().add_class("content") listbox.set_header_func(self.build_list_header, None) - + self.listbox = listbox # TODO: use list model? self.update_list() - + frame.add(listbox) box.pack_start(frame, True, True, 2) - + self.add(box) - + def update_list(self, *args): self.data = list(self.get_objects()) for w in self.listbox.get_children(): w.destroy() - + lastgroup = None for obj in self.data: mn = self.build_row(obj) self.listbox.add(mn) self.listbox.show_all() - + def get_objects(self): return [] - + def build_list_header(self, row, before, *user_data): + if len(self.data) == 0: + return obj1 = self.data[row.get_index()] group_txt1 = self.group_by(obj1) if group_txt1 is None: @@ -154,15 +162,15 @@ if group_txt2 != group_txt1: h = ListRowHeader(group_txt1) row.set_header(h) - + def group_by(self, obj): return None - + def build_row(self, obj): row = Handy.ActionRow(activatable=True, selectable=False) row.set_title(str(obj)) return row - + def on_activate(self, listbox, actionrow): ... @@ -177,7 +185,7 @@ def __init__(self, conf, **kwargs): super().__init__(**kwargs) - + meta = models.Meta() LBL_PROPS = { @@ -187,15 +195,16 @@ } box = Gtk.VBox(valign=Gtk.Align.CENTER) - + self.logoimage = MaxSizedImage(max_width=200, max_height=200) f = conf.get_logo_file(cbk=self._set_logo) box.pack_start(self.logoimage, False, False, 16) - label = Gtk.Label(**LBL_PROPS) - label.set_markup("{}".format(_clean_markup(meta.title))) - box.pack_start(label, False, False, 16) - + if meta.title: + label = Gtk.Label(**LBL_PROPS) + label.set_markup("{}".format(_clean_markup(meta.title))) + box.pack_start(label, False, False, 16) + if meta.venue is not None: label = Gtk.Label(html.unescape(meta.venue), **LBL_PROPS) label.get_style_context().add_class("dim-label") @@ -214,7 +223,7 @@ datebox.pack_start(label, False, False, 8) box.pack_start(datebox, False, False, 16) - + links = conf.metadata.get('links',None) if links is not None: frame = Gtk.Frame() @@ -224,7 +233,7 @@ if l['title'] != "Map": row = WebLinkActionRow(html.unescape(l['title']), l['url'], l.get('type', None)) listbox.add(row) - + frame.add(listbox) box.pack_start(frame, False, False, 16) @@ -240,10 +249,10 @@ class DaysPage(BaseListPage): """Days list page""" title = _("Days") - + def get_objects(self): return models.Day.all() - + def build_row(self, obj): row = Handy.ActionRow(activatable=True, selectable=False) row.set_title(obj.date.strftime(FMT_DAY_LIST)) @@ -262,10 +271,10 @@ class TracksPage(BaseListPage): """Tracks list page""" title = _("Tracks") - + def get_objects(self): return models.Track.all() - + #def group_by(self, obj): # return obj.date.strftime(FMT_DAY_LIST) @@ -281,7 +290,7 @@ subtitle = [] if len(obj.room) == 1 and obj.room[0].name != "": subtitle.append(obj.room[0].name) - + if len(obj.date) == 1: subtitle.append(obj.date[0].date.strftime(FMT_DAY_LIST)) @@ -296,7 +305,7 @@ class RoomsPage(BaseListPage): """Rooms list page""" title = _("Rooms") - + def get_objects(self): return models.Room.all() @@ -321,7 +330,7 @@ self.filters = filters self._group_by = group_by super().__init__(title=title, subtitle=subtitle) - + def group_by(self, obj): if self._group_by == "day": return obj.date.strftime(FMT_DAY_LIST) @@ -331,14 +340,14 @@ return obj.room else: return None - + def get_objects(self): return models.Event.filter(**self.filters) - + def build_row(self, obj): row = EventActionRow(obj) return row - + def on_activate(self, listbox, actionrow): idx = actionrow.get_index() obj = self.data[idx] @@ -346,6 +355,28 @@ self.pageStack.pushPage(page) +class SearchEventsPage(EventsPage): + def __init__(self, searchbar): + self.searchbar = searchbar + self.nomatch_placeholder = PlaceholderWidget( + text = _("No matches found"), + icon_name = 'system-search' + ) + self.nomatch_placeholder.show_all() + super().__init__() + + self.listbox.set_placeholder(self.nomatch_placeholder) + + def get_objects(self): + sb = self.searchbar + if sb.get_search_mode() and sb.entry.get_text() != "": + search = sb.entry.get_text().lower() + events = models.Event.search(search) + else: + events = [] + return events + + class EventDetailPage(BasePage): """Talk details page""" def __init__(self, obj, **kwargs): @@ -360,12 +391,12 @@ LBL_PROPS = { 'justify': Gtk.Justification.FILL, - 'halign' : Gtk.Align.START, + 'halign' : Gtk.Align.START, 'wrap' : True, } box = Gtk.VBox( margin_left=8, margin_right=8) - + titlebox = Gtk.VBox() label = Gtk.Label(**LBL_PROPS) @@ -377,29 +408,29 @@ label.set_markup("{}".format(_clean_markup(obj.subtitle))) #label.get_style_context().add_class("dim-label") titlebox.pack_start(label, False, False, 0) - + label = Gtk.Label(**LBL_PROPS) label.set_markup("{}".format( ", ".join([ _clean_markup(str(p)) for p in obj.persons()]))) label.get_style_context().add_class("dim-label") titlebox.pack_start(label, False, False, 0) - + box.pack_start(titlebox, False, False, 16) starbox = Gtk.HBox() - + titlebox = Gtk.VBox() label = Gtk.Label(**LBL_PROPS) label.set_markup("{}-{}".format( - obj.start.strftime("%a %H:%M"), - obj.end.strftime("%H:%M"))) + obj.start_in_tz().strftime("%a %H:%M"), + obj.end_in_tz().strftime("%H:%M"))) titlebox.pack_start(label, False, False, 0) if obj.room: label = Gtk.Label(**LBL_PROPS) label.set_markup(_("Room: {}").format(obj.room)) titlebox.pack_start(label, False, False, 0) - + if obj.track: label = Gtk.Label(**LBL_PROPS) label.set_markup(_("Track: {}").format(obj.track)) @@ -407,11 +438,11 @@ starbox.pack_start(titlebox, False, True, 0) - icon_name = "starred-symbolic" if obj.starred else "non-starred-symbolic" + icon_name = "starred-symbolic" if obj.starred else "non-starred-symbolic" self.toggle_btn = Gtk.Button.new_from_icon_name(icon_name, Gtk.IconSize.BUTTON) self.toggle_btn.connect("clicked", self.toggle_starred) starbox.pack_end(self.toggle_btn, False, False, 16) - + box.pack_start(starbox, False, False, 16) self.conflicts = list(obj.get_conflicts()) @@ -458,13 +489,42 @@ for l in obj.links(): row = WebLinkActionRow(l.name, l.href) listbox.add(row) - + frame.add(listbox) linkbox.pack_start(frame, False, False, 0) box.pack_start(linkbox, False, False, 16) self.add(box) - + + # progress indicator + Gio.Application.get_default().connect( + "tick", lambda *_: self.queue_draw() + ) + + box.connect("draw", self._on_draw) + + def _on_draw(self, widget, cr): + now = datetime.datetime.now(UTC).replace(tzinfo=None) + obj = self.obj + + w = self.get_allocated_width() + + dur = (obj.end.timestamp() - obj.start.timestamp()) + pos = (now.timestamp() - obj.start.timestamp()) + if dur > 0: + prc = min(max(pos/dur, 0.0), 1.0) + else: + # not a valid event duration + # set prc to 0 if the event is in the future or 1 if in the past + prc = int(pos >= 0) + + x = w * prc + + cr.set_source_rgb(0, 0, 0) + cr.move_to(0, 1) + cr.line_to(x, 1) + cr.stroke() + def toggle_starred(self, button): self.obj.set_star(not self.obj.starred) icon_name = "starred-symbolic" if self.obj.starred else "non-starred-symbolic" @@ -479,21 +539,41 @@ class StarredPage(BaseListPage): """Starred list page. This page is not in leaflet, but in mainstack""" - def __init__(self, **kwargs): - super().__init__(**kwargs) - placeholder = PlaceholderWidget( + def __init__(self, searchbar, **kwargs): + self.empty_placeholder = PlaceholderWidget( _("Starred Talks"), _("You don't have any starred talk yet.") + "\n" + \ _("Click on the star button to add a talk to this list " + \ "and to be reminded when they are about to start."), "starred") - placeholder.show_all() + self.empty_placeholder.show_all() + self.nomatch_placeholder = PlaceholderWidget( + text = _("No matches found"), + icon_name = 'system-search' + ) + self.nomatch_placeholder.show_all() + + self.searchbar = searchbar + + super().__init__(**kwargs) + self.get_style_context().add_class("starred-page") self.get_style_context().add_class("clean-list") - self.listbox.set_placeholder(placeholder) - + self.listbox.set_placeholder(self.empty_placeholder) + def get_objects(self): return models.Event.filter(starred = True) + + def get_objects(self): + sb = self.searchbar + if sb.get_search_mode() and sb.entry.get_text() != "": + self.listbox.set_placeholder(self.nomatch_placeholder) + search = sb.entry.get_text().lower() + events = models.Event.search(search, starred = True) + else: + self.listbox.set_placeholder(self.empty_placeholder) + events = models.Event.filter(starred = True) + return events def build_row(self, obj): row = EventActionRow(obj) @@ -503,18 +583,18 @@ idx = actionrow.get_index() obj = self.data[idx] page = EventDetailPage(obj=obj) - self.pageStack.replaceWithPage(page) + self.pageStack.pushPage(page) class MainMenuPage(Gtk.ScrolledWindow): """Leaflet sidebar menu""" - + ITEMS = ( ["EVENT", "emblem-system-symbolic", ConferencePage, None], (_("Days"), "x-office-calendar-symbolic", DaysPage, models.Day.count), (_("Tracks"), "format-justify-fill-symbolic", TracksPage, models.Track.count), (_("Rooms"),"display-projector-symbolic", RoomsPage, models.Room.count)) - + def __init__(self, pageStack, conf): super().__init__( width_request=270, @@ -524,9 +604,9 @@ self.pageStack = pageStack self.conf = conf - + self.ITEMS[0][0] = conf.title - + self.listbox = Gtk.ListBox() self.update() self.listbox.connect('row-activated', self.on_activate) @@ -544,6 +624,12 @@ self.listbox.add(mn) self.listbox.show_all() + def select_conference_page(self): + """select and show ConferencePAge""" + row = self.listbox.get_row_at_index(0) + self.listbox.select_row(row) + self.on_activate(self.listbox, row) + def on_activate(self, listbox, actionrow): idx = actionrow.item_id cls = self.ITEMS[idx][2] diff -Nru confy-0.5.1/src/remotes/ics.py confy-0.6.1/src/remotes/ics.py --- confy-0.5.1/src/remotes/ics.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/remotes/ics.py 2021-09-30 15:03:39.000000000 +0000 @@ -18,27 +18,21 @@ import time import html from datetime import datetime, timedelta, timezone +from dateutil.tz import UTC from icalendar import Calendar, Event from .exceptions import InvalidFormatException from .. import local from ..models import Meta -def utc_to_local(utc_dt): - """remove timezone info from date object - Calendar items comes with timezone info. We could keep this info and allow - users to select wich timezone they want to see. Atm, all code works without - timezones (and sqlite3 driver spit errors if we try to save a timezone-aware datetime). - We assume that this thing will be used "on premise", so every date/time will - be in conference location tz. - You have to live with this until a better option come up. - I hate timezones and datetime handling. - """ - return utc_dt.replace(tzinfo=None) +def import_ics(content:str, url:str): + """Import data from ICS + all dates will be converted to UTC and stored in db without tzinfo, + because sqlite3 driver spits errors otherwise. + """ -def import_ics(content:str, url:str): cal = Calendar.from_ical(content) _db = local.getDb() @@ -52,15 +46,16 @@ meta_title = c.get('X-WR-CALNAME') if c.name == "VEVENT": + fulltextsearch = [] eventid = c['UID'] if c.get('DTSTART'): - start = utc_to_local(c['DTSTART'].dt) + start = c['DTSTART'].dt.astimezone(UTC).replace(tzinfo=None) else: - start = utc_to_local(c['DTSTAMP'].dt) + start = c['DTSTAMP'].dt.astimezone(UTC).replace(tzinfo=None) if c.get('DURATION'): end = start + c['DURATION'].dt elif c.get('DTEND'): - end = utc_to_local(c['DTEND'].dt) + end = c['DTEND'].dt.astimezone(UTC).replace(tzinfo=None) else: end = start + timedelta(hours=1) evtdate = start.date() @@ -90,6 +85,8 @@ if end > meta_end: meta_end = end + fulltextsearch += [ s for s in [title, subtitle, abstract, description, room, track] if s is not None ] + links = [] _url = c.get('URL') if _url: @@ -105,6 +102,8 @@ # [ (eventid, p[0]) for p in persons ]) _db.executemany("""INSERT OR REPLACE INTO links (event_id, href, name) VALUES (?,?,?)""", links) + fulltextsearchstr = ' '.join(fulltextsearch) + _db.execute("""INSERT OR REPLACE INTO fts_event (event_id, text) VALUES (?, ?)""", (eventid, fulltextsearchstr)) _db.commit() with Meta() as m: diff -Nru confy-0.5.1/src/remotes/pentabarf.py confy-0.6.1/src/remotes/pentabarf.py --- confy-0.5.1/src/remotes/pentabarf.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/remotes/pentabarf.py 2021-09-30 15:03:39.000000000 +0000 @@ -19,11 +19,18 @@ import time import xml.etree.ElementTree as ET +from dateutil.tz import UTC, tzlocal + from .exceptions import InvalidFormatException from .. import local from ..models import Meta +def _local_to_utc_to_unset(dt): + dt = dt.replace(tzinfo=tzlocal()) + dt = dt.astimezone(UTC) + return dt.replace(tzinfo=None) + def _get_text(root, nodename): text = "" if root is not None: @@ -32,7 +39,16 @@ text = node.text return text + + + def import_pentabarf(xmlstr:str, url:str): + """Import data from Pentabarf XML + + As far I can tell, Pentabarf XML doesn't declare timezone. + We will import dates in local timezone, then convert to UTC, then + remove timezone info to store dates in db (because sqlite3 cries otherwise) + """ root = ET.fromstring(xmlstr) if root.tag != "schedule": raise InvalidFormatException(_("Invalid pentabarf format")) @@ -54,8 +70,11 @@ for eday in root.iter('day'): date = eday.attrib['date'] for eevent in eday.iter('event'): + fulltextsearch = [] eventid = eevent.attrib['id'] - start = datetime.datetime.strptime(date + " " + eevent.find('start').text, "%Y-%m-%d %H:%M") + start = _local_to_utc_to_unset( + datetime.datetime.strptime(date + " " + eevent.find('start').text, "%Y-%m-%d %H:%M") + ) end = eevent.find('duration').text.split(":") end = start + datetime.timedelta(hours=int(end[0]), minutes=int(end[1])) evtdate = start.date() @@ -69,6 +88,9 @@ description = _get_text(eevent, 'description') persons = [ (e.attrib.get('id', e.text), e.text) for e in eevent.iter('person') if e.text is not None ] + fulltextsearch += [ s for s in [title, subtitle, abstract, description, room, track] if s is not None ] + fulltextsearch += [p[1] for p in persons] + links = [] for e in eevent.iter('link'): name = e.text @@ -100,5 +122,8 @@ [ (eventid, p[0]) for p in persons ]) _db.executemany("""INSERT OR REPLACE INTO links (event_id, href, name) VALUES (?,?,?)""", links) + + fulltextsearchstr = ' '.join(fulltextsearch) + _db.execute("""INSERT OR REPLACE INTO fts_event (event_id, text) VALUES (?, ?)""", (eventid, fulltextsearchstr)) _db.commit() diff -Nru confy-0.5.1/src/settings.py confy-0.6.1/src/settings.py --- confy-0.5.1/src/settings.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/settings.py 2021-09-30 15:03:39.000000000 +0000 @@ -17,6 +17,7 @@ from gi.repository import Gio from gi.repository import Handy +from dateutil import tz # in secs CACHE_NOCACHE = 0 @@ -50,7 +51,7 @@ class Settings(Gio.Settings): - _instsance = None + _instance = None def __init__(self): """ @@ -60,7 +61,7 @@ @classmethod def instance(kls): - return kls._instsance + return kls._instance @classmethod def init(kls, app_id): @@ -69,7 +70,7 @@ """ settings = Gio.Settings.new(app_id) settings.__class__ = Settings - kls._instsance = settings + kls._instance = settings return settings def get_list_cache(self): @@ -78,4 +79,6 @@ def get_event_cache(self): return CacheDuration.get_duration(self.get_int('event-cache')) - + def get_timezone(self): + return tz.tzlocal() + diff -Nru confy-0.5.1/src/shortcuts.ui confy-0.6.1/src/shortcuts.ui --- confy-0.5.1/src/shortcuts.ui 1970-01-01 00:00:00.000000000 +0000 +++ confy-0.6.1/src/shortcuts.ui 2021-09-30 15:03:39.000000000 +0000 @@ -0,0 +1,49 @@ + + + + + + 1 + + + 1 + shortcuts + 12 + + + 1 + + + 1 + <Primary>F + Find + + + + + 1 + <Primary>L + Return to events list + + + + + 1 + <Primary>comma + Preferences + + + + + + + + + + diff -Nru confy-0.5.1/src/widgets.py confy-0.6.1/src/widgets.py --- confy-0.5.1/src/widgets.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/widgets.py 2021-09-30 15:03:39.000000000 +0000 @@ -18,6 +18,8 @@ import datetime import html +from dateutil.tz import UTC + from gi.repository import GLib from gi.repository import GObject from gi.repository import Gio @@ -59,7 +61,8 @@ icontype = ftype if fmin == 'pdf' or 'document' in fmin: icontype = ftype - + + self.content_type = icontype ficon = Gio.content_type_get_icon(icontype) # I have to manage icon by hand.. ouf @@ -68,18 +71,22 @@ def weblinkactionrowactivated(listbox, actionrow): - Gio.app_info_launch_default_for_uri(actionrow.url, None) + appinfo = Gio.app_info_get_default_for_type(actionrow.content_type, True) + if appinfo is not None: + appinfo.launch_uris([actionrow.url], None) + else: + Gio.app_info_launch_default_for_uri(actionrow.url, None) + - class EventActionRow(Handy.ActionRow): def __init__(self, obj): super().__init__(activatable=True, selectable=False) - + subtitle = "{}-{}".format( - obj.start.strftime("%a %H:%M"), - obj.end.strftime("%H:%M")) + obj.start_in_tz().strftime("%a %H:%M"), + obj.end_in_tz().strftime("%H:%M")) if obj.room: subtitle = "{} ({})".format( @@ -96,22 +103,50 @@ subtitle = "{} - {}".format( subtitle, ", ".join([str(p) for p in ps])) - + self.set_title(html.unescape(obj.title)) self.set_subtitle(html.unescape(subtitle)) self.obj = obj obj.connect('update', self.on_update) - - icon_name = "starred-symbolic" if obj.starred else "non-starred-symbolic" + + icon_name = "starred-symbolic" if obj.starred else "non-starred-symbolic" self.toggle_btn = Gtk.Button.new_from_icon_name(icon_name, Gtk.IconSize.BUTTON) self.toggle_btn.connect("clicked", self.toggle_starred) - self.add_prefix(self.toggle_btn) - + self.add(self.toggle_btn) + + Gio.Application.get_default().connect( + "tick", lambda *_: self.queue_draw() + ) + + self.connect("draw", self._on_draw) + + def _on_draw(self, widget, cr): + now = datetime.datetime.now(UTC).replace(tzinfo=None) + obj = self.obj + + h = self.get_allocated_height() + + dur = (obj.end.timestamp() - obj.start.timestamp()) + pos = (now.timestamp() - obj.start.timestamp()) + if dur > 0: + prc = min(max(pos/dur, 0.0), 1.0) + else: + # not a valid event duration + # set prc to 0 if the event is in the future or 1 if in the past + prc = int(pos >= 0) + + y = h * prc + + cr.set_source_rgb(0, 0, 0) + cr.move_to(1, 0) + cr.line_to(1, y) + cr.stroke() + def on_update(self, *args): icon_name = "starred-symbolic" if self.obj.starred else "non-starred-symbolic" self.toggle_btn.get_image().set_from_icon_name(icon_name, Gtk.IconSize.BUTTON) - + def toggle_starred(self, button): self.obj.set_star(not self.obj.starred) @@ -132,7 +167,7 @@ super().__init__(valign = Gtk.Align.CENTER) img = Gtk.Image.new_from_pixbuf( Gtk.IconTheme.get_default().load_icon( - icon_name, 256, 0)) + icon_name, 128, 0)) self.pack_start(img, False, False, 16) LBL_PROPS = { @@ -194,7 +229,7 @@ lbl1.set_markup("{}".format(msg)) lbl2 = Gtk.Label(str(error)) lbl2.get_style_context().add_class("dim-label") - + self.pack_start(img, False, False, 16) self.pack_start(lbl1, False, False, 0) self.pack_start(lbl2, False, False, 0) @@ -260,6 +295,28 @@ self.set_reveal_child(False) +class SearchBarOverlay(Handy.SearchBar): + def __init__(self, **kwargs): + opts = dict( + halign = Gtk.Align.FILL, + valign = Gtk.Align.START, + show_close_button = True + ) + opts.update(kwargs) + super().__init__(**opts) + clamp = Handy.Clamp() + self.entry = Gtk.SearchEntry(can_focus=True) + clamp.add(self.entry) + self.add(clamp) + self.show_all() + + self.connect('notify::search-mode-enabled', self._on_search_mode_changed) + + def _on_search_mode_changed(self, *args): + if self.get_search_mode(): + self.entry.set_text("") + self.entry.grab_focus() + class OkCancelDialog(Gtk.Dialog): CANCEL = 0 OK = 1 @@ -540,6 +597,7 @@ self._originalpb = pixbuf super().set_from_pixbuf(pixbuf) + class MaxSizedImage(Gtk.Image): def __init__(self, max_width, max_height, **kwargs): super().__init__(**kwargs) @@ -565,3 +623,4 @@ h, GdkPixbuf.InterpType.BILINEAR) super().set_from_pixbuf(pixbuf) + diff -Nru confy-0.5.1/src/window.py confy-0.6.1/src/window.py --- confy-0.5.1/src/window.py 2020-12-30 13:17:38.000000000 +0000 +++ confy-0.6.1/src/window.py 2021-09-30 15:03:39.000000000 +0000 @@ -16,6 +16,7 @@ # along with this program. If not, see . import datetime +import re from gi.repository import GLib from gi.repository import Gtk @@ -31,7 +32,7 @@ from . import models from .preferences import PreferencesWindow from .widgets import LoadingWidget, ErrorWidget, PlaceholderWidget -from .widgets import NotificationOverlay, LoadingOverlay +from .widgets import NotificationOverlay, LoadingOverlay, SearchBarOverlay from .widgets import InputDialog, ConferenceEditDialog @@ -58,11 +59,45 @@ class StartView(pages.BaseListPage): + """ + window + overlay + notification + loading + title_bar + open_button + search_button + update_button + + + box + search + column + box + titlebox (if title or subtitle is set) + title