~karlo-jez/gtg/gtgonline

« back to all changes in this revision

Viewing changes to dbusserver/dbuswrapper.py

  • Committer: Karlo Jež
  • Date: 2010-05-25 18:20:23 UTC
  • Revision ID: keks@keks-laptop-20100525182023-4iiio5ji2z9are00
Task treeview enhancements

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import dbus
 
2
import dbus.glib
 
3
import dbus.service
 
4
import unicodedata
 
5
 
 
6
from GTG.core import CoreConfig
 
7
 
 
8
BUSNAME = CoreConfig.BUSNAME
 
9
BUSFACE = CoreConfig.BUSINTERFACE
 
10
 
 
11
 
 
12
def dsanitize(data):
 
13
    """
 
14
    Clean up a dict so that it can be transmitted through D-Bus.
 
15
    D-Bus does not have concepts for empty or null arrays or values 
 
16
    so these need to be converted into blank values D-Bus accepts.
 
17
    @return: Cleaned up dictionary
 
18
    """
 
19
    for k, v in data.items():
 
20
        # Manually specify an arbitrary content type for empty Python arrays
 
21
        # because D-Bus can't handle the type conversion for empty arrays
 
22
        if not v and isinstance(v, list):
 
23
            data[k] = dbus.Array([], "s")
 
24
        # D-Bus has no concept of a null or empty value so we have to convert
 
25
        # None types to something else. I use an empty string because it has
 
26
        # the same behavior as None in a Python conditional expression
 
27
        elif v == None:
 
28
            data[k] = ""
 
29
 
 
30
    return data
 
31
 
 
32
task111 = dbus.Dictionary(dsanitize({
 
33
          "id": "111",
 
34
          "status": "Active",
 
35
          "title": "Make a fake GTG dbus server",
 
36
          "duedate": "2010-10-10",
 
37
          "startdate": "2010-01-01",
 
38
          "donedate": "",
 
39
          "tags": ["@gtg", "@gsoc"],
 
40
          "text": "You really should make it",
 
41
          "subtask": ["112","113"],
 
42
          "parents": [],
 
43
          }), signature="sv")
 
44
 
 
45
task112 = dbus.Dictionary(dsanitize({
 
46
          "id": "112",
 
47
          "status": "Active",
 
48
          "title": "Rest a bit before doing the server",
 
49
          "duedate": "2010-10-10",
 
50
          "startdate": "2010-01-01",
 
51
          "donedate": "",
 
52
          "tags": ["@gtg", "@gsoc", "@freetime"],
 
53
          "text": "Take as much time as you need",
 
54
          "subtask": [],
 
55
          "parents": ["111"],
 
56
          }), signature="sv")
 
57
          
 
58
task113 = dbus.Dictionary(dsanitize({
 
59
          "id": "113",
 
60
          "status": "Active",
 
61
          "title": "Find out what a 'server' is",
 
62
          "duedate": "2010-10-10",
 
63
          "startdate": "2010-01-01",
 
64
          "donedate": "",
 
65
          "tags": ["@gtg", "@gsoc", "@research"],
 
66
          "text": "Check out wikipedia",
 
67
          "subtask": [],
 
68
          "parents": ["111"],
 
69
          }), signature="sv")
 
70
 
 
71
def task_to_dict(tid):
 
72
    if tid == "111":
 
73
        return task111
 
74
    elif tid == "112":
 
75
        return task112
 
76
    elif tid == "113":
 
77
        return task113
 
78
 
 
79
 
 
80
class DBusTaskWrapper(dbus.service.Object):
 
81
    """
 
82
    D-Bus service object that exposes GTG's task store to third-party apps
 
83
    """
 
84
 
 
85
    def __init__(self):
 
86
        # Attach the object to D-Bus
 
87
        self.bus = dbus.SessionBus()
 
88
        bus_name = dbus.service.BusName(BUSNAME, bus=self.bus)
 
89
        dbus.service.Object.__init__(self, bus_name, BUSFACE)
 
90
 
 
91
    @dbus.service.method(BUSNAME)
 
92
    def get_task(self, tid):
 
93
        """
 
94
        Retrieve a specific task by ID and return the data
 
95
        """
 
96
        toret = task_to_dict(tid)
 
97
        return toret
 
98
 
 
99
    @dbus.service.method(BUSNAME)
 
100
    def get_tasks(self):
 
101
        """
 
102
        Retrieve a list of task data dicts
 
103
        """
 
104
        return self.get_tasks_filtered(['all'])
 
105
 
 
106
    @dbus.service.method(BUSNAME, in_signature="as")
 
107
    def get_active_tasks(self, tags):
 
108
        """
 
109
        Retrieve a list of task data dicts
 
110
        """
 
111
        return self.get_tasks_filtered(['active', 'workable'])
 
112
 
 
113
    @dbus.service.method(BUSNAME, in_signature="as")
 
114
    def get_task_ids_filtered(self, filters):
 
115
        """
 
116
        Filters the task list and provides list of remaining ids
 
117
        @param:  List of strings for filters to apply.  See the
 
118
         filters_bank documentation for a list of stock filters.
 
119
        @return: List of ids
 
120
        """
 
121
        return ["111","112","113"]
 
122
 
 
123
    @dbus.service.method(BUSNAME, in_signature="as")
 
124
    def get_tasks_filtered(self, filters):
 
125
        """
 
126
        Gets a list of tasks for the given filters
 
127
        @param:  List of strings for filters to apply.  See the
 
128
         filters_bank documentation for a list of stock filters.
 
129
        @return: List of task dicts
 
130
        """
 
131
        tasks = self.get_task_ids_filtered(filters)
 
132
        if tasks:
 
133
            return [self.get_task(id) for id in tasks]
 
134
        else:
 
135
            return dbus.Array([], "s")
 
136
 
 
137
    @dbus.service.method(BUSNAME)
 
138
    def has_task(self, tid):
 
139
        """
 
140
        Returns true if the task id is present in the task backend.
 
141
        Task could be either open or closed, but not deleted.
 
142
        """
 
143
        return self.req.has_task(tid)
 
144
 
 
145
    @dbus.service.method(BUSNAME)
 
146
    def delete_task(self, tid):
 
147
        """
 
148
        Delete the given task id from the repository.
 
149
        """
 
150
        self.req.delete_task(tid)
 
151
 
 
152
    @dbus.service.method(BUSNAME, in_signature="sssssassas")
 
153
    def new_task(self, status, title, duedate, startdate, donedate, tags,
 
154
                 text, subtasks):
 
155
        """
 
156
        Generate a new task object and return the task data as a dict
 
157
        @param status:     One of 'Active', 'Dismiss', or 'Done'
 
158
        @param title:      String name of the task
 
159
        @param duedate:    Date the task is due, such as "2010-05-01".
 
160
         also supports 'now', 'soon', 'later'
 
161
        @param startdate:  Date the task will be started
 
162
        @param donedate:   Date the task was finished
 
163
        @param tags:       List of strings for tags to apply for this task
 
164
        @param text:       String description
 
165
        @param subtasks:   A list of task ids of tasks to add as children
 
166
        @return: A dictionary with the data of the newly created task
 
167
        """
 
168
        nt = self.req.new_task(tags=tags)
 
169
        for sub in subtasks:
 
170
            nt.add_child(sub)
 
171
        nt.set_status(status, donedate=dates.strtodate(donedate))
 
172
        nt.set_title(title)
 
173
        nt.set_due_date(dates.strtodate(duedate))
 
174
        nt.set_start_date(dates.strtodate(startdate))
 
175
        nt.set_text(text)
 
176
        return task_to_dict(nt)
 
177
 
 
178
    @dbus.service.method(BUSNAME)
 
179
    def modify_task(self, tid, task_data):
 
180
        """
 
181
        Updates the task with ID tid using the provided information
 
182
        in the task_data structure.  Note that any fields left blank
 
183
        or undefined in task_data will clear the value in the task,
 
184
        so the best way to update a task is to first retrieve it via
 
185
        get_task(tid), modify entries as desired, and send it back
 
186
        via this function.        
 
187
        """
 
188
        task = self.req.get_task(tid)
 
189
        task.set_status(task_data["status"], donedate=dates.strtodate(task_data["donedate"]))
 
190
        task.set_title(task_data["title"])
 
191
        task.set_due_date(dates.strtodate(task_data["duedate"]))
 
192
        task.set_start_date(dates.strtodate(task_data["startdate"]))
 
193
        task.set_text(task_data["text"])
 
194
 
 
195
        for tag in task_data["tags"]:
 
196
            task.add_tag(tag)
 
197
        for sub in task_data["subtask"]:
 
198
            task.add_child(sub)
 
199
        return task_to_dict(task)
 
200
 
 
201
    @dbus.service.method(BUSNAME)
 
202
    def open_task_editor(self, tid):
 
203
        """
 
204
        Launches the GUI task editor showing the task with ID tid.
 
205
 
 
206
        This routine returns as soon as the GUI has launched.
 
207
        """
 
208
        self.view_manager.open_task(tid)
 
209
        
 
210
    @dbus.service.method(BUSNAME, in_signature="ss")
 
211
    def open_new_task(self, title, description):
 
212
        """
 
213
        Launches the GUI task editor with a new task.  The task is not
 
214
        guaranteed to exist after the editor is closed, since the user
 
215
        could cancel the editing session.
 
216
 
 
217
        This routine returns as soon as the GUI has launched.
 
218
        """
 
219
        nt = self.req.new_task(newtask=True)
 
220
        nt.set_title(title)
 
221
        if description != "":
 
222
            nt.set_text(description)
 
223
        uid = nt.get_id()
 
224
        self.view_manager.open_task(uid,thisisnew=True)
 
225
 
 
226
    @dbus.service.method(BUSNAME)
 
227
    def hide_task_browser(self):
 
228
        """
 
229
        Causes the main task browser to become invisible.  It is still
 
230
        running but there will be no visible indication of this.
 
231
        """
 
232
        self.view_manager.hide_browser()
 
233
 
 
234
    @dbus.service.method(BUSNAME)
 
235
    def iconify_task_browser(self):
 
236
        """
 
237
        Minimizes the task browser
 
238
        """
 
239
        self.view_manager.iconify_browser()
 
240
 
 
241
    @dbus.service.method(BUSNAME)
 
242
    def show_task_browser(self):
 
243
        """
 
244
        Shows and unminimizes the task browser and brings it to the
 
245
        top of the z-order.
 
246
        """
 
247
        self.view_manager.show_browser()
 
248
 
 
249
    @dbus.service.method(BUSNAME)
 
250
    def is_task_browser_visible(self):
 
251
        """
 
252
        Returns true if task browser is visible, either minimized or
 
253
        unminimized, with or without active focus.
 
254
        """
 
255
        return self.view_manager.is_browser_visible()