235 lines
7.8 KiB
JavaScript
235 lines
7.8 KiB
JavaScript
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
|
||
|
*
|
||
|
* Copyright (C) 2010 Seif Lotfy <seif@lotfy.com>
|
||
|
* Copyright (C) 2011 Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
|
||
|
* Copyright (C) 2010-2011 Collabora Ltd.
|
||
|
* Authored by: Seif Lotfy <seif@lotfy.com>
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation; either version 2, 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 General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||
|
* 02111-1307, USA.
|
||
|
*/
|
||
|
|
||
|
const DBus = imports.dbus;
|
||
|
|
||
|
const SIG_EVENT = '(asaasay)';
|
||
|
const MAX_TIMESTAMP = 9999999999999;
|
||
|
|
||
|
// Number of results given by fullTextSearch; 100 is probably enough.
|
||
|
// Note: We can't currently increase this number to anything above 132, due to
|
||
|
// https://bugs.launchpad.net/zeitgeist-extensions/+bug/716503
|
||
|
const MAX_RESULTS = 100;
|
||
|
|
||
|
const ResultType = {
|
||
|
// http://zeitgeist-project.com/docs/0.6/datamodel.html#resulttype
|
||
|
// We currently only use MOST_POPULAR_SUBJECTS
|
||
|
MOST_POPULAR_SUBJECTS: 4,
|
||
|
};
|
||
|
|
||
|
/* Zeitgeist Subjects (files, people, etc.) */
|
||
|
|
||
|
function Subject(uri, interpretation, manifestation, origin, mimetype, text, storage) {
|
||
|
this._init(uri, interpretation, manifestation, origin, mimetype, text, storage);
|
||
|
};
|
||
|
|
||
|
Subject.prototype = {
|
||
|
_init: function(uri, interpretation, manifestation, origin, mimetype, text, storage) {
|
||
|
this.uri = uri;
|
||
|
this.interpretation = interpretation;
|
||
|
this.manifestation = manifestation;
|
||
|
this.origin = origin;
|
||
|
this.mimetype = mimetype;
|
||
|
this.text = text;
|
||
|
this.storage = storage;
|
||
|
},
|
||
|
};
|
||
|
|
||
|
Subject.fromPlain = function(rawSubject) {
|
||
|
return new Subject(rawSubject[0], // uri
|
||
|
rawSubject[1], // interpretation
|
||
|
rawSubject[2], // manifestation
|
||
|
rawSubject[3], // origin
|
||
|
rawSubject[4], // mimetype
|
||
|
rawSubject[5], // text
|
||
|
rawSubject[6]); // storage
|
||
|
};
|
||
|
|
||
|
Subject.toPlain = function(subject) {
|
||
|
let rawSubject = [];
|
||
|
rawSubject[0] = subject.uri;
|
||
|
rawSubject[1] = subject.interpretation;
|
||
|
rawSubject[2] = subject.manifestation
|
||
|
rawSubject[3] = subject.origin;
|
||
|
rawSubject[4] = subject.mimetype;
|
||
|
rawSubject[5] = subject.text;
|
||
|
rawSubject[6] = subject.storage;
|
||
|
return rawSubject;
|
||
|
};
|
||
|
|
||
|
/* Zeitgeist Events */
|
||
|
|
||
|
function Event(interpretation, manifestation, actor, subjects, payload) {
|
||
|
this._init(interpretation, manifestation, actor, subjects, payload);
|
||
|
};
|
||
|
|
||
|
Event.prototype = {
|
||
|
_init: function(interpretation, manifestation, actor, subjects, payload) {
|
||
|
this.id = 0;
|
||
|
this.timestamp = 0;
|
||
|
this.actor = actor;
|
||
|
this.interpretation = interpretation;
|
||
|
this.manifestation = manifestation;
|
||
|
this.actor = actor;
|
||
|
this.payload = payload;
|
||
|
this.subjects = subjects;
|
||
|
},
|
||
|
};
|
||
|
|
||
|
Event.fromPlain = function(rawEvent) {
|
||
|
let subjects = rawEvent[1].map(Subject.fromPlain);
|
||
|
let event = new Event(rawEvent[0][2], // interpretation
|
||
|
rawEvent[0][3], // manifestation
|
||
|
rawEvent[0][4], // actor
|
||
|
subjects, // subjects
|
||
|
rawEvent[2]);// payload
|
||
|
event.id = rawEvent[0][0]; // id
|
||
|
event.timestamp = rawEvent[0][1]; // timestamp
|
||
|
return event;
|
||
|
};
|
||
|
|
||
|
Event.toPlain = function(event) {
|
||
|
let rawEvent = [];
|
||
|
rawEvent[0] = [];
|
||
|
rawEvent[0][0] = event.id.toString();
|
||
|
rawEvent[0][1] = event.timestamp.toString();
|
||
|
rawEvent[0][2] = event.interpretation;
|
||
|
rawEvent[0][3] = event.manifestation;
|
||
|
rawEvent[0][4] = event.actor;
|
||
|
rawEvent[1] = event.subjects.map(Subject.toPlain);
|
||
|
rawEvent[2] = event.payload;
|
||
|
return rawEvent;
|
||
|
};
|
||
|
|
||
|
// Zeitgeist D-Bus interface definitions. Note that most of these are
|
||
|
// incomplete, and only cover the methods/properties/signals that
|
||
|
// we're currently using.
|
||
|
|
||
|
/* Zeitgeist D-Bus Interface */
|
||
|
|
||
|
const LOG_NAME = 'org.gnome.zeitgeist.Engine';
|
||
|
const LOG_PATH = '/org/gnome/zeitgeist/log/activity';
|
||
|
const LogIface = {
|
||
|
name: 'org.gnome.zeitgeist.Log',
|
||
|
methods: [
|
||
|
{ name: 'GetEvents',
|
||
|
inSignature: 'au',
|
||
|
outSignature: 'a'+SIG_EVENT },
|
||
|
{ name: 'FindRelatedUris',
|
||
|
inSignature: 'au',
|
||
|
outSignature: '(xx)a(' + SIG_EVENT + ')a'+ SIG_EVENT + 'uuu' },
|
||
|
{ name: 'FindEventIds',
|
||
|
inSignature: '(xx)a' + SIG_EVENT + 'uuu',
|
||
|
outSignature: 'au' },
|
||
|
{ name: 'FindEvents',
|
||
|
inSignature: '(xx)a' + SIG_EVENT + 'uuu',
|
||
|
outSignature: 'a' + SIG_EVENT },
|
||
|
{ name: 'InsertEvents',
|
||
|
inSignature: 'a' + SIG_EVENT,
|
||
|
outSignature: 'au' },
|
||
|
{ name: 'DeleteEvents',
|
||
|
inSignature: 'au',
|
||
|
outSignature: '(xx)' },
|
||
|
{ name: 'DeleteLog',
|
||
|
inSignature: '',
|
||
|
outSignature: '' },
|
||
|
{ name: 'Quit',
|
||
|
inSignature: '',
|
||
|
outSignature: '' },
|
||
|
// FIXME: Add missing DBus Methods
|
||
|
// - InstallMonitor
|
||
|
// - RemoveMonitor
|
||
|
],
|
||
|
properties: [
|
||
|
{ name: 'Get',
|
||
|
inSignature: 'ss',
|
||
|
outSignature: 'v',
|
||
|
access: 'read' },
|
||
|
{ name: 'Set',
|
||
|
inSignature: 'ssv',
|
||
|
outSignature: '',
|
||
|
access: 'read' },
|
||
|
{ name: 'GetAll',
|
||
|
inSignature: 's',
|
||
|
outSignature: 'a{sv}',
|
||
|
access: 'read' },
|
||
|
]
|
||
|
};
|
||
|
|
||
|
const Log = DBus.makeProxyClass(LogIface);
|
||
|
const _log = new Log(DBus.session, LOG_NAME, LOG_PATH);
|
||
|
|
||
|
function findEvents(timeRange, eventTemplates, storageState, numEvents, resultType, callback) {
|
||
|
function handler(results, error) {
|
||
|
if (error != null)
|
||
|
log("Error querying Zeitgeist for events: "+error);
|
||
|
else
|
||
|
callback(results.map(Event.fromPlain));
|
||
|
}
|
||
|
_log.FindEventsRemote(timeRange, eventTemplates.map(Event.toPlain),
|
||
|
storageState, numEvents, resultType, handler);
|
||
|
}
|
||
|
|
||
|
/* Zeitgeist Full-Text-Search Interface */
|
||
|
|
||
|
const INDEX_NAME = 'org.gnome.zeitgeist.Engine';
|
||
|
const INDEX_PATH = '/org/gnome/zeitgeist/index/activity';
|
||
|
const IndexIface = {
|
||
|
name: 'org.gnome.zeitgeist.Index',
|
||
|
methods: [
|
||
|
{ name: 'Search',
|
||
|
inSignature: 's(xx)a'+SIG_EVENT+'uuu',
|
||
|
outSignature: 'a'+SIG_EVENT+'u' },
|
||
|
],
|
||
|
};
|
||
|
|
||
|
const Index = DBus.makeProxyClass(IndexIface);
|
||
|
const _index = new Index(DBus.session, INDEX_NAME, INDEX_PATH);
|
||
|
|
||
|
/**
|
||
|
* fullTextSearch:
|
||
|
*
|
||
|
* Asynchronously search Zeitgeist's index for events relating to the query.
|
||
|
*
|
||
|
* @param query The query string, using asterisks for wildcards. Wildcards must
|
||
|
* be used at the start and/or end of a string to get relevant information.
|
||
|
* @param eventTemplates Zeitgeist event templates, see
|
||
|
* http://zeitgeist-project.com/docs/0.6/datamodel.html#event for more
|
||
|
* information
|
||
|
* @param callback The callback, takes a list containing Zeitgeist.Event
|
||
|
* objects
|
||
|
*/
|
||
|
function fullTextSearch(query, eventTemplates, callback) {
|
||
|
function handler(results, error) {
|
||
|
if (error != null)
|
||
|
log("Error searching with Zeitgeist FTS: "+error);
|
||
|
else
|
||
|
callback(results[0].map(Event.fromPlain));
|
||
|
}
|
||
|
_index.SearchRemote(query, [0, MAX_TIMESTAMP],
|
||
|
eventTemplates.map(Event.toPlain),
|
||
|
0, // offset into the search results
|
||
|
MAX_RESULTS,
|
||
|
ResultType.MOST_POPULAR_SUBJECTS, handler);
|
||
|
}
|