diff options
author | Philip Van Hoof <philip@codeminded.be> | 2009-09-23 18:18:29 +0200 |
---|---|---|
committer | Philip Van Hoof <philip@codeminded.be> | 2009-09-24 14:46:17 +0200 |
commit | 0fe11f41708a6b4d872e409b2fc8a5a9bea625d4 (patch) | |
tree | e979f1336a01c5205a8a0f62a4a4200dbc2ca4ca | |
parent | 680b62d1a794e4309c79d88d0fea7c344e2f891b (diff) | |
download | tracker-0fe11f41708a6b4d872e409b2fc8a5a9bea625d4.tar.gz |
Refactoring of the Evolution push plugin
-rw-r--r-- | src/libtracker-common/tracker-sparql-builder.vala | 6 | ||||
-rw-r--r-- | src/plugins/evolution/Makefile.am | 52 | ||||
-rw-r--r-- | src/plugins/evolution/org.freedesktop.Tracker1.Miner.EMails.service | 2 | ||||
-rw-r--r-- | src/plugins/evolution/tracker-evolution-common.h | 79 | ||||
-rw-r--r-- | src/plugins/evolution/tracker-evolution-plugin.c | 1641 | ||||
-rw-r--r-- | src/plugins/evolution/tracker-evolution-plugin.h | 11 | ||||
-rw-r--r-- | src/plugins/evolution/tracker-evolution-plugin.xml | 11 | ||||
-rw-r--r-- | src/plugins/evolution/tracker-evolution-registrar.c | 902 | ||||
-rw-r--r-- | src/plugins/evolution/tracker-evolution-registrar.h | 94 | ||||
-rw-r--r-- | src/plugins/evolution/tracker-evolution-registrar.xml | 39 | ||||
-rw-r--r-- | src/plugins/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 bbcc077d3..530d5b3c4 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 4a919182d..50b08e464 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 000000000..506c90dd3 --- /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-common.h b/src/plugins/evolution/tracker-evolution-common.h deleted file mode 100644 index ecdb80628..000000000 --- a/src/plugins/evolution/tracker-evolution-common.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2008, Nokia - * - * This library 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 of the License, or (at your option) any later version. - * - * This library 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 library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Authors: - * Philip Van Hoof <philip@codeminded.be> - */ - -#ifndef __TRACKER_EVOLUTION_COMMON_H__ -#define __TRACKER_EVOLUTION_COMMON_H__ - -/* Latest spec location: http://live.gnome.org/Evolution/Metadata */ - -#define TRACKER_EVOLUTION_INDEXER_PATH "/org/freedesktop/Tracker1/Indexer/Evolution/Registrar" - -#define TRACKER_EVOLUTION_REGISTRAR_SERVICE "org.freedesktop.Tracker1" -#define TRACKER_EVOLUTION_REGISTRAR_PATH "/org/freedesktop/Tracker1/Evolution/Registrar" -#define TRACKER_EVOLUTION_REGISTRAR_INTERFACE "org.freedesktop.email.metadata.Registrar" - -#define TRACKER_EVOLUTION_MANAGER_SERVICE "org.gnome.evolution" -#define TRACKER_EVOLUTION_MANAGER_PATH "/org/freedesktop/email/metadata/Manager" -#define TRACKER_EVOLUTION_MANAGER_INTERFACE "org.freedesktop.email.metadata.Manager" - -#define DBUS_ERROR_DOMAIN "TrackerEvolution" -#define DBUS_ERROR g_quark_from_static_string (DBUS_ERROR_DOMAIN) - -#define TRACKER_EVOLUTION_PREDICATE_SUBJECT "EMailMeta:MessageSubject" -#define TRACKER_EVOLUTION_PREDICATE_SENT "EMailMeta:MessageSent" -#define TRACKER_EVOLUTION_PREDICATE_FROM "EMailMeta:MessageFrom" -#define TRACKER_EVOLUTION_PREDICATE_TO "EMailMeta:MessageTo" -#define TRACKER_EVOLUTION_PREDICATE_CC "EMailMeta:MessageCc" -#define TRACKER_EVOLUTION_PREDICATE_SEEN "EMailMeta:MessageSeen" -#define TRACKER_EVOLUTION_PREDICATE_ANSWERED "EMailMeta:MessageAnswered" -#define TRACKER_EVOLUTION_PREDICATE_FORWARDED "EMailMeta:MessageForwarded" -#define TRACKER_EVOLUTION_PREDICATE_DELETED "EMailMeta:MessageDeleted" -#define TRACKER_EVOLUTION_PREDICATE_SIZE "EMailMeta:MessageSize" - -#define TRACKER_EVOLUTION_PREDICATE_JUNK "Evolution:MessageJunk" -#define TRACKER_EVOLUTION_PREDICATE_FILE "Evolution:MessageFile" -#define TRACKER_EVOLUTION_PREDICATE_UID "Evolution:MessageUid" -#define TRACKER_EVOLUTION_PREDICATE_FLAGGED "Evolution:MessageFlagged" -#define TRACKER_EVOLUTION_PREDICATE_TAG "Evolution:MessageTag" - -#define TRACKER_TYPE_G_STRV_ARRAY (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRV)) - -#define dbus_async_return_if_fail(expr,context) \ - G_STMT_START { \ - if G_LIKELY(expr) { } else { \ - GError *error = NULL; \ - \ - g_set_error (&error, \ - DBUS_ERROR, \ - 0, \ - "Assertion `%s' failed", \ - #expr); \ - \ - dbus_g_method_return_error (context, error); \ - g_error_free (error); \ - \ - return; \ - }; \ - } G_STMT_END - -#endif /* __TRACKER_EVOLUTION_COMMON_H__ */ diff --git a/src/plugins/evolution/tracker-evolution-plugin.c b/src/plugins/evolution/tracker-evolution-plugin.c index c3a84fb84..6871c20b0 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 3f59936fb..906f6a81f 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-evolution-plugin.xml b/src/plugins/evolution/tracker-evolution-plugin.xml deleted file mode 100644 index 8bb0a9ad0..000000000 --- a/src/plugins/evolution/tracker-evolution-plugin.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<node name="/"> - <interface name="org.freedesktop.email.metadata.Manager"> - <method name="Register"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="o" name="registrar_path" direction="in" /> - <arg type="u" name="last_modseq" direction="in" /> - </method> - </interface> -</node> - diff --git a/src/plugins/evolution/tracker-evolution-registrar.c b/src/plugins/evolution/tracker-evolution-registrar.c deleted file mode 100644 index 1a95554ee..000000000 --- a/src/plugins/evolution/tracker-evolution-registrar.c +++ /dev/null @@ -1,902 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2008, Nokia - * - * This library 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 of the License, or (at your option) any later version. - * - * This library 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 library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Authors: - * Philip Van Hoof <philip@codeminded.be> - */ - -#include "config.h" - -#include <string.h> - -#include <glib-object.h> -#include <dbus/dbus-glib-bindings.h> - -#include <libtracker-data/tracker-data-manager.h> -#include <libtracker-common/tracker-ontology.h> -#include <libtracker-common/tracker-sparql-builder.h> -#include <libtracker-common/tracker-dbus.h> - -#include <tracker-store/tracker-push-registrar.h> -#include <tracker-store/tracker-store.h> -#include <tracker-store/tracker-dbus.h> - -#define __TRACKER_EVOLUTION_REGISTRAR_C__ - -#include "tracker-evolution-registrar.h" -#include "tracker-evolution-registrar-glue.h" - -#define TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_EVOLUTION_REGISTRAR, TrackerEvolutionRegistrarPrivate)) - -#define TRACKER_TYPE_EVOLUTION_PUSH_REGISTRAR (tracker_evolution_push_registrar_get_type ()) -#define TRACKER_EVOLUTION_PUSH_REGISTRAR(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), TRACKER_TYPE_EVOLUTION_PUSH_REGISTRAR, TrackerEvolutionPushRegistrar)) - -#define NIE_DATASOURCE TRACKER_NIE_PREFIX "DataSource" -#define NIE_DATASOURCE_P 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" - -typedef struct TrackerEvolutionPushRegistrar TrackerEvolutionPushRegistrar; -typedef struct TrackerEvolutionPushRegistrarClass TrackerEvolutionPushRegistrarClass; - -struct TrackerEvolutionPushRegistrar { - TrackerPushRegistrar parent_instance; -}; - -struct TrackerEvolutionPushRegistrarClass { - TrackerPushRegistrarClass parent_class; -}; - -typedef struct { - gpointer dummy; -} TrackerEvolutionRegistrarPrivate; - -enum { - PROP_0, -}; - - -static GType tracker_evolution_push_registrar_get_type (void) G_GNUC_CONST; - -G_DEFINE_TYPE (TrackerEvolutionRegistrar, tracker_evolution_registrar, G_TYPE_OBJECT) -G_DEFINE_TYPE (TrackerEvolutionPushRegistrar, tracker_evolution_push_registrar, TRACKER_TYPE_PUSH_REGISTRAR); - -static void -tracker_evolution_registrar_finalize (GObject *object) -{ - G_OBJECT_CLASS (tracker_evolution_registrar_parent_class)->finalize (object); -} - - -static void -tracker_evolution_registrar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -tracker_evolution_registrar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -tracker_evolution_registrar_class_init (TrackerEvolutionRegistrarClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = tracker_evolution_registrar_finalize; - object_class->set_property = tracker_evolution_registrar_set_property; - object_class->get_property = tracker_evolution_registrar_get_property; - - g_type_class_add_private (object_class, sizeof (TrackerEvolutionRegistrarPrivate)); -} - -static void -tracker_evolution_registrar_init (TrackerEvolutionRegistrar *object) -{ -} - - - - - -#if 0 -static void -extract_mime_parts (GMimeObject *object, - gpointer user_data) -{ - const gchar *message_subject = user_data; - gchar *subject = NULL; - const gchar *disposition, *filename; - GMimePart *part; - - if (GMIME_IS_MESSAGE_PART (object)) { - GMimeMessage *message; - - message = g_mime_message_part_get_message (GMIME_MESSAGE_PART (object)); - - if (message) { - g_mime_message_foreach_part (message, extract_mime_parts, user_data); - g_object_unref (message); - } - - return; - } else if (GMIME_IS_MULTIPART (object)) { - g_mime_multipart_foreach (GMIME_MULTIPART (object), extract_mime_parts, user_data); - return; - } - - part = GMIME_PART (object); - disposition = g_mime_part_get_content_disposition (part); - - if (!disposition || - (g_strcmp0 (disposition, GMIME_DISPOSITION_ATTACHMENT) != 0 && - g_strcmp0 (disposition, GMIME_DISPOSITION_INLINE) != 0)) { - return; - } - - filename = g_mime_part_get_filename (GMIME_PART (object)); - - if (!filename || - g_strcmp0 (filename, "signature.asc") == 0 || - g_strcmp0 (filename, "signature.pgp") == 0) { - return; - } - - if (filename) { - GHashTable *data; - TrackerModuleMetadata *metadata; - gchar *subject; - - /* This is not a path but a URI: don't use the OS's dir separator - * here, use the '/'. Another option is to use '#' instead of '/' - * here. This depends on how we want to format the URI and what - * Evolution can cope with as URI for an attachment (I don't - * think it can cope with any attachment URI, btw). */ - - subject = g_strdup_printf ("%s/%s", message_subject, - filename); - - data_insert_statement (subject, - "File:Path", - filename); - - data_insert_statement (subject, - "File:Name", - filename); - - g_free (subject); - } -} - -static gchar * -get_object_encoding (GMimeObject *object) -{ - const gchar *start_encoding, *end_encoding; - const gchar *content_type = NULL; - - if (GMIME_IS_MESSAGE (object)) { - content_type = g_mime_message_get_header (GMIME_MESSAGE (object), "Content-Type"); - } else if (GMIME_IS_PART (object)) { - content_type = g_mime_part_get_content_header (GMIME_PART (object), "Content-Type"); - } - - if (!content_type) { - return NULL; - } - - start_encoding = strstr (content_type, "charset="); - - if (!start_encoding) { - return NULL; - } - - start_encoding += strlen ("charset="); - - if (start_encoding[0] == '"') { - /* encoding is quoted */ - start_encoding++; - end_encoding = strstr (start_encoding, "\""); - } else { - end_encoding = strstr (start_encoding, ";"); - } - - if (end_encoding) { - return g_strndup (start_encoding, end_encoding - start_encoding); - } else { - return g_strdup (start_encoding); - } -} -#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 -perform_set (TrackerEvolutionRegistrar *object, - const gchar *subject, - const GStrv predicates, - const GStrv values) -{ - guint i = 0; - TrackerSparqlBuilder *sparql; - const gchar *uri = subject; - - sparql = tracker_sparql_builder_new_update (); - - tracker_sparql_builder_insert_open (sparql); - - tracker_sparql_builder_subject_iri (sparql, DATASOURCE_URN); - tracker_sparql_builder_predicate (sparql, "rdf:type"); - tracker_sparql_builder_object_iri (sparql, NIE_DATASOURCE); - - tracker_sparql_builder_subject_iri (sparql, subject); - 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_iri (sparql, NIE_DATASOURCE_P); - tracker_sparql_builder_object_iri (sparql, DATASOURCE_URN); - - while (predicates [i] != NULL && values[i] != NULL) { - - /* TODO: TRACKER_EVOLUTION_PREDICATE_JUNK (!) - * TRACKER_EVOLUTION_PREDICATE_ANSWERED - * TRACKER_EVOLUTION_PREDICATE_FLAGGED - * TRACKER_EVOLUTION_PREDICATE_FORWARDED - * TRACKER_EVOLUTION_PREDICATE_DELETED (!) - * TRACKER_EVOLUTION_PREDICATE_SIZE (!) : - * - * I don't have predicates in Tracker's ontology for these. In - * Jürg's vstore branch we are working with Nepomuk as ontology- - * set. Perhaps when we merge this to that branch that we can - * improve this situation. */ - - -#if 0 - - /* Disabling this as I can't find any version of GMime-2.0 that - * wont crash on any of my test E-mails. Going to ask Garnacho - * to migrate to GMime-2.4 with his old Evolution support. */ - - if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_FILE) == 0) { - GMimeStream *stream; - GMimeParser *parser; - GMimeMessage *message; - gint fd; - gchar *text, *orig_text, *ptr, *encoding; - gchar *path = g_strdup (values[i]); - off_t offset = 0; - gboolean is_html; - - ptr = strstr (path, "/!"); - if (ptr) { - offset = (off_t) atol (ptr+2); - *ptr = '\0'; - } - - fd = tracker_file_open (path, FALSE); - - g_free (path); - - if (fd == -1) - goto cont; - - stream = g_mime_stream_fs_new_with_bounds (fd, offset, -1); - - if (!stream) { - close (fd); - goto cont; - } - - parser = g_mime_parser_new_with_stream (stream); - - if (!parser) { - g_object_unref (stream); - goto cont; - } - - g_mime_parser_set_scan_from (parser, FALSE); - - message = g_mime_parser_construct_message (parser); - - if (!message) { - g_object_unref (parser); - g_object_unref (stream); - goto cont; - } - - g_mime_message_foreach_part (message, - extract_mime_parts, - subject); - - orig_text = g_mime_message_get_body (message, TRUE, &is_html); - - if (orig_text) { - - encoding = get_object_encoding (GMIME_OBJECT (message)); - - if (encoding) { - text = g_convert (text, -1, "utf8", encoding, NULL, NULL, NULL); - g_free (orig_text); - } else - text = orig_text; - - data_insert_statement (object, subject, - METADATA_EMAIL_TEXT, - text); - - g_free (text); - g_free (encoding); - } - - g_object_unref (message); - g_object_unref (parser); - g_object_unref (stream); - } -#endif - - if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_TAG) == 0) { - gchar *key, *value; - - if (!values[i] || strlen (values[i]) < 1) - goto cont; - - key = g_strdup (values[i]); - value = strchr (key, '='); - - tracker_sparql_builder_subject_iri (sparql, subject); - - if (value) { - *value = '\0'; - value++; - } - - if (value) { - tracker_sparql_builder_predicate (sparql, "nao:hasProperty"); - - tracker_sparql_builder_object_blank_open (sparql); - - tracker_sparql_builder_predicate (sparql, "rdf:type"); - tracker_sparql_builder_object (sparql, "nao:Property"); - - tracker_sparql_builder_predicate (sparql, "nao:propertyName"); - tracker_sparql_builder_object_string (sparql, key); - - tracker_sparql_builder_predicate (sparql, "nao:propertyValue"); - tracker_sparql_builder_object_string (sparql, value); - - tracker_sparql_builder_object_blank_close (sparql); - - } else { - 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, key); - - tracker_sparql_builder_object_blank_close (sparql); - - } - - g_free (key); - } - - if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_SUBJECT) == 0) { - tracker_sparql_builder_subject_iri (sparql, subject); - tracker_sparql_builder_predicate (sparql, "nmo:messageSubject"); - tracker_sparql_builder_object_string (sparql, values[i]); - } - - if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_SENT) == 0) { - tracker_sparql_builder_subject_iri (sparql, subject); - tracker_sparql_builder_predicate (sparql, "nmo:receivedDate"); - tracker_sparql_builder_object_string (sparql, values[i]); - } - - if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_FROM) == 0) { - gchar *email_uri, *email = NULL, *fullname = NULL; - - get_email_and_fullname (values[i], &email, &fullname); - - email_uri = tracker_uri_printf_escaped ("mailto:%s", email); - - 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); - - tracker_sparql_builder_subject_iri (sparql, subject); - tracker_sparql_builder_predicate (sparql, "nmo:from"); - - 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); - } - - 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); - } - - - if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_TO) == 0) { - gchar *email_uri, *email = NULL, *fullname = NULL; - - get_email_and_fullname (values[i], &email, &fullname); - - email_uri = tracker_uri_printf_escaped ("mailto:%s", email); - - 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); - - tracker_sparql_builder_subject_iri (sparql, subject); - tracker_sparql_builder_predicate (sparql, "nmo:to"); - - 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); - } - - 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); - } - - if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_CC) == 0) { - gchar *email_uri, *email = NULL, *fullname = NULL; - - get_email_and_fullname (values[i], &email, &fullname); - - email_uri = tracker_uri_printf_escaped ("mailto:%s", email); - - 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); - - tracker_sparql_builder_subject_iri (sparql, subject); - tracker_sparql_builder_predicate (sparql, "nmo:cc"); - - 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); - } - - 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); - } - - cont: - - i++; - } - - tracker_sparql_builder_insert_close (sparql); - - tracker_store_queue_sparql_update (tracker_sparql_builder_get_result (sparql), - NULL, NULL, NULL); - - g_object_unref (sparql); -} - -static void -perform_unset (TrackerEvolutionRegistrar *object, - const gchar *subject) -{ - gchar *sparql = g_strdup_printf ("DELETE { <%s> a rdfs:Resource }", subject); - - tracker_store_queue_sparql_update (sparql, NULL, NULL, NULL); - - g_free (sparql); -} - -static void -perform_cleanup (TrackerEvolutionRegistrar *object) -{ - tracker_store_queue_sparql_update ("DELETE { ?s a rdfs:Resource } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", NULL, NULL, NULL); - /* tracker_store_queue_sparql_update ("DELETE { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", NULL, NULL, NULL); */ -} - -static void -set_stored_last_modseq (guint last_modseq) -{ - tracker_data_manager_set_db_option_int64 ("EvolutionLastModseq", (gint64) last_modseq); -} - -static void -on_commit (gpointer user_data) -{ - set_stored_last_modseq (GPOINTER_TO_UINT (user_data)); -} - - -void -tracker_evolution_registrar_set (TrackerEvolutionRegistrar *object, - const gchar *subject, - const GStrv predicates, - const GStrv values, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror) -{ - guint request_id; - - request_id = tracker_dbus_get_next_request_id (); - - tracker_dbus_request_new (request_id, - "D-Bus request to set one: 'Evolution' "); - - dbus_async_return_if_fail (subject != NULL, context); - - if (predicates && values) { - - dbus_async_return_if_fail (g_strv_length (predicates) == - g_strv_length (values), context); - - perform_set (object, subject, predicates, values); - } - - tracker_store_queue_commit (on_commit, GUINT_TO_POINTER (modseq), NULL); - - dbus_g_method_return (context); - - tracker_dbus_request_success (request_id); -} - - -void -tracker_evolution_registrar_set_many (TrackerEvolutionRegistrar *object, - const GStrv subjects, - const GPtrArray *predicates, - const GPtrArray *values, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror) -{ - guint request_id; - guint len, i = 0; - - request_id = tracker_dbus_get_next_request_id (); - - dbus_async_return_if_fail (subjects != NULL, context); - dbus_async_return_if_fail (predicates != NULL, context); - dbus_async_return_if_fail (values != NULL, context); - - len = g_strv_length (subjects); - - dbus_async_return_if_fail (len == predicates->len, context); - dbus_async_return_if_fail (len == values->len, context); - - tracker_dbus_request_new (request_id, - "D-Bus request to set many: 'Evolution' " - "'%d'", len); - - while (subjects[i] != NULL) { - perform_set (object, - subjects[i], - g_ptr_array_index (predicates, i), - g_ptr_array_index (values, i)); - i++; - } - - tracker_store_queue_commit (on_commit, - GUINT_TO_POINTER (modseq), - NULL); - - dbus_g_method_return (context); - - tracker_dbus_request_success (request_id); -} - - - -void -tracker_evolution_registrar_unset_many (TrackerEvolutionRegistrar *object, - const GStrv subjects, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror) -{ - guint i = 0; - guint request_id; - - request_id = tracker_dbus_get_next_request_id (); - - tracker_dbus_request_new (request_id, - "D-Bus request to unset many: 'Evolution' " - "'%d'", g_strv_length (subjects)); - - dbus_async_return_if_fail (subjects != NULL, context); - - while (subjects[i] != NULL) { - perform_unset (object, subjects[i]); - i++; - } - - tracker_store_queue_commit (on_commit, GUINT_TO_POINTER (modseq), NULL); - - dbus_g_method_return (context); - - tracker_dbus_request_success (request_id); -} - -void -tracker_evolution_registrar_unset (TrackerEvolutionRegistrar *object, - const gchar *subject, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror) -{ - guint request_id; - - request_id = tracker_dbus_get_next_request_id (); - - tracker_dbus_request_new (request_id, - "D-Bus request to unset one: 'Evolution'"); - - dbus_async_return_if_fail (subject != NULL, context); - - perform_unset (object, subject); - - tracker_store_queue_commit (on_commit, GUINT_TO_POINTER (modseq), NULL); - - dbus_g_method_return (context); - - tracker_dbus_request_success (request_id); -} - -void -tracker_evolution_registrar_cleanup (TrackerEvolutionRegistrar *object, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror) -{ - guint request_id; - - request_id = tracker_dbus_get_next_request_id (); - - tracker_dbus_request_new (request_id, - "D-Bus request to cleanup: 'Evolution'"); - - perform_cleanup (object); - - tracker_store_queue_commit (on_commit, GUINT_TO_POINTER (modseq), NULL); - - dbus_g_method_return (context); - - tracker_dbus_request_success (request_id); -} - - -static void -on_manager_destroy (DBusGProxy *proxy, gpointer user_data) -{ - return; -} - -static void -tracker_evolution_push_registrar_enable (TrackerPushRegistrar *registrar, - DBusGConnection *connection, - DBusGProxy *dbus_proxy, - GError **error) -{ - GError *nerror = NULL; - guint result; - DBusGProxy *manager_proxy; - GObject *object; - - tracker_push_registrar_set_object (registrar, NULL); - tracker_push_registrar_set_manager (registrar, NULL); - - manager_proxy = dbus_g_proxy_new_for_name (connection, - TRACKER_EVOLUTION_MANAGER_SERVICE, - TRACKER_EVOLUTION_MANAGER_PATH, - TRACKER_EVOLUTION_MANAGER_INTERFACE); - - /* Creation of the registrar */ - if (!org_freedesktop_DBus_request_name (dbus_proxy, - TRACKER_EVOLUTION_REGISTRAR_SERVICE, - DBUS_NAME_FLAG_DO_NOT_QUEUE, - &result, &nerror)) { - - g_critical ("Could not setup D-Bus, %s in use\n", - TRACKER_EVOLUTION_REGISTRAR_SERVICE); - - if (nerror) { - g_propagate_error (error, nerror); - return; - } - } - - if (nerror) { - g_propagate_error (error, nerror); - return; - } - - object = g_object_new (TRACKER_TYPE_EVOLUTION_REGISTRAR, NULL); - - dbus_g_object_type_install_info (G_OBJECT_TYPE (object), - &dbus_glib_tracker_evolution_registrar_object_info); - - dbus_g_connection_register_g_object (connection, - TRACKER_EVOLUTION_REGISTRAR_PATH, - object); - - /* Registration of the registrar to the manager - the cast is fine and checked */ - dbus_g_proxy_call_no_reply (manager_proxy, "Register", - G_TYPE_OBJECT, object, - G_TYPE_UINT, (guint) tracker_data_manager_get_db_option_int64 ("EvolutionLastModseq"), - G_TYPE_INVALID, - G_TYPE_INVALID); - - /* If while we had a proxy for the manager the manager shut itself down, - * then we'll get rid of our registrar too, in on_manager_destroy */ - - g_signal_connect (manager_proxy, "destroy", - G_CALLBACK (on_manager_destroy), registrar); - - tracker_push_registrar_set_object (registrar, object); - tracker_push_registrar_set_manager (registrar, manager_proxy); - - g_object_unref (object); /* sink own */ - g_object_unref (manager_proxy); /* sink own */ - - g_debug ("Enabled Push module 'Evolution'"); -} - -static void -tracker_evolution_push_registrar_disable (TrackerPushRegistrar *registrar) -{ - tracker_push_registrar_set_object (registrar, NULL); - tracker_push_registrar_set_manager (registrar, NULL); - g_debug ("Disabled Push module 'Evolution'"); -} - -static void -tracker_evolution_push_registrar_class_init (TrackerEvolutionPushRegistrarClass *klass) -{ - TrackerPushRegistrarClass *p_class = TRACKER_PUSH_REGISTRAR_CLASS (klass); - - p_class->enable = tracker_evolution_push_registrar_enable; - p_class->disable = tracker_evolution_push_registrar_disable; -} - -static void -tracker_evolution_push_registrar_init (TrackerEvolutionPushRegistrar *registrar) -{ - return; -} - -TrackerPushRegistrar * -tracker_push_module_init (void) -{ - GObject *object; - - object = g_object_new (TRACKER_TYPE_EVOLUTION_PUSH_REGISTRAR, NULL); - - tracker_push_registrar_set_service (TRACKER_PUSH_REGISTRAR (object), - TRACKER_EVOLUTION_MANAGER_SERVICE); - - return TRACKER_PUSH_REGISTRAR (object); -} - -void -tracker_push_module_shutdown (TrackerPushRegistrar *registrar) -{ - tracker_evolution_push_registrar_disable (registrar); -} diff --git a/src/plugins/evolution/tracker-evolution-registrar.h b/src/plugins/evolution/tracker-evolution-registrar.h deleted file mode 100644 index 1635c69f9..000000000 --- a/src/plugins/evolution/tracker-evolution-registrar.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2008, Nokia - * - * This library 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 of the License, or (at your option) any later version. - * - * This library 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 library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Authors: - * Philip Van Hoof <philip@codeminded.be> - */ - -#ifndef __LIBTRACKER_EVOLUTION_REGISTRAR_H__ -#define __LIBTRACKER_EVOLUTION_REGISTRAR_H__ - -#if !defined (TRACKER_ENABLE_INTERNALS) && !defined (TRACKER_COMPILATION) -#error "TRACKER_ENABLE_INTERNALS not defined, this must be defined to use tracker's internal functions" -#endif - -#include <dbus/dbus-glib-bindings.h> - -#include <tracker-store/tracker-push.h> -#include "tracker-evolution-common.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_EVOLUTION_REGISTRAR (tracker_evolution_registrar_get_type()) -#define TRACKER_EVOLUTION_REGISTRAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_EVOLUTION_REGISTRAR, TrackerEvolutionRegistrar)) -#define TRACKER_EVOLUTION_REGISTRAR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_EVOLUTION_REGISTRAR, TrackerEvolutionRegistrarClass)) -#define TRACKER_EVOLUTION_REGISTRAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_EVOLUTION_REGISTRAR, TrackerEvolutionRegistrarClass)) - -G_BEGIN_DECLS - -#ifndef __TRACKER_EVOLUTION_REGISTRAR_C__ -extern const DBusGMethodInfo *registrar_methods; -#endif - -typedef struct TrackerEvolutionRegistrar TrackerEvolutionRegistrar; -typedef struct TrackerEvolutionRegistrarClass TrackerEvolutionRegistrarClass; - -struct TrackerEvolutionRegistrar { - GObject parent; -}; - -struct TrackerEvolutionRegistrarClass { - GObjectClass parent; -}; - -GType tracker_evolution_registrar_get_type (void); - -void tracker_evolution_registrar_set (TrackerEvolutionRegistrar *object, - const gchar *subject, - const GStrv predicates, - const GStrv values, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror); -void tracker_evolution_registrar_set_many (TrackerEvolutionRegistrar *object, - const GStrv subjects, - const GPtrArray *predicates, - const GPtrArray *values, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror); -void tracker_evolution_registrar_unset_many (TrackerEvolutionRegistrar *object, - const GStrv subjects, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror); -void tracker_evolution_registrar_unset (TrackerEvolutionRegistrar *object, - const gchar *subject, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror); -void tracker_evolution_registrar_cleanup (TrackerEvolutionRegistrar *object, - const guint modseq, - DBusGMethodInvocation *context, - GError *derror); - - -G_END_DECLS - -#endif /* __LIBTRACKER_EVOLUTION_REGISTRAR_H__ */ diff --git a/src/plugins/evolution/tracker-evolution-registrar.xml b/src/plugins/evolution/tracker-evolution-registrar.xml deleted file mode 100644 index 1f4d0b84b..000000000 --- a/src/plugins/evolution/tracker-evolution-registrar.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<node name="/"> - <interface name="org.freedesktop.email.metadata.Registrar"> - - <method name="Set"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="s" name="subject" direction="in" /> - <arg type="as" name="predicates" direction="in" /> - <arg type="as" name="values" direction="in" /> - <arg type="u" name="modseq" direction="in" /> - </method> - - <method name="SetMany"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="as" name="subjects" direction="in" /> - <arg type="aas" name="predicates" direction="in" /> - <arg type="aas" name="values" direction="in" /> - <arg type="u" name="modseq" direction="in" /> - </method> - - <method name="Unset"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="s" name="subject" direction="in" /> - <arg type="u" name="modseq" direction="in" /> - </method> - - <method name="UnsetMany"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="as" name="subjects" direction="in" /> - <arg type="u" name="modseq" direction="in" /> - </method> - - <method name="Cleanup"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="u" name="modseq" direction="in" /> - </method> - - </interface> -</node> 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 000000000..7e490e558 --- /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 |