diff -Nru synapse-0.2.99.4/debian/changelog synapse-0.2.99.4/debian/changelog --- synapse-0.2.99.4/debian/changelog 2022-03-10 12:02:21.000000000 +0000 +++ synapse-0.2.99.4/debian/changelog 2022-10-25 10:10:26.000000000 +0000 @@ -1,3 +1,15 @@ +synapse (0.2.99.4-3build1+ppa1) jammy; urgency=medium + + * Add to my PPA. + - Add build-depends on libappindicator3-dev and libindicator3-dev + to enable application indicators support. + - Add build-depends on librest-dev to enable the REST plugin. + - Add build-depends on dh-autoreconf for the new plugins. + - d/patches/0002-filezilla-plugin.patch: add Filezilla plugin. + - d/patches/0003-remmina-plugin.patch: add Remmina plugin. + + -- Peter Meiser Tue, 25 Oct 2022 12:10:26 +0200 + synapse (0.2.99.4-3build1) jammy; urgency=medium * No-change rebuild against latest gdk-pixbuf diff -Nru synapse-0.2.99.4/debian/control synapse-0.2.99.4/debian/control --- synapse-0.2.99.4/debian/control 2020-04-25 14:58:30.000000000 +0000 +++ synapse-0.2.99.4/debian/control 2020-12-24 22:26:23.000000000 +0000 @@ -4,12 +4,16 @@ Priority: optional Build-Depends: debhelper (>= 12), debhelper-compat (= 12), + dh-autoreconf, intltool, + libappindicator3-dev, libgee-0.8-dev, libgtk-3-dev, + libindicator3-dev, libjson-glib-dev, libkeybinder-3.0-dev, libnotify-dev, + librest-dev, libzeitgeist-2.0-dev, pkg-config, valac diff -Nru synapse-0.2.99.4/debian/patches/0002-filezilla-plugin.patch synapse-0.2.99.4/debian/patches/0002-filezilla-plugin.patch --- synapse-0.2.99.4/debian/patches/0002-filezilla-plugin.patch 1970-01-01 00:00:00.000000000 +0000 +++ synapse-0.2.99.4/debian/patches/0002-filezilla-plugin.patch 2020-12-24 22:25:21.000000000 +0000 @@ -0,0 +1,219 @@ +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -27,6 +27,7 @@ + src/plugins/dictionary.vala + src/plugins/directory-plugin.vala + src/plugins/file-op-plugin.vala ++src/plugins/filezilla.vala + src/plugins/gnome-bookmarks-plugin.vala + src/plugins/hybrid-search-plugin.vala + src/plugins/imgur-plugin.vala +--- a/src/plugins/filezilla-plugin.vala ++++ b/src/plugins/filezilla-plugin.vala +@@ -0,0 +1,186 @@ ++/* ++ * Copyright (C) 2013 Tom Beckmann ++ * Copyright (C) 2018 Peter Meiser ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Authored by Tom Beckmann ++ * ++ */ ++ ++namespace Synapse ++{ ++ public class FilezillaPlugin : Object, Activatable, ItemProvider ++ { ++ public bool enabled { get; set; default = true; } ++ private Gee.ArrayList sites; ++ ++ protected File config_file; ++ protected FileMonitor monitor; ++ ++ static construct ++ { ++ register_plugin (); ++ } ++ ++ construct ++ { ++ sites = new Gee.ArrayList (); ++ } ++ ++ public void activate () ++ { ++ this.config_file = File.new_for_path (Environment.get_home_dir () + "/.config/filezilla/sitemanager.xml"); ++ ++ parse_site_config.begin (); ++ ++ try { ++ this.monitor = config_file.monitor_file (FileMonitorFlags.NONE); ++ this.monitor.changed.connect (this.handle_site_config_update); ++ } ++ catch (IOError e) ++ { ++ warning ("Failed to start monitoring changes of filezilla site config file"); ++ } ++ } ++ ++ public void deactivate () {} ++ ++ static void register_plugin () ++ { ++ PluginRegistry.get_default ().register_plugin ( ++ typeof (FilezillaPlugin), ++ "Filezilla", // Plugin title ++ _("Connect to Filezilla sites"), // description ++ "applications-internet", // icon name ++ register_plugin, // reference to this function ++ // true if user's system has all required components which the plugin needs ++ (Environment.find_program_in_path ("filezilla") != null), ++ _("Filezilla is not installed") // error message ++ ); ++ } ++ ++ private async void parse_site_config () ++ { ++ sites.clear (); ++ ++ try ++ { ++ var dis = new DataInputStream (config_file.read ()); ++ ++ string line; ++ string? host = null; ++ string? name = null; ++ ++ while ((line = yield dis.read_line_async (Priority.DEFAULT)) != null) ++ { ++ var relevant = line.substring (line.index_of ("<") + 1, 4); ++ if (relevant == "Host") ++ host = line.slice (line.index_of ("") + 6, line.index_of ("")); ++ else if (relevant == "Name") ++ name = line.slice (line.index_of ("") + 6, line.index_of ("")); ++ ++ if (host != null && name != null) { ++ debug ("site added: %s:%s\n", name, host); ++ sites.add (new Site (name, host)); ++ host = null; ++ name = null; ++ } ++ } ++ } ++ catch (Error e) ++ { ++ warning ("%s: %s", config_file.get_path (), e.message); ++ } ++ } ++ ++ public void handle_site_config_update (FileMonitor monitor, ++ File file, ++ File? other_file, ++ FileMonitorEvent event_type) ++ { ++ if (event_type == FileMonitorEvent.CHANGES_DONE_HINT) ++ { ++ message ("filezilla config has changed, reparsing"); ++ parse_site_config.begin (); ++ } ++ } ++ ++ public bool handles_query (Query query) ++ { ++ return sites.size > 0 && ++ ( QueryFlags.ACTIONS in query.query_type || ++ QueryFlags.INTERNET in query.query_type); ++ } ++ ++ public async ResultSet? search (Query q) throws SearchError ++ { ++ Idle.add (search.callback); ++ yield; ++ q.check_cancellable (); ++ ++ var results = new ResultSet (); ++ ++ var matchers = Query.get_matchers_for_query (q.query_string, 0, ++ RegexCompileFlags.OPTIMIZE | RegexCompileFlags.CASELESS); ++ ++ foreach (var site in sites) ++ { ++ foreach (var matcher in matchers) ++ { ++ if (matcher.key.match (site.description) || matcher.key.match (site.title)) ++ { ++ results.add (site, matcher.value - MatchScore.INCREMENT_SMALL); ++ break; ++ } ++ } ++ } ++ ++ q.check_cancellable (); ++ ++ return results; ++ } ++ ++ private class Site : ActionMatch ++ { ++ ++ public override void do_action () ++ { ++ try ++ { ++ AppInfo ai = AppInfo.create_from_commandline ( ++ "filezilla --site=\"0%s\"".printf (this.title), ++ "filezilla", 0); ++ ai.launch (null, null); ++ } ++ catch (Error err) ++ { ++ warning ("%s", err.message); ++ } ++ } ++ ++ public Site (string name, string host) ++ { ++ Object ( ++ title: name, ++ description: _("Connect to %s").printf (host), ++ has_thumbnail: false, ++ icon_name: "applications-internet" ++ ); ++ ++ } ++ } ++ } ++} +--- a/src/plugins/Makefile.am ++++ b/src/plugins/Makefile.am +@@ -32,6 +32,7 @@ + chromium-plugin.vala \ + command-plugin.vala \ + file-op-plugin.vala \ ++ filezilla-plugin.vala \ + desktop-file-plugin.vala \ + devhelp-search.vala \ + ssh-plugin.vala \ +--- a/src/ui/synapse-main.vala ++++ b/src/ui/synapse-main.vala +@@ -173,6 +173,7 @@ + typeof (XnoiseActions), + typeof (ChromiumPlugin), + typeof (FileOpPlugin), ++ typeof (FilezillaPlugin), + typeof (PidginPlugin), + typeof (PassPlugin), + typeof (ChatActions), diff -Nru synapse-0.2.99.4/debian/patches/0003-remmina-plugin.patch synapse-0.2.99.4/debian/patches/0003-remmina-plugin.patch --- synapse-0.2.99.4/debian/patches/0003-remmina-plugin.patch 1970-01-01 00:00:00.000000000 +0000 +++ synapse-0.2.99.4/debian/patches/0003-remmina-plugin.patch 2020-12-24 22:25:21.000000000 +0000 @@ -0,0 +1,259 @@ +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -37,6 +37,7 @@ + src/plugins/pass-plugin.vala + src/plugins/pastebin-plugin.vala + src/plugins/pidgin-plugin.vala ++src/plugins/remmina-plugin.vala + src/plugins/rhythmbox-plugin.vala + src/plugins/screensaver-plugin.vala + src/plugins/selection-plugin.vala +--- a/src/plugins/Makefile.am ++++ b/src/plugins/Makefile.am +@@ -49,6 +49,7 @@ + pass-plugin.vala \ + pastebin-plugin.vala \ + pidgin-plugin.vala \ ++ remmina-plugin.vala \ + rhythmbox-plugin.vala \ + selection-plugin.vala \ + test-slow-plugin.vala \ +--- a/src/plugins/remmina-plugin.vala ++++ b/src/plugins/remmina-plugin.vala +@@ -0,0 +1,226 @@ ++/* ++ * Copyright (C) 2018 Peter Meiser ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Authored by Peter Meiser ++ * ++ */ ++ ++namespace Synapse ++{ ++ public class RemminaPlugin : Object, Activatable, ItemProvider ++ { ++ public bool enabled { get; set; default = true; } ++ private Gee.ArrayList sessions; ++ ++ private File remmina_directory; ++ private List monitors; ++ ++ static construct ++ { ++ register_plugin (); ++ } ++ ++ construct ++ { ++ sessions = new Gee.ArrayList (); ++ } ++ ++ public void activate () ++ { ++ remmina_directory = File.new_for_path ( ++ "%s/remmina".printf (Environment.get_user_data_dir ()) ++ ); ++ update_sessions(); ++ } ++ ++ public void deactivate () {} ++ ++ static void register_plugin () ++ { ++ PluginRegistry.get_default ().register_plugin ( ++ typeof (RemminaPlugin), ++ "Remmina", // Plugin title ++ _("Connect to Remmina sessions"), // description ++ "org.remmina.Remmina", // icon name ++ register_plugin, // reference to this function ++ // true if user's system has all required components which the plugin needs ++ (Environment.find_program_in_path ("remmina") != null), ++ _("Remmina is not installed") // error message ++ ); ++ } ++ ++ private void update_sessions () { ++ foreach (unowned FileMonitor monitor in monitors) { ++ monitor.cancel (); ++ } ++ monitors = null; ++ ++ try { ++ monitors = activate_monitors (remmina_directory); ++ } catch (Error err) { ++ warning ("Unable to monitor remmina directory: %s", err.message); ++ } ++ try { ++ parse_sessions (remmina_directory); ++ } catch (Error err) { ++ warning ("Unable to parse remmina sessions: %s", err.message); ++ } ++ } ++ ++ private List activate_monitors (File directory) throws Error { ++ List result = new List (); ++ ++ FileEnumerator enumerator = directory.enumerate_children ( ++ FileAttribute.STANDARD_NAME, ++ 0 ++ ); ++ ++ FileMonitor monitor = directory.monitor_directory (FileMonitorFlags.NONE, null); ++ monitor.set_rate_limit (500); ++ monitor.changed.connect ((src, dest, event) => { ++ debug ("Detected a change (%s) in remmina sessions. Reloading", event.to_string ()); ++ update_sessions (); ++ }); ++ result.append (monitor); ++ ++ FileInfo? info = null; ++ while ((info = enumerator.next_file (null)) != null) { ++ if (info.get_is_hidden ()) continue; ++ ++ } ++ ++ return result; ++ } ++ ++ private async void parse_sessions (File directory) { ++ ++ sessions.clear(); ++ ++ FileEnumerator enumerator = directory.enumerate_children ( ++ FileAttribute.STANDARD_NAME, ++ 0 ++ ); ++ ++ FileInfo? info = null; ++ while ((info = enumerator.next_file (null)) != null) { ++ File target_file = File.new_for_path (directory.get_child (info.get_name ()).get_path ()); ++ ++ debug ("target_file is %s", target_file.get_path ()); ++ ++ try ++ { ++ var dis = new DataInputStream (target_file.read ()); ++ ++ string line; ++ string? host = null; ++ string? name = null; ++ string? protocol = null; ++ ++ while ((line = yield dis.read_line_async (Priority.DEFAULT)) != null) ++ { ++ string[] relevant = line.split ("=", 2); ++ if (relevant[0] == "name") ++ name = relevant[1]; ++ else if (relevant[0] == "server") ++ host = relevant[1]; ++ else if (relevant[0] == "protocol") ++ protocol = relevant[1]; ++ ++ if (host != null && name != null && protocol != null) { ++ debug ("session added: %s:%s:%s\n", name, host, protocol); ++ sessions.add (new Session (target_file.get_path(), name, host, protocol)); ++ host = null; ++ name = null; ++ protocol = null; ++ } ++ } ++ } ++ catch (Error err) ++ { ++ warning ("parse_sessions: %s", err.message); ++ } ++ } ++ } ++ ++ public bool handles_query (Query query) ++ { ++ return sessions.size > 0 && ++ ( QueryFlags.ACTIONS in query.query_type || ++ QueryFlags.INTERNET in query.query_type); ++ } ++ ++ public async ResultSet? search (Query q) throws SearchError ++ { ++ Idle.add (search.callback); ++ yield; ++ q.check_cancellable (); ++ ++ var results = new ResultSet (); ++ ++ var matchers = Query.get_matchers_for_query (q.query_string, 0, ++ RegexCompileFlags.OPTIMIZE | RegexCompileFlags.CASELESS); ++ ++ foreach (var session in sessions) ++ { ++ foreach (var matcher in matchers) ++ { ++ if (matcher.key.match (session.description) || matcher.key.match (session.title)) ++ { ++ results.add (session, matcher.value - MatchScore.INCREMENT_SMALL); ++ break; ++ } ++ } ++ } ++ ++ q.check_cancellable (); ++ ++ return results; ++ } ++ ++ private class Session : ActionMatch ++ { ++ public string file_name { get; construct; } ++ ++ public override void do_action () ++ { ++ try ++ { ++ AppInfo ai = AppInfo.create_from_commandline ( ++ "remmina --connect=\"%s\"".printf (file_name), ++ "remmina", 0); ++ ai.launch (null, null); ++ } ++ catch (Error err) ++ { ++ warning ("%s", err.message); ++ } ++ } ++ ++ public Session (string file_name, string name, string host, string protocol) ++ { ++ Object ( ++ file_name: file_name, ++ title: name, ++ description: _("Connect to %s via %s").printf (host, protocol), ++ has_thumbnail: false, ++ icon_name: "org.remmina.Remmina" ++ ); ++ ++ } ++ } ++ } ++} +--- a/src/ui/synapse-main.vala ++++ b/src/ui/synapse-main.vala +@@ -163,6 +163,7 @@ + typeof (ScreenSaverPlugin), + typeof (SystemManagementPlugin), + typeof (CommandPlugin), ++ typeof (RemminaPlugin), + typeof (RhythmboxActions), + typeof (BansheeActions), + typeof (DirectoryPlugin), diff -Nru synapse-0.2.99.4/debian/patches/series synapse-0.2.99.4/debian/patches/series --- synapse-0.2.99.4/debian/patches/series 2020-04-25 14:58:30.000000000 +0000 +++ synapse-0.2.99.4/debian/patches/series 2020-12-24 22:25:21.000000000 +0000 @@ -1 +1,3 @@ 0001-silence-desktop-entry-lacks-keywords-entry.patch +0002-filezilla-plugin.patch +0003-remmina-plugin.patch