Merge lp:~mhr3/dockmanager/metadata-update into lp:dockmanager

Proposed by Michal Hruby
Status: Merged
Merged at revision: 32
Proposed branch: lp:~mhr3/dockmanager/metadata-update
Merge into: lp:dockmanager
Diff against target: 497 lines (+260/-74)
16 files modified
configure.ac (+4/-5)
daemon/dockmanager-daemon.vala (+188/-15)
metadata/banshee_control.py.info (+5/-4)
metadata/deluge_badge.py.info (+5/-4)
metadata/emesene_control.py.info (+5/-4)
metadata/gajim_badge.py.info (+5/-4)
metadata/gtg_menus.py.info (+5/-4)
metadata/liferea_badge.py.info (+5/-4)
metadata/open_terminal_here.py.info (+5/-4)
metadata/pidgin_control.py.info (+5/-4)
metadata/rhythmbox_control.py.info (+5/-4)
metadata/tomboy_menus.py.info (+5/-4)
metadata/transmission_badge.py.info (+5/-4)
metadata/tsclient_menus.py.info (+5/-4)
metadata/zeitgeist_journal.py.info (+4/-3)
metadata/zeitgeist_menus.py.info (+4/-3)
To merge this branch: bzr merge lp:~mhr3/dockmanager/metadata-update
Reviewer Review Type Date Requested Status
Robert Dyer (community) Needs Fixing
Review via email: mp+26745@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Robert Dyer (psybers) wrote :

First of all, your diff includes way more than what you wanted. You should fix that up.

Second, what is the point to the metadata changes? What is the format used? Is it just a true INI file format? Must we verify the section is named 'DEFAULT'? What if it isnt, do we still use it? Will we allow other sections, if so what are those?

review: Needs Fixing
Revision history for this message
Michal Hruby (mhr3) wrote :

It includes changes to the daemon which read this format, so it's related.

It's standard key-file format used everywhere (and parser for it available in glib), section name is required in keyfiles, therefore if it's not there, it's invalid. As for supporting more sections and/or keys it's easily possible when needed.

Revision history for this message
Robert Dyer (psybers) wrote :

Ok but the name of the section, is that a standard? Or are we going to just grab the first section in the file? What if there are more sections?

Revision history for this message
Michal Hruby (mhr3) wrote :

The APIs reading keyfiles usually need both group name and key name, so you shouldn't just grab the first one, anyway maybe we should use something more specific than "DEFAULT" (for example .desktop files use "DesktopEntry"), perhaps "DockmanagerHelper"?

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

The new metadata-file format is fine. "DockmanagerHelper" sounds good.

lp:~mhr3/dockmanager/metadata-update updated
32. By Michal Hruby

Use DockmanagerHelper

Revision history for this message
Michal Hruby (mhr3) wrote :

