Merge lp:~gentoo90/synapse-project/remmina into lp:synapse-project

Proposed by gentoo90
Status: Needs review
Proposed branch: lp:~gentoo90/synapse-project/remmina
Merge into: lp:synapse-project
Diff against target: 237 lines (+200/-0)
4 files modified
po/POTFILES.skip (+1/-0)
src/plugins/Makefile.am (+1/-0)
src/plugins/remmina-plugin.vala (+197/-0)
src/ui/synapse-main.vala (+1/-0)
To merge this branch: bzr merge lp:~gentoo90/synapse-project/remmina
Reviewer Review Type Date Requested Status
Synapse core team Pending
Review via email: mp+347339@code.launchpad.net

Commit message

Add a plugin for Remmina remote desktop client.

Description of the change

Add a plugin for Remmina remote desktop client.
https://www.remmina.org/

To post a comment you must log in.

Unmerged revisions

667. By gentoo90

Add Remmina plugin

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'po/POTFILES.skip'
2--- po/POTFILES.skip 2016-04-01 05:58:51 +0000
3+++ po/POTFILES.skip 2018-06-03 13:39:20 +0000
4@@ -37,6 +37,7 @@
5 src/plugins/pass-plugin.c
6 src/plugins/pastebin-plugin.c
7 src/plugins/pidgin-plugin.c
8+src/plugins/remmina-plugin.c
9 src/plugins/rhythmbox-plugin.c
10 src/plugins/screensaver-plugin.c
11 src/plugins/selection-plugin.c
12
13=== modified file 'src/plugins/Makefile.am'
14--- src/plugins/Makefile.am 2016-04-01 05:58:51 +0000
15+++ src/plugins/Makefile.am 2018-06-03 13:39:20 +0000
16@@ -48,6 +48,7 @@
17 pass-plugin.vala \
18 pastebin-plugin.vala \
19 pidgin-plugin.vala \
20+ remmina-plugin.vala \
21 rhythmbox-plugin.vala \
22 selection-plugin.vala \
23 test-slow-plugin.vala \
24
25=== added file 'src/plugins/remmina-plugin.vala'
26--- src/plugins/remmina-plugin.vala 1970-01-01 00:00:00 +0000
27+++ src/plugins/remmina-plugin.vala 2018-06-03 13:39:20 +0000
28@@ -0,0 +1,197 @@
29+/*
30+ * Copyright (C) 2018 Igor Shaula <gentoo90@gmail.com>
31+ *
32+ * This program is free software; you can redistribute it and/or modify
33+ * it under the terms of the GNU General Public License as published by
34+ * the Free Software Foundation; either version 2 of the License, or
35+ * (at your option) any later version.
36+ *
37+ * This program is distributed in the hope that it will be useful,
38+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
39+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40+ * GNU General Public License for more details.
41+ *
42+ * You should have received a copy of the GNU General Public License
43+ * along with this program; if not, write to the Free Software
44+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
45+ *
46+ * Authored by Igor Shaula <gentoo90@gmail.com>
47+ *
48+ */
49+
50+namespace Synapse
51+{
52+ public class RemminaPlugin : Object, Activatable, ItemProvider
53+ {
54+ public bool enabled { get; set; default = true; }
55+ private Gee.HashMap<string, RemminaHost> hosts;
56+
57+ protected File config_dir;
58+ protected FileMonitor monitor;
59+
60+ static construct
61+ {
62+ register_plugin ();
63+ }
64+
65+ construct
66+ {
67+ hosts = new Gee.HashMap<string, RemminaHost> ();
68+ }
69+
70+ public void activate ()
71+ {
72+ this.config_dir = File.new_for_path (Environment.get_home_dir () + "/.remmina");
73+
74+ update_hosts.begin ();
75+
76+ try {
77+ this.monitor = config_dir.monitor_directory (FileMonitorFlags.NONE);
78+ this.monitor.changed.connect (this.handle_remmina_config_update);
79+ }
80+ catch (IOError e)
81+ {
82+ warning ("Failed to start monitoring changes of ssh client config file");
83+ }
84+ }
85+
86+ public void deactivate ()
87+ {
88+ }
89+
90+ static void register_plugin ()
91+ {
92+ PluginRegistry.get_default ().register_plugin (
93+ typeof (RemminaPlugin),
94+ _("Remmina"),
95+ _("Open remote connection in Remmina."),
96+ "remmina",
97+ register_plugin,
98+ Environment.find_program_in_path ("remmina") != null,
99+ _("Remmina is not installed")
100+ );
101+ }
102+
103+ private async void update_hosts ()
104+ {
105+ hosts.clear ();
106+
107+ try
108+ {
109+ FileEnumerator enumerator = yield config_dir.enumerate_children_async (
110+ "standard::*",
111+ FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
112+
113+ FileInfo info;
114+ while ((info = enumerator.next_file (null)) != null)
115+ {
116+ try // one broken file should not break the whole thing
117+ {
118+ if (info.get_content_type () == "application/x-remmina")
119+ {
120+ warning ("REM_FILEEEEEAA: %s", info.get_name ());
121+ File file = config_dir.resolve_relative_path (info.get_name ());
122+ string host_name = yield parse_remmina_file (file);
123+ hosts.set (host_name, new RemminaHost (host_name, file.get_path ()));
124+ }
125+ }
126+ catch (Error e)
127+ {
128+ warning ("%s: %s", config_dir.get_path (), e.message);
129+ }
130+ }
131+ }
132+ catch (Error e)
133+ {
134+ warning ("%s: %s", config_dir.get_path (), e.message);
135+ }
136+ }
137+
138+ private async string parse_remmina_file (File file) throws Error
139+ {
140+ var dis = new DataInputStream (file.read ());
141+
142+ string line;
143+ while ((line = yield dis.read_line_async (Priority.DEFAULT)) != null)
144+ {
145+ if (line.index_of ("name=") == 0)
146+ {
147+ string host_name = line.split ("=")[1];
148+ warning ("FOUND_IT: %s", host_name);
149+ return host_name;
150+ }
151+ }
152+ throw new IOError.INVALID_DATA ("Host name not found");
153+ }
154+
155+ public void handle_remmina_config_update (FileMonitor monitor,
156+ File file,
157+ File? other_file,
158+ FileMonitorEvent event_type)
159+ {
160+ if (event_type == FileMonitorEvent.CHANGES_DONE_HINT)
161+ {
162+ message ("remmina config is changed, reparsing");
163+ update_hosts.begin ();
164+ }
165+ }
166+
167+ public bool handles_query (Query query)
168+ {
169+ return hosts.size > 0 &&
170+ ( QueryFlags.ACTIONS in query.query_type ||
171+ QueryFlags.INTERNET in query.query_type);
172+ }
173+
174+ public async ResultSet? search (Query q) throws SearchError
175+ {
176+ Idle.add (search.callback);
177+ yield;
178+ q.check_cancellable ();
179+
180+ var results = new ResultSet ();
181+
182+ var matchers = Query.get_matchers_for_query (q.query_string, 0,
183+ RegexCompileFlags.OPTIMIZE | RegexCompileFlags.CASELESS);
184+
185+ foreach (var host in hosts.values) //workaround for missing HashMap.iterator() method
186+ {
187+ foreach (var matcher in matchers)
188+ {
189+ if (matcher.key.match (host.host_query))
190+ {
191+ results.add (host, matcher.value - MatchScore.INCREMENT_SMALL);
192+ break;
193+ }
194+ }
195+ }
196+
197+ q.check_cancellable ();
198+
199+ return results;
200+ }
201+
202+ private class RemminaHost : ActionMatch
203+ {
204+ public string host_query { get; construct set; }
205+ public string file_path { get; construct set; }
206+
207+ public override void do_action ()
208+ {
209+ Utils.open_command_line ("remmina -c %s".printf (file_path), null);
210+ }
211+
212+ public RemminaHost (string host_name, string file_path)
213+ {
214+ Object (
215+ title: host_name,
216+ description: _("Connect with Remmina"),
217+ has_thumbnail: false,
218+ icon_name: "remmina",
219+ host_query: host_name,
220+ file_path: file_path
221+ );
222+ }
223+ }
224+ }
225+}
226
227=== modified file 'src/ui/synapse-main.vala'
228--- src/ui/synapse-main.vala 2016-04-01 05:58:51 +0000
229+++ src/ui/synapse-main.vala 2018-06-03 13:39:20 +0000
230@@ -177,6 +177,7 @@
231 typeof (PassPlugin),
232 typeof (ChatActions),
233 typeof (ZealPlugin),
234+ typeof (RemminaPlugin),
235 #if HAVE_ZEITGEIST
236 typeof (ZeitgeistPlugin),
237 typeof (ZeitgeistRelated),