From 5c9052ba1bc66ebfc852ddd715ec1d654550d3fa Mon Sep 17 00:00:00 2001 From: birros Date: Wed, 21 Apr 2021 03:03:50 +0200 Subject: [PATCH] feat: remove gvfs use and bump to tracker-sparql-3 Fixes #19 --- HACKING.md | 7 - README.md | 6 +- .../flatpak/com.github.birros.WebArchives.yml | 38 +----- meson.build | 2 +- po/es.po | 16 --- po/fr.po | 28 ---- po/nl.po | 16 --- src/app/services/remote.vala | 16 --- src/app/services/tracker-service.vala | 10 +- src/app/ui/content/home-view.vala | 29 +---- src/app/utils/dbus-utils.vala | 20 --- src/app/utils/file-downloader.vala | 121 +++++++++--------- 12 files changed, 81 insertions(+), 228 deletions(-) diff --git a/HACKING.md b/HACKING.md index 6cad6c6..0427882 100644 --- a/HACKING.md +++ b/HACKING.md @@ -114,13 +114,6 @@ You can run it directly using the app launcher or using this command : ## Todo -- __CRITICAL__ : Handle the absence of system services such as Tracker or GVFS's -http backend : - 1. use D-Bus to test whether the service is available or not - 2. on the application's homepage, use a banner to indicate the absence of - services - 3. display instructions in a modal window, depending on the system used, to - install them - Propose ZIM format recognition for GNU/Linux distributions (mimetype) - Refactoring the settings : maximize, window size, night mode - Write help manual diff --git a/README.md b/README.md index 85e407f..3af16cd 100644 --- a/README.md +++ b/README.md @@ -93,17 +93,17 @@ application appear in your launcher. It can also be executed from a terminal : Some __problems__ may occur when running the application, especially if your desktop environment does not use [GTK+], such as __[Kde]__. -The installation of __two additional services__ is then required on the system +The installation of __tracker service__ is then required on the system side to solve these problems, requiring the execution of one of these commands depending on your distribution : __Debian & Ubuntu__ : - apt install tracker gvfs-backends + apt install tracker __Fedora__ : - dnf install tracker gvfs + dnf install tracker ### Other installation methods diff --git a/build-aux/flatpak/com.github.birros.WebArchives.yml b/build-aux/flatpak/com.github.birros.WebArchives.yml index 8d0ef1f..027d7c2 100644 --- a/build-aux/flatpak/com.github.birros.WebArchives.yml +++ b/build-aux/flatpak/com.github.birros.WebArchives.yml @@ -13,14 +13,9 @@ finish-args: - --socket=pulseaudio # Used to list automatically indexed local files - --filesystem=home - - --talk-name=org.freedesktop.Tracker1 - - --env=TRACKER_SPARQL_BACKEND=bus - # Used to access gvfs's http backend to download files + - --talk-name=org.freedesktop.Tracker3.Miner.Files + # Used to download files - --share=network - - --talk-name=org.gtk.vfs - - --talk-name=org.gtk.vfs.* - # Dconf migration (TODO: to remove around 2020) - - --metadata=X-DConf=migrate-path=/com/github/birros/WebArchives/ modules: - name: xapian-core config-opts: @@ -89,33 +84,6 @@ modules: url: https://github.com/birros/libzim-glib/archive/v3.2.0.tar.gz sha256: 89cbc55254d90c70de2de8ee7f2b4aff97f582ae7f495ddfee518ef136de9357 - - name: tracker - buildsystem: meson - builddir: true - cleanup: - - /bin - - /etc - - /include - - /lib/libtracker-control* - - /lib/libtracker-mine* - - /lib/*.la - - /lib/tracker-2.0/*.la - - /lib/girepository-1.0 - - /lib/pkgconfig - - /lib/systemd - - /libexec - - /share/bash-completion - - /share/dbus-1 - - /share/gir-1.0 - - /share/gtk-doc - - /share/man - - /share/runtime - - /share/vala - sources: - - type: archive - url: https://ftp.gnome.org/pub/GNOME/sources/tracker/2.3/tracker-2.3.6.tar.xz - sha256: bd1eb4122135296fa7b57b1c3fa0ed602cf7d06c0b8e534d0bd17ff5f97feef2 - - name: libgee build-options: env: @@ -173,7 +141,7 @@ modules: # # require - # libzim-glib, tracker, libisocodes, libhandy + # libzim-glib, libisocodes, libhandy # subprojects/darkreader require # nodejs # diff --git a/meson.build b/meson.build index eeeae86..cab7d8f 100644 --- a/meson.build +++ b/meson.build @@ -24,7 +24,7 @@ sqlite_dep = dependency('sqlite3') webkit_dep = dependency('webkit2gtk-4.0') soup_dep = dependency('libsoup-2.4') webkit_web_extension_dep = dependency('webkit2gtk-web-extension-4.0') -tracker_dep = dependency('tracker-sparql-2.0') +tracker_dep = dependency('tracker-sparql-3.0') xml_dep = dependency('libxml-2.0') isocodes_dep = dependency('libisocodes') handy_dep = dependency('libhandy-1', version : '>=1.0.0') diff --git a/po/es.po b/po/es.po index 6bb6d69..103c7bc 100644 --- a/po/es.po +++ b/po/es.po @@ -492,22 +492,6 @@ msgstr "" "No hay ningún archivador descargable disponible. Por favor, actualice esta " "lista usando el botón apropiado." -#: src/app/ui/content/home-view.vala:39 -msgid "" -"It seems that a GVFS component " -"is not installed on your system. WebArchives cannot list downloadable " -"archives.\n" -"\n" -"Please install this component using your package manager, then restart " -"your session.\n" -"\n" -"• Debian or Ubuntu:\n" -" # apt install gvfs-backends\n" -"\n" -"• Fedora:\n" -" # dnf install gvfs" -msgstr "" - #: src/app/ui/content/home-view.vala:63 msgid "Cannot open the archive file" msgstr "No se puede abrir el archivador" diff --git a/po/fr.po b/po/fr.po index e38e392..32449e0 100644 --- a/po/fr.po +++ b/po/fr.po @@ -506,34 +506,6 @@ msgstr "" "Aucune archive disponible en téléchargement. Veuillez rafraîchir cette " "liste à l'aide du bouton approprié." -#: src/app/ui/content/home-view.vala:39 -msgid "" -"It seems that a GVFS component " -"is not installed on your system. WebArchives cannot list downloadable " -"archives.\n" -"\n" -"Please install this component using your package manager, then restart " -"your session.\n" -"\n" -"• Debian or Ubuntu:\n" -" # apt install gvfs-backends\n" -"\n" -"• Fedora:\n" -" # dnf install gvfs" -msgstr "" -"Il semble qu'un composant GVFS " -"n'est pas installé sur votre système. WebArchives ne peut pas lister " -"les archives téléchargeables.\n" -"\n" -"Veuillez installer ce composant à l'aide de votre gestionnaire de " -"paquets, puis redémarrez votre session.\n" -"\n" -"• Debian ou Ubuntu:\n" -" # apt install gvfs-backends\n" -"\n" -"• Fedora:\n" -" # dnf install gvfs" - #: src/app/ui/content/home-view.vala:63 msgid "Cannot open the archive file" msgstr "Impossible d'ouvrir l'archive" diff --git a/po/nl.po b/po/nl.po index dabffa5..1312ba1 100644 --- a/po/nl.po +++ b/po/nl.po @@ -491,22 +491,6 @@ msgstr "" "Geen archief beschikbaar om te downloaden. Vernieuw deze lijst met de " "juiste knop." -#: src/app/ui/content/home-view.vala:39 -msgid "" -"It seems that a GVFS component " -"is not installed on your system. WebArchives cannot list downloadable " -"archives.\n" -"\n" -"Please install this component using your package manager, then restart " -"your session.\n" -"\n" -"• Debian or Ubuntu:\n" -" # apt install gvfs-backends\n" -"\n" -"• Fedora:\n" -" # dnf install gvfs" -msgstr "" - #: src/app/ui/content/home-view.vala:63 msgid "Cannot open the archive file" msgstr "Kan het archiefbestand niet openen" diff --git a/src/app/services/remote.vala b/src/app/services/remote.vala index ee11901..9b6ec81 100644 --- a/src/app/services/remote.vala +++ b/src/app/services/remote.vala @@ -6,22 +6,10 @@ public class WebArchives.Remote : Object { public int64 timestamp {get; set; default = 0; } public bool downloading {get; private set; default = false;} public double progress {get; private set; default = 0; } - public bool enabled {get; private set; default = false;} public Remote (ArchiveStore archive_store) { this.archive_store = archive_store; - if ( - DBusUtils.is_name_activatable ("org.gtk.vfs.Daemon") && - DBusUtils.is_gvfs_backend_supported ("http") - ) { - enabled = true; - info ("HTTP GVFS backend is present"); - } else { - enabled = false; - info ("HTTP GVFS backend is not present"); - } - // build library path string cache_dir = Environment.get_user_cache_dir (); string files_folder = Path.build_filename ( @@ -31,10 +19,6 @@ public class WebArchives.Remote : Object { } public void refresh () { - if (!enabled) { - return; - } - FileDownloader library_downloader = new FileDownloader (); library_downloader.download_file (LIBRARY_URL, library_path); library_downloader.complete.connect (() => { diff --git a/src/app/services/tracker-service.vala b/src/app/services/tracker-service.vala index 7a7945e..7141cfe 100644 --- a/src/app/services/tracker-service.vala +++ b/src/app/services/tracker-service.vala @@ -6,7 +6,9 @@ public class WebArchives.TrackerService : Object { public TrackerService (ArchiveStore archive_store) { this.archive_store = archive_store; - if (DBusUtils.is_name_activatable ("org.freedesktop.Tracker1")) { + if (DBusUtils.is_name_activatable ( + "org.freedesktop.Tracker3.Miner.Files" + )) { enabled = true; info ("Tracker is present"); } else { @@ -28,7 +30,11 @@ public class WebArchives.TrackerService : Object { // build tracker list try { Tracker.Sparql.Connection connection = - Tracker.Sparql.Connection.@get (); + Tracker.Sparql.Connection.bus_new( + "org.freedesktop.Tracker3.Miner.Files", + null, + null + ); Tracker.Sparql.Cursor cursor = connection.query ( """ SELECT nie:url(?f) diff --git a/src/app/ui/content/home-view.vala b/src/app/ui/content/home-view.vala index 9e9ef22..3ea3d3b 100644 --- a/src/app/ui/content/home-view.vala +++ b/src/app/ui/content/home-view.vala @@ -35,18 +35,6 @@ public class WebArchives.HomeView : Gtk.Overlay { """No archive available for download. Please refresh this list using the appropriate button.""" ); - private const string REMOTE_WARNING_MESSAGE = _( -"""It seems that a GVFS component is not installed on your system. WebArchives cannot list downloadable archives. - -Please install this component using your package manager, then restart your session. - -• Debian or Ubuntu: - # apt install gvfs-backends - -• Fedora: - # dnf install gvfs""" - ); - public HomeView (Context context) { this.context = context; @@ -225,9 +213,6 @@ public class WebArchives.HomeView : Gtk.Overlay { remote_header_comboboxtext.changed.connect (() => { language_changed (); }); - if (!context.remote.enabled) { - remote_header_comboboxtext.sensitive = false; - } remote_header_box.add (remote_header_comboboxtext); StatusLabel remote_last_refreshed = new StatusLabel (); @@ -254,9 +239,6 @@ public class WebArchives.HomeView : Gtk.Overlay { remote_header_button.clicked.connect (() => { context.remote.refresh (); }); - if (!context.remote.enabled) { - remote_header_button.sensitive = false; - } remote_header_box.add (remote_header_button); Gtk.Frame remote_frame = new Gtk.Frame (null); @@ -270,12 +252,7 @@ public class WebArchives.HomeView : Gtk.Overlay { remote_frame.add (remote_list_box); Gtk.Label remote_placeholder; - if (context.remote.enabled) { - remote_placeholder = new Gtk.Label (REMOTE_INFO_MESSAGE); - } else { - remote_placeholder = new Gtk.Label (REMOTE_WARNING_MESSAGE); - remote_placeholder.selectable = true; - } + remote_placeholder = new Gtk.Label (REMOTE_INFO_MESSAGE); remote_placeholder.use_markup = true; remote_placeholder.margin = 12; remote_placeholder.wrap = true; @@ -293,9 +270,7 @@ public class WebArchives.HomeView : Gtk.Overlay { } remote_model = null; - if (context.remote.enabled) { - language_changed (); - } + language_changed (); show_all (); } diff --git a/src/app/utils/dbus-utils.vala b/src/app/utils/dbus-utils.vala index 62739a8..ec8c440 100644 --- a/src/app/utils/dbus-utils.vala +++ b/src/app/utils/dbus-utils.vala @@ -38,24 +38,4 @@ public class WebArchives.DBusUtils : Object { } return false; } - - public static bool is_gvfs_backend_supported (string protocol) { - try { - MountTracker interface = Bus.get_proxy_sync ( - BusType.SESSION, "org.gtk.vfs.Daemon", - "/org/gtk/vfs/mounttracker" - ); - - string[] types = interface.list_mount_types (); - - if (array_contains (types, protocol)) { - return true; - } else { - return false; - } - } catch (Error e) { - warning (e.message); - } - return false; - } } diff --git a/src/app/utils/file-downloader.vala b/src/app/utils/file-downloader.vala index dcfce83..75c7c1f 100644 --- a/src/app/utils/file-downloader.vala +++ b/src/app/utils/file-downloader.vala @@ -1,6 +1,3 @@ -/** - * Requires access to gvfs. - */ public class WebArchives.FileDownloader : Object { public double progress {get; private set; default = 0;} public signal void complete (); @@ -9,6 +6,8 @@ public class WebArchives.FileDownloader : Object { private uint64 header_size; private uint64 header_modified; + private uint64 local_modified; + private uint64 current_length; private bool error; private string source; @@ -27,76 +26,84 @@ public class WebArchives.FileDownloader : Object { create_dir (filepath); delete_file (filepath + ".part"); + local_modified = get_file_timestamp (filepath); + + var session = new Soup.Session (); + var message = new Soup.Message ("GET", source); + + message.got_headers.connect((message) => { + if (message.status_code != 200) { + return; + } + + // header_size + header_size = message.response_headers.get_content_length(); - File file = File.new_for_uri (source); - get_infos.begin (file, () => { + // header_modified + var last_modified = message.response_headers.get_one("Last-Modified"); + DateTime modification_time = parse_modification_date_time(last_modified); + header_modified = modification_time.to_unix (); + + // debug info ("header_size : %llu", header_size); info ("header_modified : %llu", header_modified); - - uint64 local_modified = get_file_timestamp (filepath); info ("local_modified : %llu", local_modified); - if ( - !error && - (header_modified == 0 || header_modified > local_modified) - ) { + // stop if no header_modified or if local is more recent than remote + if (header_modified == 0 || local_modified > header_modified) { + session.abort(); + canceled(); + } + }); + + message.got_chunk.connect((message, buf) => { + // progress + current_length += buf.length; + if (header_size > 0) { + progress = (double) (current_length / (double) header_size); + } + }); + + session.queue_message (message, (sess, msg) => { + // cancel if not ok + if (msg.status_code != 200) { + canceled(); + return; + } + + try { + // delete previous file delete_file (filepath); + + // write data DataOutputStream dos = create_part_file (filepath); + dos.write (msg.response_body.data); + dos.flush (); - get_file.begin (file, dos, () => { - if (!error) { - rename_part_file (filepath); - complete (); - } else { - delete_file (filepath + ".part"); - canceled (); - } - }); - } else { + // rename file & complete + rename_part_file (filepath); + complete (); + } catch (Error e) { + warning (e.message); canceled (); } }); } - private async void get_infos (File file) { - try { - FileInfo info = yield file.query_info_async ( - "standard::size,time::modified", 0 - ); - header_size = info.get_size (); - DateTime modification_time = info.get_modification_date_time (); - header_modified = modification_time.to_unix (); - } catch (Error e) { - warning (e.message); - error = true; - } - } - - private async void get_file (File file, DataOutputStream dos) { - try { - FileInputStream inputstream = file.read (); - DataInputStream dis = new DataInputStream (inputstream); - - uint8[] buffer = new uint8[100]; - ssize_t size; - while ((size = yield dis.read_async (buffer)) > 0) { - current_length += size; - - try { - dos.write (buffer[0:size]); - } catch (Error e) { - warning (e.message); - } - - if (header_size > 0) { - progress = (double) (current_length / (double) header_size); + private DateTime parse_modification_date_time (string? last_modified_full) { + if (last_modified_full != null) { + var parts = last_modified_full.split(", "); + if (parts.length > 1) { + var last_modified = parts[1]; + var time = Time(); + var res = time.strptime(last_modified, "%d %b %Y %H:%M:%S GMT"); + if (res != null) { + var last_modified_iso = time.format("%Y-%m-%dT%H:%M:%SZ"); + return new DateTime.from_iso8601 (last_modified_iso, null); } } - dos.flush (); - } catch (Error e) { - warning (e.message); - error = true; } + return new DateTime.now_utc(); } private static void rename_part_file (string filepath) {