tracker r1754 - in branches/indexer-split: . src/tracker-indexer/modules
- From: carlosg svn gnome org
- To: svn-commits-list gnome org
- Subject: tracker r1754 - in branches/indexer-split: . src/tracker-indexer/modules
- Date: Tue, 24 Jun 2008 15:07:24 +0000 (UTC)
Author: carlosg
Date: Tue Jun 24 15:07:24 2008
New Revision: 1754
URL: http://svn.gnome.org/viewvc/tracker?rev=1754&view=rev
Log:
2008-06-24 Carlos Garnacho <carlos imendio com>
* src/tracker-indexer/modules/Makefile.am:
* src/tracker-indexer/modules/evolution.c: Module for Evolution,
initially it supports local and IMAP mailboxes. It's still missing
message body and attachments retrieval.
Added:
branches/indexer-split/src/tracker-indexer/modules/evolution.c
Modified:
branches/indexer-split/ChangeLog
branches/indexer-split/src/tracker-indexer/modules/Makefile.am
Modified: branches/indexer-split/src/tracker-indexer/modules/Makefile.am
==============================================================================
--- branches/indexer-split/src/tracker-indexer/modules/Makefile.am (original)
+++ branches/indexer-split/src/tracker-indexer/modules/Makefile.am Tue Jun 24 15:07:24 2008
@@ -6,15 +6,18 @@
-DLIBDIR=\""$(libdir)"\" \
-DLOCALEDIR=\""$(localedir)"\" \
-DINDEXER_MODULES_DIR=\"$(indexer_modulesdir)\" \
+ -D_GNU_SOURCE \
-I$(top_srcdir)/src \
$(GMODULE_CFLAGS) \
$(GIO_LIBS) \
- $(GLIB2_CFLAGS)
+ $(GLIB2_CFLAGS) \
+ $(GMIME_CFLAGS)
indexer_modules_LTLIBRARIES = \
libtracker-indexer-applications.la \
libtracker-indexer-files.la \
- libtracker-indexer-gaim-conversations.la
+ libtracker-indexer-gaim-conversations.la \
+ libtracker-indexer-evolution.la
# Applications module
libtracker_indexer_applications_la_SOURCES = applications.c
@@ -41,3 +44,11 @@
$(GMODULE_LIBS) \
$(GIO_LIBS) \
$(GLIB2_LIBS)
+
+# Evolution
+libtracker_indexer_evolution_la_SOURCES = evolution.c
+libtracker_indexer_evolution_la_LDFLAGS = $(module_flags)
+libtracker_indexer_evolution_la_LIBADD = \
+ $(GMODULE_LIBS) \
+ $(GLIB2_LIBS) \
+ $(GMIME_LIBS)
Added: branches/indexer-split/src/tracker-indexer/modules/evolution.c
==============================================================================
--- (empty file)
+++ branches/indexer-split/src/tracker-indexer/modules/evolution.c Tue Jun 24 15:07:24 2008
@@ -0,0 +1,597 @@
+/* Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
+ * 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.
+ */
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gmime/gmime.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <tracker-indexer/tracker-module.h>
+#include <libtracker-common/tracker-file-utils.h>
+#include <libtracker-common/tracker-type-utils.h>
+
+#define METADATA_FILE_PATH "File:Path"
+#define METADATA_FILE_NAME "File:Name"
+#define METADATA_EMAIL_RECIPIENT "Email:Recipient"
+#define METADATA_EMAIL_DATE "Email:Date"
+#define METADATA_EMAIL_SENDER "Email:Sender"
+#define METADATA_EMAIL_SUBJECT "Email:Subject"
+
+typedef union EvolutionFileData EvolutionFileData;
+typedef struct EvolutionLocalData EvolutionLocalData;
+typedef struct EvolutionImapData EvolutionImapData;
+typedef enum MailStorageType MailStorageType;
+
+enum MailStorageType {
+ MAIL_STORAGE_NONE,
+ MAIL_STORAGE_LOCAL,
+ MAIL_STORAGE_IMAP
+};
+
+struct EvolutionLocalData {
+ MailStorageType type;
+ GMimeStream *stream;
+ GMimeParser *parser;
+ GMimeMessage *message;
+};
+
+struct EvolutionImapData {
+ MailStorageType type;
+ gint fd;
+ FILE *summary;
+ guint n_messages;
+ guint cur_message;
+};
+
+union EvolutionFileData {
+ MailStorageType type;
+ EvolutionLocalData mbox;
+ EvolutionImapData imap;
+};
+
+enum SummaryDataType {
+ SUMMARY_TYPE_INT32,
+ SUMMARY_TYPE_UINT32,
+ SUMMARY_TYPE_STRING,
+ SUMMARY_TYPE_TOKEN,
+ SUMMARY_TYPE_TIME_T
+};
+
+static gboolean
+read_summary (FILE *summary,
+ ...)
+{
+ va_list args;
+ gint value_type;
+
+ if (!summary) {
+ return FALSE;
+ }
+
+ va_start (args, summary);
+
+ while ((value_type = va_arg (args, gint)) != -1) {
+ switch (value_type) {
+ case SUMMARY_TYPE_TIME_T:
+ case SUMMARY_TYPE_INT32: {
+ gint32 value, *dest;
+
+ if (fread (&value, sizeof (gint32), 1, summary) != 1) {
+ return FALSE;
+ }
+
+ dest = va_arg (args, gint32*);
+
+ if (dest) {
+ *dest = g_ntohl (value);
+ }
+ break;
+ }
+ case SUMMARY_TYPE_UINT32: {
+ guint32 *dest, value = 0;
+ gint c;
+
+ while (((c = fgetc (summary)) & 0x80) == 0 && c != EOF) {
+ value |= c;
+ value <<= 7;
+ }
+
+ if (c == EOF) {
+ return FALSE;
+ } else {
+ value |= (c & 0x7f);
+ }
+
+ dest = va_arg (args, guint32*);
+
+ if (dest) {
+ *dest = value;
+ }
+ break;
+ }
+ case SUMMARY_TYPE_STRING:
+ case SUMMARY_TYPE_TOKEN: {
+ guint32 len;
+ gchar *str, **dest;
+
+ /* read string length */
+ read_summary (summary, SUMMARY_TYPE_UINT32, &len, -1);
+ dest = va_arg (args, gchar **);
+
+ if (dest) {
+ *dest = NULL;
+ }
+
+ if (value_type == SUMMARY_TYPE_TOKEN) {
+ if (len < 32) {
+ continue;
+ } else {
+ len -= 31;
+ }
+ }
+
+ if (len <= 1) {
+ continue;
+ }
+
+ str = g_malloc0 (len);
+
+ if (fread (str, len - 1, 1, summary) != 1) {
+ g_free (str);
+ return FALSE;
+ }
+
+ if (dest) {
+ *dest = str;
+ } else {
+ g_free (str);
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ va_end (args);
+
+ return TRUE;
+}
+
+G_CONST_RETURN gchar *
+tracker_module_get_name (void)
+{
+ /* Return module name here */
+ return "Evolution";
+}
+
+gchar **
+tracker_module_get_directories (void)
+{
+ gchar **dirs;
+
+ g_mime_init (0);
+
+ dirs = g_new0 (gchar *, 3);
+ dirs[0] = g_build_filename (g_get_home_dir (), ".evolution", "mail", "local", NULL);
+ dirs[1] = g_build_filename (g_get_home_dir (), ".evolution", "mail", "imap", NULL);
+
+ return dirs;
+}
+
+static MailStorageType
+get_mail_storage_type_from_path (const gchar *path)
+{
+ MailStorageType type = MAIL_STORAGE_NONE;
+ gchar *basename, *local_dir, *imap_dir;
+
+ basename = g_path_get_basename (path);
+ local_dir = g_build_filename (g_get_home_dir (), ".evolution", "mail", "local", NULL);
+ imap_dir = g_build_filename (g_get_home_dir (), ".evolution", "mail", "imap", NULL);
+
+ if (g_str_has_prefix (path, local_dir) &&
+ strchr (basename, '.') == NULL) {
+ type = MAIL_STORAGE_LOCAL;
+ } else if (g_str_has_prefix (path, imap_dir) &&
+ strcmp (basename, "summary") == 0) {
+ type = MAIL_STORAGE_IMAP;
+ }
+
+ /* Exclude non wanted folders */
+ if (strcasestr (path, "junk") ||
+ strcasestr (path, "spam") ||
+ strcasestr (path, "trash") ||
+ strcasestr (path, "drafts") ||
+ strcasestr (path, "outbox")) {
+ type = MAIL_STORAGE_NONE;
+ }
+
+ g_free (local_dir);
+ g_free (imap_dir);
+ g_free (basename);
+
+ return type;
+}
+
+static GMimeStream *
+email_get_stream (const gchar *path,
+ gint flags,
+ off_t start)
+{
+ GMimeStream *stream;
+ gint fd;
+
+ fd = g_open (path, flags, S_IRUSR | S_IWUSR);
+
+ if (fd == -1) {
+ return NULL;
+ }
+
+ stream = g_mime_stream_fs_new_with_bounds (fd, start, -1);
+
+ if (!stream) {
+ close (fd);
+ }
+
+ return stream;
+}
+
+static gint
+read_summary_header (FILE *summary)
+{
+ gint32 version, n_messages;
+
+ read_summary (summary,
+ SUMMARY_TYPE_INT32, &version,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, &n_messages,
+ -1);
+
+ if ((version < 0x100 && version >= 13)) {
+ read_summary (summary,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ -1);
+ }
+
+ if (version != 0x30c) {
+ read_summary (summary,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ -1);
+ }
+
+ return n_messages;
+}
+
+gpointer
+tracker_module_file_get_data (const gchar *path)
+{
+ EvolutionFileData *data = NULL;
+ MailStorageType type;
+
+ type = get_mail_storage_type_from_path (path);
+
+ if (type == MAIL_STORAGE_NONE) {
+ return NULL;
+ }
+
+ data = g_slice_new0 (EvolutionFileData);
+ data->type = type;
+
+ if (type == MAIL_STORAGE_IMAP) {
+ EvolutionImapData *imap_data;
+
+ imap_data = (EvolutionImapData *) data;
+
+ imap_data->fd = tracker_file_open (path, TRUE);
+
+ if (imap_data->fd == -1) {
+ return NULL;
+ }
+
+ imap_data->summary = fdopen (imap_data->fd, "r");
+ imap_data->n_messages = read_summary_header (imap_data->summary);
+ imap_data->cur_message = 1;
+ } else {
+ EvolutionLocalData *local_data;
+
+ local_data = (EvolutionLocalData *) data;
+
+#if defined(__linux__)
+ local_data->stream = email_get_stream (path, O_RDONLY | O_NOATIME, 0);
+#else
+ local_data->stream = email_get_stream (path, O_RDONLY, 0);
+#endif
+
+ if (local_data->stream) {
+ local_data->parser = g_mime_parser_new_with_stream (local_data->stream);
+ g_mime_parser_set_scan_from (local_data->parser, TRUE);
+
+ /* Initialize to the first message */
+ local_data->message = g_mime_parser_construct_message (local_data->parser);
+ }
+ }
+
+ return data;
+}
+
+static void
+free_imap_data (EvolutionImapData *data)
+{
+ fclose (data->summary);
+ close (data->fd);
+}
+
+static void
+free_local_data (EvolutionLocalData *data)
+{
+ if (data->message) {
+ g_object_unref (data->message);
+ }
+
+ if (data->parser) {
+ g_object_unref (data->parser);
+ }
+
+ if (data->stream) {
+ g_mime_stream_close (data->stream);
+ g_object_unref (data->stream);
+ }
+}
+
+void
+tracker_module_file_free_data (gpointer file_data)
+{
+ EvolutionFileData *data;
+
+ data = (EvolutionFileData *) file_data;
+
+ if (data->type == MAIL_STORAGE_LOCAL) {
+ free_local_data ((EvolutionLocalData *) data);
+ } else if (data->type == MAIL_STORAGE_IMAP) {
+ free_imap_data ((EvolutionImapData *) data);
+ }
+
+ g_slice_free (EvolutionFileData, data);
+}
+
+GHashTable *
+get_metadata_for_mbox (TrackerFile *file)
+{
+ EvolutionLocalData *data;
+ GMimeMessage *message;
+ GHashTable *metadata;
+ time_t date;
+
+ data = file->data;
+ message = data->message;
+
+ if (!message) {
+ return NULL;
+ }
+
+ metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL,
+ (GDestroyNotify) g_free);
+
+ g_mime_message_get_date (message, &date, NULL);
+ g_hash_table_insert (metadata, METADATA_EMAIL_DATE,
+ tracker_uint_to_string (date));
+
+ g_hash_table_insert (metadata, METADATA_EMAIL_SENDER,
+ g_strdup (g_mime_message_get_sender (message)));
+ g_hash_table_insert (metadata, METADATA_EMAIL_SUBJECT,
+ g_strdup (g_mime_message_get_subject (message)));
+
+ /* Missing:
+ *
+ * Recipients:
+ * To
+ * CC
+ * BCC
+ * Body
+ * Attachments
+ */
+
+ return metadata;
+}
+
+void
+skip_content_info (FILE *summary)
+{
+ guint32 count, i;
+
+ if (fgetc (summary)) {
+ read_summary (summary,
+ SUMMARY_TYPE_TOKEN, NULL,
+ SUMMARY_TYPE_TOKEN, NULL,
+ SUMMARY_TYPE_UINT32, &count,
+ -1);
+
+ if (count <= 500) {
+ for (i = 0; i < count; i++) {
+ read_summary (summary,
+ SUMMARY_TYPE_TOKEN, NULL,
+ SUMMARY_TYPE_TOKEN, NULL,
+ -1);
+ }
+ }
+
+ read_summary (summary,
+ SUMMARY_TYPE_TOKEN, NULL,
+ SUMMARY_TYPE_TOKEN, NULL,
+ SUMMARY_TYPE_TOKEN, NULL,
+ SUMMARY_TYPE_UINT32, NULL,
+ -1);
+ }
+
+ read_summary (summary,
+ SUMMARY_TYPE_UINT32, &count,
+ -1);
+
+ for (i = 0; i < count; i++) {
+ skip_content_info (summary);
+ }
+}
+
+GHashTable *
+get_metadata_for_imap (TrackerFile *file)
+{
+ EvolutionImapData *data;
+ GHashTable *metadata;
+ gchar *uid, *subject, *from, *to;
+ gint32 i, count;
+ time_t date;
+
+ data = file->data;
+
+ if (data->cur_message > data->n_messages) {
+ return NULL;
+ }
+
+ read_summary (data->summary,
+ SUMMARY_TYPE_STRING, &uid, /* message uid */
+ SUMMARY_TYPE_UINT32, NULL, /* flags */
+ SUMMARY_TYPE_UINT32, NULL, /* size */
+ SUMMARY_TYPE_TIME_T, NULL, /* date sent */
+ SUMMARY_TYPE_TIME_T, &date, /* date received */
+ SUMMARY_TYPE_STRING, &subject, /* subject */
+ SUMMARY_TYPE_STRING, &from, /* from */
+ SUMMARY_TYPE_STRING, &to, /* to */
+ SUMMARY_TYPE_STRING, NULL, /* cc */
+ SUMMARY_TYPE_STRING, NULL, /* mlist */
+ -1);
+
+ metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL,
+ (GDestroyNotify) g_free);
+
+ g_hash_table_insert (metadata, METADATA_EMAIL_DATE,
+ tracker_uint_to_string (date));
+
+ g_hash_table_insert (metadata, METADATA_EMAIL_SENDER, from);
+ g_hash_table_insert (metadata, METADATA_EMAIL_SUBJECT, subject);
+
+ g_free (uid);
+ g_free (to);
+
+ read_summary (data->summary,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_UINT32, &count,
+ -1);
+
+ /* references */
+ for (i = 0; i < count; i++) {
+ read_summary (data->summary,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ -1);
+ }
+
+ read_summary (data->summary, SUMMARY_TYPE_UINT32, &count, -1);
+
+ /* user flags */
+ for (i = 0; i < count; i++) {
+ read_summary (data->summary, SUMMARY_TYPE_STRING, NULL, -1);
+ }
+
+ read_summary (data->summary, SUMMARY_TYPE_UINT32, &count, -1);
+
+ /* user tags */
+ for (i = 0; i < count; i++) {
+ read_summary (data->summary,
+ SUMMARY_TYPE_STRING, NULL,
+ SUMMARY_TYPE_STRING, NULL,
+ -1);
+ }
+
+ /* server flags */
+ read_summary (data->summary,
+ SUMMARY_TYPE_UINT32, NULL,
+ -1);
+
+ skip_content_info (data->summary);
+
+ return metadata;
+}
+
+GHashTable *
+tracker_module_file_get_metadata (TrackerFile *file)
+{
+ EvolutionFileData *data;
+
+ data = file->data;
+
+ if (!data) {
+ /* It isn't any of the files the
+ * module is interested for */
+ return NULL;
+ }
+
+ switch (data->type) {
+ case MAIL_STORAGE_LOCAL:
+ return get_metadata_for_mbox (file);
+ case MAIL_STORAGE_IMAP:
+ return get_metadata_for_imap (file);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+gboolean
+tracker_module_file_iter_contents (TrackerFile *file)
+{
+ EvolutionFileData *data;
+
+ data = file->data;
+
+ if (data->type == MAIL_STORAGE_IMAP) {
+ EvolutionImapData *imap_data = file->data;
+
+ imap_data->cur_message++;
+
+ return (imap_data->cur_message < imap_data->n_messages);
+ } else if (data->type == MAIL_STORAGE_LOCAL) {
+ EvolutionLocalData *local_data = file->data;
+
+ if (!local_data->parser) {
+ return FALSE;
+ }
+
+ if (local_data->message) {
+ g_object_unref (local_data->message);
+ }
+
+ local_data->message = g_mime_parser_construct_message (local_data->parser);
+
+ return (local_data->message != NULL);
+ }
+
+ return FALSE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]