Merge lp:~seif/dockmanager/enhance-zeitgeist-menus into lp:dockmanager
- enhance-zeitgeist-menus
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Rico Tzschichholz | Approve | ||
Review via email: mp+43714@code.launchpad.net |
Commit message
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)
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:/
> You are the owner of lp:~seif/dockmanager/enhance-zeitgeist-menus.
>
--
This is me doing some advertisement for my blog http://
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
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(
try:
appinfo = gio.unix.
if appinfo:
except ...
- 79. By Robert Dyer
-
better code
Rico Tzschichholz (ricotz) : | # |
- 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
Preview Diff
1 | === modified file 'scripts/zeitgeist_menus.py' | |||
2 | --- scripts/zeitgeist_menus.py 2010-08-06 23:14:20 +0000 | |||
3 | +++ scripts/zeitgeist_menus.py 2010-12-20 16:08:12 +0000 | |||
4 | @@ -28,11 +28,14 @@ | |||
5 | 28 | import urllib | 28 | import urllib |
6 | 29 | import os | 29 | import os |
7 | 30 | import subprocess | 30 | import subprocess |
8 | 31 | import gio | ||
9 | 32 | |||
10 | 33 | home = "file://" + os.path.expanduser("~") | ||
11 | 31 | 34 | ||
12 | 32 | try: | 35 | try: |
13 | 33 | from dockmanager.dockmanager import DockManagerItem, DockManagerSink, DOCKITEM_IFACE | 36 | from dockmanager.dockmanager import DockManagerItem, DockManagerSink, DOCKITEM_IFACE |
14 | 34 | from zeitgeist.client import ZeitgeistClient | 37 | from zeitgeist.client import ZeitgeistClient |
16 | 35 | from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation, StorageState | 38 | from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation, StorageState, TimeRange |
17 | 36 | from signal import signal, SIGTERM | 39 | from signal import signal, SIGTERM |
18 | 37 | from sys import exit | 40 | from sys import exit |
19 | 38 | except ImportError, e: | 41 | except ImportError, e: |
20 | @@ -41,9 +44,9 @@ | |||
21 | 41 | try: | 44 | try: |
22 | 42 | CLIENT = ZeitgeistClient() | 45 | CLIENT = ZeitgeistClient() |
23 | 43 | version = [int(x) for x in CLIENT.get_version()] | 46 | version = [int(x) for x in CLIENT.get_version()] |
25 | 44 | MIN_VERSION = [0, 3, 2, 0] | 47 | MIN_VERSION = [0, 4, 0, 0] |
26 | 45 | if version < MIN_VERSION: | 48 | if version < MIN_VERSION: |
28 | 46 | print "PLEASE USE ZEITGEIST 0.3.2 or above" | 49 | print "PLEASE USE ZEITGEIST 0.4.0 or above" |
29 | 47 | exit() | 50 | exit() |
30 | 48 | 51 | ||
31 | 49 | 52 | ||
32 | @@ -51,105 +54,146 @@ | |||
33 | 51 | print "Unable to connect to Zeitgeist, won't send events. Reason: '%s'" %e | 54 | print "Unable to connect to Zeitgeist, won't send events. Reason: '%s'" %e |
34 | 52 | exit() | 55 | exit() |
35 | 53 | 56 | ||
36 | 54 | class MostUsedProvider(): | ||
37 | 55 | def __init__(self): | ||
38 | 56 | self._zg = CLIENT | ||
39 | 57 | self.results = [] | ||
40 | 58 | |||
41 | 59 | def get_path_most_used(self, path, handler, is_directoy=True): | ||
42 | 60 | today = time.time() * 1000 | ||
43 | 61 | delta = (today - 14 * 86400000) | ||
44 | 62 | |||
45 | 63 | def exists(uri): | ||
46 | 64 | return not uri.startswith("file://") or os.path.exists(urllib.unquote(str(uri[7:]))) | ||
47 | 65 | |||
48 | 66 | def _handle_find_events(ids): | ||
49 | 67 | self._zg.get_events(ids, _handle_get_events) | ||
50 | 68 | |||
51 | 69 | def _handle_get_events(events): | ||
52 | 70 | uris = [] | ||
53 | 71 | uris_counter = {} | ||
54 | 72 | titles = {} | ||
55 | 73 | for event in events: | ||
56 | 74 | for subject in event.subjects: | ||
57 | 75 | if exists(subject.uri): | ||
58 | 76 | if not subject.uri in uris: | ||
59 | 77 | uris.append(subject.uri) | ||
60 | 78 | titles[subject.uri] = subject.text | ||
61 | 79 | uris_counter[subject.uri] = 0 | ||
62 | 80 | uris_counter[subject.uri] += 1 | ||
63 | 81 | |||
64 | 82 | counter = [] | ||
65 | 83 | for k, v in uris_counter.iteritems(): | ||
66 | 84 | counter.append((v, k)) | ||
67 | 85 | counter.sort(reverse = True) | ||
68 | 86 | |||
69 | 87 | recent =[] | ||
70 | 88 | temp = [i[1] for i in counter] | ||
71 | 89 | for uri in uris: | ||
72 | 90 | if not uri in temp[0:5]: | ||
73 | 91 | recent.append(uri) | ||
74 | 92 | results = [] | ||
75 | 93 | results.append(recent[0:5]) | ||
76 | 94 | |||
77 | 95 | results.append(counter[0:5]) | ||
78 | 96 | |||
79 | 97 | # add also titles to the result list | ||
80 | 98 | new_results = [] | ||
81 | 99 | new_results.append(map(lambda x: (x, titles[x]), results[0])) | ||
82 | 100 | new_results.append(map(lambda x: (x[1], titles[x[1]]), results[1])) | ||
83 | 101 | |||
84 | 102 | handler(new_results) | ||
85 | 103 | |||
86 | 104 | event = Event() | ||
87 | 105 | if is_directoy: | ||
88 | 106 | subject = Subject() | ||
89 | 107 | subject.set_origin(path) | ||
90 | 108 | event.set_subjects([subject]) | ||
91 | 109 | self._zg.find_events_for_templates([event],_handle_get_events, [delta, today], StorageState.Any, 0, 0) | ||
92 | 110 | else: | ||
93 | 111 | path = "application://" + path.split("/")[-1] | ||
94 | 112 | event.set_actor(path) | ||
95 | 113 | self._zg.find_events_for_templates([event],_handle_get_events, [delta, today], StorageState.Any, 0, 0) | ||
96 | 114 | |||
97 | 115 | |||
98 | 116 | class ZGItem(DockManagerItem): | 57 | class ZGItem(DockManagerItem): |
99 | 117 | def __init__(self, sink, path): | 58 | def __init__(self, sink, path): |
100 | 118 | DockManagerItem.__init__(self, sink, path) | 59 | DockManagerItem.__init__(self, sink, path) |
106 | 119 | self.mostusedprovider = MostUsedProvider() | 60 | self.monitor = None |
107 | 120 | self.update_most_used() | 61 | self.recent = [] |
108 | 121 | 62 | self.most = [] | |
109 | 122 | def update_most_used(self): | 63 | self.ids = {} |
110 | 123 | has_uri = True | 64 | |
111 | 65 | self.has_uri = True | ||
112 | 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") |
113 | 125 | |||
114 | 126 | if not self.uri: | 67 | if not self.uri: |
116 | 127 | has_uri = False | 68 | self.has_uri = False |
117 | 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") |
118 | 129 | self.uri = 'application://%s' % self.uri[self.uri.rfind('/')+1:] | 70 | self.uri = 'application://%s' % self.uri[self.uri.rfind('/')+1:] |
119 | 71 | |||
120 | 72 | self.app_info = None | ||
121 | 73 | app_uri = self.iface.Get(DOCKITEM_IFACE, "DesktopFile", dbus_interface="org.freedesktop.DBus.Properties") | ||
122 | 74 | apps = gio.app_info_get_all() | ||
123 | 75 | app = None | ||
124 | 76 | t_app = app_uri.split("/")[-1].replace(".desktop", "") | ||
125 | 77 | if t_app: | ||
126 | 78 | for app in apps: | ||
127 | 79 | if t_app in app.get_executable(): | ||
128 | 80 | self.app_info = app | ||
129 | 81 | break | ||
130 | 82 | |||
131 | 83 | self.update_entries() | ||
132 | 130 | 84 | ||
133 | 85 | def update_entries(self, x=None, y=None, z=None): | ||
134 | 86 | self.recent = [] | ||
135 | 87 | self.most = [] | ||
136 | 88 | |||
137 | 131 | if not self.uri: | 89 | if not self.uri: |
138 | 132 | return | 90 | return |
139 | 133 | 91 | ||
152 | 134 | self.mostusedprovider.get_path_most_used (self.uri, self._handle_get_most_used, has_uri) | 92 | def reformat_strings(): |
153 | 135 | 93 | titles = {} | |
154 | 136 | def _handle_get_most_used(self, results): | 94 | for r in self.recent: |
155 | 137 | uris = results[0] | 95 | if not r[1] in titles: |
156 | 138 | if len(uris) > 0: | 96 | titles[r[1]] = [] |
157 | 139 | for uri, title in uris: | 97 | titles[r[1]].append(r) |
158 | 140 | self.add_menu_item_uri(uri, "Other Recently Used Items", title) | 98 | for m in self.most: |
159 | 141 | uris = results[1] | 99 | if not m[1] in titles: |
160 | 142 | if len(uris) > 0: | 100 | titles[m[1]] = [] |
161 | 143 | for uri, title in uris: | 101 | titles[m[1]].append(m) |
162 | 144 | self.add_menu_item_uri(uri, "Most Used Items", title) | 102 | for t in titles: |
163 | 145 | 103 | if len(titles[t]) > 1: | |
164 | 104 | for l in titles[t]: | ||
165 | 105 | for i, r in enumerate(self.recent): | ||
166 | 106 | if l == r: | ||
167 | 107 | self.recent[i][1] = r[1] + " (" + r[0].replace(home, "~") + ")" | ||
168 | 108 | break | ||
169 | 109 | for i, r in enumerate(self.most): | ||
170 | 110 | if l == r: | ||
171 | 111 | self.most[i][1] = r[1] + " (" + r[0].replace(home, "~") + ")" | ||
172 | 112 | break | ||
173 | 113 | |||
174 | 114 | def exists(uri): | ||
175 | 115 | return uri.startswith("note://") or os.path.exists(urllib.unquote(str(uri[7:]))) | ||
176 | 116 | |||
177 | 117 | def handle_most(results): | ||
178 | 118 | self.most = [] | ||
179 | 119 | for event in results: | ||
180 | 120 | if exists(event.subjects[0].uri): | ||
181 | 121 | self.most.append([event.subjects[0].uri, event.subjects[0].text]) | ||
182 | 122 | if len(self.most) >= 5: | ||
183 | 123 | break | ||
184 | 124 | reformat_strings() | ||
185 | 125 | self.update_menu() | ||
186 | 126 | |||
187 | 127 | def handle_recent(results): | ||
188 | 128 | self.recent = [] | ||
189 | 129 | for event in results: | ||
190 | 130 | if exists(event.subjects[0].uri): | ||
191 | 131 | self.recent.append([event.subjects[0].uri, event.subjects[0].text]) | ||
192 | 132 | subj = Subject() | ||
193 | 133 | subj.uri = "!"+event.subjects[0].uri | ||
194 | 134 | template.subjects.append(subj) | ||
195 | 135 | if len(self.recent) >= 5: | ||
196 | 136 | break | ||
197 | 137 | CLIENT.find_events_for_templates([template], handle_most, num_events = 1000, result_type = 4) | ||
198 | 138 | |||
199 | 139 | template = Event() | ||
200 | 140 | if self.has_uri: | ||
201 | 141 | subj = Subject() | ||
202 | 142 | subj.set_uri(self.uri+"/*") | ||
203 | 143 | template.set_subjects([subj]) | ||
204 | 144 | else: | ||
205 | 145 | template.set_actor(self.uri) | ||
206 | 146 | |||
207 | 147 | CLIENT.find_events_for_templates([template], handle_recent, num_events = 1000, result_type = 2) | ||
208 | 148 | |||
209 | 149 | if not self.monitor: | ||
210 | 150 | self.monitor = CLIENT.install_monitor(TimeRange.always(), [template], self.update_entries, self.update_entries) | ||
211 | 151 | |||
212 | 152 | def update_menu(self): | ||
213 | 153 | for id in self.ids: | ||
214 | 154 | self.remove_menu_item(id) | ||
215 | 155 | self.ids.clear() | ||
216 | 156 | uris = self.most | ||
217 | 157 | for uri in uris: | ||
218 | 158 | uri, title = uri[0], uri[1] | ||
219 | 159 | icon = self.get_icon(uri) | ||
220 | 160 | self.ids[(self.add_menu_item(title, icon, "Other Popular"))] = uri | ||
221 | 161 | uris = self.recent | ||
222 | 162 | for uri in uris: | ||
223 | 163 | uri, title = uri[0], uri[1] | ||
224 | 164 | icon = self.get_icon(uri) | ||
225 | 165 | print icon | ||
226 | 166 | self.ids[(self.add_menu_item(title, icon, "Latest"))] = uri | ||
227 | 167 | |||
228 | 168 | def get_icon(self, uri): | ||
229 | 169 | if uri.startswith("note://"): | ||
230 | 170 | return "tomboy-note" | ||
231 | 171 | file_ = gio.File(uri) | ||
232 | 172 | info = file_.query_info('standard::icon,thumbnail::path') | ||
233 | 173 | thumbnail_path = info.get_attribute_as_string('thumbnail::path') | ||
234 | 174 | if thumbnail_path: | ||
235 | 175 | return thumbnail_path | ||
236 | 176 | else: | ||
237 | 177 | icon = info.get_icon() | ||
238 | 178 | icon_path = None | ||
239 | 179 | if isinstance(icon, gio.ThemedIcon): | ||
240 | 180 | icon_path = icon.get_names()[0] | ||
241 | 181 | elif isinstance(icon, gio.FileIcon): | ||
242 | 182 | icon_path = icon.get_file().get_path() | ||
243 | 183 | return icon_path | ||
244 | 184 | |||
245 | 185 | def menu_pressed(self, menu_id): | ||
246 | 186 | if menu_id in self.ids: | ||
247 | 187 | if self.app_info: | ||
248 | 188 | self.app_info.launch([gio.File(self.ids[menu_id])]) | ||
249 | 189 | else: | ||
250 | 190 | subprocess.Popen(['xdg-open', self.ids[menu_id]]) | ||
251 | 146 | 191 | ||
252 | 147 | class ZGSink(DockManagerSink): | 192 | class ZGSink(DockManagerSink): |
253 | 148 | def item_path_found(self, pathtoitem, item): | 193 | def item_path_found(self, pathtoitem, item): |
254 | 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") != "": |
255 | 150 | self.items[pathtoitem] = ZGItem(self, pathtoitem) | 195 | self.items[pathtoitem] = ZGItem(self, pathtoitem) |
256 | 151 | 196 | ||
257 | 152 | |||
258 | 153 | zgsink = ZGSink() | 197 | zgsink = ZGSink() |
259 | 154 | 198 | ||
260 | 155 | def cleanup (): | 199 | def cleanup (): |
261 | @@ -157,10 +201,7 @@ | |||
262 | 157 | 201 | ||
263 | 158 | if __name__ == "__main__": | 202 | if __name__ == "__main__": |
264 | 159 | mainloop = gobject.MainLoop(is_running=True) | 203 | mainloop = gobject.MainLoop(is_running=True) |
265 | 160 | |||
266 | 161 | atexit.register (cleanup) | 204 | atexit.register (cleanup) |
267 | 162 | |||
268 | 163 | signal(SIGTERM, lambda signum, stack_frame: exit(1)) | 205 | signal(SIGTERM, lambda signum, stack_frame: exit(1)) |
269 | 164 | |||
270 | 165 | while mainloop.is_running(): | 206 | while mainloop.is_running(): |
271 | 166 | mainloop.run() | 207 | mainloop.run() |
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 :(