Merge lp:~manishsinha/cheers/insertion into lp:~cheers/cheers/trunk

Status: Merged
Merged at revision: 17
Proposed branch: lp:~manishsinha/cheers/insertion
Merge into: lp:~cheers/cheers/trunk
Diff against target: 464 lines (+222/-51)
10 files modified
LICENSE (+21/-0)
MAINTAINERS (+1/-0)
README (+38/-0)
aa.trophy (+1/-0)
cheers-daemon (+29/-0)
cheers-daemon.py (+0/-27)
cheers/client.py (+14/-15)
cheers/config.py (+11/-0)
cheers/datastore.py (+96/-4)
cheers/server.py (+11/-5)
To merge this branch: bzr merge lp:~manishsinha/cheers/insertion
Reviewer Review Type Date Requested Status
Cheers Pending
Review via email: mp+39438@code.launchpad.net

Description of the change

Implemented the insertion of trophies and fixed the client python bindings

To post a comment you must log in.
lp:~manishsinha/cheers/insertion updated
17. By Manish Sinha (मनीष सिन्हा)

Updated README, LICENSE, MAINTAINERS and fixed the name of the daemon file

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'LICENSE'
2--- LICENSE 2010-10-03 18:20:14 +0000
3+++ LICENSE 2010-10-27 12:43:44 +0000
4@@ -0,0 +1,21 @@
5+# The MIT/X11/Expat License
6+
7+# Copyright (c) 2010 Manish Sinha<mail@manishsinha.net>
8+
9+# Permission is hereby granted, free of charge, to any person obtaining a copy
10+# of this software and associated documentation files (the "Software"), to deal
11+# in the Software without restriction, including without limitation the rights
12+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+# copies of the Software, and to permit persons to whom the Software is
14+# furnished to do so, subject to the following conditions:
15+
16+# The above copyright notice and this permission notice shall be included in
17+# all copies or substantial portions of the Software.
18+
19+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+# THE SOFTWARE.
26
27=== modified file 'MAINTAINERS'
28--- MAINTAINERS 2010-10-03 18:20:14 +0000
29+++ MAINTAINERS 2010-10-27 12:43:44 +0000
30@@ -0,0 +1,1 @@
31+Manish Sinha <mail@manishsinha.net>
32
33=== modified file 'README'
34--- README 2010-10-03 18:20:14 +0000
35+++ README 2010-10-27 12:43:44 +0000
36@@ -0,0 +1,38 @@
37+Cheers is a trophya warding framework. It runs as a daemon activating a DBus Session bus over which applications can talk to it.
38+
39+It is written using python, sqlite, dbus
40+
41+Prerequisties
42+---------------
43+To get cheers up and running, you need the following packages. Please check your distribution for the exact name of the packages
44+* python
45+* python-dbus
46+* python-sqlite
47+* python-gio
48+* python-glib
49+* python-gtk
50+
51+
52+
53+Running
54+---------
55+Execute cheers-daemon using the command
56+
57+./cheers-daemon.py
58+
59+
60+Registering a trophy
61+---------------------
62+
63+Cheers keeps a watch on three folders for new trophies when the server is running. These two folders are
64+* /usr/share/cheers/trophies
65+* /usr/local/share/cheers/trophies
66+* ~/.local/share/cheers/trophies
67+
68+A sample trophy aa.trophy is provided. Put it under the folder ~/.local/share/cheers/trophies to register the trophy
69+
70+
71+Debugging
72+------------
73+
74+Use D-feet DBus debugger to have a look at the DBus API
75
76=== added file 'aa.trophy'
77--- aa.trophy 1970-01-01 00:00:00 +0000
78+++ aa.trophy 2010-10-27 12:43:44 +0000
79@@ -0,0 +1,1 @@
80+{"id":"Name","setname":"Music", "seticon": "", "app":"application://banshee.desktop", "appname":"Banshee Music Player", "title":"FM Junkie", "iconpath":"", "priority": 1, "unlocked": "False", "stockicon":"", "desc": {"1": {"lang":"en-us", "desc": "Listen to Music alot"}, "2": {"lang":"en-uk", "desc": "Listen to Music a lot, a lot"}}}
81
82=== added file 'cheers-daemon'
83--- cheers-daemon 1970-01-01 00:00:00 +0000
84+++ cheers-daemon 2010-10-27 12:43:44 +0000
85@@ -0,0 +1,29 @@
86+#! /usr/bin/env python
87+
88+# The MIT/X11/Expat License
89+# Copyright (c) 2010 Manish Sinha<mail@manishsinha.net>
90+
91+# Permission is hereby granted, free of charge, to any person obtaining a copy
92+# of this software and associated documentation files (the "Software"), to deal
93+# in the Software without restriction, including without limitation the rights
94+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
95+# copies of the Software, and to permit persons to whom the Software is
96+# furnished to do so, subject to the following conditions:
97+
98+# The above copyright notice and this permission notice shall be included in
99+# all copies or substantial portions of the Software.
100+
101+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
102+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
103+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
104+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
105+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
106+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
107+# THE SOFTWARE.
108+
109+
110+from cheers import server
111+
112+if __name__ == "__main__":
113+
114+ server.TrophyServer()
115
116=== removed file 'cheers-daemon.py'
117--- cheers-daemon.py 2010-10-17 20:31:25 +0000
118+++ cheers-daemon.py 1970-01-01 00:00:00 +0000
119@@ -1,27 +0,0 @@
120-# The MIT/X11/Expat License
121-# Copyright (c) 2010 Manish Sinha<mail@manishsinha.net>
122-
123-# Permission is hereby granted, free of charge, to any person obtaining a copy
124-# of this software and associated documentation files (the "Software"), to deal
125-# in the Software without restriction, including without limitation the rights
126-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
127-# copies of the Software, and to permit persons to whom the Software is
128-# furnished to do so, subject to the following conditions:
129-
130-# The above copyright notice and this permission notice shall be included in
131-# all copies or substantial portions of the Software.
132-
133-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
134-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
135-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
136-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
137-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
138-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
139-# THE SOFTWARE.
140-
141-
142-from cheers import server
143-
144-
145-if __name__ == "__main__":
146- cheers_server = server.TrophyServer()
147
148=== modified file 'cheers/client.py'
149--- cheers/client.py 2010-10-03 19:24:44 +0000
150+++ cheers/client.py 2010-10-27 12:43:44 +0000
151@@ -30,7 +30,7 @@
152
153 def __init__(self):
154 bus = dbus.SessionBus()
155- self.__interface = bus.get_object(OMG_BUS_NAME, OMG_OBJECT_PATH)
156+ self.__interface = bus.get_object(CHEERS_BUS_NAME, CHEERS_OBJECT_PATH)
157
158 def AwardTrophy(self, id, setname):
159 """ Awards the trophy specified by it's id and the setName.
160@@ -39,23 +39,19 @@
161 If the trophy has been registered, then it is awarded a small notify-osd(libnotify) notification is shown.
162 If the trophy is not registered or has already been awarded, then nothing happens. Call GetTrophy(id,set) to check whether it trophy exists or has already been awarded.
163 """
164- self.__interface.AwardTrophy(id, setname)
165+ self.__interface.AwardTrophy(id)
166
167 def DeleteTrophy(self, id, setname):
168 """ Deletes the trophy permanently from the trophy store.
169
170 This is reverse of registering a trophy. This action is irreversible. Use with caution """
171
172- res = self.__interface.DeleteTrophy(id, setname)
173-
174- return Response(res[0], res[1], res[2])
175-
176- def UnAwardTrophy(self, id, setname):
177+ self.__interface.DeleteTrophy(id)
178+
179+ def UnAwardTrophy(self, id):
180 """ Do the reverse of awarding the trophy. Useful for debugging purposes """
181
182- res = self.__interface.UnAwardTrophy(id, setname)
183-
184- return Response(res[0], res[1], res[2])
185+ self.__interface.UnAwardTrophy(id)
186
187
188 def GetTrophies(self):
189@@ -64,10 +60,10 @@
190 trophy_list = self.__interface.GetTrophies()
191 return [self.__UnwrapTrophy(trp) for trp in trophy_list]
192
193- def GetTrophy(self, id, setname):
194+ def GetTrophy(self, id):
195 """ Get a trophy given it's id and setname """
196
197- trophy = self.__interface.GetTrophy(str(id), str(setname))
198+ trophy = self.__interface.GetTrophy(str(id))
199 return self.__UnwrapTrophy(trophy)
200
201 def GetTrophyBySet(self, setname):
202@@ -82,7 +78,7 @@
203 trophy_list = self.__interface.GetTrophyByApp(str(appname))
204 return [self.__UnwrapTrophy(trp) for trp in trophy_list]
205
206- def GetTrophyById(self, id):
207+ def GetTrophy(self, id):
208 """ Get the trophie registered by it's ID"""
209
210 trophy_list = self.__interface.GetTrophyById(str(id))
211@@ -97,12 +93,15 @@
212
213 def Quit(self):
214 """ Exits the OMG Daemon """
215-
216- self.__interface.Quit()
217+ try:
218+ self.__interface.Quit()
219+ except dbus.DBusException:
220+ pass
221
222 def __UnwrapTrophy(self, trophy):
223 """ Unwraps the trophy instances as per the positions """
224
225+ print(trophy)
226 return Trophy(trophy[0], trophy [1], trophy [2], trophy [4], \
227 trophy[5], trophy[6], trophy[7], trophy[3], \
228 trophy[8], trophy[9], trophy[10], trophy[11])
229
230=== modified file 'cheers/config.py'
231--- cheers/config.py 2010-10-12 19:29:39 +0000
232+++ cheers/config.py 2010-10-27 12:43:44 +0000
233@@ -31,6 +31,7 @@
234
235 trophy_dump_path = os.path.join(cheers_data_path, "trophies")
236 global_trophy_path = "/usr/share/cheers/trophies"
237+global_trophy_path_local = "/usr/local/share/cheers/trophies"
238
239 DATA_STORE_TYPE = "sqlite"
240
241@@ -47,10 +48,20 @@
242 create_desc_command = "CREATE TABLE description (id TEXT, language TEXT, desc TEXT)"
243 create_app_command = "CREATE TABLE app(appid INTEGER, app TEXT, appname TEXT)"
244 create_set_command = "CREATE TABLE appset(setid INTEGER, setname TEXT, seticon TEXT)"
245+create_history_command = "CREATE TABLE history(id TEXT, timestamp INTEGER)"
246+
247+insert_history_command = "INSERT INTO history VALUES(?,?)"
248+insert_trophy_command = "INSERT INTO trophy VALUES(?,?,?,?,?,?,?,?,?)"
249+insert_desc_command = "INSERT INTO description VALUES(?,?,?)"
250+insert_app_command = "INSERT INTO app VALUES(?,?,?)"
251+insert_set_command = "INSERT INTO appset VALUES(?,?,?)"
252
253 fetch_trophy_where = "SELECT trophy.id, trophy.title, trophy.iconpath, app.app, app.appname, appset.setname, appset.seticon, trophy.priority, trophy.unlocked, trophy.timestamp, trophy.stockicon FROM trophy, app,appset WHERE trophy.app=app.appid and trophy.appset=appset.setid and %s=:value"
254 fetch_trophy_all = "select trophy.id, trophy.title, trophy.iconpath, app.app, app.appname, appset.setname, appset.seticon, trophy.priority, trophy.unlocked, trophy.timestamp, trophy.stockicon FROM trophy, app,appset WHERE trophy.app=app.appid and trophy.appset=appset.setid"
255 fetch_description = "SELECT language, desc FROM description WHERE id=:Id"
256+fetch_history = "SELECT * FROM history WHERE id=?"
257+fetch_set_byname = "SELECT * FROM appset WHERE setname=?"
258+fetch_app_byapp = "SELECT * FROM app where app=?"
259
260 award_trophy_command = "UPDATE trophy SET unlocked=1 WHERE id=?"
261 unaward_trophy_command = "UPDATE trophy SET unlocked=0 WHERE id=?"
262
263=== modified file 'cheers/datastore.py'
264--- cheers/datastore.py 2010-10-12 19:29:39 +0000
265+++ cheers/datastore.py 2010-10-27 12:43:44 +0000
266@@ -22,6 +22,8 @@
267 import os
268 import sqlite3
269 import config
270+import random
271+import datetime
272
273 class SqliteStore():
274 """ Implement the data storage based using sqlite as backend
275@@ -46,27 +48,116 @@
276 # Try creating the tables
277 try:
278 self.__cur.execute(config.create_trophy_command)
279+ except sqlite3.OperationalError:
280+ print("Trophy Table existed")
281+
282+ try:
283 self.__cur.execute(config.create_desc_command)
284+ except sqlite3.OperationalError:
285+ print("Description Table existed")
286+
287+ try:
288 self.__cur.execute(config.create_app_command)
289+ except sqlite3.OperationalError:
290+ print("App Table existed")
291+
292+ try:
293 self.__cur.execute(config.create_set_command)
294- print("All tables create successfully")
295- except sqlite3.OperationalError:
296- print("Table existed")
297+ except sqlite3.OperationalError:
298+ print("Set Table existed")
299+
300+ try:
301+ self.__cur.execute(config.create_history_command)
302+ except sqlite3.OperationalError:
303+ print("History Table existed")
304+
305
306 self.__res_cursor=None
307
308+ def AddTrophy(self, json_data):
309+ """ Add the trophy to the database from the JSON data passed """
310+
311+ res_history = self.__cur.execute(config.fetch_history, (json_data["id"],))
312+ fetch_trp = config.fetch_trophy_where %("id",)
313+ res_trophy = self.__cur.execute(fetch_trp, { "value":json_data["id"] })
314+ if(len(res_history.fetchall()) == 0 and len(res_trophy.fetchall()) == 0):
315+
316+ # Searching and Inserting Sets
317+ set_list = self.__cur.execute(config.fetch_set_byname, (json_data["setname"],))
318+ matched_set = set_list.fetchone()
319+ if matched_set is None:
320+ # Does not exist, create one
321+ print("Set '%s' does not exist. Creating." %(json_data["setname"],))
322+ setid = int(random.random()*10000000)
323+ self.__cur.execute(config.insert_set_command, (setid, json_data["setname"], json_data["seticon"]))
324+ else:
325+ # Exists. Use it
326+ print("Set '%s' already exists. Will be reused" %(matched_set[1],))
327+ setid = matched_set[0]
328+
329+ # Searching and Inserting Apps
330+ app_list = self.__cur.execute(config.fetch_app_byapp, (json_data["app"],))
331+ matched_app = app_list.fetchone()
332+ if matched_app is None:
333+ # Does not exist, create one
334+ print("App '%s' does not exist. Creating." %(json_data["app"],))
335+ appid = int(random.random()*10000000)
336+ self.__cur.execute(config.insert_app_command, (appid, json_data["app"], json_data["appname"]))
337+ else:
338+ # Exists. Use it
339+ print("App '%s' already exists. Will be reused" %(matched_app[1],))
340+ appid = matched_app[0]
341+
342+
343+ # Remove all description for this Id if present
344+ desc_list = self.__cur.execute(config.remove_desc_command, (json_data["id"],))
345+ # Inserting Description
346+ desc_list = json_data["desc"]
347+ for desc in desc_list.values():
348+ self.__cur.execute(config.insert_desc_command, (json_data["id"], desc["lang"], desc["desc"]))
349+
350+ timestamp = int(datetime.datetime(1970,01,01).today().strftime("%s"))
351+
352+ try:
353+ # Inserting Trophy
354+ is_present = self.Search("trophy.id", json_data["id"])
355+ if len(is_present) > 0:
356+ print("The trophy '%s' already exists" %(json_data["id"], ))
357+ else:
358+ self.__cur.execute(config.insert_trophy_command, ( json_data["id"], \
359+ json_data["title"], \
360+ json_data["iconpath"], \
361+ appid, \
362+ setid, \
363+ int(json_data["priority"]), \
364+ bool(json_data["unlocked"]), \
365+ timestamp, \
366+ json_data["stockicon"]))
367+
368+ # Inserting History
369+ self.__cur.execute(config.insert_history_command, (json_data["id"], timestamp))
370+
371+ self.__conn.commit()
372+ pass
373+ except:
374+ raise
375+
376+
377 def AwardTrophy(self, id):
378 """ Award the trophy """
379+
380 self.__cur.execute(config.award_trophy_command, (id,))
381 self.__conn.commit()
382
383 def UnAwardTrophy(self, id):
384 """ Un-Award the trophy """
385+
386 self.__cur.execute(config.unaward_trophy_command, (id,))
387 self.__conn.commit()
388
389 def DeleteTrophy(self, id):
390 """ Un-Award the trophy """
391+
392 self.__cur.execute(config.remove_trophy_command, (id,))
393 self.__cur.execute(config.remove_desc_command, (id,))
394 self.__conn.commit()
395@@ -94,6 +185,7 @@
396
397 for val in self.__res_cursor:
398 desc_cursor = self.__cur.execute(config.fetch_description, {"Id": val[0]})
399+ print(desc_cursor)
400 # Create the Localization Description
401 desc_list = [[desc[0], desc[1]] for desc in desc_cursor]
402
403@@ -102,13 +194,13 @@
404
405 trophy_list.append(trp)
406
407- print(trophy_list)
408 return trophy_list
409
410 def _CreateTrophyDBus(self, desc_list, trp):
411 """ Create the DBus representation of Trophy which is to be sent
412 over DBus matching the signature a(ssaasssssisbxs)
413 """
414+
415 if trp[8] == 0:
416 unlocked = 0
417 else:
418
419=== modified file 'cheers/server.py'
420--- cheers/server.py 2010-10-17 20:31:25 +0000
421+++ cheers/server.py 2010-10-27 12:43:44 +0000
422@@ -63,15 +63,20 @@
423 global_monitor = global_dump.monitor_directory(gio.FILE_MONITOR_NONE, None)
424 global_monitor.connect("changed", self.directory_changed)
425
426+ if os.path.exists(config.global_trophy_path_local):
427+ global_dump_local = gio.File(config.global_trophy_path_local)
428+ global_monitor_local = global_dump_local.monitor_directory(gio.FILE_MONITOR_NONE, None)
429+ global_monitor_local.connect("changed", self.directory_changed)
430+
431 # Start the MainLoop
432 glib.MainLoop().run()
433
434 def directory_changed(self, monitor, file1, file2, evt_type):
435 """ The callback for handling the directory changes notification """
436
437- if (evt_type in (gio.FILE_MONITOR_EVENT_CREATED,)):
438- print "Changed:", file1, file2, evt_type
439- self.AddTrophy(file1.get_path())
440+ if (evt_type in (gio.FILE_MONITOR_EVENT_CREATED,)):
441+ print "Changed:", file1, file2, evt_type
442+ self.AddTrophy(file1.get_path())
443
444 def AddTrophy(self, trophy_file):
445 """ Read the JSON trophy files and register it """
446@@ -81,6 +86,7 @@
447 json_data = json.load(fs)
448 fs.close()
449
450+ self.__store.AddTrophy(json_data)
451
452 @dbus.service.method(config.CHEERS_BUS_NAME, in_signature='s')
453 def DeleteTrophy(self, id):
454@@ -135,8 +141,8 @@
455
456
457
458- @dbus.service.method(config.CHEERS_BUS_NAME, in_signature='ss')
459- def UnAwardTrophy(self, id, setname):
460+ @dbus.service.method(config.CHEERS_BUS_NAME, in_signature='s')
461+ def UnAwardTrophy(self, id):
462 """ Find the trophy to be unawarded, unaward it and send a async reply via event """
463
464 trophies = self.__store.Search("trophy.id", id)

Subscribers

People subscribed via source and target branches