Branch updated, please merge when Docky is ready to handle it.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'configure.ac'
--- configure.ac 2010-06-02 11:27:12 +0000
+++ configure.ac 2010-06-05 13:05:33 +0000
@@ -13,18 +13,17 @@
1313
14dnl Bzr Revno, if release set BZR_REVNO to the release version number14dnl Bzr Revno, if release set BZR_REVNO to the release version number
15if test -d $top_srcdir/.bzr ; then15if test -d $top_srcdir/.bzr ; then
16 BZR_REVNO=`bzr version-info --custom \16 BZR_REVNO=`bzr revno`
17 --template="{revno}"`
18else17else
19 BZR_REVNO=0.118 BZR_REVNO=0.1
20fi19fi
21AC_SUBST(BZR_REVNO)20AC_SUBST(BZR_REVNO)
2221
23if test -d $top_srcdir/.bzr ; then22if test -e $top_srcdir/.version_info ; then
23 VERSION_INFO=`cat .version_info`
24elif test -d $top_srcdir/.bzr ; then
24 VERSION_INFO=`bzr version-info --custom \25 VERSION_INFO=`bzr version-info --custom \
25 --template="bzr {branch_nick} r{revno}"`26 --template="bzr {branch_nick} r{revno}"`
26elif test -e $top_srcdir/.version_info ; then
27 VERSION_INFO=`cat .version_info`
28else27else
29 VERSION_INFO="Release"28 VERSION_INFO="Release"
30fi29fi
3130
=== modified file 'daemon/dockmanager-daemon.vala'
--- daemon/dockmanager-daemon.vala 2010-06-02 09:39:27 +0000
+++ daemon/dockmanager-daemon.vala 2010-06-05 13:05:33 +0000
@@ -24,12 +24,35 @@
2424
25namespace DockManager25namespace DockManager
26{26{
27 const string GROUP_NAME = "DockmanagerHelper";
28
29 public struct HelperInfo
30 {
31 string path;
32 string? name;
33 string? description;
34 string? icon_name;
35 string? app_name;
36 bool app_available;
37 }
38
39 private struct HelperProcessInfo
40 {
41 int pid;
42 uint timer_id;
43 }
44
27 [DBus (name = "org.dockmanager.Daemon")]45 [DBus (name = "org.dockmanager.Daemon")]
28 public interface DaemonInterface: GLib.Object46 public interface DaemonInterface: GLib.Object
29 {47 {
48 public abstract HelperInfo[] get_all_helpers () throws DBus.Error;
49 public abstract void run_helper (string path) throws DBus.Error;
50 public abstract void stop_helper (string path) throws DBus.Error;
51 public abstract void restart_all () throws DBus.Error;
30 public abstract void show_preferences () throws DBus.Error;52 public abstract void show_preferences () throws DBus.Error;
31 public abstract void embed_preferences (int64 xid) throws DBus.Error;53 public abstract void embed_preferences (int64 xid) throws DBus.Error;
32 public abstract void restart_all () throws DBus.Error;54
55 public signal void helper_stopped (string path);
33 }56 }
3457
35 const string DBUS_UNIQUE_NAME = "org.dockmanager.Daemon";58 const string DBUS_UNIQUE_NAME = "org.dockmanager.Daemon";
@@ -50,11 +73,14 @@
50 }73 }
51 }74 }
5275
53 private HashTable<string, int> helpers;76 private HashTable<string, HelperProcessInfo?> helper_process_info;
77 private List<HelperInfo?> all_scripts;
5478
55 public HelperDaemon ()79 public HelperDaemon ()
56 {80 {
57 helpers = new HashTable<string, int> (str_hash, str_equal);81 helper_process_info =
82 new HashTable<string, HelperProcessInfo?> (str_hash, str_equal);
83 all_scripts = new List<HelperInfo?> ();
58 }84 }
5985
60 public override void constructed ()86 public override void constructed ()
@@ -92,6 +118,7 @@
92 {118 {
93 connection.register_object ("/org/dockmanager/Daemon", this);119 connection.register_object ("/org/dockmanager/Daemon", this);
94120
121 this.init ();
95 this.run_helpers ();122 this.run_helpers ();
96123
97 Gtk.main ();124 Gtk.main ();
@@ -107,47 +134,172 @@
107 }134 }
108 }135 }
109136
137 private void init ()
138 {
139 string[] prefixes =
140 {
141 Build.PKGDATADIR,
142 Environment.get_user_data_dir () + "/dockmanager"
143 };
144
145 foreach (unowned string prefix in prefixes)
146 {
147 string path = prefix + "/scripts";
148 string metadata_dir = prefix + "/metadata/";
149 var scripts_dir = DesktopAgnostic.VFS.file_new_for_path (path);
150 if (!scripts_dir.exists ()) continue;
151
152 foreach (var f in scripts_dir.enumerate_children ())
153 {
154 var hi = HelperInfo ();
155 hi.path = f.path;
156 hi.app_available = true; // probably... we'll set it later
157 all_scripts.append (hi);
158 }
159
160 foreach (unowned HelperInfo? hi in all_scripts)
161 {
162 string metadata = metadata_dir + Path.get_basename (hi.path) + ".info";
163 var metadata_file = DesktopAgnostic.VFS.file_new_for_path (metadata);
164 if (!metadata_file.exists ()) continue;
165
166 string contents;
167 size_t length;
168 metadata_file.load_contents (out contents, out length);
169
170 var keyfile = new KeyFile ();
171 try
172 {
173 keyfile.load_from_data (contents, length, KeyFileFlags.NONE);
174 }
175 catch (KeyFileError err)
176 {
177 warning ("Cannot load %s: %s", metadata, err.message);
178 continue;
179 }
180
181 try
182 {
183 hi.name = keyfile.get_string (GROUP_NAME, "Name");
184 hi.description = keyfile.get_string (GROUP_NAME, "Description");
185 }
186 catch (KeyFileError err)
187 {
188 warning ("Required key missing in %s", metadata);
189 continue;
190 }
191 try
192 {
193 hi.icon_name = keyfile.get_string (GROUP_NAME, "Icon");
194 }
195 catch (KeyFileError err) { }
196 try
197 {
198 int status;
199 hi.app_name = keyfile.get_string (GROUP_NAME, "AppName");
200 Process.spawn_command_line_sync ("which " + hi.app_name, null, null,
201 out status);
202 hi.app_available = status == 0;
203 }
204 catch (GLib.Error err)
205 {
206 warning ("%s", err.message);
207 }
208 }
209 }
210 }
211
110 public void run_helpers ()212 public void run_helpers ()
111 {213 {
112 foreach (Value v in _helper_list)214 foreach (Value v in _helper_list)
113 {215 {
114 unowned string helper = v.get_string ();216 unowned string helper = v.get_string ();
115 int pid = run_helper (helper);217 run_helper (helper);
116 helpers.insert (helper, pid);
117 }218 }
118219
119 helpers.@foreach ((k, v) =>220 helper_process_info.@foreach ((k, v) =>
120 {221 {
121 unowned string key = (string) k;222 unowned string key = (string) k;
122 int val = (int)(long) v;223 unowned HelperProcessInfo? val = (HelperProcessInfo?) v;
123 debug ("%s: %d", key, val);224 debug ("%s: %d", key, val.pid);
124 });225 });
125 }226 }
126227
127 public int run_helper (string uri)228 private int get_helper_pid (string path)
229 {
230 unowned HelperProcessInfo? hpi = helper_process_info.lookup (path);
231 return hpi != null ? hpi.pid : 0;
232 }
233
234 public void run_helper (string path) throws DBus.Error
128 {235 {
129 Pid child_pid = 0;236 Pid child_pid = 0;
130 string[] argv;237 string[] argv;
131238
239 if (get_helper_pid (path) != 0)
240 {
241 debug ("%s is already running", path);
242 return;
243 }
244
132 try245 try
133 {246 {
134 Shell.parse_argv (uri, out argv);247 Shell.parse_argv (path, out argv);
135 var flags = SpawnFlags.DO_NOT_REAP_CHILD | SpawnFlags.SEARCH_PATH;248 var flags = SpawnFlags.DO_NOT_REAP_CHILD | SpawnFlags.SEARCH_PATH;
136 Process.spawn_async (null, argv, null, flags, null, out child_pid);249 Process.spawn_async (null, argv, null, flags, null, out child_pid);
137 ChildWatch.add (child_pid, this.child_died);250 ChildWatch.add_full (Priority.DEFAULT, child_pid, (pid, status) =>
251 {
252 debug ("[%d] \"%s\" exitted", pid, Path.get_basename (path));
253 unowned HelperProcessInfo? hpi = helper_process_info.lookup (path);
254 if (hpi != null)
255 {
256 if (hpi.timer_id != 0)
257 {
258 Source.remove (hpi.timer_id);
259 }
260 hpi.pid = 0;
261 hpi.timer_id = 0;
262 }
263 Process.close_pid (pid);
264 helper_stopped (path);
265 });
138 }266 }
139 catch (GLib.Error err)267 catch (GLib.Error err)
140 {268 {
141 warning ("%s", err.message);269 warning ("%s", err.message);
142 return 0;270 throw new DBus.Error.SPAWN_FAILED (err.message);
143 }271 }
144272
145 return (int)child_pid;273 unowned HelperProcessInfo? hpi = helper_process_info.lookup (path);
274 if (hpi != null)
275 {
276 hpi.pid = (int) child_pid;
277 }
278 else
279 {
280 var pi = HelperProcessInfo ();
281 pi.pid = (int) child_pid;
282 helper_process_info.insert (path, pi);
283 }
146 }284 }
147285
148 private void child_died (Pid pid, int status)286 public void stop_helper (string path) throws DBus.Error
149 {287 {
150 debug ("[%d] died, status: %d", pid, status);288 int pid = get_helper_pid (path);
289 if (pid == 0) return;
290
291 unowned HelperProcessInfo? hpi = helper_process_info.lookup (path);
292 Posix.kill ((Posix.pid_t)pid, Posix.SIGTERM);
293
294 hpi.timer_id = Timeout.add (2000, () =>
295 {
296 if (hpi.pid != 0)
297 {
298 Posix.kill ((Posix.pid_t)hpi.pid, Posix.SIGKILL);
299 }
300 hpi.timer_id = 0;
301 return false;
302 });
151 }303 }
152304
153 public void show_preferences ()305 public void show_preferences ()
@@ -158,6 +310,27 @@
158 {310 {
159 }311 }
160312
313 public HelperInfo[] get_all_helpers ()
314 {
315 int i = 0;
316
317 HelperInfo[] helpers = new HelperInfo [all_scripts.length ()];
318 foreach (unowned HelperInfo hi in all_scripts)
319 {
320 // our custom copy, dbus doesn't like NULLs
321 helpers[i].path = hi.path;
322 helpers[i].name = hi.name != null ? hi.name : "";
323 helpers[i].description = hi.description != null ? hi.description : "";
324 helpers[i].icon_name = hi.icon_name != null ? hi.icon_name : "";
325 helpers[i].app_name = hi.app_name != null ? hi.app_name : "";
326 helpers[i].app_available = hi.app_available;
327
328 i++;
329 }
330
331 return helpers;
332 }
333
161 public void restart_all ()334 public void restart_all ()
162 {335 {
163 }336 }
164337
=== modified file 'metadata/banshee_control.py.info'
--- metadata/banshee_control.py.info 2010-06-02 02:54:39 +0000
+++ metadata/banshee_control.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Banshee Controls"1[DockmanagerHelper]
2DESCRIPTION="Control Banshee media playback"2Name=Banshee Controls
3ICON="banshee"3Description=Control Banshee media playback
4APPURI="/usr/bin/banshee"4Icon=banshee
5AppName=banshee
56
=== modified file 'metadata/deluge_badge.py.info'
--- metadata/deluge_badge.py.info 2010-06-02 02:54:39 +0000
+++ metadata/deluge_badge.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Deluge"1[DockmanagerHelper]
2DESCRIPTION="Show transfer rates"2Name=Deluge
3ICON="deluge"3Description=Show transfer rates
4APPURI="/usr/bin/deluge"4Icon=deluge
5AppName=deluge
56
=== modified file 'metadata/emesene_control.py.info'
--- metadata/emesene_control.py.info 2010-06-02 02:54:39 +0000
+++ metadata/emesene_control.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Emesene Controls"1[DockmanagerHelper]
2DESCRIPTION="See your message count status on Emesene"2Name=Emesene Controls
3ICON="emesene"3Description=See your message count status on Emesene
4APPURI="/usr/bin/emesene"4Icon=emesene
5AppName=emesene
56
=== modified file 'metadata/gajim_badge.py.info'
--- metadata/gajim_badge.py.info 2010-06-02 02:54:39 +0000
+++ metadata/gajim_badge.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Gajim"1[DockmanagerHelper]
2DESCRIPTION="Shows new messages count"2Name=Gajim
3ICON="gajim"3Description=Shows new messages count
4APPURI="/usr/bin/gajim"4Icon=gajim
5AppName=gajim
56
=== modified file 'metadata/gtg_menus.py.info'
--- metadata/gtg_menus.py.info 2010-06-02 02:54:39 +0000
+++ metadata/gtg_menus.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Getting Things GNOME!"1[DockmanagerHelper]
2DESCRIPTION="Access your tasks"2Name=Getting Things GNOME!
3ICON="gtg"3Description=Access your tasks
4APPURI="/usr/bin/gtg"4Icon=gtg
5AppName=gtg
56
=== modified file 'metadata/liferea_badge.py.info'
--- metadata/liferea_badge.py.info 2010-06-02 02:54:39 +0000
+++ metadata/liferea_badge.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Liferea"1[DockmanagerHelper]
2DESCRIPTION="Shows unread messages count"2Name=Liferea
3ICON="liferea"3Description=Shows unread messages count
4APPURI="/usr/bin/liferea"4Icon=liferea
5AppName=liferea
56
=== modified file 'metadata/open_terminal_here.py.info'
--- metadata/open_terminal_here.py.info 2010-06-02 02:54:39 +0000
+++ metadata/open_terminal_here.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Open Terminal Here"1[DockmanagerHelper]
2DESCRIPTION="Opens a terminal at the selected location"2Name=Open Terminal Here
3ICON="gnome-terminal"3Description=Opens a terminal at the selected location
4APPURI="/usr/bin/gnome-terminal"4Icon=gnome-terminal
5AppName=gnome-terminal
56
=== modified file 'metadata/pidgin_control.py.info'
--- metadata/pidgin_control.py.info 2010-06-02 02:54:39 +0000
+++ metadata/pidgin_control.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Pidgin Controls"1[DockmanagerHelper]
2DESCRIPTION="Control your availability and connectivity status on Pidgin"2Name=Pidgin Controls
3ICON="pidgin"3Description=Control your availability and connectivity status on Pidgin
4APPURI="/usr/bin/pidgin"4Icon=pidgin
5AppName=pidgin
56
=== modified file 'metadata/rhythmbox_control.py.info'
--- metadata/rhythmbox_control.py.info 2010-06-02 02:54:39 +0000
+++ metadata/rhythmbox_control.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Rhythmbox Controls"1[DockmanagerHelper]
2DESCRIPTION="Control Rhythmbox media playback"2Name=Rhythmbox Controls
3ICON="rhythmbox"3Description=Control Rhythmbox media playback
4APPURI="/usr/bin/rhythmbox"4Icon=rhythmbox
5AppName=rhythmbox
56
=== modified file 'metadata/tomboy_menus.py.info'
--- metadata/tomboy_menus.py.info 2010-06-02 02:54:39 +0000
+++ metadata/tomboy_menus.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Tomboy Notes"1[DockmanagerHelper]
2DESCRIPTION="Access your Tomboy notes"2Name=Tomboy Notes
3ICON="tomboy"3Description=Access your Tomboy notes
4APPURI="/usr/bin/tomboy"4Icon=tomboy
5AppName=tomboy
56
=== modified file 'metadata/transmission_badge.py.info'
--- metadata/transmission_badge.py.info 2010-06-02 02:54:39 +0000
+++ metadata/transmission_badge.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Transmission"1[DockmanagerHelper]
2DESCRIPTION="Show transfer rates"2Name=Transmission
3ICON="transmission"3Description=Show transfer rates
4APPURI="/usr/bin/transmission"4Icon=transmission
5AppName=transmission
56
=== modified file 'metadata/tsclient_menus.py.info'
--- metadata/tsclient_menus.py.info 2010-06-02 02:54:39 +0000
+++ metadata/tsclient_menus.py.info 2010-06-05 13:05:33 +0000
@@ -1,4 +1,5 @@
1NAME="Terminal Server Client"1[DockmanagerHelper]
2DESCRIPTION="Jump directly to Terminal Server Client bookmarks"2Name=Terminal Server Client
3ICON="tsclient"3Description=Jump directly to Terminal Server Client bookmarks
4APPURI="/usr/bin/tsclient"4Icon=tsclient
5AppName=tsclient
56
=== modified file 'metadata/zeitgeist_journal.py.info'
--- metadata/zeitgeist_journal.py.info 2010-06-02 10:08:48 +0000
+++ metadata/zeitgeist_journal.py.info 2010-06-05 13:05:33 +0000
@@ -1,3 +1,4 @@
1NAME="Zeitgeist Journal"1[DockmanagerHelper]
2DESCRIPTION="Provides a journal of all activity for the selected application supplied by Zeitgeist"2Name=Zeitgeist Journal
3APPURI="/usr/bin/zeitgeist-daemon"3Description=Provides a journal of all activity for the selected application supplied by Zeitgeist
4AppName=zeitgeist-daemon
45
=== modified file 'metadata/zeitgeist_menus.py.info'
--- metadata/zeitgeist_menus.py.info 2010-06-02 10:08:48 +0000
+++ metadata/zeitgeist_menus.py.info 2010-06-05 13:05:33 +0000
@@ -1,3 +1,4 @@
1NAME="Zeitgeist Integration"1[DockmanagerHelper]
2DESCRIPTION="Interfaces with Zeitgeist to supply a list of most used items for an application"2Name=Zeitgeist Integration
3APPURI="/usr/bin/zeitgeist-daemon"3Description=Interfaces with Zeitgeist to supply a list of most used items for an application
4AppName=zeitgeist-daemon

Subscribers

People subscribed via source and target branches

to status/vote changes: