Hi Jamie

This patch incorporates all I've done in the deskbar-handler so far.

The problem[1] reported a race condition with the handler dbus
connection and trackerd, this should now be fixed. I've put the
connection to dbus into the query method, i.e. the dbus connection
will be setup on the first search. This happens to work pretty good.
Another issue that is fixed now - when trackerd cannot be started by
dbus (i.e. an exception is thrown) I catch the exception and print an
error on stderr (xsession-errors will show this for bug reports) -
this prevent deskbar from being left nonfunctional (as reported).

Applications and Conversations are now supported. For conversations I
extract all information shown on the deskbar search results from the
log file path - that works pretty well and my test (on all logs i have
here, some 10MiB!) showed no issues.

Application data is extracted from the result returned by tracker -
that is application name, what is executed (shown in Deskbar results,
as does the Programs applet) and the icon. Also this worked pretty
good.

Please test this and ping me on issues ;)

Cheers, Marcus
diff --git a/python/deskbar-handler/tracker-handler.py b/python/deskbar-handler/tracker-handler.py
index 72fb72f..3d5ce17 100644
--- a/python/deskbar-handler/tracker-handler.py
+++ b/python/deskbar-handler/tracker-handler.py
@@ -9,7 +9,7 @@ import gnome
 import gobject
 from gettext import gettext as _
 
-import re, cgi
+import re, cgi, sys
 import os.path
 import dbus
 
@@ -64,14 +64,25 @@ HANDLERS = {
 			"videos"	: {	
 				"name": _("Videos"),
 			},
+			"conversations" : {
+				"name": _("Conversations"),
+			},
+			"applications" : {
+				"name": _("Applications"),
+			},
 		},
 	},
 }
 
 #For now description param it's not used
 TYPES = {
-	"Conversations"	: {
-		"description": (_("See  conversations %s") % "<i>%(publisher)s</i>" ) + "\n<b>%(base)s</b>",
+	"Applications"	: {
+		"description": (_("Launch %s (%s)") % ("<b>%(name)s</b>", "<i>%(app_name)s</i>") ),
+		"category": "applications",
+		"action": "xdg-open %(uri)s",
+		},
+	"GaimConversations"	: {
+		"description": (_("See %s conversation\n%s %s\nfrom %s") % ("<b>%(proto)s</b>", "%(channel)s", "<b>%(conv_to)s</b>", "<i>%(time)s</i>")),
 		"category": "conversations",
 		},
 	"Email"	: {
@@ -163,14 +174,17 @@ class TrackerLiveFileMatch (Match):
 		
 		self.result["base"] = self.base
 		self.result["dir"] = self.dir
-		
+
 		# Set the match icon
 		try:
 			self._icon = deskbar.Utils.load_icon(TYPES[result['type']]["icon"])
 		except:
-			self._icon = deskbar.Utils.load_icon_for_file(result['uri'])
-		
-		print result
+			if self.result.has_key ('icon'):
+				self._icon = deskbar.Utils.load_icon_for_desktop_icon (result ['icon'])
+			else:
+				self._icon = deskbar.Utils.load_icon_for_file(result['uri'])
+
+		#print result
 
 	def get_name(self, text=None):
 		try:
@@ -186,6 +200,9 @@ class TrackerLiveFileMatch (Match):
 	
 	def get_hash(self, text=None):
 		try:
+			if self.result ['type'] == 'Applications':
+				# return a name that matches the one returned by the Program handler of deskbar
+				return "generic_" + self.result ['app_basename']
 			return self.result['uri']
 		except:
 			pass
@@ -232,49 +249,102 @@ class TrackerLiveFileMatch (Match):
 
 class TrackerLiveSearchHandler(SignallingHandler):
 	def __init__(self):
+		import re
 		SignallingHandler.__init__(self, "tracker")
-		bus = dbus.SessionBus()
-		self.tracker = bus.get_object('org.freedesktop.Tracker','/org/freedesktop/tracker')
-		self.search_iface = dbus.Interface(self.tracker, 'org.freedesktop.Tracker.Search')
-		self.keywords_iface = dbus.Interface(self.tracker, 'org.freedesktop.Tracker.Keywords')
-		self.files_iface = dbus.Interface(self.tracker, 'org.freedesktop.Tracker.Files')
+		# initing on search request, see self.query
+		self.tracker = self.search_iface = self.keywords_iface = self.files_iface = None
 		self.set_delay (500)
-		
+		self.conv_re = re.compile (r'^.*?/logs/([^/]+)/([^/]+)/([^/]+)/(.+?)\.(:?txt|html)$') # all, proto, account, to-whom, time
+
 	def recieve_hits (self, qstring, hits, max):
 		matches = []
 		self.results = {}
 		
 		for info in hits:
-			output = {} 
+			output = {}
 			output['name'] = os.path.basename(info[0])
 			output['uri'] = str(cgi.escape(info[0]))
 			output['type'] = info[1]
-			if TYPES.has_key(output['type']) == 0:
+
+			if not TYPES.has_key(output['type']):
 				output['type'] = "Other Files"	
-			try:
-				self.results[output['type']].append(output)
-			except:
-				self.results[output['type']] = [output]
 			
 			if output["type"] == "Email":
 				output["title"] = cgi.escape(info[3])
 				output["publisher"] = cgi.escape(info[4])
-			
+
+			elif output['type'] in ('GaimConversations', 'Conversations'):
+				output ['uri'] = info [0]
+				m = self.conv_re.match (output['uri'])
+				output['channel']=_("with")
+				output['proto']=output['conv_from']=output['conv_to']=output['time']="" # XXX, never happened during tests
+				if m:
+					output['proto'] = m.group (1)
+					output['conv_from'] = m.group (2)
+					output['conv_to'] = m.group (3)
+					output['time'] = m.group (4)
+				if output['conv_to'].endswith ('.chat'):
+					output['channel'] = _("in channel")
+					output['conv_to'] = output['conv_to'].replace (".chat","")
+				if output['proto'] == 'irc':
+					nick_server = output['conv_from'].split ('@')
+					if len (nick_server) > 1:
+						output['conv_to'] = "%s on %s" % (output['conv_to'], nick_server[1])
+				# escape those entities, purple uses this to escape / on jabber channel/user conversations
+				output['uri'] = output['uri'].replace ("%", "%25")
+				# escape irc channel prefixes, else the path name parsing of stops at '#' (this holds also for the icon search)
+				output['uri'] = output['uri'].replace ("#", "%23")
+
+			elif output['type'] == 'Applications':
+				# print info
+				#   dbus.Array(
+				#   [
+				#     dbus.String(u'/usr/share/applications/gksu.desktop'), # TrackerUri  0
+				#     dbus.String(u'Applications'),                         # TrackerType 1
+				#     dbus.String(u'Application'),                          # DesktopType 2
+				#     dbus.String(u'Root Terminal'),                        # DesktopName 3
+				#     dbus.String(u'gksu /usr/bin/x-terminal-emulator'),    # DesktopExec 4
+				#     dbus.String(u'gksu-root-terminal')                    # DesktopIcon 5
+				#   ],
+				#   signature=dbus.Signature('s'))
+				# Strip %U or whatever arguments in Exec field
+				output['app_name'] = re.sub(r'%\w+', '', info [4]).strip ()
+				output['app_basename'] = cgi.escape (os.path.basename (output['app_name']))
+				output['app_name'] = cgi.escape (output['app_name'])
+				output['name'] = cgi.escape (info [3])
+				output['icon'] = len (info) == 6 and cgi.escape (info [5]) or ''
+
+			try:
+				self.results[output['type']].append(output)
+			except:
+				self.results[output['type']] = [output]
+	
 		for key in self.results.keys():
-				for res in self.results[key][0:MAX_RESULTS]:
-					matches.append(TrackerLiveFileMatch(self,res))
+			for res in self.results[key][0:MAX_RESULTS]:
+				matches.append(TrackerLiveFileMatch(self,res))
 				#if len(self.results[key]) > MAX_RESULTS:
 				#	matches.append( TrackerMoreMatch(self,qstring,key) )
 		self.emit_query_ready(qstring, matches)
 		print "Tracker response for %s, - %s hits returned, %s shown" % (qstring, len(hits), len(matches))
 		
 	def recieve_error (self, error):
-		print "*** Tracker dbus error:", error
+		print >> sys.stderr, "*** Tracker dbus error:", error
 				
 	def query (self, qstring, max):
+		if not self.tracker:
+			try:
+				bus = dbus.SessionBus()
+				self.tracker = bus.get_object('org.freedesktop.Tracker','/org/freedesktop/tracker')
+				self.search_iface = dbus.Interface(self.tracker, 'org.freedesktop.Tracker.Search')
+				self.keywords_iface = dbus.Interface(self.tracker, 'org.freedesktop.Tracker.Keywords')
+				self.files_iface = dbus.Interface(self.tracker, 'org.freedesktop.Tracker.Files')
+				print "Connected to Tracker"
+			except:
+				print >> sys.stderr, "DBus connection to tracker failed, check your settings."
+				return
 		if qstring.count("tag:") == 0: 
-			self.search_iface.TextDetailed (-1, "Files", qstring, 0,10, reply_handler=lambda hits : self.recieve_hits(qstring, hits, max), error_handler=self.recieve_error)
-			self.search_iface.TextDetailed (-1, "Emails", qstring, 0,10, reply_handler=lambda hits : self.recieve_hits(qstring, hits, max), error_handler=self.recieve_error)
+			for service in ("Files", "Emails", "Conversations", "Applications"):
+				self.search_iface.TextDetailed (-1, service, qstring, 0,10, reply_handler=lambda hits : self.recieve_hits(qstring, hits, max), error_handler=self.recieve_error)
 			print "Tracker query:", qstring
 		else:
 			if self.tracker.GetVersion() == 502:
_______________________________________________
tracker-list mailing list
tracker-list@gnome.org
http://mail.gnome.org/mailman/listinfo/tracker-list

Reply via email to