# -.- coding: utf-8 -.- # Zeitgeist # # Copyright © 2011 Seif Lotfy # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 2.1 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # import os, sys import time import dbus import dbus.service import logging import gi from gi.repository import Tracker from zeitgeist.datamodel import Symbol, StorageState, ResultType, TimeRange, NULL_EVENT, NEGATION_OPERATOR from _zeitgeist.engine.datamodel import Event, Subject from _zeitgeist.engine.extension import Extension from _zeitgeist.engine import constants from zeitgeist.datamodel import Interpretation, Manifestation logging.basicConfig(level=logging.DEBUG) log = logging.getLogger("zeitgeist.tracker") TRACKER_DBUS_OBJECT_PATH = "/org/gnome/zeitgeist/tracker/activity" TRACKER_DBUS_INTERFACE = "org.gnome.zeitgeist.Tracker" # When sorting by of the COALESCING_RESULT_TYPES result types, # we need to fetch some extra events from the Xapian index because # the final result set will be coalesced on some property of the event COALESCING_RESULT_TYPES = [ \ ResultType.MostRecentSubjects, ResultType.LeastRecentSubjects, ResultType.MostPopularSubjects, ResultType.LeastPopularSubjects, ResultType.MostRecentActor, ResultType.LeastRecentActor, ResultType.MostPopularActor, ResultType.LeastPopularActor, ] class TrackerSearchExtension (Extension, dbus.service.Object): """ Full text indexing and searching extension for Zeitgeist """ PUBLIC_METHODS = [] def __init__ (self, engine): Extension.__init__(self, engine) dbus.service.Object.__init__(self, dbus.SessionBus(), TRACKER_DBUS_OBJECT_PATH) self.conn = Tracker.SparqlConnection.get (None) self._engine = engine @dbus.service.method(TRACKER_DBUS_INTERFACE, in_signature="s(xx)a("+constants.SIG_EVENT+")uuu", out_signature="a("+constants.SIG_EVENT+")u") def Search(self, query_string, time_range, filter_templates, offset, count, result_type): """ DBus method to perform a full text search against the contents of the Tracker. Returns an array of events. """ time_range = TimeRange(time_range[0], time_range[1]) filter_templates = map(Event, filter_templates) query = 'select nie:url(?urn) { ?urn a rdfs:Resource ; fts:match "%s*" }' %query_string cursor = self.conn.query (query, None) uris = [] new_templates = [] while (cursor.next (None)): uri = cursor.get_string (0)[0] uris.append(uri) events = self._engine.find_events(time_range, filter_templates, StorageState.Any, 1000, result_type) new_events = [] for event in events: for subject in event.subjects: if subject.uri in uris: new_events.append(event) return self._make_events_sendable(new_events), 0 def _make_events_sendable(self, events): for event in events: if event is not None: event._make_dbus_sendable() return [NULL_EVENT if event is None else event for event in events]