[kupfer] Split tracker plugin into 'tracker' and 'tracker1' plugins
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer] Split tracker plugin into 'tracker' and 'tracker1' plugins
- Date: Thu, 29 Apr 2010 16:22:07 +0000 (UTC)
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]