From e20b37d7380fbfab84f16922be12830297e9de9b Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Sun, 16 Jun 2024 20:34:43 +0300 Subject: [PATCH 01/10] feat(mv): enable caching for clapper --- build-aux/clapper/clapper.json | 10 +++++++--- meson.build | 4 ++++ src/Views/MediaViewer.vala | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/build-aux/clapper/clapper.json b/build-aux/clapper/clapper.json index 8a33c887..17c0818a 100644 --- a/build-aux/clapper/clapper.json +++ b/build-aux/clapper/clapper.json @@ -16,7 +16,11 @@ { "type": "git", "url": "https://github.com/Rafostar/clapper.git", - "branch": "master" - } + "branch": "df371c698add3598a4e2b94f6bf3a1f939706fd8" + }, + { + "type": "shell", + "commands": ["sed -i \"s/version: '0.7.0',/version: '0.8.0',/g\" meson.build"] + } ] -} \ No newline at end of file +} diff --git a/meson.build b/meson.build index 3ab0b9fb..6cdfc8df 100644 --- a/meson.build +++ b/meson.build @@ -107,6 +107,10 @@ if clapper_support and clapper_dep.found () and clapper_dep.version().version_co if (clapper_dep.get_variable('features').split().contains('mpris')) add_project_arguments(['--define=CLAPPER_MPRIS'], language: 'vala') endif + + if clapper_dep.version().version_compare('>=0.8.0') + add_project_arguments(['--define=CLAPPER_0_8'], language: 'vala') + endif endif if gtk_dep.version().version_compare('>=4.14') diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index ae00db97..e5209ad7 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -412,8 +412,14 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { } } + #if CLAPPER + string clapper_cache_dir; + Gee.HashMap clapper_cached_items; + #endif construct { #if CLAPPER + clapper_cached_items = new Gee.HashMap (); + clapper_cache_dir = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S, Tuba.cache_path, "clapper"); // Clapper can have > 1.0 volumes last_used_volume = settings.media_viewer_last_used_volume; #else @@ -546,6 +552,9 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { ~MediaViewer () { debug ("Destroying MediaViewer"); context_menu.unparent (); + #if CLAPPER_0_8 + clapper_cached_items.clear (); + #endif } private void on_visible_toggle () { @@ -948,6 +957,13 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { valign = Gtk.Align.END, fullscreenable = false }); + + #if CLAPPER_0_8 + video.player.download_dir = clapper_cache_dir; + video.player.download_enabled = true; + video.player.download_complete.connect (on_clapper_download_complete); + #endif + #if CLAPPER_MPRIS var mpris = new Clapper.Mpris ( "org.mpris.MediaPlayer2.Tuba", @@ -977,7 +993,17 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { item = new Item (video, final_friendly_url, final_preview, true); #if CLAPPER - var clp_item = new Clapper.MediaItem (url); + Clapper.MediaItem clp_item; + #if CLAPPER_0_8 + if (clapper_cached_items.has_key (url)) { + clp_item = clapper_cached_items.get (url); + } else { + #endif + clp_item = new Clapper.MediaItem (url); + #if CLAPPER_0_8 + } + #endif + video.player.queue.add_item (clp_item); video.player.queue.select_item (clp_item); add_todo_item (item); @@ -1030,6 +1056,12 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { if (as_is || stream) add_todo_item (item); } + #if CLAPPER_0_8 + private void on_clapper_download_complete (Clapper.MediaItem clp_media_item, string location) { + clapper_cached_items.set (clp_media_item.uri, clp_media_item); + } + #endif + private Gee.ArrayList todo_items = new Gee.ArrayList (); private void add_todo_item (Item todo_item) { if (revealed) { From 9f5436f3564b2f8d062e6765f49449a786435a4e Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Sun, 16 Jun 2024 21:05:13 +0300 Subject: [PATCH 02/10] chore: lock the hashmap behind the 0_8 flag --- build-aux/clapper/clapper.json | 2 +- src/Views/MediaViewer.vala | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/build-aux/clapper/clapper.json b/build-aux/clapper/clapper.json index 17c0818a..58b67ce1 100644 --- a/build-aux/clapper/clapper.json +++ b/build-aux/clapper/clapper.json @@ -16,7 +16,7 @@ { "type": "git", "url": "https://github.com/Rafostar/clapper.git", - "branch": "df371c698add3598a4e2b94f6bf3a1f939706fd8" + "branch": "master" }, { "type": "shell", diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index e5209ad7..233ac9eb 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -414,11 +414,16 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { #if CLAPPER string clapper_cache_dir; - Gee.HashMap clapper_cached_items; + #if CLAPPER_0_8 + Gee.HashMap clapper_cached_items; + #endif #endif construct { #if CLAPPER - clapper_cached_items = new Gee.HashMap (); + #if CLAPPER_0_8 + clapper_cached_items = new Gee.HashMap (); + #endif + clapper_cache_dir = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S, Tuba.cache_path, "clapper"); // Clapper can have > 1.0 volumes last_used_volume = settings.media_viewer_last_used_volume; From e2af7abae938586e65c4b352116c48cadecae5d3 Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Mon, 17 Jun 2024 19:20:19 +0300 Subject: [PATCH 03/10] chore: put cache dir behind the 0.8 flag too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rafał Dzięgiel --- src/Views/MediaViewer.vala | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index 233ac9eb..d6f914bb 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -412,19 +412,17 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { } } - #if CLAPPER + #if CLAPPER_0_8 string clapper_cache_dir; - #if CLAPPER_0_8 - Gee.HashMap clapper_cached_items; - #endif + Gee.HashMap clapper_cached_items; #endif construct { #if CLAPPER #if CLAPPER_0_8 clapper_cached_items = new Gee.HashMap (); + clapper_cache_dir = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S, Tuba.cache_path, "clapper"); #endif - clapper_cache_dir = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S, Tuba.cache_path, "clapper"); // Clapper can have > 1.0 volumes last_used_volume = settings.media_viewer_last_used_volume; #else From df6ab371e73837e75b9b179dcb8804a251aa5d4a Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Tue, 18 Jun 2024 17:15:50 +0300 Subject: [PATCH 04/10] feat: cache cleanup --- src/Views/MediaViewer.vala | 61 +++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index d6f914bb..fedd8d63 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -413,14 +413,20 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { } #if CLAPPER_0_8 + struct ClapperCacheItem { + public Clapper.MediaItem media_item; + public string location; + } + string clapper_cache_dir; - Gee.HashMap clapper_cached_items; + Gee.HashMap clapper_cached_items; #endif construct { #if CLAPPER #if CLAPPER_0_8 - clapper_cached_items = new Gee.HashMap (); + clapper_cached_items = new Gee.HashMap (); clapper_cache_dir = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S, Tuba.cache_path, "clapper"); + clapper_cache_cleanup (true); #endif // Clapper can have > 1.0 volumes @@ -556,7 +562,9 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { debug ("Destroying MediaViewer"); context_menu.unparent (); #if CLAPPER_0_8 + clapper_cache_cleanup (true); clapper_cached_items.clear (); + clapper_cached_locations.clear (); #endif } @@ -911,6 +919,7 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { items.clear (); revealed = false; + clapper_cache_cleanup (); } private void update_revealer_widget (int pos = -1) { @@ -999,7 +1008,7 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { Clapper.MediaItem clp_item; #if CLAPPER_0_8 if (clapper_cached_items.has_key (url)) { - clp_item = clapper_cached_items.get (url); + clp_item = clapper_cached_items.get (url).media_item; } else { #endif clp_item = new Clapper.MediaItem (url); @@ -1060,8 +1069,52 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { } #if CLAPPER_0_8 + // libgee's hashmaps do not preserve insertion order. + // We need the order to know what we should cleanup + // (older items get cleaned up first). + Gee.ArrayList clapper_cached_locations = new Gee.ArrayList (); private void on_clapper_download_complete (Clapper.MediaItem clp_media_item, string location) { - clapper_cached_items.set (clp_media_item.uri, clp_media_item); + clapper_cached_items.set (clp_media_item.uri, {clp_media_item, location}); + clapper_cached_locations.add (location); + } + + private void clapper_cache_cleanup (bool all = false) { + if (!all) { + int to_remove = clapper_cached_locations.size - 3; // TODO: make it 10 before merging + if (to_remove > 0) { + var sliced = clapper_cached_locations.slice (0, to_remove); + clapper_cached_locations.remove_all (sliced); + + clapper_cached_items.foreach (e => { + if (!clapper_cached_locations.contains (e.value.location)) + clapper_cached_items.unset (e.key); + + return true; + }); + } + } + + try { + Dir dir = Dir.open (clapper_cache_dir, 0); + string? name = null; + + while ((name = dir.read_name ()) != null) { + string path = Path.build_filename (clapper_cache_dir, name); + if (!all && clapper_cached_locations.contains (path)) continue; + + File file = File.new_for_path (path); + file.delete_async.begin (Priority.LOW, null, (obj, res) => { + try { + file.delete_async.end (res); + } catch (Error e) { + warning (@"Error while deleting Clapper's cache: $(e.message)"); + } + }); + } + } catch (FileError e) { + warning (@"Error while opening Clapper's cache: $(e.message)"); + } + return; } #endif From 7b55fdec0913801956471feee8c0eed96efb96ff Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Tue, 18 Jun 2024 17:23:51 +0300 Subject: [PATCH 05/10] fix: move clapper_cache_cleanup on reset behind the clapper flag --- src/Views/MediaViewer.vala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index fedd8d63..aa3cb5a5 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -919,7 +919,10 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { items.clear (); revealed = false; - clapper_cache_cleanup (); + + #if CLAPPER_0_8 + clapper_cache_cleanup (); + #endif } private void update_revealer_widget (int pos = -1) { From da48f3319c06a782ad924d681b67e746beceedcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= <40623528+Rafostar@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:00:12 +0200 Subject: [PATCH 06/10] feat(mv): Use "Clapper.MediaItem.cached" constructor (#1044) Simplify code by storing only URIs and their cache file locations as strings, then use newly added "Clapper.MediaItem.cached" constructor to recreate an item. --- src/Views/MediaViewer.vala | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index aa3cb5a5..e2667f31 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -413,18 +413,13 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { } #if CLAPPER_0_8 - struct ClapperCacheItem { - public Clapper.MediaItem media_item; - public string location; - } - string clapper_cache_dir; - Gee.HashMap clapper_cached_items; + Gee.HashMap clapper_cached_urls; #endif construct { #if CLAPPER #if CLAPPER_0_8 - clapper_cached_items = new Gee.HashMap (); + clapper_cached_urls = new Gee.HashMap (); clapper_cache_dir = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S, Tuba.cache_path, "clapper"); clapper_cache_cleanup (true); #endif @@ -563,7 +558,7 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { context_menu.unparent (); #if CLAPPER_0_8 clapper_cache_cleanup (true); - clapper_cached_items.clear (); + clapper_cached_urls.clear (); clapper_cached_locations.clear (); #endif } @@ -1010,13 +1005,9 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { #if CLAPPER Clapper.MediaItem clp_item; #if CLAPPER_0_8 - if (clapper_cached_items.has_key (url)) { - clp_item = clapper_cached_items.get (url).media_item; - } else { - #endif - clp_item = new Clapper.MediaItem (url); - #if CLAPPER_0_8 - } + clp_item = new Clapper.MediaItem.cached (url, clapper_cached_urls.get (url)); + #else + clp_item = new Clapper.MediaItem (url); #endif video.player.queue.add_item (clp_item); @@ -1077,7 +1068,7 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { // (older items get cleaned up first). Gee.ArrayList clapper_cached_locations = new Gee.ArrayList (); private void on_clapper_download_complete (Clapper.MediaItem clp_media_item, string location) { - clapper_cached_items.set (clp_media_item.uri, {clp_media_item, location}); + clapper_cached_urls.set (clp_media_item.uri, location); clapper_cached_locations.add (location); } @@ -1088,9 +1079,9 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { var sliced = clapper_cached_locations.slice (0, to_remove); clapper_cached_locations.remove_all (sliced); - clapper_cached_items.foreach (e => { - if (!clapper_cached_locations.contains (e.value.location)) - clapper_cached_items.unset (e.key); + clapper_cached_urls.foreach (e => { + if (!clapper_cached_locations.contains (e.value)) + clapper_cached_urls.unset (e.key); return true; }); From 554e235bc51739e5a7f687bb02318b9249bd492a Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Thu, 25 Jul 2024 22:10:55 +0300 Subject: [PATCH 07/10] feat: create clapper cache folder if it doesn't exist --- src/Views/MediaViewer.vala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index b442b9ed..5072f1aa 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -421,6 +421,15 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { #if CLAPPER_0_8 clapper_cached_urls = new Gee.HashMap (); clapper_cache_dir = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S, Tuba.cache_path, "clapper"); + var dir = File.new_for_path (clapper_cache_dir); + if (!dir.query_exists ()) { + try { + dir.make_directory_with_parents (); + } catch (Error e) { + critical (@"Couldn't create Clapper cache dir: $(e.message)"); + } + } + clapper_cache_cleanup (true); #endif From 6e3cba4f208bfb289a0efa662ba3b35d2e50cb2f Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Thu, 25 Jul 2024 22:11:15 +0300 Subject: [PATCH 08/10] feat: clear cache on shutdown --- src/Views/MediaViewer.vala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index 5072f1aa..49e70f4c 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -431,6 +431,7 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { } clapper_cache_cleanup (true); + app.shutdown.connect (() => clapper_cache_cleanup (true)); #endif // Clapper can have > 1.0 volumes From 339d4993c81c432504e143a47d3e4454b9fe5ee0 Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Thu, 25 Jul 2024 22:11:35 +0300 Subject: [PATCH 09/10] feat: bump max cache from 3 to 10 items --- src/Views/MediaViewer.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index 49e70f4c..d31490d5 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -1091,7 +1091,7 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { private void clapper_cache_cleanup (bool all = false) { if (!all) { - int to_remove = clapper_cached_locations.size - 3; // TODO: make it 10 before merging + int to_remove = clapper_cached_locations.size - 10; if (to_remove > 0) { var sliced = clapper_cached_locations.slice (0, to_remove); clapper_cached_locations.remove_all (sliced); From f9fa8f4edf25523072a128ba5ec252ebf4b3127c Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Mon, 5 Aug 2024 22:16:45 +0300 Subject: [PATCH 10/10] feat: create multiple MPRIS instances --- src/Views/MediaViewer.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index ba748fa8..e7baadc2 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -1005,7 +1005,7 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { #if CLAPPER #if CLAPPER_MPRIS video.player.add_feature (new Clapper.Mpris ( - "org.mpris.MediaPlayer2.Tuba", + @"org.mpris.MediaPlayer2.Tuba.instance$(items.size)", Build.NAME, Build.DOMAIN ));