GTG

Merge lp:~segphault/gtg/dbus into lp:~gtg/gtg/old-trunk

Proposed by Ryan Paul
Status: Merged
Merged at revision: not available
Proposed branch: lp:~segphault/gtg/dbus
Merge into: lp:~gtg/gtg/old-trunk
Diff against target: None lines
To merge this branch: bzr merge lp:~segphault/gtg/dbus
Reviewer Review Type Date Requested Status
Gtg developers Pending
Review via email: mp+8489@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'GTG/core/dbuswrapper.py'
2--- GTG/core/dbuswrapper.py 1970-01-01 00:00:00 +0000
3+++ GTG/core/dbuswrapper.py 2009-07-09 20:03:12 +0000
4@@ -0,0 +1,120 @@
5+import gobject, dbus.glib, dbus, dbus.service
6+
7+BUSNAME = "org.GTG"
8+
9+def dsanitize(data):
10+ # Clean up a dict so that it can be transmitted through D-Bus
11+ for k, v in data.items():
12+ # Manually specify an arbitrary content type for empty Python arrays
13+ # because D-Bus can't handle the type conversion for empty arrays
14+ if not v and isinstance(v, list):
15+ data[k] = dbus.Array([], "s")
16+ # D-Bus has no concept of a null or empty value so we have to convert None
17+ # types to something else. I use an empty string because it has the same
18+ # behavior as None in a Python conditional expression
19+ elif v == None:
20+ data[k] = ""
21+
22+ return data
23+
24+def task_to_dict(task):
25+ # Translate a task object into a D-Bus dictionary
26+ return dbus.Dictionary(dsanitize({
27+ "id": task.get_id(),
28+ "status": task.get_status(),
29+ "title": task.get_title(),
30+ "duedate": task.get_due_date(),
31+ "startdate": task.get_start_date(),
32+ "donedate": task.get_closed_date(),
33+ "tags": task.get_tags_name(),
34+ "text": task.get_text(),
35+ "subtask": task.get_subtasks_tid(),
36+ }), signature="sv")
37+
38+class DBusTaskWrapper(dbus.service.Object):
39+ # D-Bus service object that exposes GTG's task store to third-party apps
40+ def __init__(self, req, ui):
41+ # Attach the object to D-Bus
42+ self.bus = dbus.SessionBus()
43+ bus_name = dbus.service.BusName(BUSNAME, bus=self.bus)
44+ dbus.service.Object.__init__(self, bus_name, "/org/GTG")
45+ self.req = req
46+ self.ui = ui
47+
48+ @dbus.service.method(BUSNAME)
49+ def get_task_ids(self):
50+ # Retrieve a list of task ID values
51+ return self.req.get_tasks_list(status=["Active", "Done"], started_only=False)
52+
53+ @dbus.service.method(BUSNAME)
54+ def get_task(self, tid):
55+ # Retrieve a specific task by ID and return the data
56+ return task_to_dict(self.req.get_task(tid))
57+
58+ @dbus.service.method(BUSNAME)
59+ def get_tasks(self):
60+ # Retrieve a list of task data dicts
61+ return [self.get_task(id) for id in self.get_task_ids()]
62+
63+ @dbus.service.method(BUSNAME, in_signature="asasbb")
64+ def get_task_ids_filtered(self, tags, status, started_only, is_root):
65+ # Retrieve a list of task IDs filtered by specified parameters
66+ ids = self.req.get_tasks_list(tags, status, False, started_only, is_root)
67+ # If there are no matching tasks, return an empty D-Bus array
68+ return ids if ids else dbus.Array([], "s")
69+
70+ @dbus.service.method(BUSNAME, in_signature="asasbb")
71+ def get_tasks_filtered(self, tags, status, started_only, is_root):
72+ # Retrieve a list of task data discts filtered by specificed parameters
73+ tasks = self.get_task_ids_filtered(tags, status, started_only, is_root)
74+ # If no tasks match the filter, return an empty D-Bus array
75+ return [self.get_task(id) for id in tasks] if tasks else dbus.Array([], "s")
76+
77+ @dbus.service.method(BUSNAME)
78+ def has_task(self, tid):
79+ return self.req.has_task(tid)
80+
81+ @dbus.service.method(BUSNAME)
82+ def delete_task(self, tid):
83+ self.req.delete_task(tid)
84+
85+ @dbus.service.method(BUSNAME, in_signature="sssssassas")
86+ def new_task(self, status, title, duedate, startdate, donedate, tags, text, subtasks):
87+ # Generate a new task object and return the task data as a dict
88+ nt = self.req.new_task()
89+ for sub in subtasks: nt.add_subtask(sub)
90+ for tag in tags: nt.add_tag(tag)
91+ nt.set_status(status, donedate=donedate)
92+ nt.set_title(title)
93+ nt.set_due_date(duedate)
94+ nt.set_start_date(startdate)
95+ nt.set_text(text)
96+ return task_to_dict(nt)
97+
98+ @dbus.service.method(BUSNAME)
99+ def modify_task(self, tid, task_data):
100+ # Apply supplied task data to the task object with the specified ID
101+ task = self.req.get_task(tid)
102+ task.set_status(task_data["status"], donedate=task_data["donedate"])
103+ task.set_title(task_data["title"])
104+ task.set_due_date(task_data["duedate"])
105+ task.set_start_date(task_data["startdate"])
106+ task.set_text(task_data["text"])
107+
108+ for tag in task_data["tags"]: task.add_tag(tag)
109+ for sub in task_data["subtask"]: task.add_subtask(sub)
110+ return task_to_dict(task)
111+
112+ @dbus.service.method(BUSNAME)
113+ def open_task_editor(self, tid):
114+ self.ui.open_task(tid)
115+
116+ @dbus.service.method(BUSNAME)
117+ def hide_task_browser(self):
118+ self.ui.window.hide()
119+
120+ @dbus.service.method(BUSNAME)
121+ def show_task_browser(self):
122+ self.ui.window.present()
123+ self.ui.window.move(self.ui.priv["window_xpos"], self.ui.priv["window_ypos"])
124+
125
126=== modified file 'GTG/gtg.py'
127--- GTG/gtg.py 2009-06-18 08:56:33 +0000
128+++ GTG/gtg.py 2009-07-09 08:31:53 +0000
129@@ -48,6 +48,7 @@
130 #our own imports
131 from GTG.taskbrowser.browser import TaskBrowser
132 from GTG.core.datastore import DataStore
133+from GTG.core.dbuswrapper import DBusTaskWrapper
134 from GTG.core import CoreConfig
135
136 #=== OBJECTS ===================================================================
137@@ -100,6 +101,7 @@
138 # Launch task browser
139 req = ds.get_requester()
140 tb = TaskBrowser(req, config.conf_dict)
141+ DBusTaskWrapper(req, tb)
142 tb.main()
143
144 # Ideally we should load window geometry configuration from a config.

Subscribers

People subscribed via source and target branches

to status/vote changes: