[kupfer] Split tracker plugin into 'tracker' and 'tracker1' plugins



commit 66a1ffe551a1c4c52f6a9a4ba3e8efab706eae6a
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Thu Apr 29 18:19:16 2010 +0200

    Split tracker plugin into 'tracker' and 'tracker1' plugins
    
    Plugin name follows D-bus api version, which is called Tracker1 for
    current Tracker 0.8.x.
    
    The old tracker 0.6 plugin will stay until we move it into contrib or
    where it might go..

 data/defaults.cfg         |    2 +-
 kupfer/plugin/tracker.py  |  124 +++++++++--------------------
 kupfer/plugin/tracker1.py |  194 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 233 insertions(+), 87 deletions(-)
---
diff --git a/data/defaults.cfg b/data/defaults.cfg
index eb5b5f5..2c7d9a7 100644
--- a/data/defaults.cfg
+++ b/data/defaults.cfg
@@ -94,7 +94,7 @@ kupfer_enabled = True
 [plugin_show_text]
 kupfer_enabled = True
 
-[plugin_tracker]
+[plugin_tracker1]
 kupfer_enabled = False
 
 [plugin_triggers]
diff --git a/kupfer/plugin/tracker.py b/kupfer/plugin/tracker.py
index bc98027..ca7c363 100644
--- a/kupfer/plugin/tracker.py
+++ b/kupfer/plugin/tracker.py
@@ -1,4 +1,9 @@
-__kupfer_name__ = _("Tracker")
+"""
+Tracker plugins are versioned by the D-Bus API version
+This is version naught, working with the "original" tracker 0.6.x
+versions.
+"""
+__kupfer_name__ = _("Tracker 0.6")
 __kupfer_sources__ = ("TrackerTagsSource", )
 __kupfer_text_sources__ = ()
 __kupfer_contents__ = ("TrackerQuerySource", )
@@ -15,8 +20,6 @@ __author__ = "Ulrik Sverdrup <ulrik sverdrup gmail com>"
 import os
 from xml.etree.cElementTree import ElementTree
 
-import dbus
-import gio
 import gobject
 
 from kupfer.objects import Action, Source, Leaf
@@ -27,16 +30,13 @@ from kupfer import kupferstring
 from kupfer import plugin_support
 
 
+
 plugin_support.check_dbus_connection()
 
 SERVICE_NAME = "org.freedesktop.Tracker"
 SEARCH_OBJECT_PATH = "/org/freedesktop/Tracker/Search"
 SEARCH_INTERFACE = "org.freedesktop.Tracker.Search"
 
-SERVICE1_NAME = "org.freedesktop.Tracker1"
-SEARCH_OBJECT1_PATH = "/org/freedesktop/Tracker1/Resources"
-SEARCH1_INTERFACE = "org.freedesktop.Tracker1.Resources"
-
 class TrackerSearch (Action):
 	def __init__(self):
 		Action.__init__(self, _("Search in Tracker"))
@@ -68,84 +68,6 @@ class TrackerSearchHere (Action):
 	def item_types(self):
 		yield TextLeaf
 
-def is_ok_char(c):
-	return c.isalnum() or c == " "
-
-def get_file_results_sparql(searchobj, query, max_items):
-	# We don't have any real escape function for queries
-	# so we instead strip everything not alphanumeric
-	clean_query = u"".join([c for c in query if is_ok_char(c)])
-	sql = u"""SELECT tracker:coalesce (nie:url (?s), ?s)
-	          WHERE {  ?s fts:match "%s*" .  ?s tracker:available true . }
-			  ORDER BY tracker:weight(?s)
-			  OFFSET 0 LIMIT %d""" % (clean_query, int(max_items))
-
-	pretty.print_debug(__name__, "Searching for %s (%s)",
-			repr(clean_query), repr(query))
-	pretty.print_debug(__name__, sql)
-	results = searchobj.SparqlQuery(sql)
-
-	gio_File = gio.File
-	for result in results:
-		yield FileLeaf(gio_File(result[0]).get_path())
-
-def get_file_results_old(searchobj, query, max_items):
-	try:
-		file_hits = searchobj.Text(1, "Files", query, 0, max_items)
-	except dbus.DBusException, exc:
-		pretty.print_error(__name__, exc)
-		return
-
-	for filestr in file_hits:
-		# A bit of encoding carousel
-		# dbus strings are subclasses of unicode
-		# but FileLeaf expects a filesystem encoded object
-		bytes = filestr.decode("UTF-8", "replace")
-		filename = gobject.filename_from_utf8(bytes)
-		yield ConstructFileLeaf(filename)
-
-use_version = None
-versions = {
-	"0.8": (SERVICE1_NAME, SEARCH_OBJECT1_PATH, SEARCH1_INTERFACE),
-	"0.6": (SERVICE_NAME, SEARCH_OBJECT_PATH, SEARCH_INTERFACE),
-}
-
-version_query = {
-	"0.8": get_file_results_sparql,
-	"0.6": get_file_results_old,
-}
-
-
-def get_searchobject(sname, opath, sinface):
-	bus = dbus.SessionBus()
-	searchobj = None
-	try:
-		tobj = bus.get_object(sname, opath)
-		searchobj = dbus.Interface(tobj, sinface)
-	except dbus.DBusException, exc:
-		pretty.print_debug(__name__, exc)
-	return searchobj
-
-def get_tracker_filequery(query, max_items):
-	searchobj = None
-	global use_version
-	if use_version is None:
-		for version, (sname, opath, sinface) in versions.items():
-			pretty.print_debug(__name__, "Trying", sname, version)
-			searchobj = get_searchobject(sname, opath, sinface)
-			if searchobj is not None:
-				use_version = version
-				break
-	else:
-		searchobj = get_searchobject(*versions[use_version])
-	if searchobj is None:
-		use_version = None
-		pretty.print_error(__name__, "Could not connect to Tracker")
-		return ()
-
-	queryfunc = version_query[use_version]
-	return queryfunc(searchobj, query, max_items)
-
 class TrackerQuerySource (Source):
 	def __init__(self, query):
 		Source.__init__(self, name=_('Results for "%s"') % query)
@@ -156,7 +78,37 @@ class TrackerQuerySource (Source):
 		return self.query
 
 	def get_items(self):
-		return get_tracker_filequery(self.query, self.max_items)
+		try:
+			import dbus
+		except ImportError:
+			pretty.print_info(__name__, "Dbus not available!")
+			return
+		bus = dbus.SessionBus()
+		try:
+			tobj = bus.get_object(SERVICE_NAME, SEARCH_OBJECT_PATH)
+			searchobj = dbus.Interface(tobj, SEARCH_INTERFACE)
+		except dbus.DBusException, exc:
+			pretty.print_error(__name__, exc)
+			pretty.print_error(__name__, "Could not connect to Tracker")
+			return
+
+		# Text interface
+		# (i) live_query_id, (s) service, (s) search_text,
+		# (i) offset, (i) max_hits
+		# Returns array of strings for results
+		try:
+			file_hits = searchobj.Text(1, "Files", self.query, 0, self.max_items)
+		except dbus.DBusException, exc:
+			pretty.print_error(__name__, exc)
+			return
+
+		for filestr in file_hits:
+			# A bit of encoding carousel
+			# dbus strings are subclasses of unicode
+			# but FileLeaf expects a filesystem encoded object
+			bytes = filestr.decode("UTF-8", "replace")
+			filename = gobject.filename_from_utf8(bytes)
+			yield ConstructFileLeaf(filename)
 
 	def get_description(self):
 		return _('Results for "%s"') % self.query
diff --git a/kupfer/plugin/tracker1.py b/kupfer/plugin/tracker1.py
new file mode 100644
index 0000000..e476d7f
--- /dev/null
+++ b/kupfer/plugin/tracker1.py
@@ -0,0 +1,194 @@
+"""
+Tracker plugins are versioned by the D-Bus API version
+This is version naught, working with tracker 0.8.x,
+where the API is called Tracker1
+versions.
+"""
+__kupfer_name__ = _("Tracker 0.8")
+__kupfer_sources__ = ()
+__kupfer_text_sources__ = ()
+__kupfer_contents__ = ("TrackerQuerySource", )
+__kupfer_actions__ = (
+		"TrackerSearchHere",
+	)
+__description__ = _("Tracker desktop search integration")
+__version__ = "2010-04-01"
+__author__ = "Ulrik Sverdrup <ulrik sverdrup gmail com>"
+
+import os
+from xml.etree.cElementTree import ElementTree
+
+import dbus
+import gio
+import gobject
+
+from kupfer.objects import Action, Source, Leaf
+from kupfer.objects import TextLeaf, SourceLeaf, TextSource, FileLeaf
+from kupfer.obj.objects import ConstructFileLeaf
+from kupfer import utils, pretty
+from kupfer import kupferstring
+from kupfer import plugin_support
+
+
+plugin_support.check_dbus_connection()
+
+SERVICE_NAME = "org.freedesktop.Tracker"
+SEARCH_OBJECT_PATH = "/org/freedesktop/Tracker/Search"
+SEARCH_INTERFACE = "org.freedesktop.Tracker.Search"
+
+SERVICE1_NAME = "org.freedesktop.Tracker1"
+SEARCH_OBJECT1_PATH = "/org/freedesktop/Tracker1/Resources"
+SEARCH1_INTERFACE = "org.freedesktop.Tracker1.Resources"
+
+class TrackerSearch (Action):
+	def __init__(self):
+		Action.__init__(self, _("Search in Tracker"))
+
+	def activate(self, leaf):
+		utils.launch_commandline("tracker-search-tool %s" % leaf.object)
+	def get_description(self):
+		return _("Open Tracker Search Tool and search for this term")
+	def get_icon_name(self):
+		return "search"
+	def item_types(self):
+		yield TextLeaf
+
+
+class TrackerSearchHere (Action):
+	def __init__(self):
+		Action.__init__(self, _("Get Tracker Results..."))
+
+	def is_factory(self):
+		return True
+
+	def activate(self, leaf):
+		return TrackerQuerySource(leaf.object)
+
+	def get_description(self):
+		return _("Show Tracker results for query")
+	def get_icon_name(self):
+		return "tracker"
+	def item_types(self):
+		yield TextLeaf
+
+def is_ok_char(c):
+	return c.isalnum() or c == " "
+
+def get_file_results_sparql(searchobj, query, max_items):
+	# We don't have any real escape function for queries
+	# so we instead strip everything not alphanumeric
+	clean_query = u"".join([c for c in query if is_ok_char(c)])
+	sql = u"""SELECT tracker:coalesce (nie:url (?s), ?s)
+	          WHERE {  ?s fts:match "%s*" .  ?s tracker:available true . }
+			  ORDER BY tracker:weight(?s)
+			  OFFSET 0 LIMIT %d""" % (clean_query, int(max_items))
+
+	pretty.print_debug(__name__, "Searching for %s (%s)",
+			repr(clean_query), repr(query))
+	pretty.print_debug(__name__, sql)
+	results = searchobj.SparqlQuery(sql)
+
+	gio_File = gio.File
+	for result in results:
+		yield FileLeaf(gio_File(result[0]).get_path())
+
+def get_file_results_old(searchobj, query, max_items):
+	try:
+		file_hits = searchobj.Text(1, "Files", query, 0, max_items)
+	except dbus.DBusException, exc:
+		pretty.print_error(__name__, exc)
+		return
+
+	for filestr in file_hits:
+		# A bit of encoding carousel
+		# dbus strings are subclasses of unicode
+		# but FileLeaf expects a filesystem encoded object
+		bytes = filestr.decode("UTF-8", "replace")
+		filename = gobject.filename_from_utf8(bytes)
+		yield ConstructFileLeaf(filename)
+
+use_version = None
+versions = {
+	"0.8": (SERVICE1_NAME, SEARCH_OBJECT1_PATH, SEARCH1_INTERFACE),
+	"0.6": (SERVICE_NAME, SEARCH_OBJECT_PATH, SEARCH_INTERFACE),
+}
+
+version_query = {
+	"0.8": get_file_results_sparql,
+	"0.6": get_file_results_old,
+}
+
+
+def get_searchobject(sname, opath, sinface):
+	bus = dbus.SessionBus()
+	searchobj = None
+	try:
+		tobj = bus.get_object(sname, opath)
+		searchobj = dbus.Interface(tobj, sinface)
+	except dbus.DBusException, exc:
+		pretty.print_debug(__name__, exc)
+	return searchobj
+
+def get_tracker_filequery(query, max_items):
+	searchobj = None
+	global use_version
+	if use_version is None:
+		for version, (sname, opath, sinface) in versions.items():
+			pretty.print_debug(__name__, "Trying", sname, version)
+			searchobj = get_searchobject(sname, opath, sinface)
+			if searchobj is not None:
+				use_version = version
+				break
+	else:
+		searchobj = get_searchobject(*versions[use_version])
+	if searchobj is None:
+		use_version = None
+		pretty.print_error(__name__, "Could not connect to Tracker")
+		return ()
+
+	queryfunc = version_query[use_version]
+	return queryfunc(searchobj, query, max_items)
+
+class TrackerQuerySource (Source):
+	def __init__(self, query):
+		Source.__init__(self, name=_('Results for "%s"') % query)
+		self.query = query
+		self.max_items = 50
+
+	def repr_key(self):
+		return self.query
+
+	def get_items(self):
+		return get_tracker_filequery(self.query, self.max_items)
+
+	def get_description(self):
+		return _('Results for "%s"') % self.query
+	def get_icon_name(self):
+		return "tracker"
+
+	@classmethod
+	def decorates_type(cls):
+		return FileLeaf
+	@classmethod
+	def decorate_item(cls, leaf):
+		# FIXME: Very simplified .savedSearch parsing, so far we only support
+		# the query, without additional filtering. The simplest form of
+		# .savedSearch file is saved by nautilus as following:
+		# <query version="1.0">
+		#   <text>QUERY GOES HERE</text>
+		# </query>
+
+		if not leaf.object.endswith(".savedSearch"):
+			return None
+		try:
+			et = ElementTree(file=leaf.object)
+			query = et.getroot().find("text").text
+			return cls(query)
+		except Exception:
+			return None
+
+
+# FIXME: Port tracker tag sources and actions
+# to the new, much more powerful sparql + dbus API
+# (using tracker-tag as in 0.6 is a plain hack and a dead end)
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]