[tracker: 1/2] Refactoring of the Evolution push plugin
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker: 1/2] Refactoring of the Evolution push plugin
- Date: Thu, 24 Sep 2009 12:52:46 +0000 (UTC)
commit 0fe11f41708a6b4d872e409b2fc8a5a9bea625d4
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Sep 23 18:18:29 2009 +0200
Refactoring of the Evolution push plugin
src/libtracker-common/tracker-sparql-builder.vala | 6 +
src/plugins/evolution/Makefile.am | 52 +-
.../org.freedesktop.Tracker1.Miner.EMails.service | 2 +
src/plugins/evolution/tracker-evolution-common.h | 79 -
src/plugins/evolution/tracker-evolution-plugin.c | 1641 ++++++++++++--------
src/plugins/evolution/tracker-evolution-plugin.h | 11 +-
src/plugins/evolution/tracker-evolution-plugin.xml | 11 -
.../evolution/tracker-evolution-registrar.c | 902 -----------
.../evolution/tracker-evolution-registrar.h | 94 --
.../evolution/tracker-evolution-registrar.xml | 39 -
.../evolution/tracker-miner-emails.desktop.in | 6 +
11 files changed, 990 insertions(+), 1853 deletions(-)
---
diff --git a/src/libtracker-common/tracker-sparql-builder.vala b/src/libtracker-common/tracker-sparql-builder.vala
index bbcc077..530d5b3 100644
--- a/src/libtracker-common/tracker-sparql-builder.vala
+++ b/src/libtracker-common/tracker-sparql-builder.vala
@@ -45,6 +45,12 @@ public class Tracker.SparqlBuilder : Object {
states += State.UPDATE;
}
+ public void drop_graph (string iri)
+ requires (state == State.UPDATE)
+ {
+ str.append ("DROP GRAPH <%s>\n".printf (iri));
+ }
+
public void insert_open ()
requires (state == State.UPDATE)
{
diff --git a/src/plugins/evolution/Makefile.am b/src/plugins/evolution/Makefile.am
index 4a91918..50b08e4 100644
--- a/src/plugins/evolution/Makefile.am
+++ b/src/plugins/evolution/Makefile.am
@@ -11,6 +11,9 @@ INCLUDES = \
$(EVOLUTION_PLUGIN_CFLAGS) \
$(GCOV_CFLAGS)
+servicedir = $(DBUS_SERVICES_DIR)
+service_DATA = org.freedesktop.Tracker1.Miner.EMails.service
+
%.eplug.in: %.eplug.xml
LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@
@@ -28,55 +31,40 @@ eplugin_LTLIBRARIES = liborg-freedesktop-Tracker-evolution-plugin.la
module_flags = -module -avoid-version -no-undefined
-pushd_modulesdir = $(libdir)/tracker-$(TRACKER_API_VERSION)/push-modules/daemon
-
-pushd_modules_LTLIBRARIES = libtracker-module-evolution-daemon-module.la
-
-libtracker_module_evolution_daemon_module_la_SOURCES = \
- tracker-evolution-registrar.c \
- tracker-evolution-registrar.h \
- tracker-evolution-common.h \
- tracker-evolution-registrar-glue.h
-
-libtracker_module_evolution_daemon_module_la_LDFLAGS = $(module_flags)
-
-libtracker_module_evolution_daemon_module_la_LIBADD = \
- $(top_builddir)/src/libtracker-data/libtracker-data.la \
- $(top_builddir)/src/libtracker-db/libtracker-db.la \
- $(top_builddir)/src/libtracker-common/libtracker-common.la \
- $(GMODULE_LIBS) \
- $(DBUS_LIBS) \
- $(GTHREAD_LIBS) \
- $(GIO_LIBS) \
- $(GLIB2_LIBS) \
- $(GCOV_LIBS)
-
liborg_freedesktop_Tracker_evolution_plugin_la_SOURCES = \
tracker-evolution-plugin.c \
- tracker-evolution-plugin.h \
- tracker-evolution-common.h \
- tracker-evolution-plugin-glue.h
+ tracker-evolution-plugin.h
liborg_freedesktop_Tracker_evolution_plugin_la_LDFLAGS = -module -avoid-version
-liborg_freedesktop_Tracker_evolution_plugin_la_LDLIBS = \
+liborg_freedesktop_Tracker_evolution_plugin_la_LIBADD = \
+ $(top_builddir)/src/libtracker-client/libtracker-client- TRACKER_API_VERSION@.la \
+ $(top_builddir)/src/libtracker-common/libtracker-common.la \
+ $(top_builddir)/src/libtracker-miner/libtracker-miner.la \
$(EVOLUTION_PLUGIN_LIBS) \
$(DBUS_LIBS) \
$(GCOV_LIBS)
-dbus_sources = \
- tracker-evolution-plugin-glue.h \
- tracker-evolution-registrar-glue.h
+desktop_in_files = tracker-miner-emails.desktop.in
+
+tracker_minersdir = $(datadir)/tracker/miners
+
+tracker_miners_DATA = tracker-miner-emails.desktop
+
+ INTLTOOL_DESKTOP_RULE@
+
+EXTRA_DIST = $(desktop_in_files)
+CLEANFILES = $(tracker_miners_DATA)
+
%-glue.h: %.xml
$(DBUSBINDINGTOOL) --mode=glib-server --output=$@ --prefix=$(subst -,_,$*) $^
BUILT_SOURCES = \
- $(dbus_sources) \
$(eplugin_DATA)
CLEANFILES = \
$(BUILT_SOURCES) \
org-freedesktop-Tracker-evolution-plugin.eplug
-EXTRA_DIST = \
+EXTRA_DIST = $(service_DATA) \
org-freedesktop-Tracker-evolution-plugin.eplug.xml
diff --git a/src/plugins/evolution/org.freedesktop.Tracker1.Miner.EMails.service b/src/plugins/evolution/org.freedesktop.Tracker1.Miner.EMails.service
new file mode 100644
index 0000000..506c90d
--- /dev/null
+++ b/src/plugins/evolution/org.freedesktop.Tracker1.Miner.EMails.service
@@ -0,0 +1,2 @@
+[D-BUS Service]
+Name=org.freedesktop.Tracker1.Miner.EMails
diff --git a/src/plugins/evolution/tracker-evolution-plugin.c b/src/plugins/evolution/tracker-evolution-plugin.c
index c3a84fb..6871c20 100644
--- a/src/plugins/evolution/tracker-evolution-plugin.c
+++ b/src/plugins/evolution/tracker-evolution-plugin.c
@@ -44,6 +44,20 @@
#include <camel/camel-db.h>
#include <camel/camel-offline-store.h>
#include <camel/camel-session.h>
+#include <camel/camel-url.h>
+#include <camel/camel-stream.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-multipart.h>
+#include <camel/camel-multipart-encrypted.h>
+#include <camel/camel-multipart-signed.h>
+#include <camel/camel-medium.h>
+#include <camel/camel-gpg-context.h>
+#include <camel/camel-smime-context.h>
+#include <camel/camel-string-utils.h>
+#include <camel/camel-stream-filter.h>
+#include <camel/camel-stream-null.h>
+#include <camel/camel-mime-filter-charset.h>
+#include <camel/camel-mime-filter-windows.h>
#include <mail/mail-config.h>
#include <mail/mail-session.h>
@@ -55,8 +69,13 @@
#include <libedataserver/e-account.h>
#include <libedataserver/e-account-list.h>
+#include <libtracker-client/tracker.h>
+#include <libtracker-common/tracker-sparql-builder.h>
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-utils.h>
+#include <libtracker-common/tracker-type-utils.h>
+
#include "tracker-evolution-plugin.h"
-#include "tracker-evolution-plugin-glue.h"
/* This runs in-process of evolution (in the mailer, as a EPlugin). It has
* access to the CamelSession using the external variable 'session'. The header
@@ -69,9 +88,19 @@
* reads, never writes). We hope that's sufficient for not having to get our
* code involved in Camel's cruel inneryard of having to lock the db_r ptr. */
-#define MAX_BEFORE_SEND 2000
+#define MAX_BEFORE_SEND 50
+#define QUEUED_SETS_PER_MAINLOOP 100
+
+#define TRACKER_SERVICE "org.freedesktop.Tracker1"
-G_DEFINE_TYPE (TrackerEvolutionPlugin, tracker_evolution_plugin, G_TYPE_OBJECT)
+#define NIE_DATASOURCE TRACKER_NIE_PREFIX "DataSource"
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define NMO_PREFIX TRACKER_NMO_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+#define NAO_PREFIX TRACKER_NAO_PREFIX
+#define DATASOURCE_URN "urn:nepomuk:datasource:1cb1eb90-1241-11de-8c30-0800200c9a66"
+
+G_DEFINE_TYPE (TrackerEvolutionPlugin, tracker_evolution_plugin, TRACKER_TYPE_MINER)
#define TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_EVOLUTION_PLUGIN, TrackerEvolutionPluginPrivate))
@@ -91,10 +120,8 @@ G_DEFINE_TYPE (TrackerEvolutionPlugin, tracker_evolution_plugin, G_TYPE_OBJECT)
* during registration of accounts and folders). I know this is cruel. I know. */
typedef struct {
+ TrackerEvolutionPlugin *self; /* weak */
guint64 last_checkout;
- DBusGProxy *registrar;
- guint signal;
- gchar *sender;
} ClientRegistry;
typedef struct {
@@ -129,22 +156,39 @@ typedef struct {
} RegisterInfo;
typedef struct {
- DBusGConnection *connection;
- GHashTable *registrars;
GStaticRecMutex *mutex;
GHashTable *registered_folders;
GHashTable *cached_folders;
GHashTable *registered_stores;
GList *registered_clients;
EAccountList *accounts;
+ TrackerClient *client;
+ DBusGProxy *dbus_proxy;
+ DBusGConnection *connection;
+ time_t last_time;
+ gboolean resuming, paused;
+ guint total_popped, of_total;
} TrackerEvolutionPluginPrivate;
-enum {
- PROP_0,
- PROP_CONNECTION
-};
+typedef struct {
+ TrackerSparqlBuilder *sparql;
+ guint count;
+} QueuedSet;
+
+typedef struct {
+ IntroductionInfo *intro_info;
+ CamelStore *store;
+ CamelDB *cdb_r;
+ CamelFolderInfo *iter;
+} TryAgainInfo;
+
+typedef struct {
+ TrackerEvolutionPlugin *self;
+ gchar *account_uri;
+ CamelFolderInfo *iter;
+} GetFolderInfo;
-static DBusGProxy *dbus_proxy = NULL;
+static GQueue *many_queue = NULL;
static TrackerEvolutionPlugin *manager = NULL;
static GStaticRecMutex glock = G_STATIC_REC_MUTEX_INIT;
static guint register_count = 0;
@@ -153,33 +197,87 @@ static guint register_count = 0;
static void register_account (TrackerEvolutionPlugin *self, EAccount *account);
static void unregister_account (TrackerEvolutionPlugin *self, EAccount *account);
int e_plugin_lib_enable (EPluginLib *ep, int enable);
-static void metadata_set_many (TrackerEvolutionPlugin *self, GStrv subjects, GPtrArray *predicates, GPtrArray *values);
-static void metadata_unset_many (TrackerEvolutionPlugin *self, GStrv subjects);
-
+static void miner_started (TrackerMiner *miner);
+static void miner_stopped (TrackerMiner *miner);
+static void miner_paused (TrackerMiner *miner);
+static void miner_resumed (TrackerMiner *miner);
/* First a bunch of helper functions. */
-
-static GList *
-get_recipient_list (const gchar *str)
+#if 0
+static ssize_t
+camel_stream_format_text (CamelDataWrapper *dw, CamelStream *stream)
{
- GList *list = NULL;
- gchar **arr;
- gint i;
-
- if (!str) {
- return NULL;
+ CamelStreamFilter *filter_stream;
+ CamelMimeFilterCharset *filter;
+ const char *charset = "UTF-8"; /* I default to UTF-8, like it or not */
+ CamelMimeFilterWindows *windows = NULL;
+ ssize_t bytes = -1;
+
+ if (dw->mime_type && (charset = camel_content_type_param
+ (dw->mime_type, "charset")) &&
+ g_ascii_strncasecmp(charset, "iso-8859-", 9) == 0)
+ {
+ CamelStream *null;
+
+ /* Since a few Windows mailers like to claim they sent
+ * out iso-8859-# encoded text when they really sent
+ * out windows-cp125#, do some simple sanity checking
+ * before we move on... */
+
+ null = camel_stream_null_new();
+ filter_stream = camel_stream_filter_new_with_stream(null);
+ camel_object_unref(null);
+ windows = (CamelMimeFilterWindows *)camel_mime_filter_windows_new(charset);
+ camel_stream_filter_add (filter_stream, (CamelMimeFilter *)windows);
+ camel_data_wrapper_decode_to_stream (dw, (CamelStream *)filter_stream);
+ camel_stream_flush ((CamelStream *)filter_stream);
+ camel_object_unref (filter_stream);
+ charset = camel_mime_filter_windows_real_charset (windows);
}
- arr = g_strsplit (str, ",", -1);
+ filter_stream = camel_stream_filter_new_with_stream (stream);
- for (i = 0; arr[i]; i++) {
- g_strstrip (arr[i]);
- list = g_list_prepend (list, g_strdup (arr[i]));
+ if ((filter = camel_mime_filter_charset_new_convert (charset, "UTF-8"))) {
+ camel_stream_filter_add (filter_stream, (CamelMimeFilter *) filter);
+ camel_object_unref (filter);
}
- g_strfreev (arr);
+ bytes = camel_data_wrapper_decode_to_stream (dw, (CamelStream *)filter_stream);
+ camel_stream_flush ((CamelStream *)filter_stream);
+ camel_object_unref (filter_stream);
+
+ if (windows)
+ camel_object_unref(windows);
- return g_list_reverse (list);
+ return bytes;
+}
+
+#endif
+
+static void
+get_email_and_fullname (const gchar *line, gchar **email, gchar **fullname)
+{
+ gchar *ptr = g_utf8_strchr (line, -1, '<');
+
+ if (ptr) {
+ gchar *holder;
+
+ holder = g_strdup (line);
+ ptr = g_utf8_strchr (holder, -1, '<');
+ *ptr = '\0';
+ ptr++;
+ *fullname = holder;
+ holder = ptr;
+ ptr = g_utf8_strchr (ptr, -1, '>');
+ if (ptr) {
+ *ptr = '\0';
+ }
+ *email = g_strdup (holder);
+
+ } else {
+ *email = g_strdup (line);
+ *fullname = NULL;
+ }
}
static void
@@ -210,92 +308,244 @@ folder_registry_new (const gchar *account_uri,
}
static void
-process_fields (GPtrArray *predicates_temp,
- GPtrArray *values_temp,
- gchar *uid,
- guint flags,
- gchar *sent,
- gchar *subject,
- gchar *from,
- gchar *to,
- gchar *cc,
- gchar *size,
- CamelFolder *folder)
+on_replied (GError *error, gpointer user_data)
+{
+ g_object_unref (user_data);
+}
+
+static void
+send_sparql_update (TrackerEvolutionPlugin *self, const gchar *sparql)
{
- GList *list, *l;
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_UID));
- g_ptr_array_add (values_temp, g_strdup (uid));
+ if (priv->client) {
+ tracker_resources_batch_sparql_update_async (priv->client, sparql,
+ on_replied,
+ g_object_ref (self));
+ }
+}
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_SEEN));
- g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_SEEN) ? "True" : "False"));
+static void
+send_sparql_commit (TrackerEvolutionPlugin *self, gboolean update)
+{
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_JUNK));
- g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_JUNK) ? "True" : "False"));
+ if (priv->client) {
+ if (update) {
+ gchar *date_s = tracker_date_to_string (time (NULL));
+ gchar *update = g_strdup_printf ("DELETE { <" DATASOURCE_URN "> nie:contentLastModified ?d } "
+ "WHERE { <" DATASOURCE_URN "> a nie:InformationElement ; nie:contentLastModified ?d } \n"
+ "INSERT { <" DATASOURCE_URN "> nie:contentLastModified \"%s\" }",
+ date_s);
+ g_free (date_s);
+ tracker_resources_batch_sparql_update_async (priv->client, update,
+ on_replied,
+ g_object_ref (self));
+
+ g_free (update);
+ }
+
+ tracker_resources_batch_commit_async (priv->client, on_replied,
+ g_object_ref (self));
+ }
+}
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_DELETED));
- g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_DELETED) ? "True" : "False"));
+static void
+add_contact (TrackerSparqlBuilder *sparql, const gchar *predicate, const gchar *uri, const gchar *value)
+{
+ gchar *email_uri, *email = NULL, *fullname = NULL;
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_ANSWERED));
- g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_ANSWERED) ? "True" : "False"));
+ get_email_and_fullname (value, &email, &fullname);
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_FLAGGED));
- g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_FLAGGED) ? "True" : "False"));
+ email_uri = tracker_uri_printf_escaped ("mailto:%s", email);
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_FORWARDED));
- g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_FORWARDED) ? "True" : "False"));
+ tracker_sparql_builder_subject_iri (sparql, email_uri);
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object (sparql, "nco:EmailAddress");
+ tracker_sparql_builder_subject_iri (sparql, email_uri);
+ tracker_sparql_builder_predicate (sparql, "nco:emailAddress");
+ tracker_sparql_builder_object_string (sparql, email);
- if (subject && g_utf8_validate (subject, -1, NULL)) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_SUBJECT));
- g_ptr_array_add (values_temp, g_strdup (subject));
+ tracker_sparql_builder_subject_iri (sparql, uri);
+ tracker_sparql_builder_predicate (sparql, predicate);
+
+ tracker_sparql_builder_object_blank_open (sparql);
+
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object (sparql, "nco:Contact");
+
+ if (fullname) {
+ tracker_sparql_builder_predicate (sparql, "nco:fullname");
+ tracker_sparql_builder_object_string (sparql, fullname);
+ g_free (fullname);
}
- list = get_recipient_list (to);
- for (l = list; l; l = l->next) {
- if (l->data && g_utf8_validate (l->data, -1, NULL)) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TO));
- g_ptr_array_add (values_temp, l->data);
- } else
- g_free (l->data);
+ tracker_sparql_builder_predicate (sparql, "nco:hasEmailAddress");
+ tracker_sparql_builder_object_iri (sparql, email_uri);
+
+ tracker_sparql_builder_object_blank_close (sparql);
+
+ g_free (email_uri);
+ g_free (email);
+}
+
+static void
+process_fields (TrackerSparqlBuilder *sparql, const gchar *uid, guint flags,
+ time_t sent, const gchar *subject, const gchar *from, const gchar *to,
+ const gchar *cc, const gchar *size, CamelFolder *folder, const gchar *uri)
+{
+ gchar **arr;
+ guint i;
+
+ tracker_sparql_builder_subject_iri (sparql, DATASOURCE_URN);
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object_iri (sparql, NIE_DATASOURCE);
+
+ /* for contentLastModified */
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object (sparql, "nie:InformationElement");
+
+ tracker_sparql_builder_subject_iri (sparql, uri);
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object (sparql, "nmo:Email");
+
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object (sparql, "nmo:MailboxDataObject");
+
+ tracker_sparql_builder_predicate (sparql, "tracker:available");
+ tracker_sparql_builder_object_boolean (sparql, TRUE);
+
+ /* The URI of the InformationElement should be a UUID URN */
+ tracker_sparql_builder_predicate (sparql, "nie:isStoredAs");
+ tracker_sparql_builder_object_iri (sparql, uri);
+
+ tracker_sparql_builder_predicate (sparql, "nie:dataSource");
+ tracker_sparql_builder_object_iri (sparql, DATASOURCE_URN);
+
+ if (size && g_utf8_validate (size, -1, NULL)) {
+ tracker_sparql_builder_predicate (sparql, "nie:byteSize");
+ tracker_sparql_builder_object_string (sparql, size);
}
- g_list_free (list);
- if (from && g_utf8_validate (from, -1, NULL)) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_FROM));
- g_ptr_array_add (values_temp, g_strdup (from));
+ if (subject && g_utf8_validate (subject, -1, NULL)) {
+ tracker_sparql_builder_predicate (sparql, "nmo:messageSubject");
+ tracker_sparql_builder_object_string (sparql, subject);
}
- if (size && g_utf8_validate (size, -1, NULL)) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_SIZE));
- g_ptr_array_add (values_temp, g_strdup (size));
+ tracker_sparql_builder_predicate (sparql, "nmo:receivedDate");
+ tracker_sparql_builder_object_date (sparql, &sent);
+
+ tracker_sparql_builder_predicate (sparql, "nmo:isDeleted");
+ tracker_sparql_builder_object_boolean (sparql, (flags & CAMEL_MESSAGE_DELETED));
+
+ tracker_sparql_builder_predicate (sparql, "nmo:isAnswered");
+ tracker_sparql_builder_object_boolean (sparql, (flags & CAMEL_MESSAGE_ANSWERED));
+
+ tracker_sparql_builder_predicate (sparql, "nmo:isFlagged");
+ tracker_sparql_builder_object_boolean (sparql, (flags & CAMEL_MESSAGE_FLAGGED));
+
+ tracker_sparql_builder_predicate (sparql, "nmo:isRead");
+ tracker_sparql_builder_object_boolean (sparql, (flags & CAMEL_MESSAGE_SEEN));
+
+ /*
+ g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_UID));
+ g_ptr_array_add (values_temp, g_strdup (uid));
+
+ g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_JUNK));
+ g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_JUNK) ? "True" : "False"));
+
+ g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_FORWARDED));
+ g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_FORWARDED) ? "True" : "False"));
+ */
+
+ if (to && (arr = g_strsplit (to, ",", -1)) != NULL) {
+ for (i = 0; arr[i]; i++) {
+ g_strstrip (arr[i]);
+
+ if (g_utf8_validate (arr[i], -1, NULL)) {
+ add_contact (sparql, "nmo:to", uri, arr[i]);
+ }
+ }
+ g_strfreev (arr);
}
- list = get_recipient_list (cc);
- for (l = list; l; l = l->next) {
- if (l->data && g_utf8_validate (l->data, -1, NULL)) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_CC));
- g_ptr_array_add (values_temp, l->data);
- } else
- g_free (l->data);
+ if (from && g_utf8_validate (from, -1, NULL)) {
+ add_contact (sparql, "nmo:from", uri, from);
}
- g_list_free (list);
- if (sent && g_utf8_validate (sent, -1, NULL)) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_SENT));
- g_ptr_array_add (values_temp, g_strdup (sent));
+ if (cc && (arr = g_strsplit (cc, ",", -1)) != NULL) {
+ for (i = 0; arr[i]; i++) {
+ g_strstrip (arr[i]);
+ if (g_utf8_validate (arr[i], -1, NULL)) {
+ add_contact (sparql, "nmo:cc", uri, arr[i]);
+ }
+ }
+ g_strfreev (arr);
}
+#if 0
+ /* This massively slows down Evolution, we need to do this in a queue
+ * instead. Therefore I'm disabling this code for now. The code does
+ * a parse of each already-once-downloaded E-mail. This is obviously
+ * excessive and expensive for the performance of Evolution. */
+
if (folder) {
gchar *filen = camel_folder_get_filename (folder, uid, NULL);
if (filen) {
if (g_file_test (filen, G_FILE_TEST_EXISTS)) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_FILE));
- g_ptr_array_add (values_temp, filen);
- } else
- g_free (filen);
+ CamelMimeMessage *mime = camel_folder_get_message (folder, uid, NULL);
+ if (mime) {
+ CamelDataWrapper *containee;
+ containee = camel_medium_get_content_object (CAMEL_MEDIUM (mime));
+
+ if (CAMEL_IS_MULTIPART (containee)) {
+ guint i, parts = camel_multipart_get_number (CAMEL_MULTIPART (containee));
+ for (i = 0; i < parts; i++) {
+ CamelMimePart *tpart = camel_multipart_get_part (CAMEL_MULTIPART (containee), i);
+ CamelContentType *type;
+
+ type = camel_mime_part_get_content_type (tpart);
+ if (camel_content_type_is (type, "text", "*")) {
+ CamelStream *stream = camel_stream_mem_new ();
+ CamelDataWrapper *wrapper;
+ CamelStreamMem *mem = (CamelStreamMem *) stream;
+ gssize bytes = -1;
+
+ wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (tpart));
+ if (!wrapper) {
+ wrapper = camel_data_wrapper_new ();
+ camel_medium_set_content_object (CAMEL_MEDIUM (tpart), wrapper);
+ camel_object_unref (wrapper);
+ }
+
+ if (wrapper->stream) {
+ camel_stream_reset (wrapper->stream);
+
+ if (camel_content_type_is (wrapper->mime_type, "text", "plain"))
+ bytes = camel_stream_format_text (wrapper, stream);
+ else
+ bytes = camel_data_wrapper_decode_to_stream (wrapper, stream);
+
+ /* The validate check always fails for me, don't know why yet */
+ if (bytes > 0 && g_utf8_validate ((gchar *) mem->buffer->data, -1, NULL)) {
+ tracker_sparql_builder_subject_iri (sparql, uri);
+ tracker_sparql_builder_predicate (sparql, "nie:plainTextContent");
+ tracker_sparql_builder_object_string (sparql, (gchar *) mem->buffer->data);
+ }
+ }
+
+ camel_object_unref (stream);
+ }
+ }
+ }
+ camel_object_unref (mime);
+ }
+ }
+ g_free (filen);
}
}
+#endif
}
/* When new messages arrive to- or got deleted from the summary, called in
@@ -310,7 +560,6 @@ on_folder_summary_changed (CamelFolder *folder,
gpointer user_data)
{
OnSummaryChangedInfo *info = user_data;
- TrackerEvolutionPlugin *self = info->self;
CamelFolderSummary *summary;
gchar *account_uri = info->account_uri;
GPtrArray *merged;
@@ -328,17 +577,19 @@ on_folder_summary_changed (CamelFolder *folder,
/* the uid_added member contains the added-to-the-summary items */
if (changes->uid_added && changes->uid_added->len > 0) {
- for (i = 0; i < changes->uid_added->len; i++)
+ for (i = 0; i < changes->uid_added->len; i++) {
g_ptr_array_add (merged, changes->uid_added->pdata[i]);
+ }
}
/* the uid_changed member contains the changed-in-the-summary items */
if (changes->uid_changed && changes->uid_changed->len > 0) {
- gboolean found = FALSE;
guint y;
for (i = 0; i < changes->uid_changed->len; i++) {
+ gboolean found = FALSE;
+
for (y = 0; y < merged->len; y++) {
if (strcmp (merged->pdata[y], changes->uid_changed->pdata[i]) == 0) {
found = TRUE;
@@ -346,117 +597,120 @@ on_folder_summary_changed (CamelFolder *folder,
}
}
- if (!found)
+ if (!found) {
g_ptr_array_add (merged, changes->uid_changed->pdata[i]);
+ }
}
}
- if (merged->len > 0) {
- GPtrArray *predicates_array = g_ptr_array_new ();
- GPtrArray *values_array = g_ptr_array_new ();
- gchar **subjects = (gchar **) g_malloc0 (sizeof (gchar *) * merged->len + 1);
- guint y;
+ for (i = 0; i< merged->len; i++) {
+ const gchar *subject, *to, *from, *cc, *uid = NULL;
+ gchar *size;
+ time_t sent;
+ guint flags;
+ CamelMessageInfo *linfo;
+ const CamelTag *ctags;
+ const CamelFlag *cflags;
- y = 0;
+ linfo = camel_folder_summary_uid (summary, merged->pdata[i]);
- for (i = 0; i< merged->len; i++) {
- gchar *subject, *to, *from, *cc, *uid = NULL, *sent, *size;
- guint flags;
- gchar **values, **predicates;
- CamelMessageInfo *linfo;
- GPtrArray *values_temp = g_ptr_array_new ();
- GPtrArray *predicates_temp = g_ptr_array_new ();
- const CamelTag *ctags;
- const CamelFlag *cflags;
+ if (linfo) {
+ uid = (gchar *) camel_message_info_uid (linfo);
+ }
- linfo = camel_folder_summary_uid (summary, merged->pdata[i]);
+ if (linfo && uid) {
+ gchar *uri;
+ TrackerSparqlBuilder *sparql;
- if (linfo)
- uid = (gchar *) camel_message_info_uid (linfo);
+ subject = camel_message_info_subject (linfo);
+ to = camel_message_info_to (linfo);
+ from = camel_message_info_from (linfo);
+ cc = camel_message_info_cc (linfo);
+ flags = (guint) camel_message_info_flags (linfo);
- if (linfo && uid) {
- guint j, max;
+ /* Camel returns a time_t, I think a uint64 is the best fit here */
+ sent = camel_message_info_date_sent (linfo);
- subject = (gchar *) camel_message_info_subject (linfo);
- to = (gchar *) camel_message_info_to (linfo);
- from = (gchar *) camel_message_info_from (linfo);
- cc = (gchar *) camel_message_info_cc (linfo);
- flags = (guint) camel_message_info_flags (linfo);
+ /* Camel returns a uint32, so %u */
+ size = g_strdup_printf ("%u", camel_message_info_size (linfo));
- /* Camel returns a time_t, I think a uint64 is the best fit here */
- sent = g_strdup_printf ("%"G_GUINT64_FORMAT, (guint64) camel_message_info_date_sent (linfo));
+ /* This is not a path but a URI, don't use the
+ * OS's directory separator here */
- /* Camel returns a uint32, so %u */
- size = g_strdup_printf ("%u", camel_message_info_size (linfo));
+ uri = g_strdup_printf ("%s%s/%s",
+ em_uri,
+ camel_folder_get_full_name (folder),
+ uid);
- process_fields (predicates_temp, values_temp, uid,
- flags, sent, subject, from, to, cc,
- size, folder);
+ sparql = tracker_sparql_builder_new_update ();
- cflags = camel_message_info_user_flags (linfo);
- while (cflags) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
- g_ptr_array_add (values_temp, g_strdup_printf ("%s=True", cflags->name));
- cflags = cflags->next;
- }
+ tracker_sparql_builder_drop_graph (sparql, uri);
- ctags = camel_message_info_user_tags (linfo);
- while (ctags) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
- g_ptr_array_add (values_temp, g_strdup_printf ("%s=%s", ctags->name, ctags->value));
- ctags = ctags->next;
- }
+ tracker_sparql_builder_insert_open (sparql);
- if (values_temp->len != predicates_temp->len)
- g_critical ("values_temp->len != predicates_temp->len");
+ process_fields (sparql, uid, flags, sent, subject,
+ from, to, cc, size, folder, uri);
- max = MIN (values_temp->len, predicates_temp->len);
+ cflags = camel_message_info_user_flags (linfo);
+ while (cflags) {
+ tracker_sparql_builder_subject_iri (sparql, uri);
- values = (gchar **) g_malloc0 (sizeof (gchar*) * max + 1);
- predicates = (gchar **) g_malloc0 (sizeof (gchar*) * max + 1);
+ tracker_sparql_builder_predicate (sparql, "nao:hasTag");
+ tracker_sparql_builder_object_blank_open (sparql);
- for (j = 0; j < max; j++) {
- predicates[j] = predicates_temp->pdata[j];
- values[j] = values_temp->pdata[j];
- }
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object (sparql, "nao:Tag");
+
+ tracker_sparql_builder_predicate (sparql, "nao:prefLabel");
+ tracker_sparql_builder_object_string (sparql, cflags->name);
+ tracker_sparql_builder_object_blank_close (sparql);
- predicates[j] = NULL;
- values[j] = NULL;
+ cflags = cflags->next;
+ }
- g_ptr_array_add (values_array, values);
- g_ptr_array_add (predicates_array, predicates);
+ ctags = camel_message_info_user_tags (linfo);
+ while (ctags) {
+ tracker_sparql_builder_subject_iri (sparql, uri);
- /* This is not a path but a URI, don't use the
- * OS's directory separator here */
+ tracker_sparql_builder_predicate (sparql, "nao:hasProperty");
+ tracker_sparql_builder_object_blank_open (sparql);
- subjects[y] = g_strdup_printf ("%s%s/%s",
- em_uri,
- camel_folder_get_full_name (folder),
- uid);
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object (sparql, "nao:Property");
- g_ptr_array_free (predicates_temp, TRUE);
- g_ptr_array_free (values_temp, TRUE);
+ tracker_sparql_builder_predicate (sparql, "nao:propertyName");
+ tracker_sparql_builder_object_string (sparql, ctags->name);
+
+ tracker_sparql_builder_predicate (sparql, "nao:propertyValue");
+ tracker_sparql_builder_object_string (sparql, ctags->value);
- y++;
+ tracker_sparql_builder_object_blank_close (sparql);
+ ctags = ctags->next;
}
- if (linfo)
- camel_message_info_free (linfo);
- }
+ tracker_sparql_builder_insert_close (sparql);
+
+ send_sparql_update (info->self, tracker_sparql_builder_get_result (sparql));
+
+/*
+ I saw a crash here, can't figure out why, it was
+ in strcmp of g_object_set (maybe multi-threading
+ of Camel is involved?)
- subjects[y] = NULL;
+ g_object_set (info->self, "progress",
+ (gdouble) (merged->len - i) / merged->len,
+ "status", _("Updating"),
+ NULL);
+*/
- /* This goes to all currently registered registrars */
+ g_object_unref (sparql);
- metadata_set_many (self, subjects, predicates_array, values_array);
+ g_free (size);
+ g_free (uri);
+ }
- g_strfreev (subjects);
- for (i = 0; i < values_array->len; i++)
- g_strfreev (values_array->pdata[i]);
- g_ptr_array_free (values_array, TRUE);
- for (i = 0; i < predicates_array->len; i++)
- g_strfreev (predicates_array->pdata[i]);
- g_ptr_array_free (predicates_array, TRUE);
+ if (linfo)
+ camel_message_info_free (linfo);
}
g_ptr_array_free (merged, TRUE);
@@ -464,67 +718,63 @@ on_folder_summary_changed (CamelFolder *folder,
/* the uid_removed member contains the removed-from-the-summary items */
if (changes->uid_removed && changes->uid_removed->len > 0) {
- gchar **subjects = (gchar **) g_malloc0 (sizeof (gchar *) * changes->uid_removed->len + 1);
+ GString *sparql = g_string_new ("DELETE { \n");
for (i = 0; i< changes->uid_removed->len; i++) {
/* This is not a path but a URI, don't use the OS's
* directory separator here */
- subjects[i] = g_strdup_printf ("%s%s/%s", em_uri,
- camel_folder_get_full_name (folder),
- (char*) changes->uid_removed->pdata[i]);
+ g_string_append_printf (sparql, "\t<%s%s/%s> a rdfs:Resource . \n",
+ em_uri,
+ camel_folder_get_full_name (folder),
+ (char*) changes->uid_removed->pdata[i]);
}
- subjects[i] = NULL;
+ g_string_append_c (sparql, '}');
- /* This goes to all currently registered registrars */
+ send_sparql_update (info->self, sparql->str);
+ g_string_free (sparql, TRUE);
+ }
- metadata_unset_many (self, subjects);
+ send_sparql_commit (info->self, TRUE);
+
+ /* g_object_set (info->self, "progress",
+ 1.0, NULL); */
- g_strfreev (subjects);
- }
g_free (em_uri);
}
/* Info about this many_queue can be found in introduce_walk_folders_in_folder */
-#define QUEUED_SETS_PER_MAINLOOP 2
-
-typedef struct {
- GStrv subjects;
- GPtrArray *values_array;
- GPtrArray *predicates_array;
- DBusGProxy *registrar;
- TrackerEvolutionPlugin *self;
- gchar *sender;
-} QueuedSet;
-
-static GQueue *many_queue = NULL;
-
static void
queued_set_free (QueuedSet *queued_set)
{
- guint i;
+ g_object_unref (queued_set->sparql);
+ g_slice_free (QueuedSet, queued_set);
+}
- g_strfreev (queued_set->subjects);
- for (i = 0; i < queued_set->values_array->len; i++)
- g_strfreev (queued_set->values_array->pdata[i]);
- g_ptr_array_free (queued_set->values_array, TRUE);
- for (i = 0; i < queued_set->predicates_array->len; i++)
- g_strfreev (queued_set->predicates_array->pdata[i]);
- g_ptr_array_free (queued_set->predicates_array, TRUE);
- g_object_unref (queued_set->registrar);
- g_object_unref (queued_set->self);
- g_free (queued_set->sender);
+static void
+clean_many_queue (void)
+{
+ gint i;
- g_slice_free (QueuedSet, queued_set);
+ if (!many_queue) {
+ return;
+ }
+
+ for (i = 0; i < many_queue->length; i++) {
+ QueuedSet *remove_candidate;
+ remove_candidate = g_queue_peek_nth (many_queue, i);
+ queued_set_free (g_queue_pop_nth (many_queue, i));
+ }
}
static gboolean
many_idle_handler (gpointer user_data)
{
- QueuedSet *queued_set;
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (user_data);
+ QueuedSet *queued_set = NULL;
gint popped;
g_return_val_if_fail (QUEUED_SETS_PER_MAINLOOP > 0, FALSE);
@@ -536,9 +786,7 @@ many_idle_handler (gpointer user_data)
for (queued_set = g_queue_pop_head (many_queue), popped = 1;
queued_set != NULL && popped < QUEUED_SETS_PER_MAINLOOP;
queued_set = g_queue_pop_head (many_queue), popped++) {
- TrackerEvolutionPlugin *self = queued_set->self;
- TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
-
+
/* During initial introduction the client-registrar might
* decide to crash, disconnect, stop listening. That
* would result in critical warnings so we start ignoring
@@ -547,72 +795,79 @@ many_idle_handler (gpointer user_data)
* We nonetheless need to handle these items to clean up
* the queue properly, of course. */
- if (priv->registrars && g_hash_table_lookup (priv->registrars, queued_set->sender)) {
- dbus_g_proxy_call_no_reply (queued_set->registrar,
- "SetMany",
- G_TYPE_STRV, queued_set->subjects,
- TRACKER_TYPE_G_STRV_ARRAY, queued_set->predicates_array,
- TRACKER_TYPE_G_STRV_ARRAY, queued_set->values_array,
- G_TYPE_UINT, (guint) time (NULL),
- G_TYPE_INVALID,
- G_TYPE_INVALID);
+ if (priv->client) {
+ const gchar *query;
+
+ query = tracker_sparql_builder_get_result (queued_set->sparql);
+
+ priv->total_popped++;
+
+ if (priv->total_popped > priv->of_total) {
+ priv->total_popped = priv->of_total;
+ }
+
+ g_object_set (user_data, "progress",
+ (gdouble) (priv->of_total - priv->total_popped) / priv->of_total,
+ "status", _("Updating"),
+ NULL);
+
+ send_sparql_update (user_data, query);
} else {
- gint i;
-
/* Performance improvement: remove all that had
* this disconnected registrar from the queue */
-
- for (i = 0; i < many_queue->length; i++) {
- QueuedSet *remove_candidate;
-
- remove_candidate = g_queue_peek_nth (many_queue, i);
-
- if (remove_candidate->registrar == queued_set->registrar) {
- queued_set_free (g_queue_pop_nth (many_queue, i));
- }
- }
+
+ g_object_set (user_data, "progress",
+ 1.0, NULL);
+
+ clean_many_queue ();
}
-
+
queued_set_free (queued_set);
}
+ if (!queued_set) {
+ send_sparql_commit (user_data, TRUE);
+ g_object_set (user_data, "progress",
+ 1.0, NULL);
+ }
+
return queued_set ? TRUE : FALSE;
}
static void
many_idle_destroy (gpointer user_data)
{
+ g_object_unref (user_data);
g_queue_free (many_queue);
many_queue = NULL;
}
static void
-start_many_handler (void)
+start_many_handler (TrackerEvolutionPlugin *self)
{
- /* We just slow it down to 'once per second' (for now, we can tweak this
- * afterward, of course, but once per second seems to work great) */
g_idle_add_full (G_PRIORITY_LOW,
- many_idle_handler,
- NULL,
- many_idle_destroy);
+ many_idle_handler,
+ g_object_ref (self),
+ many_idle_destroy);
}
/* Initial upload of more recent than last_checkout items, called in the mainloop */
static void
introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
- CamelFolderInfo *iter,
- CamelStore *store, CamelDB *cdb_r,
- gchar *account_uri,
- ClientRegistry *info)
+ CamelFolderInfo *iter,
+ CamelStore *store, CamelDB *cdb_r,
+ gchar *account_uri,
+ ClientRegistry *info)
{
TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
gchar *em_uri = em_uri_from_camel (account_uri);
while (iter) {
- guint i, ret = SQLITE_OK;
+ guint ret = SQLITE_OK;
gchar *query;
sqlite3_stmt *stmt = NULL;
gboolean more = TRUE;
+ TrackerSparqlBuilder *sparql = NULL;
/* This query is the culprint of the functionality: it fetches
* all the metadata from the summary table where modified is
@@ -627,6 +882,11 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
* allows this 'modseq' optimization (is in fact recommending
* it over using Cleanup() each time) */
+ /* TODO: add bodystructure and then prepare a full MIME structure
+ * using the NMO ontology, by parsing the bodystructure.
+ * Bodystructures can be found in %s_bodystructure when they
+ * exist (not guaranteed). In IMAP BODYSTRUCTURE format. */
+
query = sqlite3_mprintf ("SELECT uid, flags, read, deleted, " /* 0 - 3 */
"replied, important, junk, attachment, " /* 4 - 7 */
"size, dsent, dreceived, subject, " /* 8 - 11 */
@@ -642,16 +902,13 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
ret = sqlite3_prepare_v2 (cdb_r->db, query, -1, &stmt, NULL);
while (more) {
- GPtrArray *subjects_a = g_ptr_array_new ();
- GPtrArray *predicates_array = g_ptr_array_new ();
- GPtrArray *values_array = g_ptr_array_new ();
guint count = 0;
more = FALSE;
while (ret == SQLITE_OK || ret == SQLITE_BUSY || ret == SQLITE_ROW) {
- gchar **values, **predicates;
- gchar *subject, *to, *from, *cc, *sent, *uid, *size;
+ gchar *subject, *to, *from, *cc, *uid, *size;
+ time_t sent;
gchar *part, *label, *p;
guint flags;
@@ -670,14 +927,14 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
uid = (gchar *) sqlite3_column_text (stmt, 0);
if (uid) {
- GPtrArray *predicates_temp = g_ptr_array_new ();
- GPtrArray *values_temp = g_ptr_array_new ();
CamelFolder *folder;
guint max = 0, j;
+ gchar *uri;
+ gboolean opened = FALSE;
flags = (guint ) sqlite3_column_int (stmt, 1);
size = (gchar *) sqlite3_column_text (stmt, 8);
- sent = (gchar *) sqlite3_column_text (stmt, 9);
+ sent = (time_t) sqlite3_column_int64 (stmt, 9);
subject = (gchar *) sqlite3_column_text (stmt, 11);
from = (gchar *) sqlite3_column_text (stmt, 12);
to = (gchar *) sqlite3_column_text (stmt, 13);
@@ -687,8 +944,20 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
folder = g_hash_table_lookup (priv->cached_folders, iter->full_name);
- process_fields (predicates_temp, values_temp, uid, flags, sent,
- subject, from, to, cc, size, folder);
+ uri = g_strdup_printf ("%s%s/%s", em_uri,
+ iter->full_name, uid);
+
+ if (!sparql) {
+ sparql = tracker_sparql_builder_new_update ();
+ }
+
+ tracker_sparql_builder_drop_graph (sparql, uri);
+
+ tracker_sparql_builder_insert_open (sparql);
+
+ process_fields (sparql, uid, flags, sent,
+ subject, from, to, cc, size,
+ folder, uri);
g_static_rec_mutex_unlock (priv->mutex);
@@ -700,13 +969,24 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
if (part[j] == ' ') {
part[j] = 0;
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
- g_ptr_array_add (values_temp, g_strdup_printf ("%s=True", label));
+
+ if (!opened) {
+ tracker_sparql_builder_subject_iri (sparql, uri);
+ opened = TRUE;
+ }
+
+ tracker_sparql_builder_predicate (sparql, "nao:hasTag");
+ tracker_sparql_builder_object_blank_open (sparql);
+
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object (sparql, "nao:Tag");
+
+ tracker_sparql_builder_predicate (sparql, "nao:prefLabel");
+ tracker_sparql_builder_object_string (sparql, label);
+ tracker_sparql_builder_object_blank_close (sparql);
label = &(part[j+1]);
}
}
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
- g_ptr_array_add (values_temp, g_strdup (label));
}
g_free (p);
@@ -720,41 +1000,32 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
EXTRACT_STRING (value)
if (name && g_utf8_validate (name, -1, NULL) &&
value && g_utf8_validate (value, -1, NULL)) {
- g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
- g_ptr_array_add (values_temp, g_strdup_printf ("%s=%s", name, value));
- }
- g_free(name);
- g_free(value);
- }
- g_free (p);
-
- if (values_temp->len != predicates_temp->len)
- g_critical ("values_temp->len != predicates_temp->len");
-
- max = MIN (values_temp->len, predicates_temp->len);
- values = (gchar **) g_malloc0 (sizeof (gchar*) * max + 1);
- predicates = (gchar **) g_malloc0 (sizeof (gchar*) * max + 1);
-
- for (j = 0; j < max; j++) {
- predicates[j] = predicates_temp->pdata[j];
- values[j] = values_temp->pdata[j];
- }
+ if (!opened) {
+ tracker_sparql_builder_subject_iri (sparql, uri);
+ opened = TRUE;
+ }
- predicates[j] = NULL;
- values[j] = NULL;
+ tracker_sparql_builder_predicate (sparql, "nao:hasProperty");
+ tracker_sparql_builder_object_blank_open (sparql);
- /* This is not a path but a URI, don't use the
- * OS's directory separator here */
+ tracker_sparql_builder_predicate (sparql, "rdf:type");
+ tracker_sparql_builder_object (sparql, "nao:Property");
- g_ptr_array_add (subjects_a, g_strdup_printf ("%s%s/%s", em_uri,
- iter->full_name, uid));
+ tracker_sparql_builder_predicate (sparql, "nao:propertyName");
+ tracker_sparql_builder_object_string (sparql, name);
+
+ tracker_sparql_builder_predicate (sparql, "nao:propertyValue");
+ tracker_sparql_builder_object_string (sparql, value);
- g_ptr_array_add (predicates_array, predicates);
- g_ptr_array_add (values_array, values);
+ tracker_sparql_builder_object_blank_close (sparql);
+ }
+ g_free(name);
+ g_free(value);
+ }
+ g_free (p);
- g_ptr_array_free (predicates_temp, TRUE);
- g_ptr_array_free (values_temp, TRUE);
+ tracker_sparql_builder_insert_close (sparql);
count++;
}
@@ -776,16 +1047,10 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
}
- if (count > 0) {
- gchar **subjects;
+ if (count > 0 && sparql) {
QueuedSet *queued_set;
gboolean start_handler = FALSE;
- subjects = (gchar **) g_malloc0 (sizeof (gchar *) * subjects_a->len + 1);
- for (i = 0; i < subjects_a->len; i++)
- subjects[i] = g_ptr_array_index (subjects_a, i);
- subjects[i] = NULL;
-
/* The many_queue stuff:
* Why is this? Ah! Good question and glad you ask.
* We noticed that hammering the DBus isn't exactly
@@ -795,12 +1060,10 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
queued_set = g_slice_new (QueuedSet);
- queued_set->subjects = subjects;
- queued_set->predicates_array = predicates_array;
- queued_set->values_array = values_array;
- queued_set->registrar = g_object_ref (info->registrar);
- queued_set->self = g_object_ref (self);
- queued_set->sender = g_strdup (info->sender);
+ queued_set->sparql = sparql; /* Keep ref */
+ queued_set->count = count;
+
+ sparql = NULL;
if (!many_queue) {
many_queue = g_queue_new ();
@@ -808,32 +1071,34 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
}
g_queue_push_tail (many_queue,
- queued_set);
+ queued_set);
- if (start_handler) {
- start_many_handler ();
- }
+ priv->of_total++;
- } else {
+ if (priv->of_total > priv->total_popped) {
+ g_object_set (self, "progress",
+ (gdouble) (priv->of_total - priv->total_popped) / priv->of_total,
+ NULL);
+ }
- for (i = 0; i < values_array->len; i++)
- g_strfreev (values_array->pdata[i]);
- g_ptr_array_free (values_array, TRUE);
+ if (start_handler) {
+ start_many_handler (self);
+ }
- for (i = 0; i < predicates_array->len; i++)
- g_strfreev (predicates_array->pdata[i]);
- g_ptr_array_free (predicates_array, TRUE);
+ } else if (sparql) {
+ g_object_unref (sparql);
+ sparql = NULL;
}
- g_ptr_array_free (subjects_a, TRUE);
-
}
sqlite3_finalize (stmt);
sqlite3_free (query);
if (iter->child) {
- introduce_walk_folders_in_folder (self, iter->child, store, cdb_r, account_uri, info);
+ introduce_walk_folders_in_folder (self, iter->child,
+ store, cdb_r,
+ account_uri, info);
}
iter = iter->next;
@@ -859,8 +1124,10 @@ introduce_store_deal_with_deleted (TrackerEvolutionPlugin *self,
guint i, ret;
gchar *em_uri = em_uri_from_camel (account_uri);
- query = sqlite3_mprintf ("SELECT uid, mailbox FROM Deletes WHERE modified > %" G_GUINT64_FORMAT,
- info->last_checkout);
+ query = sqlite3_mprintf ("SELECT uid, mailbox "
+ "FROM Deletes "
+ "WHERE modified > %" G_GUINT64_FORMAT,
+ info->last_checkout);
/* This creates a thread apparently */
cdb_r = camel_db_clone (store->cdb_r, NULL);
@@ -919,27 +1186,26 @@ introduce_store_deal_with_deleted (TrackerEvolutionPlugin *self,
}
if (count > 0) {
- gchar **subjects;
+ GString *sparql = g_string_new ("DELETE { \n");
+
+ for (i = 0; i < subjects_a->len; i++) {
+ g_string_append_printf (sparql, "\t<%s> a rdfs:Resource . \n",
+ (gchar *) g_ptr_array_index (subjects_a, i));
+ }
- subjects = (gchar **) g_malloc0 (sizeof (gchar *) * subjects_a->len + 1);
- for (i = 0; i < subjects_a->len; i++)
- subjects[i] = g_ptr_array_index (subjects_a, i);
- subjects[i] = NULL;
+ g_string_append_c (sparql, '}');
- dbus_g_proxy_call_no_reply (info->registrar,
- "UnsetMany",
- G_TYPE_STRV, subjects,
- G_TYPE_UINT, (guint) time (NULL),
- G_TYPE_INVALID,
- G_TYPE_INVALID);
+ send_sparql_update (self, sparql->str);
+ g_string_free (sparql, TRUE);
- g_strfreev (subjects);
}
g_ptr_array_free (subjects_a, TRUE);
}
+ send_sparql_commit (self, FALSE);
+
sqlite3_finalize (stmt);
sqlite3_free (query);
@@ -993,7 +1259,9 @@ get_last_deleted_time (TrackerEvolutionPlugin *self)
cdb_r = camel_db_clone (store->cdb_r, NULL);
- query = sqlite3_mprintf ("SELECT time FROM Deletes ORDER BY time LIMIT 1");
+ query = sqlite3_mprintf ("SELECT time "
+ "FROM Deletes "
+ "ORDER BY time LIMIT 1");
ret = sqlite3_prepare_v2 (cdb_r->db, query, -1, &stmt, NULL);
@@ -1019,12 +1287,6 @@ get_last_deleted_time (TrackerEvolutionPlugin *self)
return smallest;
}
-typedef struct {
- TrackerEvolutionPlugin *self;
- gchar *account_uri;
- CamelFolderInfo *iter;
-} GetFolderInfo;
-
static void
register_on_get_folder (gchar *uri, CamelFolder *folder, gpointer user_data)
{
@@ -1049,14 +1311,17 @@ register_on_get_folder (gchar *uri, CamelFolder *folder, gpointer user_data)
}
hook_id = camel_object_hook_event (folder, "folder_changed",
- CAMEL_CALLBACK (on_folder_summary_changed),
- registry->hook_info);
+ CAMEL_CALLBACK (on_folder_summary_changed),
+ registry->hook_info);
registry->hook_info->hook_id = hook_id;
- g_hash_table_replace (priv->registered_folders, &hook_id,
- registry);
- g_hash_table_replace (priv->cached_folders, g_strdup (iter->full_name),
- folder);
+ g_hash_table_replace (priv->registered_folders,
+ GINT_TO_POINTER (hook_id),
+ registry);
+
+ g_hash_table_replace (priv->cached_folders,
+ g_strdup (iter->full_name),
+ folder);
not_ready:
@@ -1083,12 +1348,13 @@ register_walk_folders_in_folder (TrackerEvolutionPlugin *self,
g_static_rec_mutex_lock (priv->mutex);
if (!priv->registered_folders) {
- priv->registered_folders = g_hash_table_new_full (g_int_hash, g_int_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) folder_registry_free);
+ priv->registered_folders = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) folder_registry_free);
+
priv->cached_folders = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) NULL);
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
}
g_static_rec_mutex_unlock (priv->mutex);
@@ -1108,11 +1374,12 @@ register_walk_folders_in_folder (TrackerEvolutionPlugin *self,
* integrated with the Evolution UI application */
mail_get_folder (iter->uri, 0, register_on_get_folder, info,
- mail_msg_unordered_push);
+ mail_msg_unordered_push);
if (iter->child) {
- register_walk_folders_in_folder (self, iter->child, store,
- account_uri);
+ register_walk_folders_in_folder (self, iter->child,
+ store,
+ account_uri);
}
iter = iter->next;
@@ -1162,11 +1429,12 @@ unregister_on_get_folder (gchar *uri, CamelFolder *folder, gpointer user_data)
g_object_unref (info->self);
g_free (info);
}
+
static void
unregister_walk_folders_in_folder (TrackerEvolutionPlugin *self,
- CamelFolderInfo *titer,
- CamelStore *store,
- gchar *account_uri)
+ CamelFolderInfo *titer,
+ CamelStore *store,
+ gchar *account_uri)
{
/* Recursively walks all the folders in store */
@@ -1181,11 +1449,12 @@ unregister_walk_folders_in_folder (TrackerEvolutionPlugin *self,
* integrated with the Evolution UI application */
mail_get_folder (titer->uri, 0, unregister_on_get_folder, info,
- mail_msg_unordered_push);
+ mail_msg_unordered_push);
if (titer->child) {
- unregister_walk_folders_in_folder (self, titer->child, store,
- account_uri);
+ unregister_walk_folders_in_folder (self, titer->child,
+ store,
+ account_uri);
}
titer = titer->next;
@@ -1195,10 +1464,6 @@ unregister_walk_folders_in_folder (TrackerEvolutionPlugin *self,
static void
client_registry_info_free (ClientRegistry *info)
{
- if (info->signal != 0) /* known (see below) */
- g_signal_handler_disconnect (info->registrar, info->signal);
- g_object_unref (info->registrar);
- g_free (info->sender);
g_slice_free (ClientRegistry, info);
}
@@ -1207,23 +1472,13 @@ client_registry_info_copy (ClientRegistry *info)
{
ClientRegistry *ninfo = g_slice_new0 (ClientRegistry);
- ninfo->signal = 0; /* known */
- ninfo->sender = g_strdup (info->sender);
ninfo->last_checkout = info->last_checkout;
- ninfo->registrar = g_object_ref (info->registrar);
return ninfo;
}
/* For info about this try-again stuff, look at on_got_folderinfo_introduce */
-typedef struct {
- IntroductionInfo *intro_info;
- CamelStore *store;
- CamelDB *cdb_r;
- CamelFolderInfo *iter;
-} TryAgainInfo;
-
static gboolean
try_again (gpointer user_data)
{
@@ -1232,11 +1487,11 @@ try_again (gpointer user_data)
IntroductionInfo *intro_info = info->intro_info;
introduce_walk_folders_in_folder (intro_info->self,
- info->iter,
- info->store,
- info->cdb_r,
- intro_info->account_uri,
- intro_info->info);
+ info->iter,
+ info->store,
+ info->cdb_r,
+ intro_info->account_uri,
+ intro_info->info);
return FALSE;
}
@@ -1263,8 +1518,8 @@ try_again_d (gpointer user_data)
static gboolean
on_got_folderinfo_introduce (CamelStore *store,
- CamelFolderInfo *iter,
- void *data)
+ CamelFolderInfo *iter,
+ void *data)
{
TryAgainInfo *info = g_new0 (TryAgainInfo, 1);
@@ -1296,8 +1551,8 @@ on_got_folderinfo_introduce (CamelStore *store,
if (register_count != 0) {
g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, 10,
- try_again, info,
- try_again_d);
+ try_again, info,
+ try_again_d);
} else {
try_again (info);
try_again_d (info);
@@ -1308,8 +1563,8 @@ on_got_folderinfo_introduce (CamelStore *store,
static void
introduce_account_to (TrackerEvolutionPlugin *self,
- EAccount *account,
- ClientRegistry *info)
+ EAccount *account,
+ ClientRegistry *info)
{
CamelProvider *provider;
CamelStore *store;
@@ -1358,7 +1613,7 @@ introduce_account_to (TrackerEvolutionPlugin *self,
static void
introduce_account_to_all (TrackerEvolutionPlugin *self,
- EAccount *account)
+ EAccount *account)
{
TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
GList *copy = priv->registered_clients;
@@ -1373,114 +1628,116 @@ introduce_account_to_all (TrackerEvolutionPlugin *self,
static void
introduce_accounts_to (TrackerEvolutionPlugin *self,
- ClientRegistry *info)
+ ClientRegistry *info)
{
TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
EIterator *it;
- for (it = e_list_get_iterator (E_LIST (priv->accounts)); e_iterator_is_valid (it); e_iterator_next (it))
+ for (it = e_list_get_iterator (E_LIST (priv->accounts)); e_iterator_is_valid (it); e_iterator_next (it)) {
introduce_account_to (self, (EAccount *) e_iterator_get (it), info);
+ }
g_object_unref (it);
}
static void
-register_client (TrackerEvolutionPlugin *self,
- guint64 last_checkout,
- DBusGProxy *registrar,
- gchar *sender,
- guint dsignal)
+register_client_second_half (ClientRegistry *info)
{
- TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
- guint64 too_old = get_last_deleted_time (self);
- ClientRegistry *info = g_slice_new0 (ClientRegistry);
-
- info->sender = g_strdup (sender);
- info->signal = dsignal;
- info->registrar = g_object_ref (registrar);
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (info->self);
+ guint64 too_old = get_last_deleted_time (info->self);
/* If registrar's modseq is too old, send Cleanup (). This means that
* we tell it to start over (it must invalidate what it has). */
- if (last_checkout < too_old) {
- dbus_g_proxy_call_no_reply (registrar,
- "Cleanup",
- G_TYPE_UINT, (guint) time (NULL),
- G_TYPE_INVALID,
- G_TYPE_INVALID);
+ if (info->last_checkout < too_old) {
+
+ send_sparql_update (info->self, "DELETE { ?s a rdfs:Resource } "
+ "WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }");
+ send_sparql_commit (info->self, FALSE);
+
info->last_checkout = 0;
- } else {
- info->last_checkout = last_checkout;
}
- introduce_accounts_to (self, info);
+ priv->last_time = info->last_checkout;
+
+ introduce_accounts_to (info->self, info);
priv->registered_clients =
g_list_prepend (priv->registered_clients, info);
-
}
-
static void
-metadata_set_many (TrackerEvolutionPlugin *self,
- GStrv subjects,
- GPtrArray *predicates,
- GPtrArray *values)
+on_register_client_qry (GPtrArray *results,
+ GError *error,
+ gpointer user_data)
{
- TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
- GHashTableIter iter;
- gpointer key, value;
-
- g_static_rec_mutex_lock (priv->mutex);
-
- g_hash_table_iter_init (&iter, priv->registrars);
+ ClientRegistry *info = user_data;
+ guint i;
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- DBusGProxy *registrar = value;
+ if (error) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
+ g_slice_free (ClientRegistry, info);
+ return;
+ }
- dbus_g_proxy_call_no_reply (registrar,
- "SetMany",
- G_TYPE_STRV, subjects,
- TRACKER_TYPE_G_STRV_ARRAY, predicates,
- TRACKER_TYPE_G_STRV_ARRAY, values,
- G_TYPE_UINT, (guint) time (NULL),
- G_TYPE_INVALID,
- G_TYPE_INVALID);
+ if (!results) {
+ info->last_checkout = 0;
+ } else {
+ for (i = 0; i < results->len; i++) {
+ const gchar **str = g_ptr_array_index (results, i);
+ info->last_checkout = (guint64) tracker_string_to_date (str[0]);
+ break;
+ }
+ g_ptr_array_foreach (results, (GFunc) g_strfreev, NULL);
+ g_ptr_array_free (results, TRUE);
}
- g_static_rec_mutex_unlock (priv->mutex);
+ register_client_second_half (info);
}
static void
-metadata_unset_many (TrackerEvolutionPlugin *self,
- GStrv subjects)
+register_client (TrackerEvolutionPlugin *self)
{
TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
- GHashTableIter iter;
- gpointer key, value;
+ ClientRegistry *info = g_slice_new0 (ClientRegistry);
- g_static_rec_mutex_lock (priv->mutex);
+ info->self = self; /* weak */
+
+ if (!priv->client) {
+ return;
+ }
- g_hash_table_iter_init (&iter, priv->registrars);
+ priv->total_popped = 0;
+ priv->of_total = 0;
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- DBusGProxy *registrar = value;
+ if (!priv->resuming) {
+ const gchar *query;
+
+ query = "SELECT ?c "
+ "WHERE { <" DATASOURCE_URN "> nie:contentLastModified ?c }";
+
+ tracker_resources_sparql_query_async (priv->client, query,
+ on_register_client_qry,
+ info);
- dbus_g_proxy_call_no_reply (registrar,
- "UnsetMany",
- G_TYPE_STRV, subjects,
- G_TYPE_UINT, (guint) time (NULL),
- G_TYPE_INVALID,
- G_TYPE_INVALID);
+ } else {
+ /* This happens in case of resume, for example (which is just a
+ * complete restart. So we just get the same E-mails that we had
+ * already) */
+
+ info->last_checkout = priv->last_time;
+ register_client_second_half (info);
}
- g_static_rec_mutex_unlock (priv->mutex);
}
+
+
static void
on_folder_created (CamelStore *store, void *event_data,
- StoreRegistry *registry)
+ StoreRegistry *registry)
{
unregister_account (registry->self, registry->account);
register_account (registry->self, registry->account);
@@ -1489,8 +1746,8 @@ on_folder_created (CamelStore *store, void *event_data,
static void
on_folder_deleted (CamelStore *store,
- void *event_data,
- StoreRegistry *registry)
+ void *event_data,
+ StoreRegistry *registry)
{
unregister_account (registry->self, registry->account);
register_account (registry->self, registry->account);
@@ -1499,8 +1756,8 @@ on_folder_deleted (CamelStore *store,
static void
on_folder_renamed (CamelStore *store,
- CamelRenameInfo *info,
- StoreRegistry *registry)
+ CamelRenameInfo *info,
+ StoreRegistry *registry)
{
unregister_account (registry->self, registry->account);
register_account (registry->self, registry->account);
@@ -1509,8 +1766,8 @@ on_folder_renamed (CamelStore *store,
static StoreRegistry*
store_registry_new (gpointer co,
- EAccount *account,
- TrackerEvolutionPlugin *self)
+ EAccount *account,
+ TrackerEvolutionPlugin *self)
{
StoreRegistry *registry = g_slice_new (StoreRegistry);
@@ -1533,8 +1790,8 @@ store_registry_free (StoreRegistry *registry)
static gboolean
on_got_folderinfo_register (CamelStore *store,
- CamelFolderInfo *iter,
- void *data)
+ CamelFolderInfo *iter,
+ void *data)
{
RegisterInfo *reg_info = data;
TrackerEvolutionPlugin *self = reg_info->self;
@@ -1549,32 +1806,38 @@ on_got_folderinfo_register (CamelStore *store,
g_static_rec_mutex_lock (priv->mutex);
if (!priv->registered_stores) {
- priv->registered_stores = g_hash_table_new_full (g_int_hash, g_int_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) store_registry_free);
+ priv->registered_stores = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) store_registry_free);
}
/* Hook up catching folder changes in the store */
registry = store_registry_new (store, account, self);
hook_id = camel_object_hook_event (store, "folder_created",
- CAMEL_CALLBACK (on_folder_created),
- registry);
+ CAMEL_CALLBACK (on_folder_created),
+ registry);
registry->hook_id = hook_id;
- g_hash_table_replace (priv->registered_stores, &hook_id, registry);
+ g_hash_table_replace (priv->registered_stores,
+ GINT_TO_POINTER (hook_id),
+ registry);
registry = store_registry_new (store, account, self);
hook_id = camel_object_hook_event (store, "folder_renamed",
- CAMEL_CALLBACK (on_folder_renamed),
- registry);
+ CAMEL_CALLBACK (on_folder_renamed),
+ registry);
registry->hook_id = hook_id;
- g_hash_table_replace (priv->registered_stores, &hook_id, registry);
+ g_hash_table_replace (priv->registered_stores,
+ GINT_TO_POINTER (hook_id),
+ registry);
registry = store_registry_new (store, account, self);
hook_id = camel_object_hook_event (store, "folder_deleted",
- CAMEL_CALLBACK (on_folder_deleted),
- registry);
+ CAMEL_CALLBACK (on_folder_deleted),
+ registry);
registry->hook_id = hook_id;
- g_hash_table_replace (priv->registered_stores, &hook_id, registry);
+ g_hash_table_replace (priv->registered_stores,
+ GINT_TO_POINTER (hook_id),
+ registry);
g_static_rec_mutex_unlock (priv->mutex);
@@ -1591,7 +1854,7 @@ on_got_folderinfo_register (CamelStore *store,
static void
register_account (TrackerEvolutionPlugin *self,
- EAccount *account)
+ EAccount *account)
{
CamelProvider *provider;
CamelStore *store;
@@ -1630,8 +1893,8 @@ register_account (TrackerEvolutionPlugin *self,
static gboolean
on_got_folderinfo_unregister (CamelStore *store,
- CamelFolderInfo *titer,
- void *data)
+ CamelFolderInfo *titer,
+ void *data)
{
RegisterInfo *reg_info = data;
TrackerEvolutionPlugin *self = reg_info->self;
@@ -1664,7 +1927,7 @@ on_got_folderinfo_unregister (CamelStore *store,
static void
unregister_account (TrackerEvolutionPlugin *self,
- EAccount *account)
+ EAccount *account)
{
CamelProvider *provider;
CamelStore *store;
@@ -1701,8 +1964,8 @@ unregister_account (TrackerEvolutionPlugin *self,
static void
on_account_added (EAccountList *list,
- EAccount *account,
- TrackerEvolutionPlugin *self)
+ EAccount *account,
+ TrackerEvolutionPlugin *self)
{
register_account (self, account);
introduce_account_to_all (self, account);
@@ -1710,16 +1973,16 @@ on_account_added (EAccountList *list,
static void
on_account_removed (EAccountList *list,
- EAccount *account,
- TrackerEvolutionPlugin *self)
+ EAccount *account,
+ TrackerEvolutionPlugin *self)
{
unregister_account (self, account);
}
static void
on_account_changed (EAccountList *list,
- EAccount *account,
- TrackerEvolutionPlugin *self)
+ EAccount *account,
+ TrackerEvolutionPlugin *self)
{
unregister_account (self, account);
register_account (self, account);
@@ -1729,172 +1992,83 @@ on_account_changed (EAccountList *list,
static void
disable_plugin (void)
{
- GError *error = NULL;
- guint result;
-
- org_freedesktop_DBus_release_name (dbus_proxy, TRACKER_EVOLUTION_MANAGER_SERVICE,
- &result, &error);
-
- if (!error) {
- if (manager) {
- g_object_unref (manager);
- manager = NULL;
- }
-
- if (dbus_proxy) {
- g_object_unref (dbus_proxy);
- dbus_proxy = NULL;
- }
- } else {
- g_warning ("Could not setup D-Bus, ReleaseName of %s: %s\n",
- TRACKER_EVOLUTION_MANAGER_SERVICE, error->message);
-
- g_error_free (error);
+ if (manager) {
+ g_object_unref (manager);
+ manager = NULL;
}
}
+
static void
-enable_plugin (void)
+list_names_reply_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ gpointer user_data)
{
- DBusGConnection *connection;
GError *error = NULL;
- guint result;
-
- if (dbus_proxy && manager)
- return;
+ GStrv names = NULL;
+ guint i = 0;
- if ((dbus_proxy && !manager) || (!dbus_proxy && manager))
- disable_plugin ();
+ dbus_g_proxy_end_call (proxy, call, &error,
+ G_TYPE_STRV, &names,
+ G_TYPE_INVALID);
- if ((dbus_proxy && !manager) || (!dbus_proxy && manager))
+ if (error) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ if (names)
+ g_strfreev (names);
return;
-
- connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-
- if (error)
- goto error_handler;
-
- dbus_proxy = dbus_g_proxy_new_for_name (connection,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS);
-
- if (!org_freedesktop_DBus_request_name (dbus_proxy, TRACKER_EVOLUTION_MANAGER_SERVICE,
- DBUS_NAME_FLAG_DO_NOT_QUEUE,
- &result, &error)) {
-
- g_warning ("Could not setup D-Bus, failed at RequestName for %s\n",
- TRACKER_EVOLUTION_MANAGER_SERVICE);
-
- goto error_handler;
}
- if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
-
- g_warning ("Could not setup D-Bus, can't become primary owner of %s\n",
- TRACKER_EVOLUTION_MANAGER_SERVICE);
-
- goto error_handler;
+ while (names[i] != NULL) {
+ if (g_strcmp0 (names[i], TRACKER_SERVICE) == 0) {
+ register_client (user_data);
+ break;
+ }
+ i++;
}
- if (error)
- goto error_handler;
-
- manager = g_object_new (TRACKER_TYPE_EVOLUTION_PLUGIN,
- "connection", connection, NULL);
-
- dbus_g_object_type_install_info (G_OBJECT_TYPE (manager),
- &dbus_glib_tracker_evolution_plugin_object_info);
-
- dbus_g_connection_register_g_object (connection,
- TRACKER_EVOLUTION_MANAGER_PATH,
- G_OBJECT (manager));
-
- error_handler:
-
- if (error) {
- g_warning ("Could not setup D-Bus, %s\n", error->message);
- disable_plugin();
- g_error_free (error);
- }
+ g_strfreev (names);
}
-static gboolean
-do_remove_or_not (gpointer key, gpointer value, gpointer user_data)
-{
- if (user_data == value)
- return TRUE;
-
- return FALSE;
-}
static void
-service_gone (DBusGProxy *lproxy, TrackerEvolutionPlugin *plugin)
+name_owner_changed_cb (DBusGProxy *proxy,
+ gchar *name,
+ gchar *old_owner,
+ gchar *new_owner,
+ gpointer user_data)
{
- TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
- GList *copy = priv->registered_clients;
- GList *to_delete = NULL;
-
- g_static_rec_mutex_lock (priv->mutex);
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (user_data);
- g_hash_table_foreach_remove (priv->registrars,
- do_remove_or_not,
- lproxy);
-
- while (copy) {
- ClientRegistry *creg = copy->data;
- if (creg->registrar == lproxy)
- to_delete = g_list_prepend (to_delete, copy);
- copy = g_list_next (copy);
- }
+ if (g_strcmp0 (name, TRACKER_SERVICE) == 0) {
+ if (tracker_is_empty_string (new_owner) && !tracker_is_empty_string (old_owner)) {
+ if (priv->client) {
+ tracker_disconnect (priv->client);
+ priv->client = NULL;
+ }
+ }
- copy = to_delete;
- while (copy) {
- GList *node = copy->data;
- ClientRegistry *creg = node->data;
- priv->registered_clients = g_list_delete_link (priv->registered_clients, node);
- client_registry_info_free (creg);
- copy = g_list_next (copy);
+ if (tracker_is_empty_string (old_owner) && !tracker_is_empty_string (new_owner)) {
+ if (!priv->client) {
+ priv->client = tracker_connect (FALSE, G_MAXINT);
+ }
+ register_client (user_data);
+ }
}
-
- g_list_free (to_delete);
-
- g_static_rec_mutex_unlock (priv->mutex);
}
-void
-tracker_evolution_plugin_register (TrackerEvolutionPlugin *plugin,
- gchar *registrar_path,
- guint last_checkout,
- DBusGMethodInvocation *context,
- GError *derror)
+static void
+enable_plugin (void)
{
- TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
- gchar *sender;
- DBusGProxy *registrar;
- guint dsignal;
-
- g_static_rec_mutex_lock (priv->mutex);
-
- sender = dbus_g_method_get_sender (context);
-
- registrar = dbus_g_proxy_new_for_name (priv->connection, sender,
- registrar_path,
- TRACKER_EVOLUTION_REGISTRAR_INTERFACE);
-
- g_hash_table_replace (priv->registrars, g_strdup (sender),
- registrar);
-
- dsignal = g_signal_connect (registrar, "destroy",
- G_CALLBACK (service_gone),
- plugin);
-
- g_static_rec_mutex_unlock (priv->mutex);
+ if (manager) {
+ g_object_unref (manager);
+ }
- /* Passing uint64 over DBus ain't working :-\ */
- register_client (plugin, (guint64) last_checkout, registrar, sender, dsignal);
+ manager = g_object_new (TRACKER_TYPE_EVOLUTION_PLUGIN,
+ "name", "Emails", NULL);
- dbus_g_method_return (context);
+ g_signal_emit_by_name (manager, "started");
}
@@ -1913,7 +2087,6 @@ e_plugin_lib_enable (EPluginLib *ep, int enabled)
return 0;
}
-
static void
tracker_evolution_plugin_finalize (GObject *plugin)
{
@@ -1921,12 +2094,6 @@ tracker_evolution_plugin_finalize (GObject *plugin)
g_static_rec_mutex_lock (priv->mutex);
- g_list_foreach (priv->registered_clients,
- (GFunc) client_registry_info_free,
- NULL);
-
- g_list_free (priv->registered_clients);
-
if (priv->registered_folders) {
g_hash_table_destroy (priv->registered_folders);
g_hash_table_destroy (priv->cached_folders);
@@ -1941,81 +2108,38 @@ tracker_evolution_plugin_finalize (GObject *plugin)
g_object_unref (priv->accounts);
- g_hash_table_destroy (priv->registrars);
-
- if (priv->connection)
- dbus_g_connection_unref (priv->connection);
-
+ if (priv->client) {
+ tracker_disconnect (priv->client);
+ priv->client = NULL;
+ }
g_static_rec_mutex_unlock (priv->mutex);
- g_slice_free (GStaticRecMutex, priv->mutex);
-
- G_OBJECT_CLASS (tracker_evolution_plugin_parent_class)->finalize (plugin);
-}
-
-static void
-tracker_evolution_plugin_set_connection (TrackerEvolutionPlugin *plugin,
- DBusGConnection *connection)
-{
- TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
+ if (priv->dbus_proxy) {
+ g_object_unref (priv->dbus_proxy);
+ }
- if (priv->connection)
+ if (priv->connection) {
dbus_g_connection_unref (priv->connection);
-
- priv->connection = dbus_g_connection_ref (connection);
-}
-
-static void
-tracker_evolution_plugin_set_property (GObject *plugin,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id) {
- case PROP_CONNECTION:
- tracker_evolution_plugin_set_connection (TRACKER_EVOLUTION_PLUGIN (plugin),
- g_value_get_pointer (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (plugin, prop_id, pspec);
}
-}
-
-static void
-tracker_evolution_plugin_get_property (GObject *plugin,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- TrackerEvolutionPluginPrivate *priv;
- priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
+ g_slice_free (GStaticRecMutex, priv->mutex);
- switch (prop_id) {
- case PROP_CONNECTION:
- g_value_set_pointer (value, priv->connection);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (plugin, prop_id, pspec);
- }
+ G_OBJECT_CLASS (tracker_evolution_plugin_parent_class)->finalize (plugin);
}
+
static void
tracker_evolution_plugin_class_init (TrackerEvolutionPluginClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TrackerMinerClass *miner_class = TRACKER_MINER_CLASS (klass);
- object_class->finalize = tracker_evolution_plugin_finalize;
- object_class->set_property = tracker_evolution_plugin_set_property;
- object_class->get_property = tracker_evolution_plugin_get_property;
+ miner_class->started = miner_started;
+ miner_class->stopped = miner_stopped;
+ miner_class->paused = miner_paused;
+ miner_class->resumed = miner_resumed;
- g_object_class_install_property (object_class,
- PROP_CONNECTION,
- g_param_spec_pointer ("connection",
- "DBus connection",
- "DBus connection",
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
+ object_class->finalize = tracker_evolution_plugin_finalize;
g_type_class_add_private (object_class, sizeof (TrackerEvolutionPluginPrivate));
}
@@ -2025,16 +2149,16 @@ tracker_evolution_plugin_init (TrackerEvolutionPlugin *plugin)
{
TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
EIterator *it;
+ GError *error = NULL;
priv->mutex = g_slice_new0 (GStaticRecMutex);
g_static_rec_mutex_init (priv->mutex);
g_static_rec_mutex_lock (priv->mutex);
- priv->registrars = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_object_unref);
-
+ priv->last_time = 0;
+ priv->resuming = FALSE;
+ priv->paused = FALSE;
priv->cached_folders = NULL;
priv->registered_folders = NULL;
@@ -2043,17 +2167,158 @@ tracker_evolution_plugin_init (TrackerEvolutionPlugin *plugin)
g_static_rec_mutex_unlock (priv->mutex);
+ priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+ if (error) {
+ goto error_handler;
+ }
+
+ priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+
+ dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+
priv->accounts = g_object_ref (mail_config_get_accounts ());
- for (it = e_list_get_iterator (E_LIST (priv->accounts)); e_iterator_is_valid (it); e_iterator_next (it))
+ for (it = e_list_get_iterator (E_LIST (priv->accounts)); e_iterator_is_valid (it); e_iterator_next (it)) {
register_account (plugin, (EAccount *) e_iterator_get (it));
+ }
g_object_unref (it);
g_signal_connect (priv->accounts, "account-added",
- G_CALLBACK (on_account_added), plugin);
+ G_CALLBACK (on_account_added), plugin);
g_signal_connect (priv->accounts, "account-removed",
- G_CALLBACK (on_account_removed), plugin);
+ G_CALLBACK (on_account_removed), plugin);
g_signal_connect (priv->accounts, "account-changed",
- G_CALLBACK (on_account_changed), plugin);
+ G_CALLBACK (on_account_changed), plugin);
+ error_handler:
+
+ if (error) {
+ g_warning ("Could not setup DBus for Tracker plugin, %s\n", error->message);
+ g_signal_emit_by_name (plugin, "error");
+ g_error_free (error);
+ }
+}
+
+static void
+dbus_connect_closure (gpointer data, GClosure *closure)
+{
+ g_object_unref (data);
+}
+
+
+static void
+listnames_fini (gpointer data)
+{
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (data);
+
+ dbus_g_proxy_connect_signal (priv->dbus_proxy, "NameOwnerChanged",
+ G_CALLBACK (name_owner_changed_cb),
+ g_object_ref (data),
+ dbus_connect_closure);
+
+ g_object_unref (data);
+}
+
+static void
+miner_started (TrackerMiner *miner)
+{
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (miner);
+
+ if (!priv->client) {
+ priv->client = tracker_connect (FALSE, G_MAXINT);
+ }
+
+ dbus_g_proxy_begin_call (priv->dbus_proxy, "ListNames",
+ list_names_reply_cb,
+ g_object_ref (miner),
+ listnames_fini,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ g_object_set (miner, "progress", 0.0, "status", _("Initializing"), NULL);
+}
+
+static void
+miner_stopped (TrackerMiner *miner)
+{
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (miner);
+ miner_paused (miner);
+ priv->paused = FALSE;
+}
+
+static void
+miner_paused (TrackerMiner *miner)
+{
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (miner);
+
+ /* We don't really pause, we just completely stop */
+
+ dbus_g_proxy_disconnect_signal (priv->dbus_proxy, "NameOwnerChanged",
+ G_CALLBACK (name_owner_changed_cb),
+ miner);
+
+ /* We'll just get rid of all that are in the current queue */
+
+ clean_many_queue ();
+
+ priv->paused = TRUE;
+
+ if (priv->client) {
+ tracker_disconnect (priv->client);
+
+ /* By setting this to NULL, events will still be catched by our
+ * handlers, but the send_sparql_* calls will just ignore it.
+ * This is fine as a solution (at least for now). It allows us
+ * to avoid having to unregister everything and risk the chance
+ * of missing something (like a folder or account creation). */
+
+ priv->client = NULL;
+ }
+
+}
+
+static void
+resuming_fini (gpointer data)
+{
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (data);
+ priv->resuming = FALSE;
+
+ dbus_g_proxy_connect_signal (priv->dbus_proxy, "NameOwnerChanged",
+ G_CALLBACK (name_owner_changed_cb),
+ g_object_ref (data),
+ dbus_connect_closure);
+
+ g_object_unref (data);
+}
+
+static void
+miner_resumed (TrackerMiner *miner)
+{
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (miner);
+
+ /* We don't really resume, we just completely restart */
+
+ priv->resuming = TRUE;
+ priv->paused = FALSE;
+ priv->total_popped = 0;
+ priv->of_total = 0;
+
+ if (!priv->client) {
+ priv->client = tracker_connect (FALSE, G_MAXINT);
+ }
+
+ g_object_set (miner, "progress", 0.0, "status", _("Resuming"), NULL);
+
+ dbus_g_proxy_begin_call (priv->dbus_proxy, "ListNames",
+ list_names_reply_cb,
+ g_object_ref (miner),
+ resuming_fini,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
}
diff --git a/src/plugins/evolution/tracker-evolution-plugin.h b/src/plugins/evolution/tracker-evolution-plugin.h
index 3f59936..906f6a8 100644
--- a/src/plugins/evolution/tracker-evolution-plugin.h
+++ b/src/plugins/evolution/tracker-evolution-plugin.h
@@ -27,7 +27,7 @@
#include <dbus/dbus-glib-bindings.h>
#include <dbus/dbus-glib-lowlevel.h>
-#include "tracker-evolution-common.h"
+#include <libtracker-miner/tracker-miner.h>
#define TRACKER_TYPE_EVOLUTION_PLUGIN (tracker_evolution_plugin_get_type())
#define TRACKER_EVOLUTION_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_EVOLUTION_PLUGIN, TrackerEvolutionPlugin))
@@ -40,20 +40,15 @@ typedef struct TrackerEvolutionPlugin TrackerEvolutionPlugin;
typedef struct TrackerEvolutionPluginClass TrackerEvolutionPluginClass;
struct TrackerEvolutionPlugin {
- GObject parent;
+ TrackerMiner parent;
};
struct TrackerEvolutionPluginClass {
- GObjectClass parent;
+ TrackerMinerClass parent;
};
GType tracker_evolution_plugin_get_type (void);
-void tracker_evolution_plugin_register (TrackerEvolutionPlugin *object,
- gchar *registrar_path,
- guint last_modseq,
- DBusGMethodInvocation *context,
- GError *derror);
G_END_DECLS
diff --git a/src/plugins/evolution/tracker-miner-emails.desktop.in b/src/plugins/evolution/tracker-miner-emails.desktop.in
new file mode 100644
index 0000000..7e490e5
--- /dev/null
+++ b/src/plugins/evolution/tracker-miner-emails.desktop.in
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Encoding=UTF-8
+_Name=E-mails
+_Comment=Evolution E-mails miner
+DBusName=org.freedesktop.Tracker1.Miner.EMails
+DBusPath=/org/freedesktop/Tracker1/Miner/EMails
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]