Merge lp:~seif/dockmanager/enhance-zeitgeist-menus into lp:dockmanager

Proposed by Seif Lotfy
Status: Merged
Merged at revision: 80
Proposed branch: lp:~seif/dockmanager/enhance-zeitgeist-menus
Merge into: lp:dockmanager
Diff against target: 271 lines (+129/-88)
1 file modified
scripts/zeitgeist_menus.py (+129/-88)
To merge this branch: bzr merge lp:~seif/dockmanager/enhance-zeitgeist-menus
Reviewer Review Type Date Requested Status
Rico Tzschichholz Approve
Review via email: mp+43714@code.launchpad.net

Description of the change

I enhanced the menus by allowing them to update themselves on the fly using the zeitgeist monitors as well as use reduce memory consumption by using negations in queries (no need to ask for all events)

To post a comment you must log in.
Revision history for this message
Rico Tzschichholz (ricotz) wrote :

Nice to see you working on it :)

But the version check isn't working the current natty version 0.5.2 doesn't fit the check. Also the added items aren't right. So currently it is quite broken for me :(

review: Needs Fixing
Revision history for this message
Seif Lotfy (seif) wrote :

ah Shit I know why. There is a bug in Zeitgeist that did not get released.
Let me work aroudn that.

On Wed, Dec 15, 2010 at 8:17 AM, Rico Tzschichholz <email address hidden>wrote:

> Review: Needs Fixing
> Nice to see you working on it :)
>
> But the version check isn't working the current natty version 0.5.2 doesn't
> fit the check. Also the added items aren't right. So currently it is quite
> broken for me :(
>
>
> --
>
> https://code.launchpad.net/~seif/dockmanager/enhance-zeitgeist-menus/+merge/43714
> You are the owner of lp:~seif/dockmanager/enhance-zeitgeist-menus.
>

--
This is me doing some advertisement for my blog http://seilo.geekyogre.com

Revision history for this message
Seif Lotfy (seif) wrote :

The remaining issue is from you side guys. I finished my part.

78. By Robert Dyer

fix the add_menu_with_uri calls to properly fall back on add_menu_item

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

The menu_pressed method need some work. Now it will throw a exception in too many cases and if it fails it might not use the right application.
I think it is better to use:

if uri.endswith(".desktop"):
    try:
        appinfo = gio.unix.DesktopAppInfo(uri)
        if appinfo:
            appinfo.launch(self.ids[menu_id]])
    except ...

review: Needs Fixing
79. By Robert Dyer

better code

Revision history for this message
Rico Tzschichholz (ricotz) :
review: Approve
80. By Rico Tzschichholz

update zeitgeist-menu-helper

enhanced the menus by allowing them to update themselves on the fly
using the zeitgeist monitors as well as use reduce memory consumption
by using negations in queries (no need to ask for all events

merge lp:~seif/dockmanager/enhance-zeitgeist-menus

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'scripts/zeitgeist_menus.py'
--- scripts/zeitgeist_menus.py 2010-08-06 23:14:20 +0000
+++ scripts/zeitgeist_menus.py 2010-12-20 16:08:12 +0000
@@ -28,11 +28,14 @@
28import urllib28import urllib
29import os29import os
30import subprocess30import subprocess
31import gio
32
33home = "file://" + os.path.expanduser("~")
3134
32try:35try:
33 from dockmanager.dockmanager import DockManagerItem, DockManagerSink, DOCKITEM_IFACE36 from dockmanager.dockmanager import DockManagerItem, DockManagerSink, DOCKITEM_IFACE
34 from zeitgeist.client import ZeitgeistClient37 from zeitgeist.client import ZeitgeistClient
35 from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation, StorageState38 from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation, StorageState, TimeRange
36 from signal import signal, SIGTERM39 from signal import signal, SIGTERM
37 from sys import exit40 from sys import exit
38except ImportError, e:41except ImportError, e:
@@ -41,9 +44,9 @@
41try:44try:
42 CLIENT = ZeitgeistClient()45 CLIENT = ZeitgeistClient()
43 version = [int(x) for x in CLIENT.get_version()]46 version = [int(x) for x in CLIENT.get_version()]
44 MIN_VERSION = [0, 3, 2, 0]47 MIN_VERSION = [0, 4, 0, 0]
45 if version < MIN_VERSION:48 if version < MIN_VERSION:
46 print "PLEASE USE ZEITGEIST 0.3.2 or above"49 print "PLEASE USE ZEITGEIST 0.4.0 or above"
47 exit()50 exit()
48 51
4952
@@ -51,105 +54,146 @@
51 print "Unable to connect to Zeitgeist, won't send events. Reason: '%s'" %e54 print "Unable to connect to Zeitgeist, won't send events. Reason: '%s'" %e
52 exit()55 exit()
53 56
54class MostUsedProvider():
55 def __init__(self):
56 self._zg = CLIENT
57 self.results = []
58
59 def get_path_most_used(self, path, handler, is_directoy=True):
60 today = time.time() * 1000
61 delta = (today - 14 * 86400000)
62
63 def exists(uri):
64 return not uri.startswith("file://") or os.path.exists(urllib.unquote(str(uri[7:])))
65
66 def _handle_find_events(ids):
67 self._zg.get_events(ids, _handle_get_events)
68
69 def _handle_get_events(events):
70 uris = []
71 uris_counter = {}
72 titles = {}
73 for event in events:
74 for subject in event.subjects:
75 if exists(subject.uri):
76 if not subject.uri in uris:
77 uris.append(subject.uri)
78 titles[subject.uri] = subject.text
79 uris_counter[subject.uri] = 0
80 uris_counter[subject.uri] += 1
81
82 counter = []
83 for k, v in uris_counter.iteritems():
84 counter.append((v, k))
85 counter.sort(reverse = True)
86
87 recent =[]
88 temp = [i[1] for i in counter]
89 for uri in uris:
90 if not uri in temp[0:5]:
91 recent.append(uri)
92 results = []
93 results.append(recent[0:5])
94
95 results.append(counter[0:5])
96
97 # add also titles to the result list
98 new_results = []
99 new_results.append(map(lambda x: (x, titles[x]), results[0]))
100 new_results.append(map(lambda x: (x[1], titles[x[1]]), results[1]))
101
102 handler(new_results)
103
104 event = Event()
105 if is_directoy:
106 subject = Subject()
107 subject.set_origin(path)
108 event.set_subjects([subject])
109 self._zg.find_events_for_templates([event],_handle_get_events, [delta, today], StorageState.Any, 0, 0)
110 else:
111 path = "application://" + path.split("/")[-1]
112 event.set_actor(path)
113 self._zg.find_events_for_templates([event],_handle_get_events, [delta, today], StorageState.Any, 0, 0)
114
115
116class ZGItem(DockManagerItem):57class ZGItem(DockManagerItem):
117 def __init__(self, sink, path):58 def __init__(self, sink, path):
118 DockManagerItem.__init__(self, sink, path)59 DockManagerItem.__init__(self, sink, path)
119 self.mostusedprovider = MostUsedProvider()60 self.monitor = None
120 self.update_most_used()61 self.recent = []
121 62 self.most = []
122 def update_most_used(self):63 self.ids = {}
123 has_uri = True64
65 self.has_uri = True
124 self.uri = self.iface.Get(DOCKITEM_IFACE, "Uri", dbus_interface="org.freedesktop.DBus.Properties")66 self.uri = self.iface.Get(DOCKITEM_IFACE, "Uri", dbus_interface="org.freedesktop.DBus.Properties")
125
126 if not self.uri:67 if not self.uri:
127 has_uri = False68 self.has_uri = False
128 self.uri = self.iface.Get(DOCKITEM_IFACE, "DesktopFile", dbus_interface="org.freedesktop.DBus.Properties")69 self.uri = self.iface.Get(DOCKITEM_IFACE, "DesktopFile", dbus_interface="org.freedesktop.DBus.Properties")
129 self.uri = 'application://%s' % self.uri[self.uri.rfind('/')+1:]70 self.uri = 'application://%s' % self.uri[self.uri.rfind('/')+1:]
71
72 self.app_info = None
73 app_uri = self.iface.Get(DOCKITEM_IFACE, "DesktopFile", dbus_interface="org.freedesktop.DBus.Properties")
74 apps = gio.app_info_get_all()
75 app = None
76 t_app = app_uri.split("/")[-1].replace(".desktop", "")
77 if t_app:
78 for app in apps:
79 if t_app in app.get_executable():
80 self.app_info = app
81 break
82
83 self.update_entries()
130 84
85 def update_entries(self, x=None, y=None, z=None):
86 self.recent = []
87 self.most = []
88
131 if not self.uri:89 if not self.uri:
132 return90 return
133 91
134 self.mostusedprovider.get_path_most_used (self.uri, self._handle_get_most_used, has_uri)92 def reformat_strings():
13593 titles = {}
136 def _handle_get_most_used(self, results):94 for r in self.recent:
137 uris = results[0]95 if not r[1] in titles:
138 if len(uris) > 0:96 titles[r[1]] = []
139 for uri, title in uris:97 titles[r[1]].append(r)
140 self.add_menu_item_uri(uri, "Other Recently Used Items", title)98 for m in self.most:
141 uris = results[1]99 if not m[1] in titles:
142 if len(uris) > 0:100 titles[m[1]] = []
143 for uri, title in uris:101 titles[m[1]].append(m)
144 self.add_menu_item_uri(uri, "Most Used Items", title)102 for t in titles:
145103 if len(titles[t]) > 1:
104 for l in titles[t]:
105 for i, r in enumerate(self.recent):
106 if l == r:
107 self.recent[i][1] = r[1] + " (" + r[0].replace(home, "~") + ")"
108 break
109 for i, r in enumerate(self.most):
110 if l == r:
111 self.most[i][1] = r[1] + " (" + r[0].replace(home, "~") + ")"
112 break
113
114 def exists(uri):
115 return uri.startswith("note://") or os.path.exists(urllib.unquote(str(uri[7:])))
116
117 def handle_most(results):
118 self.most = []
119 for event in results:
120 if exists(event.subjects[0].uri):
121 self.most.append([event.subjects[0].uri, event.subjects[0].text])
122 if len(self.most) >= 5:
123 break
124 reformat_strings()
125 self.update_menu()
126
127 def handle_recent(results):
128 self.recent = []
129 for event in results:
130 if exists(event.subjects[0].uri):
131 self.recent.append([event.subjects[0].uri, event.subjects[0].text])
132 subj = Subject()
133 subj.uri = "!"+event.subjects[0].uri
134 template.subjects.append(subj)
135 if len(self.recent) >= 5:
136 break
137 CLIENT.find_events_for_templates([template], handle_most, num_events = 1000, result_type = 4)
138
139 template = Event()
140 if self.has_uri:
141 subj = Subject()
142 subj.set_uri(self.uri+"/*")
143 template.set_subjects([subj])
144 else:
145 template.set_actor(self.uri)
146
147 CLIENT.find_events_for_templates([template], handle_recent, num_events = 1000, result_type = 2)
148
149 if not self.monitor:
150 self.monitor = CLIENT.install_monitor(TimeRange.always(), [template], self.update_entries, self.update_entries)
151
152 def update_menu(self):
153 for id in self.ids:
154 self.remove_menu_item(id)
155 self.ids.clear()
156 uris = self.most
157 for uri in uris:
158 uri, title = uri[0], uri[1]
159 icon = self.get_icon(uri)
160 self.ids[(self.add_menu_item(title, icon, "Other Popular"))] = uri
161 uris = self.recent
162 for uri in uris:
163 uri, title = uri[0], uri[1]
164 icon = self.get_icon(uri)
165 print icon
166 self.ids[(self.add_menu_item(title, icon, "Latest"))] = uri
167
168 def get_icon(self, uri):
169 if uri.startswith("note://"):
170 return "tomboy-note"
171 file_ = gio.File(uri)
172 info = file_.query_info('standard::icon,thumbnail::path')
173 thumbnail_path = info.get_attribute_as_string('thumbnail::path')
174 if thumbnail_path:
175 return thumbnail_path
176 else:
177 icon = info.get_icon()
178 icon_path = None
179 if isinstance(icon, gio.ThemedIcon):
180 icon_path = icon.get_names()[0]
181 elif isinstance(icon, gio.FileIcon):
182 icon_path = icon.get_file().get_path()
183 return icon_path
184
185 def menu_pressed(self, menu_id):
186 if menu_id in self.ids:
187 if self.app_info:
188 self.app_info.launch([gio.File(self.ids[menu_id])])
189 else:
190 subprocess.Popen(['xdg-open', self.ids[menu_id]])
146191
147class ZGSink(DockManagerSink):192class ZGSink(DockManagerSink):
148 def item_path_found(self, pathtoitem, item):193 def item_path_found(self, pathtoitem, item):
149 if item.Get(DOCKITEM_IFACE, "Uri", dbus_interface="org.freedesktop.DBus.Properties") != "" or item.Get(DOCKITEM_IFACE, "DesktopFile", dbus_interface="org.freedesktop.DBus.Properties") != "":194 if item.Get(DOCKITEM_IFACE, "Uri", dbus_interface="org.freedesktop.DBus.Properties") != "" or item.Get(DOCKITEM_IFACE, "DesktopFile", dbus_interface="org.freedesktop.DBus.Properties") != "":
150 self.items[pathtoitem] = ZGItem(self, pathtoitem)195 self.items[pathtoitem] = ZGItem(self, pathtoitem)
151196
152
153zgsink = ZGSink()197zgsink = ZGSink()
154198
155def cleanup ():199def cleanup ():
@@ -157,10 +201,7 @@
157201
158if __name__ == "__main__":202if __name__ == "__main__":
159 mainloop = gobject.MainLoop(is_running=True)203 mainloop = gobject.MainLoop(is_running=True)
160
161 atexit.register (cleanup)204 atexit.register (cleanup)
162
163 signal(SIGTERM, lambda signum, stack_frame: exit(1))205 signal(SIGTERM, lambda signum, stack_frame: exit(1))
164
165 while mainloop.is_running():206 while mainloop.is_running():
166 mainloop.run()207 mainloop.run()

Subscribers

People subscribed via source and target branches

to status/vote changes: