tracker r2535 - in trunk: . data/modules src/tracker-indexer src/tracker-indexer/modules
- From: carlosg svn gnome org
- To: svn-commits-list gnome org
- Subject: tracker r2535 - in trunk: . data/modules src/tracker-indexer src/tracker-indexer/modules
- Date: Thu, 20 Nov 2008 15:29:19 +0000 (UTC)
Author: carlosg
Date: Thu Nov 20 15:29:19 2008
New Revision: 2535
URL: http://svn.gnome.org/viewvc/tracker?rev=2535&view=rev
Log:
2008-11-20 Carlos Garnacho <carlos imendio com>
Make indexer modules API GObject oriented, which allows easier
bindings development and more flexible behavior for modules.
* src/tracker-indexer/tracker-module-file.[ch]:
* src/tracker-indexer/tracker-module-iteratable.[ch]: Definition of
abstract base object and interface for modules to implement.
* src/tracker-indexer/tracker-indexer-module.[ch]: Build on top of
GTypeModule.
* src/tracker-indexer/tracker-indexer.c: Modify to use new modules
API.
* src/tracker-indexer/tracker-module.h: Removed, no longer needed.
* src/tracker-indexer/tracker-metadata-utils.[ch]: Switch API to
GFile, since modules API now also deals with it.
* src/modules/evolution-common.[ch]:
* src/modules/evolution-imap.[ch]:
* src/modules/evolution-pop.[ch]:
* src/modules/evolution.c: Implement new modules API, split POP3/IMAP
implementations, and make the module return different
TrackerModuleFile objects depending on the parsed file.
* src/modules/dummy.c:
* src/modules/files.c:
* src/modules/applications.c: Implement new modules API.
* data/modules/files.c: Specify service type.
Added:
trunk/src/tracker-indexer/modules/evolution-common.c
trunk/src/tracker-indexer/modules/evolution-common.h
trunk/src/tracker-indexer/modules/evolution-imap.c
trunk/src/tracker-indexer/modules/evolution-imap.h
trunk/src/tracker-indexer/modules/evolution-pop.c
trunk/src/tracker-indexer/modules/evolution-pop.h
trunk/src/tracker-indexer/tracker-module-file.c
trunk/src/tracker-indexer/tracker-module-file.h
trunk/src/tracker-indexer/tracker-module-iteratable.c
trunk/src/tracker-indexer/tracker-module-iteratable.h
Removed:
trunk/src/tracker-indexer/tracker-module.h
Modified:
trunk/ChangeLog
trunk/data/modules/files.module
trunk/src/tracker-indexer/Makefile.am
trunk/src/tracker-indexer/modules/Makefile.am
trunk/src/tracker-indexer/modules/applications.c
trunk/src/tracker-indexer/modules/dummy.c
trunk/src/tracker-indexer/modules/evolution.c
trunk/src/tracker-indexer/modules/files.c
trunk/src/tracker-indexer/tracker-indexer-module.c
trunk/src/tracker-indexer/tracker-indexer-module.h
trunk/src/tracker-indexer/tracker-indexer.c
trunk/src/tracker-indexer/tracker-metadata-utils.c
trunk/src/tracker-indexer/tracker-metadata-utils.h
Modified: trunk/data/modules/files.module
==============================================================================
--- trunk/data/modules/files.module (original)
+++ trunk/data/modules/files.module Thu Nov 20 15:29:19 2008
@@ -11,7 +11,7 @@
Files=*~;*.o;*.la;*.lo;*.loT;*.in;*.csproj;*.m4;*.rej;*.gmo;*.orig;*.pc;*.omf;*.aux;*.tmp;*.po;*.vmdk;*.vm*;*.nvram;*.part;autom4te;conftest;confstat;Makefile;SCCS;litmain.sh;libtool;config.status;confdefs.h;
[Index]
-Service=
+Service=Files
MimeTypes=
Files=
Modified: trunk/src/tracker-indexer/Makefile.am
==============================================================================
--- trunk/src/tracker-indexer/Makefile.am (original)
+++ trunk/src/tracker-indexer/Makefile.am Thu Nov 20 15:29:19 2008
@@ -20,12 +20,14 @@
libtracker_indexer_LTLIBRARIES = libtracker-indexer.la
libtracker_indexer_la_SOURCES = \
- tracker-metadata-utils.c
+ tracker-metadata-utils.c \
+ tracker-module-file.c \
+ tracker-module-iteratable.c
libtracker_indexerinclude_HEADERS = \
tracker-metadata-utils.h \
- tracker-module.h
-
+ tracker-module-file.h \
+ tracker-module-iteratable.h
libexec_PROGRAMS = tracker-indexer
Modified: trunk/src/tracker-indexer/modules/Makefile.am
==============================================================================
--- trunk/src/tracker-indexer/modules/Makefile.am (original)
+++ trunk/src/tracker-indexer/modules/Makefile.am Thu Nov 20 15:29:19 2008
@@ -54,7 +54,12 @@
libtracker-indexer-evolution.la
# Evolution
-libtracker_indexer_evolution_la_SOURCES = evolution.c
+libtracker_indexer_evolution_la_SOURCES = \
+ evolution-common.c \
+ evolution-imap.c \
+ evolution-pop.c \
+ evolution.c
+
libtracker_indexer_evolution_la_LDFLAGS = $(module_flags)
libtracker_indexer_evolution_la_LIBADD = \
$(GMODULE_LIBS) \
Modified: trunk/src/tracker-indexer/modules/applications.c
==============================================================================
--- trunk/src/tracker-indexer/modules/applications.c (original)
+++ trunk/src/tracker-indexer/modules/applications.c Thu Nov 20 15:29:19 2008
@@ -19,7 +19,7 @@
#include <stdlib.h>
#include <glib.h>
-#include <tracker-indexer/tracker-module.h>
+#include <tracker-indexer/tracker-module-file.h>
#include <libtracker-data/tracker-data-metadata.h>
#define GROUP_DESKTOP_ENTRY "Desktop Entry"
@@ -43,11 +43,43 @@
#define METADATA_APP_MIMETYPE "App:MimeType"
#define METADATA_APP_CATEGORIES "App:Categories"
-G_CONST_RETURN gchar *
-tracker_module_get_name (void)
+#define TRACKER_TYPE_APPLICATION_FILE (tracker_application_file_get_type ())
+#define TRACKER_APPLICATION_FILE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), TRACKER_TYPE_APPLICATION_FILE, TrackerApplicationFile))
+
+typedef struct TrackerApplicationFile TrackerApplicationFile;
+typedef struct TrackerApplicationFileClass TrackerApplicationFileClass;
+
+struct TrackerApplicationFile {
+ TrackerModuleFile parent_instance;
+};
+
+struct TrackerApplicationFileClass {
+ TrackerModuleFileClass parent_class;
+};
+
+
+static TrackerDataMetadata * tracker_application_file_get_metadata (TrackerModuleFile *file);
+
+
+G_DEFINE_DYNAMIC_TYPE (TrackerApplicationFile, tracker_application_file, TRACKER_TYPE_MODULE_FILE);
+
+
+static void
+tracker_application_file_class_init (TrackerApplicationFileClass *klass)
+{
+ TrackerModuleFileClass *file_class = TRACKER_MODULE_FILE_CLASS (klass);
+
+ file_class->get_metadata = tracker_application_file_get_metadata;
+}
+
+static void
+tracker_application_file_class_finalize (TrackerApplicationFileClass *klass)
+{
+}
+
+static void
+tracker_application_file_init (TrackerApplicationFile *file)
{
- /* Return module name here */
- return "Applications";
}
static void
@@ -100,29 +132,36 @@
}
}
-TrackerDataMetadata *
-tracker_module_file_get_metadata (TrackerFile *file)
+static TrackerDataMetadata *
+tracker_application_file_get_metadata (TrackerModuleFile *file)
{
TrackerDataMetadata *metadata;
GKeyFile *key_file;
- gchar *type, *filename;
+ GFile *f;
+ gchar *path, *type, *filename;
+
+ f = tracker_module_file_get_file (file);
+ path = g_file_get_path (f);
/* Check we're dealing with a desktop file */
- if (!g_str_has_suffix (file->path, ".desktop")) {
+ if (!g_str_has_suffix (path, ".desktop")) {
+ g_free (path);
return NULL;
}
key_file = g_key_file_new ();
- if (!g_key_file_load_from_file (key_file, file->path, G_KEY_FILE_NONE, NULL)) {
- g_debug ("Couldn't load desktop file:'%s'", file->path);
+ if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, NULL)) {
+ g_debug ("Couldn't load desktop file:'%s'", path);
g_key_file_free (key_file);
+ g_free (path);
return NULL;
}
if (g_key_file_get_boolean (key_file, GROUP_DESKTOP_ENTRY, KEY_HIDDEN, NULL)) {
g_debug ("Desktop file is 'hidden', not gathering metadata for it");
g_key_file_free (key_file);
+ g_free (path);
return NULL;
}
@@ -132,6 +171,7 @@
g_debug ("Desktop file is not of type 'Application', not gathering metadata for it");
g_key_file_free (key_file);
g_free (type);
+ g_free (path);
return NULL;
}
@@ -148,11 +188,32 @@
insert_list_from_desktop_file (metadata, METADATA_APP_MIMETYPE, key_file, KEY_MIMETYPE, FALSE);
insert_list_from_desktop_file (metadata, METADATA_APP_CATEGORIES, key_file, KEY_CATEGORIES, FALSE);
- filename = g_filename_display_basename (file->path);
+ filename = g_filename_display_basename (path);
tracker_data_metadata_insert (metadata, METADATA_FILE_NAME, filename);
g_key_file_free (key_file);
g_free (type);
+ g_free (path);
return metadata;
}
+
+
+void
+indexer_module_initialize (GTypeModule *module)
+{
+ tracker_application_file_register_type (module);
+}
+
+void
+indexer_module_shutdown (void)
+{
+}
+
+TrackerModuleFile *
+indexer_module_create_file (GFile *file)
+{
+ return g_object_new (TRACKER_TYPE_APPLICATION_FILE,
+ "file", file,
+ NULL);
+}
Modified: trunk/src/tracker-indexer/modules/dummy.c
==============================================================================
--- trunk/src/tracker-indexer/modules/dummy.c (original)
+++ trunk/src/tracker-indexer/modules/dummy.c Thu Nov 20 15:29:19 2008
@@ -17,115 +17,146 @@
* Boston, MA 02110-1301, USA.
*/
-#include <glib.h>
#include <libtracker-data/tracker-data-metadata.h>
+#include <tracker-indexer/tracker-module-file.h>
+#include <tracker-indexer/tracker-module-iteratable.h>
-void
-tracker_module_init (void)
-{
- /* Implementing this function is optional.
- *
- * Allocate here all static resources for the module.
- */
+#define DUMMY_TYPE_FILE (dummy_file_get_type ())
+#define DUMMY_FILE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), DUMMY_TYPE_FILE, DummyFile))
+
+#define MODULE_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) \
+{ \
+ const GInterfaceInfo g_implement_interface_info = { \
+ (GInterfaceInitFunc) iface_init, NULL, NULL \
+ }; \
+ g_type_module_add_interface (type_module, g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \
}
-void
-tracker_module_shutdown (void)
+typedef struct DummyFile DummyFile;
+typedef struct DummyFileClass DummyFileClass;
+
+struct DummyFile {
+ TrackerModuleFile parent_instance;
+};
+
+struct DummyFileClass {
+ TrackerModuleFileClass parent_class;
+};
+
+
+static void dummy_file_iteratable_init (TrackerModuleIteratableIface *iface);
+
+static void dummy_file_finalize (GObject *object);
+
+static void dummy_file_initialize (TrackerModuleFile *file);
+static const gchar * dummy_file_get_service_type (TrackerModuleFile *file);
+static gchar * dummy_file_get_uri (TrackerModuleFile *file);
+static gchar * dummy_file_get_text (TrackerModuleFile *file);
+static TrackerDataMetadata *
+ dummy_file_get_metadata (TrackerModuleFile *file);
+
+static gboolean dummy_file_iter_contents (TrackerModuleIteratable *iteratable);
+static guint dummy_file_get_count (TrackerModuleIteratable *iteratable);
+
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (DummyFile, dummy_file, TRACKER_TYPE_MODULE_FILE, 0,
+ MODULE_IMPLEMENT_INTERFACE (TRACKER_TYPE_MODULE_ITERATABLE,
+ dummy_file_iteratable_init))
+
+static void
+dummy_file_class_init (DummyFileClass *klass)
{
- /* Implementing this function is optional.
- *
- * Free here all resources allocated in tracker_module_init()
- */
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TrackerModuleFileClass *file_class = TRACKER_MODULE_FILE_CLASS (klass);
+
+ object_class->finalize = dummy_file_finalize;
+
+ file_class->initialize = dummy_file_initialize;
+ file_class->get_service_type = dummy_file_get_service_type;
+ file_class->get_uri = dummy_file_get_uri;
+ file_class->get_text = dummy_file_get_text;
+ file_class->get_metadata = dummy_file_get_metadata;
}
-G_CONST_RETURN gchar *
-tracker_module_get_name (void)
+static void
+dummy_file_init (DummyFile *file)
{
- /* Return module name here */
- return "Dummy";
+
}
-gpointer
-tracker_module_file_get_data (const gchar *path)
+static void
+dummy_file_iteratable_init (TrackerModuleIteratableIface *iface)
{
- /* Implementing this function is optional.
- *
- * Return here private, module specific data for path.
- * Given this data is attached to the file until it isn't
- * needed anymore. This is usually used for files that
- * contain sets of data that should be considered as separate
- * entities (for example, mboxes), so the module can internally
- * keep the state. Also see tracker_module_file_iter_contents().
- */
- return NULL;
+ iface->iter_contents = dummy_file_iter_contents;
+ iface->get_count = dummy_file_get_count;
}
-gchar *
-tracker_module_file_get_service_type (TrackerFile *file)
+static void
+dummy_file_finalize (GObject *object)
{
- /* Implementing this function is optional.
- *
- * Return the service type for the incoming path.
- *
- * If this function is not implemented, the indexer will use
- * the name of the module (tracker_module_get_name) as service.
- *
- */
- return NULL;
+ /* Free here all resources allocated by the object, if any */
+
+ /* Chain up to parent implementation */
+ G_OBJECT_CLASS (dummy_file_parent_class)->finalize (object);
}
-void
-tracker_module_file_free_data (gpointer file_data)
+static void
+dummy_file_initialize (TrackerModuleFile *file)
{
- /* Implementing this function is optional
- *
- * Free the data created previously
- * through tracker_module_file_get_data()
- */
+ /* Allocate here all resources for the file, if any */
}
-void
-tracker_module_file_get_uri (TrackerFile *file,
- gchar **dirname,
- gchar **basename)
+static const gchar *
+dummy_file_get_service_type (TrackerModuleFile *file)
{
- /* Implementing this function is optional
- *
- * Return dirname/basename for the current item, with this
- * method modules can specify different URIs for different
- * elements contained in the file. Also see
- * tracker_module_file_iter_contents()
- */
- *dirname = g_path_get_dirname (file->path);
- *basename = g_path_get_basename (file->path);
+ /* Implementing this function is optional.
+ *
+ * Return the service type for the given file.
+ *
+ * If this function is not implemented, the indexer will use
+ * whatever service name is specified in the module configuration
+ * file.
+ */
+ return NULL;
}
-TrackerMetadata *
-tracker_module_file_get_metadata (TrackerFile *file)
+static gchar *
+dummy_file_get_uri (TrackerModuleFile *file)
{
- /* Return a hashtable filled with metadata for file, given the
- * current state. Also see tracker_module_file_iter_contents()
- */
- return NULL;
+ /* Implementing this function is optional
+ *
+ * Return URI for the current item, with this method
+ * modules can specify different URIs for different
+ * elements contained in the file. See also
+ * TrackerModuleIteratable.
+ */
+ return NULL;
}
-gchar *
-tracker_module_file_get_text (TrackerFile *file)
+static gchar *
+dummy_file_get_text (TrackerModuleFile *file)
{
/* Implementing this function is optional
*
* Return here full text for file, given the current state,
- * also see tracker_module_file_iter_contents()
+ * see also TrackerModuleIteratable.
*/
return NULL;
}
-gboolean
-tracker_module_file_iter_contents (TrackerFile *file)
+static TrackerDataMetadata *
+dummy_file_get_metadata (TrackerModuleFile *file)
{
- /* Implementing this function is optional
- *
- * This function is meant to iterate the internal state,
+ /* Return a TrackerDataMetadata filled with metadata for file,
+ * given the current state. Also see TrackerModuleIteratable.
+ */
+ return NULL;
+}
+
+static gboolean
+dummy_file_iter_contents (TrackerModuleIteratable *iteratable)
+{
+ /* This function is meant to iterate the internal state,
* so it points to the next entity inside the file.
* In case there is such next entity, this function must
* return TRUE, else, returning FALSE will make the indexer
@@ -134,5 +165,34 @@
* What an "entity" is considered is left to the module
* implementation.
*/
- return FALSE;
+ return FALSE;
+}
+
+static guint
+dummy_file_get_count (TrackerModuleIteratable *iteratable)
+{
+ /* This function is meant to return the number of entities
+ * contained in the file, what an "entity" is considered is
+ * left to the module implementation.
+ */
+ return 0;
+}
+
+void
+indexer_module_initialize (GTypeModule *module)
+{
+ dummy_file_register_type (module);
+}
+
+void
+indexer_module_shutdown (void)
+{
+}
+
+TrackerModuleFile *
+indexer_module_create_file (GFile *file)
+{
+ return g_object_new (DUMMY_TYPE_FILE,
+ "file", file,
+ NULL);
}
Added: trunk/src/tracker-indexer/modules/evolution-common.c
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/modules/evolution-common.c Thu Nov 20 15:29:19 2008
@@ -0,0 +1,119 @@
+/* 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 <sys/types.h>
+#include <fcntl.h>
+#include <string.h>
+#include <tracker-indexer/tracker-metadata-utils.h>
+#include "evolution-common.h"
+
+GMimeStream *
+evolution_common_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;
+}
+
+TrackerDataMetadata *
+evolution_common_get_wrapper_metadata (GMimeDataWrapper *wrapper)
+{
+ TrackerDataMetadata *metadata;
+ GMimeStream *stream;
+ gchar *path;
+ gint fd;
+
+ path = g_build_filename (g_get_tmp_dir (), "tracker-evolution-module-XXXXXX", NULL);
+ fd = g_mkstemp (path);
+ metadata = NULL;
+
+ stream = g_mime_stream_fs_new (fd);
+
+ if (g_mime_data_wrapper_write_to_stream (wrapper, stream) != -1) {
+ GFile *file;
+
+ file = g_file_new_for_path (path);
+ g_mime_stream_flush (stream);
+
+ metadata = tracker_metadata_utils_get_data (file);
+
+ g_object_unref (file);
+ g_unlink (path);
+ }
+
+ g_mime_stream_close (stream);
+ g_object_unref (stream);
+ g_free (path);
+
+ return metadata;
+}
+
+gchar *
+evolution_common_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);
+ }
+}
Added: trunk/src/tracker-indexer/modules/evolution-common.h
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/modules/evolution-common.h Thu Nov 20 15:29:19 2008
@@ -0,0 +1,61 @@
+/* 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.
+ */
+
+#ifndef __EVOLUTION_COMMON_H__
+#define __EVOLUTION_COMMON_H__
+
+#include <glib.h>
+#include <gmime/gmime.h>
+#include <libtracker-data/tracker-data-metadata.h>
+
+G_BEGIN_DECLS
+
+#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"
+#define METADATA_EMAIL_SENT_TO "Email:SentTo"
+#define METADATA_EMAIL_CC "Email:CC"
+
+
+enum EvolutionFlags {
+ EVOLUTION_MESSAGE_ANSWERED = 1 << 0,
+ EVOLUTION_MESSAGE_DELETED = 1 << 1,
+ EVOLUTION_MESSAGE_DRAFT = 1 << 2,
+ EVOLUTION_MESSAGE_FLAGGED = 1 << 3,
+ EVOLUTION_MESSAGE_SEEN = 1 << 4,
+ EVOLUTION_MESSAGE_ATTACHMENTS = 1 << 5,
+ EVOLUTION_MESSAGE_ANSWERED_ALL = 1 << 6,
+ EVOLUTION_MESSAGE_JUNK = 1 << 7,
+ EVOLUTION_MESSAGE_SECURE = 1 << 8
+};
+
+GMimeStream * evolution_common_get_stream (const gchar *path,
+ gint flags,
+ off_t start);
+
+TrackerDataMetadata * evolution_common_get_wrapper_metadata (GMimeDataWrapper *wrapper);
+gchar * evolution_common_get_object_encoding (GMimeObject *object);
+
+
+G_END_DECLS
+
+#endif /* __EVOLUTION_COMMON_H__ */
Added: trunk/src/tracker-indexer/modules/evolution-imap.c
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/modules/evolution-imap.c Thu Nov 20 15:29:19 2008
@@ -0,0 +1,1142 @@
+/* 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 <libtracker-data/tracker-data-metadata.h>
+#include <tracker-indexer/tracker-module-file.h>
+#include <tracker-indexer/tracker-module-iteratable.h>
+#include <gconf/gconf-client.h>
+#include <string.h>
+#include "evolution-imap.h"
+#include "evolution-common.h"
+
+#define METADATA_EMAIL_RECIPIENT "Email:Recipient"
+#define METADATA_EMAIL_DATE "Email:Date"
+#define METADATA_EMAIL_SENDER "Email:Sender"
+#define METADATA_EMAIL_SUBJECT "Email:Subject"
+#define METADATA_EMAIL_SENT_TO "Email:SentTo"
+#define METADATA_EMAIL_CC "Email:CC"
+
+#define MODULE_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) \
+{ \
+ const GInterfaceInfo g_implement_interface_info = { \
+ (GInterfaceInitFunc) iface_init, NULL, NULL \
+ }; \
+ g_type_module_add_interface (type_module, g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \
+}
+
+typedef struct EvolutionAccountContext EvolutionAccountContext;
+
+
+enum {
+ SUMMARY_TYPE_INT32,
+ SUMMARY_TYPE_UINT32,
+ SUMMARY_TYPE_STRING,
+ SUMMARY_TYPE_TOKEN,
+ SUMMARY_TYPE_TIME_T
+};
+
+struct EvolutionAccountContext {
+ gchar *account;
+ gchar *uid;
+};
+
+static GHashTable *accounts = NULL;
+
+
+static void tracker_evolution_imap_file_finalize (GObject *object);
+
+static void tracker_evolution_imap_file_initialize (TrackerModuleFile *file);
+static const gchar * tracker_evolution_imap_file_get_service_type (TrackerModuleFile *file);
+static gchar * tracker_evolution_imap_file_get_uri (TrackerModuleFile *file);
+static gchar * tracker_evolution_imap_file_get_text (TrackerModuleFile *file);
+static TrackerDataMetadata *
+ tracker_evolution_imap_file_get_metadata (TrackerModuleFile *file);
+
+static void tracker_evolution_imap_file_iteratable_init (TrackerModuleIteratableIface *iface);
+static gboolean tracker_evolution_imap_file_iter_contents (TrackerModuleIteratable *iteratable);
+static guint tracker_evolution_imap_file_get_count (TrackerModuleIteratable *iteratable);
+
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (TrackerEvolutionImapFile, tracker_evolution_imap_file, TRACKER_TYPE_MODULE_FILE, 0,
+ MODULE_IMPLEMENT_INTERFACE (TRACKER_TYPE_MODULE_ITERATABLE,
+ tracker_evolution_imap_file_iteratable_init))
+
+
+static void
+tracker_evolution_imap_file_class_init (TrackerEvolutionImapFileClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TrackerModuleFileClass *file_class = TRACKER_MODULE_FILE_CLASS (klass);
+
+ object_class->finalize = tracker_evolution_imap_file_finalize;
+
+ file_class->initialize = tracker_evolution_imap_file_initialize;
+ file_class->get_service_type = tracker_evolution_imap_file_get_service_type;
+ file_class->get_uri = tracker_evolution_imap_file_get_uri;
+ file_class->get_text = tracker_evolution_imap_file_get_text;
+ file_class->get_metadata = tracker_evolution_imap_file_get_metadata;
+}
+
+static void
+tracker_evolution_imap_file_class_finalize (TrackerEvolutionImapFileClass *klass)
+{
+}
+
+static void
+tracker_evolution_imap_file_init (TrackerEvolutionImapFile *file)
+{
+}
+
+static void
+tracker_evolution_imap_file_iteratable_init (TrackerModuleIteratableIface *iface)
+{
+ iface->iter_contents = tracker_evolution_imap_file_iter_contents;
+ iface->get_count = tracker_evolution_imap_file_get_count;
+}
+
+static void
+tracker_evolution_imap_file_finalize (GObject *object)
+{
+ TrackerEvolutionImapFile *file;
+
+ file = TRACKER_EVOLUTION_IMAP_FILE (object);
+
+ g_free (file->cur_message_uid);
+
+ fclose (file->summary);
+ close (file->fd);
+
+ G_OBJECT_CLASS (tracker_evolution_imap_file_parent_class)->finalize (object);
+}
+
+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: {
+ time_t value = 0;
+ time_t *dest;
+ int size = sizeof (time_t) - 1;
+ int c = EOF;
+
+ while (size >= 0 && (c = fgetc (summary)) != EOF) {
+ value |= ((time_t) c) << (size * 8);
+ size--;
+ }
+
+ dest = va_arg (args, time_t*);
+
+ if (dest) {
+ *dest = value;
+ }
+
+ if (c == EOF) {
+ return FALSE;
+ }
+
+ break;
+ }
+ 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_try_malloc0 (len);
+ if (!str) {
+ return FALSE;
+ }
+
+ 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;
+}
+
+static gint
+read_summary_header (FILE *summary)
+{
+ gint32 version, n_messages;
+
+ read_summary (summary,
+ SUMMARY_TYPE_INT32, &version,
+ SUMMARY_TYPE_INT32, NULL, /* flags */
+ SUMMARY_TYPE_INT32, NULL, /* nextuid */
+ SUMMARY_TYPE_TIME_T, NULL, /* time */
+ SUMMARY_TYPE_INT32, &n_messages,
+ -1);
+
+ if ((version < 0x100 && version >= 13)) {
+ read_summary (summary,
+ SUMMARY_TYPE_INT32, NULL, /* unread count*/
+ SUMMARY_TYPE_INT32, NULL, /* deleted count*/
+ SUMMARY_TYPE_INT32, NULL, /* junk count */
+ -1);
+ }
+
+ if (version != 0x30c) {
+ read_summary (summary,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ -1);
+ }
+
+ return n_messages;
+}
+
+static 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);
+ }
+}
+
+static void
+account_start_element_handler (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attr_names,
+ const gchar **attr_values,
+ gpointer user_data,
+ GError **error)
+{
+ EvolutionAccountContext *account_context;
+ gint i = 0;
+
+ if (strcmp (element_name, "account") != 0) {
+ return;
+ }
+
+ account_context = (EvolutionAccountContext *) user_data;
+
+ while (attr_names[i]) {
+ if (strcmp (attr_names[i], "uid") == 0) {
+ account_context->uid = g_strdup (attr_values[i]);
+ return;
+ }
+
+ i++;
+ }
+}
+
+static gchar *
+get_account_name_from_imap_uri (const gchar *imap_uri)
+{
+ const gchar *start, *at, *semic;
+ gchar *user_name, *at_host_name, *account_name;
+
+ /* Assume url schema is:
+ * imap://foo imap free fr/;etc
+ * or
+ * imap://foo;auth=DIGEST-MD5 imap bar com/;etc
+ *
+ * We try to get "foo imap free fr".
+ */
+
+ if (!g_str_has_prefix (imap_uri, "imap://")) {
+ return NULL;
+ }
+
+ user_name = at_host_name = account_name = NULL;
+
+ /* check for embedded @ and then look for first colon after that */
+ start = imap_uri + 7;
+ at = strchr (start, '@');
+ semic = strchr (start, ';');
+
+ if ( strlen (imap_uri) < 7 || at == NULL ) {
+ return g_strdup ("Unknown");
+ }
+
+ if (semic < at) {
+ /* we have a ";auth=FOO host" schema
+ Set semic to the next semicolon, which ends the hostname. */
+ user_name = g_strndup (start, semic - start);
+ /* look for ';' at the end of the domain name */
+ semic = strchr (at, ';');
+ } else {
+ user_name = g_strndup (start, at - start);
+ }
+
+ at_host_name = g_strndup (at, (semic - 1) - at);
+
+ account_name = g_strconcat (user_name, at_host_name, NULL);
+
+ g_free (user_name);
+ g_free (at_host_name);
+
+ return account_name;
+}
+
+static void
+account_text_handler (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ EvolutionAccountContext *account_context;
+ const GSList *uri_element, *source_element;
+ gchar *url;
+
+ uri_element = g_markup_parse_context_get_element_stack (context);
+ source_element = uri_element->next;
+
+ if (strcmp ((gchar *) uri_element->data, "url") != 0 ||
+ !source_element ||
+ strcmp ((gchar *) source_element->data, "source") != 0) {
+ return;
+ }
+
+ account_context = (EvolutionAccountContext *) user_data;
+
+ url = g_strndup (text, text_len);
+ account_context->account = get_account_name_from_imap_uri (url);
+ g_free (url);
+}
+
+static void
+ensure_imap_accounts (void)
+{
+ GConfClient *client;
+ GMarkupParser parser = { 0 };
+ GMarkupParseContext *parse_context;
+ GSList *list, *l;
+ EvolutionAccountContext account_context = { 0 };
+
+ if (G_LIKELY (accounts)) {
+ return;
+ }
+
+ client = gconf_client_get_default ();
+
+ list = gconf_client_get_list (client,
+ "/apps/evolution/mail/accounts",
+ GCONF_VALUE_STRING,
+ NULL);
+
+ parser.start_element = account_start_element_handler;
+ parser.text = account_text_handler;
+ parse_context = g_markup_parse_context_new (&parser, 0, &account_context, NULL);
+
+ accounts = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
+
+ for (l = list; l; l = l->next) {
+ g_markup_parse_context_parse (parse_context, (const gchar *) l->data, -1, NULL);
+
+ if (account_context.account &&
+ account_context.uid) {
+ g_hash_table_insert (accounts,
+ account_context.account,
+ account_context.uid);
+ } else {
+ g_free (account_context.account);
+ g_free (account_context.uid);
+ }
+ }
+
+ g_markup_parse_context_free (parse_context);
+
+ g_slist_foreach (list, (GFunc) g_free, NULL);
+ g_slist_free (list);
+}
+
+static void
+tracker_evolution_imap_file_initialize (TrackerModuleFile *file)
+{
+ TrackerEvolutionImapFile *self;
+ gchar *path;
+
+ self = TRACKER_EVOLUTION_IMAP_FILE (file);
+
+ self->imap_dir = g_build_filename (g_get_home_dir (),
+ ".evolution", "mail", "imap", G_DIR_SEPARATOR_S,
+ NULL);
+
+ path = g_file_get_path (tracker_module_file_get_file (file));
+ self->fd = tracker_file_open (path, TRUE);
+ g_free (path);
+
+ if (self->fd == -1) {
+ return;
+ }
+
+ self->summary = fdopen (self->fd, "r");
+ self->n_messages = read_summary_header (self->summary);
+ self->cur_message = 1;
+
+ if (self->n_messages > 0) {
+ /* save current message uid */
+ read_summary (self->summary,
+ SUMMARY_TYPE_STRING, &self->cur_message_uid, /* message uid */
+ -1);
+ }
+
+ ensure_imap_accounts ();
+}
+
+static const gchar *
+tracker_evolution_imap_file_get_service_type (TrackerModuleFile *file)
+{
+ TrackerEvolutionImapFile *self;
+
+ self = TRACKER_EVOLUTION_IMAP_FILE (file);
+
+ if (self->current_mime_part) {
+ return "EvolutionAttachments";
+ }
+
+ return "EvolutionEmails";
+}
+
+static gchar *
+get_message_path (TrackerModuleFile *file,
+ const gchar *uid)
+{
+ gchar *path, *prefix, *message_path;
+
+ path = g_file_get_path (tracker_module_file_get_file (file));
+ prefix = g_strndup (path, strlen (path) - strlen ("summary"));
+ g_free (path);
+
+ message_path = g_strconcat (prefix, uid, ".", NULL);
+ g_free (prefix);
+
+ return message_path;
+}
+
+static gboolean
+get_attachment_info (const gchar *mime_file,
+ gchar **name,
+ GMimePartEncodingType *encoding)
+{
+ GMimeContentType *mime;
+ gchar *tmp, *mime_content;
+ const gchar *pos_content_type, *pos_encoding, *pos_end_encoding;
+
+ if (name) {
+ *name = NULL;
+ }
+
+ if (encoding) {
+ *encoding = GMIME_PART_ENCODING_DEFAULT;
+ }
+
+ if (!g_file_get_contents (mime_file, &tmp, NULL, NULL)) {
+ return FALSE;
+ }
+
+ /* all text content in lower case for comparisons */
+ mime_content = g_ascii_strdown (tmp, -1);
+ g_free (tmp);
+
+ pos_content_type = strstr (mime_content, "content-type:");
+
+ if (pos_content_type) {
+ pos_encoding = strstr (pos_content_type, "content-transfer-encoding:");
+ }
+
+ if (!pos_content_type || !pos_encoding) {
+ g_free (mime_content);
+ return FALSE;
+ }
+
+ pos_content_type += strlen ("content-type:");
+ pos_encoding += strlen ("content-transfer-encoding:");
+
+ /* ignore spaces, tab or line returns */
+ while (*pos_content_type != '\0' && (*pos_content_type == ' ' || *pos_content_type == '\t' || *pos_content_type == '\n')) {
+ pos_content_type++;
+ }
+
+ while (*pos_encoding != '\0' && *pos_encoding == ' ') {
+ pos_encoding++;
+ }
+
+ if (*pos_content_type == '\0' ||
+ *pos_encoding == '\0') {
+ g_free (mime_content);
+ return FALSE;
+ }
+
+ mime = g_mime_content_type_new_from_string (pos_content_type);
+
+ if (mime) {
+ if (name) {
+ *name = g_strdup (g_mime_content_type_get_parameter (mime, "name"));
+ }
+
+ g_mime_content_type_destroy (mime);
+ }
+
+ if (name && !*name) {
+ g_free (mime_content);
+ return FALSE;
+ }
+
+ /* Find end of encoding */
+ pos_end_encoding = pos_encoding;
+
+ while (*pos_end_encoding != '\0' &&
+ *pos_end_encoding != ' ' &&
+ *pos_end_encoding != '\n' &&
+ *pos_end_encoding != '\t') {
+ pos_end_encoding++;
+ }
+
+ if (encoding && pos_encoding != pos_end_encoding) {
+ gchar *encoding_str = g_strndup (pos_encoding, pos_end_encoding - pos_encoding);
+
+ if (strcmp (encoding_str, "7bit") == 0) {
+ *encoding = GMIME_PART_ENCODING_7BIT;
+ } else if (strcmp (encoding_str, "8bit") == 0) {
+ *encoding = GMIME_PART_ENCODING_7BIT;
+ } else if (strcmp (encoding_str, "binary") == 0) {
+ *encoding = GMIME_PART_ENCODING_BINARY;
+ } else if (strcmp (encoding_str, "base64") == 0) {
+ *encoding = GMIME_PART_ENCODING_BASE64;
+ } else if (strcmp (encoding_str, "quoted-printable") == 0) {
+ *encoding = GMIME_PART_ENCODING_QUOTEDPRINTABLE;
+ } else if (strcmp (encoding_str, "x-uuencode") == 0) {
+ *encoding = GMIME_PART_ENCODING_UUENCODE;
+ }
+
+ g_free (encoding_str);
+ }
+
+ g_free (mime_content);
+
+ return TRUE;
+}
+
+static gchar *
+get_message_uri (TrackerModuleFile *file,
+ const gchar *message_uid)
+{
+ TrackerEvolutionImapFile *self;
+ gchar *path, *uri, *dir, *subdirs;
+ GList *keys, *k;
+
+ self = TRACKER_EVOLUTION_IMAP_FILE (file);
+
+ path = g_file_get_path (tracker_module_file_get_file (file));
+ keys = g_hash_table_get_keys (accounts);
+ uri = NULL;
+
+ for (k = keys; k; k = k->next) {
+ if (!strstr (path, k->data)) {
+ continue;
+ }
+
+ dir = g_build_filename (self->imap_dir, k->data, NULL);
+
+ /* now remove all relevant info to create the email:// basename */
+ subdirs = path;
+ subdirs = tracker_string_remove (subdirs, dir);
+ subdirs = tracker_string_remove (subdirs, "/folders/");
+ subdirs = tracker_string_remove (subdirs, "/subfolders");
+ subdirs = tracker_string_remove (subdirs, "/summary");
+
+ uri = g_strdup_printf ("email://%s/%s;uid=%s",
+ (gchar *) g_hash_table_lookup (accounts, k->data),
+ subdirs,
+ message_uid);
+ g_free (subdirs);
+ g_free (dir);
+
+ break;
+ }
+
+ g_list_free (keys);
+
+ return uri;
+}
+
+static gchar *
+tracker_evolution_imap_file_get_uri (TrackerModuleFile *file)
+{
+ TrackerEvolutionImapFile *self;
+ gchar *message_uri, *part_filename;
+
+ self = TRACKER_EVOLUTION_IMAP_FILE (file);
+
+ if (!self->cur_message_uid) {
+ return NULL;
+ }
+
+ message_uri = get_message_uri (file, self->cur_message_uid);
+
+ if (!message_uri) {
+ return NULL;
+ }
+
+ if (self->current_mime_part &&
+ get_attachment_info (self->current_mime_part->data, &part_filename, NULL)) {
+ gchar *attachment_uri;
+
+ attachment_uri = g_strdup_printf ("%s/%s", message_uri, part_filename);
+ g_free (message_uri);
+ g_free (part_filename);
+
+ return attachment_uri;
+ }
+
+ return message_uri;
+}
+
+static void
+extract_message_text (GMimeObject *object,
+ gpointer user_data)
+{
+ GString *body = (GString *) user_data;
+ GMimePartEncodingType part_encoding;
+ GMimePart *part;
+ const gchar *content, *disposition, *filename;
+ gchar *encoding, *part_body;
+ gsize len;
+
+ 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_message_text, user_data);
+ g_object_unref (message);
+ }
+
+ return;
+ } else if (GMIME_IS_MULTIPART (object)) {
+ g_mime_multipart_foreach (GMIME_MULTIPART (object), extract_message_text, user_data);
+ return;
+ }
+
+ part = GMIME_PART (object);
+ filename = g_mime_part_get_filename (part);
+ disposition = g_mime_part_get_content_disposition (part);
+ part_encoding = g_mime_part_get_encoding (part);
+
+ if (part_encoding == GMIME_PART_ENCODING_BINARY ||
+ part_encoding == GMIME_PART_ENCODING_BASE64 ||
+ part_encoding == GMIME_PART_ENCODING_UUENCODE) {
+ return;
+ }
+
+ if (disposition &&
+ strcmp (disposition, GMIME_DISPOSITION_ATTACHMENT) == 0) {
+ return;
+ }
+
+ if (filename &&
+ (strcmp (filename, "signature.asc") == 0 ||
+ strcmp (filename, "signature.pgp") == 0)) {
+ return;
+ }
+
+ content = g_mime_part_get_content (GMIME_PART (object), &len);
+
+ if (!content) {
+ return;
+ }
+
+ if (g_utf8_validate (content, len, NULL)) {
+ g_string_append_len (body, content, (gssize) len);
+ return;
+ }
+
+ encoding = evolution_common_get_object_encoding (object);
+
+ if (!encoding) {
+ /* FIXME: This will break for non-utf8 text without
+ * the proper content type set
+ */
+ g_string_append_len (body, content, (gssize) len);
+ } else {
+ part_body = g_convert (content, (gssize) len, "utf8", encoding, NULL, NULL, NULL);
+ g_string_append (body, part_body);
+
+ g_free (part_body);
+ g_free (encoding);
+ }
+}
+
+static gchar *
+tracker_evolution_imap_file_get_text (TrackerModuleFile *file)
+{
+ TrackerEvolutionImapFile *self;
+ gchar *message_path;
+ GMimeStream *stream;
+ GMimeParser *parser;
+ GMimeMessage *message;
+ GString *body = NULL;
+
+ self = TRACKER_EVOLUTION_IMAP_FILE (file);
+
+ if (self->current_mime_part) {
+ /* FIXME: Extract text from attachments */
+ return NULL;
+ }
+
+ message_path = get_message_path (file, self->cur_message_uid);
+
+#if defined(__linux__)
+ stream = evolution_common_get_stream (message_path, O_RDONLY | O_NOATIME, 0);
+#else
+ stream = evolution_common_get_stream (message_path, O_RDONLY, 0);
+#endif
+
+ g_free (message_path);
+
+ if (!stream) {
+ return NULL;
+ }
+
+ parser = g_mime_parser_new_with_stream (stream);
+ g_mime_parser_set_scan_from (parser, FALSE);
+ message = g_mime_parser_construct_message (parser);
+
+ if (message) {
+ body = g_string_new (NULL);
+ g_mime_message_foreach_part (message, extract_message_text, body);
+ g_object_unref (message);
+ }
+
+ g_object_unref (stream);
+ g_object_unref (parser);
+
+ return (body) ? g_string_free (body, FALSE) : NULL;
+}
+
+static GList *
+get_recipient_list (const gchar *str)
+{
+ GList *list = NULL;
+ gchar **arr;
+ gint i;
+
+ if (!str) {
+ return NULL;
+ }
+
+ arr = g_strsplit (str, ",", -1);
+
+ for (i = 0; arr[i]; i++) {
+ g_strstrip (arr[i]);
+ list = g_list_prepend (list, g_strdup (arr[i]));
+ }
+
+ g_strfreev (arr);
+
+ return g_list_reverse (list);
+}
+
+static TrackerDataMetadata *
+get_message_metadata (TrackerModuleFile *file)
+{
+ TrackerEvolutionImapFile *self;
+ TrackerDataMetadata *metadata = NULL;
+ gchar *subject, *from, *to, *cc;
+ gint32 i, count, flags;
+ time_t date;
+ GList *list;
+ gboolean deleted;
+
+ self = TRACKER_EVOLUTION_IMAP_FILE (file);
+
+ if (!read_summary (self->summary,
+ SUMMARY_TYPE_UINT32, &flags, /* flags */
+ -1)) {
+ return NULL;
+ }
+
+ deleted = ((flags & EVOLUTION_MESSAGE_JUNK) != 0 ||
+ (flags & EVOLUTION_MESSAGE_DELETED) != 0);
+
+ subject = NULL;
+ from = NULL;
+ to = NULL;
+ cc = NULL;
+
+ if (!read_summary (self->summary,
+ 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, &cc, /* cc */
+ SUMMARY_TYPE_STRING, NULL, /* mlist */
+ -1)) {
+ g_free (subject);
+ g_free (from);
+ g_free (to);
+ g_free (cc);
+ return NULL;
+ }
+
+ if (!deleted) {
+ metadata = tracker_data_metadata_new ();
+
+ tracker_data_metadata_insert (metadata, METADATA_EMAIL_DATE,
+ tracker_guint_to_string (date));
+
+ tracker_data_metadata_insert (metadata, METADATA_EMAIL_SENDER, from);
+ tracker_data_metadata_insert (metadata, METADATA_EMAIL_SUBJECT, subject);
+
+ list = get_recipient_list (to);
+ tracker_data_metadata_insert_values (metadata, METADATA_EMAIL_SENT_TO, list);
+
+ list = get_recipient_list (cc);
+ tracker_data_metadata_insert_values (metadata, METADATA_EMAIL_CC, list);
+ }
+
+ g_free (to);
+ g_free (cc);
+
+ if (!read_summary (self->summary,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_UINT32, &count,
+ -1)) {
+ goto corruption;
+ }
+
+ /* references */
+ for (i = 0; i < count; i++) {
+ if (read_summary (self->summary,
+ SUMMARY_TYPE_INT32, NULL,
+ SUMMARY_TYPE_INT32, NULL,
+ -1)) {
+ continue;
+ }
+
+ goto corruption;
+ }
+
+ if (!read_summary (self->summary, SUMMARY_TYPE_UINT32, &count, -1)) {
+ goto corruption;
+ }
+
+ /* user flags */
+ for (i = 0; i < count; i++) {
+ if (read_summary (self->summary, SUMMARY_TYPE_STRING, NULL, -1)) {
+ continue;
+ }
+
+ goto corruption;
+ }
+
+ if (!read_summary (self->summary, SUMMARY_TYPE_UINT32, &count, -1)) {
+ goto corruption;
+ }
+
+ /* user tags */
+ for (i = 0; i < count; i++) {
+ if (read_summary (self->summary,
+ SUMMARY_TYPE_STRING, NULL,
+ SUMMARY_TYPE_STRING, NULL,
+ -1)) {
+ continue;
+ }
+
+ goto corruption;
+ }
+
+ /* server flags */
+ if (!read_summary (self->summary,
+ SUMMARY_TYPE_UINT32, NULL,
+ -1)) {
+ goto corruption;
+ }
+
+ skip_content_info (self->summary);
+
+ return metadata;
+
+corruption:
+ /* assume corruption */
+ if (metadata) {
+ tracker_data_metadata_free (metadata);
+ }
+
+ return NULL;
+}
+
+static TrackerDataMetadata *
+get_attachment_metadata (TrackerModuleFile *file,
+ const gchar *mime_file)
+{
+ TrackerDataMetadata *metadata;
+ GMimeStream *stream;
+ GMimeDataWrapper *wrapper;
+ GMimePartEncodingType encoding;
+ gchar *path, *name;
+
+ if (!get_attachment_info (mime_file, &name, &encoding)) {
+ return NULL;
+ }
+
+ path = g_strdup (mime_file);
+ path = tracker_string_remove (path, ".MIME");
+
+#if defined(__linux__)
+ stream = evolution_common_get_stream (path, O_RDONLY | O_NOATIME, 0);
+#else
+ stream = evolution_common_get_stream (path, O_RDONLY, 0);
+#endif
+
+ if (!stream) {
+ g_free (name);
+ g_free (path);
+ return NULL;
+ }
+
+ wrapper = g_mime_data_wrapper_new_with_stream (stream, encoding);
+ metadata = evolution_common_get_wrapper_metadata (wrapper);
+
+ g_object_unref (wrapper);
+ g_object_unref (stream);
+ g_free (name);
+ g_free (path);
+
+ return metadata;
+}
+
+static TrackerDataMetadata *
+tracker_evolution_imap_file_get_metadata (TrackerModuleFile *file)
+{
+ TrackerEvolutionImapFile *self;
+
+ self = TRACKER_EVOLUTION_IMAP_FILE (file);
+
+ if (self->cur_message > self->n_messages) {
+ return NULL;
+ }
+
+ if (self->current_mime_part) {
+ return get_attachment_metadata (file, self->current_mime_part->data);
+ } else {
+ return get_message_metadata (file);
+ }
+}
+
+static GList *
+extract_mime_parts (TrackerEvolutionImapFile *self)
+{
+ gboolean has_attachment = TRUE;
+ gint n_attachment = 0;
+ gchar *message_path;
+ GList *mime_parts = NULL;
+
+ message_path = get_message_path (TRACKER_MODULE_FILE (self),
+ self->cur_message_uid);
+
+ while (has_attachment) {
+ gchar *mime_file;
+
+ n_attachment++;
+ mime_file = g_strdup_printf ("%s%d.MIME", message_path, n_attachment);
+
+ if (g_file_test (mime_file, G_FILE_TEST_EXISTS)) {
+ mime_parts = g_list_prepend (mime_parts, mime_file);
+ } else {
+ g_free (mime_file);
+ has_attachment = FALSE;
+ }
+ }
+
+ g_free (message_path);
+
+ return g_list_reverse (mime_parts);
+}
+
+static gboolean
+tracker_evolution_imap_file_iter_contents (TrackerModuleIteratable *iteratable)
+{
+ TrackerEvolutionImapFile *self;
+
+ self = TRACKER_EVOLUTION_IMAP_FILE (iteratable);
+
+ /* Iterate through mime parts, if any */
+ if (!self->mime_parts) {
+ self->mime_parts = extract_mime_parts (self);
+ self->current_mime_part = self->mime_parts;
+ } else {
+ self->current_mime_part = self->current_mime_part->next;
+ }
+
+ if (self->current_mime_part) {
+ return TRUE;
+ }
+
+ g_list_foreach (self->mime_parts, (GFunc) g_free, NULL);
+ g_list_free (self->mime_parts);
+ self->mime_parts = NULL;
+
+ g_free (self->cur_message_uid);
+ self->cur_message_uid = NULL;
+
+ /* save current message uid */
+ read_summary (self->summary,
+ SUMMARY_TYPE_STRING, &self->cur_message_uid, /* message uid */
+ -1);
+
+ self->cur_message++;
+
+ return (self->cur_message < self->n_messages);
+}
+
+static guint
+tracker_evolution_imap_file_get_count (TrackerModuleIteratable *iteratable)
+{
+ TrackerEvolutionImapFile *self;
+
+ self = TRACKER_EVOLUTION_IMAP_FILE (iteratable);
+
+ return self->n_messages;
+}
+
+void
+tracker_evolution_imap_file_register (GTypeModule *module)
+{
+ tracker_evolution_imap_file_register_type (module);
+}
+
+TrackerModuleFile *
+tracker_evolution_imap_file_new (GFile *file)
+{
+ return g_object_new (TRACKER_TYPE_EVOLUTION_IMAP_FILE,
+ "file", file,
+ NULL);
+}
Added: trunk/src/tracker-indexer/modules/evolution-imap.h
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/modules/evolution-imap.h Thu Nov 20 15:29:19 2008
@@ -0,0 +1,68 @@
+/* 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.
+ */
+
+#ifndef __TRACKER_EVOLUTION_IMAP_H__
+#define __TRACKER_EVOLUTION_IMAP_H__
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <tracker-indexer/tracker-module-file.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_EVOLUTION_IMAP_FILE (tracker_evolution_imap_file_get_type())
+#define TRACKER_EVOLUTION_IMAP_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_EVOLUTION_IMAP_FILE, TrackerEvolutionImapFile))
+#define TRACKER_EVOLUTION_IMAP_FILE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_EVOLUTION_IMAP_FILE, TrackerEvolutionImapFileClass))
+#define TRACKER_IS_EVOLUTION_IMAP_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_EVOLUTION_IMAP_FILE))
+#define TRACKER_IS_EVOLUTION_IMAP_FILE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_EVOLUTION_IMAP_FILE))
+#define TRACKER_EVOLUTION_IMAP_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_EVOLUTION_IMAP_FILE, TrackerEvolutionImapFileClass))
+
+
+typedef struct TrackerEvolutionImapFile TrackerEvolutionImapFile;
+typedef struct TrackerEvolutionImapFileClass TrackerEvolutionImapFileClass;
+
+struct TrackerEvolutionImapFile {
+ TrackerModuleFile parent_instance;
+
+ gchar *imap_dir;
+
+ gint fd;
+ FILE *summary;
+ guint n_messages;
+ guint cur_message;
+ gchar *cur_message_uid;
+
+ GList *mime_parts;
+ GList *current_mime_part;
+};
+
+struct TrackerEvolutionImapFileClass {
+ TrackerModuleFileClass parent_class;
+};
+
+void tracker_evolution_pop_file_register (GTypeModule *module);
+
+TrackerModuleFile * tracker_evolution_imap_file_new (GFile *file);
+
+
+G_END_DECLS
+
+#endif /* __TRACKER_EVOLUTION_IMAP_H__ */
Added: trunk/src/tracker-indexer/modules/evolution-pop.c
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/modules/evolution-pop.c Thu Nov 20 15:29:19 2008
@@ -0,0 +1,493 @@
+/* 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 <libtracker-data/tracker-data-metadata.h>
+#include <tracker-indexer/tracker-module-file.h>
+#include <tracker-indexer/tracker-module-iteratable.h>
+#include <string.h>
+#include <fcntl.h>
+#include "evolution-pop.h"
+#include "evolution-common.h"
+
+#define MODULE_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) \
+{ \
+ const GInterfaceInfo g_implement_interface_info = { \
+ (GInterfaceInitFunc) iface_init, NULL, NULL \
+ }; \
+ g_type_module_add_interface (type_module, g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \
+}
+
+static void tracker_evolution_pop_file_finalize (GObject *object);
+
+static void tracker_evolution_pop_file_initialize (TrackerModuleFile *file);
+static const gchar * tracker_evolution_pop_file_get_service_type (TrackerModuleFile *file);
+static gchar * tracker_evolution_pop_file_get_uri (TrackerModuleFile *file);
+static gchar * tracker_evolution_pop_file_get_text (TrackerModuleFile *file);
+static TrackerDataMetadata *
+ tracker_evolution_pop_file_get_metadata (TrackerModuleFile *file);
+
+static void tracker_evolution_pop_file_iteratable_init (TrackerModuleIteratableIface *iface);
+static gboolean tracker_evolution_pop_file_iter_contents (TrackerModuleIteratable *iteratable);
+static guint tracker_evolution_pop_file_get_count (TrackerModuleIteratable *iteratable);
+
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (TrackerEvolutionPopFile, tracker_evolution_pop_file, TRACKER_TYPE_MODULE_FILE, 0,
+ MODULE_IMPLEMENT_INTERFACE (TRACKER_TYPE_MODULE_ITERATABLE,
+ tracker_evolution_pop_file_iteratable_init))
+
+
+static void
+tracker_evolution_pop_file_class_init (TrackerEvolutionPopFileClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TrackerModuleFileClass *file_class = TRACKER_MODULE_FILE_CLASS (klass);
+
+ object_class->finalize = tracker_evolution_pop_file_finalize;
+
+ file_class->initialize = tracker_evolution_pop_file_initialize;
+ file_class->get_service_type = tracker_evolution_pop_file_get_service_type;
+ file_class->get_uri = tracker_evolution_pop_file_get_uri;
+ file_class->get_text = tracker_evolution_pop_file_get_text;
+ file_class->get_metadata = tracker_evolution_pop_file_get_metadata;
+}
+
+static void
+tracker_evolution_pop_file_class_finalize (TrackerEvolutionPopFileClass *klass)
+{
+}
+
+static void
+tracker_evolution_pop_file_init (TrackerEvolutionPopFile *file)
+{
+}
+
+static void
+tracker_evolution_pop_file_iteratable_init (TrackerModuleIteratableIface *iface)
+{
+ iface->iter_contents = tracker_evolution_pop_file_iter_contents;
+}
+
+static void
+tracker_evolution_pop_file_finalize (GObject *object)
+{
+ TrackerEvolutionPopFile *file;
+
+ file = TRACKER_EVOLUTION_POP_FILE (object);
+
+ if (file->mime_parts) {
+ g_list_foreach (file->mime_parts, (GFunc) g_object_unref, NULL);
+ g_list_free (file->mime_parts);
+ }
+
+ if (file->message) {
+ g_object_unref (file->message);
+ }
+
+ if (file->parser) {
+ g_object_unref (file->parser);
+ }
+
+ if (file->stream) {
+ g_mime_stream_close (file->stream);
+ g_object_unref (file->stream);
+ }
+
+ g_free (file->local_folder);
+
+ G_OBJECT_CLASS (tracker_evolution_pop_file_parent_class)->finalize (object);
+}
+
+static void
+tracker_evolution_pop_file_initialize (TrackerModuleFile *file)
+{
+ TrackerEvolutionPopFile *self;
+ gchar *path;
+
+ self = TRACKER_EVOLUTION_POP_FILE (file);
+ path = g_file_get_path (tracker_module_file_get_file (file));
+
+ self->local_folder = g_build_filename (g_get_home_dir (),
+ ".evolution", "mail", "local", G_DIR_SEPARATOR_S,
+ NULL);
+
+#if defined(__linux__)
+ self->stream = evolution_common_get_stream (path, O_RDONLY | O_NOATIME, 0);
+#else
+ self->stream = evolution_common_get_stream (path, O_RDONLY, 0);
+#endif
+
+ if (self->stream) {
+ self->parser = g_mime_parser_new_with_stream (self->stream);
+ g_mime_parser_set_scan_from (self->parser, TRUE);
+
+ /* Initialize to the first message */
+ self->message = g_mime_parser_construct_message (self->parser);
+ }
+
+ g_free (path);
+}
+
+static const gchar *
+tracker_evolution_pop_file_get_service_type (TrackerModuleFile *file)
+{
+ TrackerEvolutionPopFile *self;
+
+ self = TRACKER_EVOLUTION_POP_FILE (file);
+
+ if (self->current_mime_part) {
+ return "EvolutionAttachments";
+ }
+
+ return "EvolutionEmails";
+}
+
+static gint
+get_message_id (GMimeMessage *message)
+{
+ const gchar *header, *pos;
+ gchar *number;
+ gint id;
+
+ header = g_mime_message_get_header (message, "X-Evolution");
+
+ if (!header) {
+ return -1;
+ }
+
+ pos = strchr (header, '-');
+
+ number = g_strndup (header, pos - header);
+ id = strtoul (number, NULL, 16);
+
+ g_free (number);
+
+ return id;
+}
+
+static gchar *
+get_message_uri (TrackerModuleFile *file,
+ GMimeMessage *message)
+{
+ TrackerEvolutionPopFile *self;
+ gchar *path, *uri, *name;
+ gint message_id;
+
+ self = TRACKER_EVOLUTION_POP_FILE (file);
+ message_id = get_message_id (message);
+
+ if (message_id < 0) {
+ return NULL;
+ }
+
+ path = g_file_get_path (tracker_module_file_get_file (file));
+ path = tracker_string_remove (path, self->local_folder);
+ path = tracker_string_remove (path, ".sbd");
+
+ uri = g_strdup_printf ("email://local local/%s;uid=%d", path, message_id);
+
+ g_free (path);
+
+ return uri;
+}
+
+static gchar *
+tracker_evolution_pop_file_get_uri (TrackerModuleFile *file)
+{
+ TrackerEvolutionPopFile *self;
+ gchar *message_uri;
+
+ self = TRACKER_EVOLUTION_POP_FILE (file);
+
+ if (!self->message) {
+ return NULL;
+ }
+
+ message_uri = get_message_uri (file, self->message);
+
+ if (!message_uri) {
+ return NULL;
+ }
+
+ if (self->current_mime_part) {
+ gchar *attachment_uri;
+ const gchar *part_filename;
+
+ part_filename = g_mime_part_get_filename (self->current_mime_part->data);
+ attachment_uri = g_strdup_printf ("%s/%s", message_uri, part_filename);
+ g_free (message_uri);
+
+ return attachment_uri;
+ }
+
+ return message_uri;
+}
+
+static gchar *
+tracker_evolution_pop_file_get_text (TrackerModuleFile *file)
+{
+ TrackerEvolutionPopFile *self;
+ gchar *text, *encoding, *utf8_text;
+ gboolean is_html;
+
+ self = TRACKER_EVOLUTION_POP_FILE (file);
+
+ if (self->current_mime_part) {
+ /* FIXME: Extract text from attachments */
+ return NULL;
+ }
+
+ text = g_mime_message_get_body (self->message, TRUE, &is_html);
+
+ if (!text) {
+ return NULL;
+ }
+
+ encoding = evolution_common_get_object_encoding (GMIME_OBJECT (self->message));
+
+ if (!encoding) {
+ /* FIXME: could still puke on non-utf8
+ * messages without proper content type
+ */
+ return text;
+ }
+
+ utf8_text = g_convert (text, -1, "utf8", encoding, NULL, NULL, NULL);
+
+ g_free (encoding);
+ g_free (text);
+
+ return utf8_text;
+}
+
+static guint
+get_message_flags (GMimeMessage *message)
+{
+ const gchar *header, *pos;
+
+ header = g_mime_message_get_header (message, "X-Evolution");
+ pos = strchr (header, '-');
+
+ return (guint) strtoul (pos + 1, NULL, 16);
+}
+
+static GList *
+get_message_recipients (GMimeMessage *message,
+ const gchar *type)
+{
+ GList *list = NULL;
+ const InternetAddressList *addresses;
+
+ addresses = g_mime_message_get_recipients (message, type);
+
+ while (addresses) {
+ InternetAddress *address;
+ gchar *str;
+
+ address = addresses->address;
+
+ if (address->name && address->value.addr) {
+ str = g_strdup_printf ("%s %s", address->name, address->value.addr);
+ } else if (address->value.addr) {
+ str = g_strdup (address->value.addr);
+ } else if (address->name) {
+ str = g_strdup (address->name);
+ } else {
+ str = NULL;
+ }
+
+ if (str) {
+ list = g_list_prepend (list, str);
+ }
+
+ addresses = addresses->next;
+ }
+
+ return g_list_reverse (list);
+}
+
+static TrackerDataMetadata *
+get_message_metadata (GMimeMessage *message)
+{
+ TrackerDataMetadata *metadata;
+ time_t date;
+ GList *list;
+
+ metadata = tracker_data_metadata_new ();
+
+ g_mime_message_get_date (message, &date, NULL);
+ tracker_data_metadata_insert (metadata, METADATA_EMAIL_DATE,
+ tracker_guint_to_string (date));
+
+ tracker_data_metadata_insert (metadata, METADATA_EMAIL_SENDER,
+ g_strdup (g_mime_message_get_sender (message)));
+ tracker_data_metadata_insert (metadata, METADATA_EMAIL_SUBJECT,
+ g_strdup (g_mime_message_get_subject (message)));
+
+ list = get_message_recipients (message, GMIME_RECIPIENT_TYPE_TO);
+ tracker_data_metadata_insert_values (metadata, METADATA_EMAIL_SENT_TO, list);
+
+ list = get_message_recipients (message, GMIME_RECIPIENT_TYPE_CC);
+ tracker_data_metadata_insert_values (metadata, METADATA_EMAIL_CC, list);
+
+ return metadata;
+}
+
+static TrackerDataMetadata *
+get_attachment_metadata (GMimePart *part)
+{
+ TrackerDataMetadata *metadata;
+ GMimeDataWrapper *content;
+
+ content = g_mime_part_get_content_object (part);
+
+ if (!content) {
+ return NULL;
+ }
+
+ metadata = evolution_common_get_wrapper_metadata (content);
+ g_object_unref (content);
+
+ return metadata;
+}
+
+static TrackerDataMetadata *
+tracker_evolution_pop_file_get_metadata (TrackerModuleFile *file)
+{
+ TrackerEvolutionPopFile *self;
+ TrackerDataMetadata *metadata;
+ guint flags;
+
+ self = TRACKER_EVOLUTION_POP_FILE (file);
+
+ if (!self->message) {
+ return NULL;
+ }
+
+ flags = get_message_flags (self->message);
+
+ if (flags & EVOLUTION_MESSAGE_JUNK ||
+ flags & EVOLUTION_MESSAGE_DELETED) {
+ return NULL;
+ }
+
+ if (self->current_mime_part) {
+ metadata = get_attachment_metadata (self->current_mime_part->data);
+ } else {
+ metadata = get_message_metadata (self->message);
+ }
+
+ return metadata;
+}
+
+static void
+extract_mime_parts (GMimeObject *object,
+ gpointer user_data)
+{
+ GList **list = (GList **) user_data;
+ 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 ||
+ (strcmp (disposition, GMIME_DISPOSITION_ATTACHMENT) != 0 &&
+ strcmp (disposition, GMIME_DISPOSITION_INLINE) != 0)) {
+ return;
+ }
+
+ filename = g_mime_part_get_filename (GMIME_PART (object));
+
+ if (!filename ||
+ strcmp (filename, "signature.asc") == 0 ||
+ strcmp (filename, "signature.pgp") == 0) {
+ return;
+ }
+
+ *list = g_list_prepend (*list, g_object_ref (object));
+}
+
+static gboolean
+tracker_evolution_pop_file_iter_contents (TrackerModuleIteratable *iteratable)
+{
+ TrackerEvolutionPopFile *self;
+
+ self = TRACKER_EVOLUTION_POP_FILE (iteratable);
+
+ if (!self->parser) {
+ return FALSE;
+ }
+
+ if (self->message) {
+ /* Iterate through mime parts, if any */
+ if (!self->mime_parts) {
+ g_mime_message_foreach_part (self->message,
+ extract_mime_parts,
+ &self->mime_parts);
+ self->current_mime_part = self->mime_parts;
+ } else {
+ self->current_mime_part = self->current_mime_part->next;
+ }
+
+ if (self->current_mime_part) {
+ return TRUE;
+ }
+
+ /* all possible mime parts have been already iterated, move on */
+ g_object_unref (self->message);
+
+ g_list_foreach (self->mime_parts, (GFunc) g_object_unref, NULL);
+ g_list_free (self->mime_parts);
+ self->mime_parts = NULL;
+ }
+
+ self->message = g_mime_parser_construct_message (self->parser);
+
+ return (self->message != NULL);
+}
+
+void
+tracker_evolution_pop_file_register (GTypeModule *module)
+{
+ tracker_evolution_pop_file_register_type (module);
+}
+
+TrackerModuleFile *
+tracker_evolution_pop_file_new (GFile *file)
+{
+ return g_object_new (TRACKER_TYPE_EVOLUTION_POP_FILE,
+ "file", file,
+ NULL);
+}
Added: trunk/src/tracker-indexer/modules/evolution-pop.h
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/modules/evolution-pop.h Thu Nov 20 15:29:19 2008
@@ -0,0 +1,64 @@
+/* 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.
+ */
+
+#ifndef __TRACKER_EVOLUTION_POP_H__
+#define __TRACKER_EVOLUTION_POP_H__
+
+#include <glib.h>
+#include <tracker-indexer/tracker-module-file.h>
+#include <gmime/gmime.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_EVOLUTION_POP_FILE (tracker_evolution_pop_file_get_type())
+#define TRACKER_EVOLUTION_POP_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_EVOLUTION_POP_FILE, TrackerEvolutionPopFile))
+#define TRACKER_EVOLUTION_POP_FILE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_EVOLUTION_POP_FILE, TrackerEvolutionPopFileClass))
+#define TRACKER_IS_EVOLUTION_POP_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_EVOLUTION_POP_FILE))
+#define TRACKER_IS_EVOLUTION_POP_FILE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_EVOLUTION_POP_FILE))
+#define TRACKER_EVOLUTION_POP_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_EVOLUTION_POP_FILE, TrackerEvolutionPopFileClass))
+
+
+typedef struct TrackerEvolutionPopFile TrackerEvolutionPopFile;
+typedef struct TrackerEvolutionPopFileClass TrackerEvolutionPopFileClass;
+
+struct TrackerEvolutionPopFile {
+ TrackerModuleFile parent_instance;
+
+ gchar *local_folder;
+
+ GMimeStream *stream;
+ GMimeParser *parser;
+ GMimeMessage *message;
+
+ GList *mime_parts;
+ GList *current_mime_part;
+};
+
+struct TrackerEvolutionPopFileClass {
+ TrackerModuleFileClass parent_class;
+};
+
+void tracker_evolution_pop_file_register (GTypeModule *module);
+
+TrackerModuleFile * tracker_evolution_pop_file_new (GFile *file);
+
+
+G_END_DECLS
+
+#endif /* __TRACKER_EVOLUTION_POP_H__ */
Modified: trunk/src/tracker-indexer/modules/evolution.c
==============================================================================
--- trunk/src/tracker-indexer/modules/evolution.c (original)
+++ trunk/src/tracker-indexer/modules/evolution.c Thu Nov 20 15:29:19 2008
@@ -17,35 +17,10 @@
* 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 <stdlib.h>
-#include <gconf/gconf-client.h>
-#include <tracker-indexer/tracker-module.h>
-#include <libtracker-data/tracker-data-metadata.h>
-#include <tracker-indexer/tracker-metadata-utils.h>
-#include <libtracker-common/tracker-utils.h>
-#include <libtracker-common/tracker-file-utils.h>
-#include <libtracker-common/tracker-type-utils.h>
+#include "evolution-pop.h"
+#include "evolution-imap.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"
-#define METADATA_EMAIL_SENT_TO "Email:SentTo"
-#define METADATA_EMAIL_CC "Email:CC"
-
-typedef union EvolutionFileData EvolutionFileData;
-typedef struct EvolutionLocalData EvolutionLocalData;
-typedef struct EvolutionImapData EvolutionImapData;
-typedef struct EvolutionAccountContext EvolutionAccountContext;
typedef enum MailStorageType MailStorageType;
enum MailStorageType {
@@ -54,369 +29,30 @@
MAIL_STORAGE_IMAP
};
-struct EvolutionLocalData {
- MailStorageType type;
- GMimeStream *stream;
- GMimeParser *parser;
- GMimeMessage *message;
-
- GList *mime_parts;
- GList *current_mime_part;
-};
-
-struct EvolutionImapData {
- MailStorageType type;
- gint fd;
- FILE *summary;
- guint n_messages;
- guint cur_message;
- gchar *cur_message_uid;
-
- GList *mime_parts;
- GList *current_mime_part;
-};
-
-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
-};
-
-struct EvolutionAccountContext {
- gchar *account;
- gchar *uid;
-};
-
-enum EvolutionFlags {
- EVOLUTION_MESSAGE_ANSWERED = 1 << 0,
- EVOLUTION_MESSAGE_DELETED = 1 << 1,
- EVOLUTION_MESSAGE_DRAFT = 1 << 2,
- EVOLUTION_MESSAGE_FLAGGED = 1 << 3,
- EVOLUTION_MESSAGE_SEEN = 1 << 4,
- EVOLUTION_MESSAGE_ATTACHMENTS = 1 << 5,
- EVOLUTION_MESSAGE_ANSWERED_ALL = 1 << 6,
- EVOLUTION_MESSAGE_JUNK = 1 << 7,
- EVOLUTION_MESSAGE_SECURE = 1 << 8
-};
-
-
static gchar *local_dir = NULL;
static gchar *imap_dir = NULL;
-static GHashTable *accounts = NULL;
-
-
-void get_imap_accounts (void);
-
-
-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: {
- time_t value = 0;
- time_t *dest;
- int size = sizeof (time_t) - 1;
- int c = EOF;
-
- while (size >= 0 && (c = fgetc (summary)) != EOF) {
- value |= ((time_t) c) << (size * 8);
- size--;
- }
-
- dest = va_arg (args, time_t*);
-
- if (dest) {
- *dest = value;
- }
-
- if (c == EOF) {
- return FALSE;
- }
-
- break;
- }
- 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_try_malloc0 (len);
- if (!str) {
- return FALSE;
- }
-
- 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;
-}
void
-tracker_module_init (void)
+indexer_module_initialize (GTypeModule *module)
{
g_mime_init (0);
- get_imap_accounts ();
local_dir = g_build_filename (g_get_home_dir (), ".evolution", "mail", "local", G_DIR_SEPARATOR_S, NULL);
imap_dir = g_build_filename (g_get_home_dir (), ".evolution", "mail", "imap", G_DIR_SEPARATOR_S, NULL);
+
+ tracker_evolution_pop_file_register (module);
+ tracker_evolution_imap_file_register (module);
}
void
-tracker_module_shutdown (void)
+indexer_module_shutdown (void)
{
- g_mime_shutdown ();
+ g_mime_shutdown ();
- g_hash_table_destroy (accounts);
g_free (local_dir);
g_free (imap_dir);
}
-G_CONST_RETURN gchar *
-tracker_module_get_name (void)
-{
- /* Return module name here */
- return "EvolutionEmails";
-}
-
-static void
-account_start_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attr_names,
- const gchar **attr_values,
- gpointer user_data,
- GError **error)
-{
- EvolutionAccountContext *account_context;
- gint i = 0;
-
- if (strcmp (element_name, "account") != 0) {
- return;
- }
-
- account_context = (EvolutionAccountContext *) user_data;
-
- while (attr_names[i]) {
- if (strcmp (attr_names[i], "uid") == 0) {
- account_context->uid = g_strdup (attr_values[i]);
- return;
- }
-
- i++;
- }
-}
-
-static gchar *
-get_account_name_from_imap_uri (const gchar *imap_uri)
-{
- const gchar *start, *at, *semic;
- gchar *user_name, *at_host_name, *account_name;
-
- /* Assume url schema is:
- * imap://foo imap free fr/;etc
- * or
- * imap://foo;auth=DIGEST-MD5 imap bar com/;etc
- *
- * We try to get "foo imap free fr".
- */
-
- if (!g_str_has_prefix (imap_uri, "imap://")) {
- return NULL;
- }
-
- user_name = at_host_name = account_name = NULL;
-
- /* check for embedded @ and then look for first colon after that */
- start = imap_uri + 7;
- at = strchr (start, '@');
- semic = strchr (start, ';');
-
- if ( strlen (imap_uri) < 7 || at == NULL ) {
- return g_strdup ("Unknown");
- }
-
- if (semic < at) {
- /* we have a ";auth=FOO host" schema
- Set semic to the next semicolon, which ends the hostname. */
- user_name = g_strndup (start, semic - start);
- /* look for ';' at the end of the domain name */
- semic = strchr (at, ';');
- } else {
- user_name = g_strndup (start, at - start);
- }
-
- at_host_name = g_strndup (at, (semic - 1) - at);
-
- account_name = g_strconcat (user_name, at_host_name, NULL);
-
- g_free (user_name);
- g_free (at_host_name);
-
- return account_name;
-}
-
-static void
-account_text_handler (GMarkupParseContext *context,
- const gchar *text,
- gsize text_len,
- gpointer user_data,
- GError **error)
-{
- EvolutionAccountContext *account_context;
- const GSList *uri_element, *source_element;
- gchar *url;
-
- uri_element = g_markup_parse_context_get_element_stack (context);
- source_element = uri_element->next;
-
- if (strcmp ((gchar *) uri_element->data, "url") != 0 ||
- !source_element ||
- strcmp ((gchar *) source_element->data, "source") != 0) {
- return;
- }
-
- account_context = (EvolutionAccountContext *) user_data;
-
- url = g_strndup (text, text_len);
- account_context->account = get_account_name_from_imap_uri (url);
- g_free (url);
-}
-
-void
-get_imap_accounts (void)
-{
- GConfClient *client;
- GMarkupParser parser = { 0 };
- GMarkupParseContext *parse_context;
- GSList *list, *l;
- EvolutionAccountContext account_context = { 0 };
-
- client = gconf_client_get_default ();
-
- list = gconf_client_get_list (client,
- "/apps/evolution/mail/accounts",
- GCONF_VALUE_STRING,
- NULL);
-
- parser.start_element = account_start_element_handler;
- parser.text = account_text_handler;
- parse_context = g_markup_parse_context_new (&parser, 0, &account_context, NULL);
-
- accounts = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_free);
-
- for (l = list; l; l = l->next) {
- g_markup_parse_context_parse (parse_context, (const gchar *) l->data, -1, NULL);
-
- if (account_context.account &&
- account_context.uid) {
- g_hash_table_insert (accounts,
- account_context.account,
- account_context.uid);
- } else {
- g_free (account_context.account);
- g_free (account_context.uid);
- }
- }
-
- g_markup_parse_context_free (parse_context);
-
- g_slist_foreach (list, (GFunc) g_free, NULL);
- g_slist_free (list);
-}
-
static MailStorageType
get_mail_storage_type_from_path (const gchar *path)
{
@@ -448,1320 +84,21 @@
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)
+TrackerModuleFile *
+indexer_module_create_file (GFile *file)
{
- gint32 version, n_messages;
-
- read_summary (summary,
- SUMMARY_TYPE_INT32, &version,
- SUMMARY_TYPE_INT32, NULL, /* flags */
- SUMMARY_TYPE_INT32, NULL, /* nextuid */
- SUMMARY_TYPE_TIME_T, NULL, /* time */
- SUMMARY_TYPE_INT32, &n_messages,
- -1);
-
- if ((version < 0x100 && version >= 13)) {
- read_summary (summary,
- SUMMARY_TYPE_INT32, NULL, /* unread count*/
- SUMMARY_TYPE_INT32, NULL, /* deleted count*/
- SUMMARY_TYPE_INT32, NULL, /* junk count */
- -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;
+ gchar *path;
- 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;
- }
+ path = g_file_get_path (file);
+ type = get_mail_storage_type_from_path (path);
+ g_free (path);
- imap_data->summary = fdopen (imap_data->fd, "r");
- imap_data->n_messages = read_summary_header (imap_data->summary);
- imap_data->cur_message = 1;
-
- if (imap_data->n_messages > 0) {
- /* save current message uid */
- read_summary (imap_data->summary,
- SUMMARY_TYPE_STRING, &imap_data->cur_message_uid, /* message uid */
- -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->mime_parts) {
- g_list_foreach (data->mime_parts, (GFunc) g_object_unref, NULL);
- g_list_free (data->mime_parts);
- }
-
- 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);
-}
-
-static gint
-get_mbox_message_id (GMimeMessage *message)
-{
- const gchar *header, *pos;
- gchar *number;
- gint id;
-
- header = g_mime_message_get_header (message, "X-Evolution");
-
- if (!header) {
- return -1;
- }
-
- pos = strchr (header, '-');
-
- number = g_strndup (header, pos - header);
- id = strtoul (number, NULL, 16);
-
- g_free (number);
-
- return id;
-}
-
-static guint
-get_mbox_message_flags (GMimeMessage *message)
-{
- const gchar *header, *pos;
-
- header = g_mime_message_get_header (message, "X-Evolution");
- pos = strchr (header, '-');
-
- return (guint) strtoul (pos + 1, NULL, 16);
-}
-
-static void
-get_mbox_uri (TrackerFile *file,
- GMimeMessage *message,
- gchar **dirname,
- gchar **basename)
-{
- gchar *dir, *name;
- gint message_id;
-
- message_id = get_mbox_message_id (message);
-
- if (message_id < 0) {
- *dirname = NULL;
- *basename = NULL;
- return;
+ if (type == MAIL_STORAGE_LOCAL) {
+ return tracker_evolution_pop_file_new (file);
+ } else if (type == MAIL_STORAGE_IMAP) {
+ return tracker_evolution_imap_file_new (file);
}
- dir = tracker_string_replace (file->path, local_dir, NULL);
- dir = tracker_string_remove (dir, ".sbd");
-
- name = g_strdup_printf ("%s;uid=%d", dir, message_id);
-
- *dirname = g_strdup ("email://local local");
- *basename = name;
-
- g_free (dir);
-}
-
-static void
-get_mbox_attachment_uri (TrackerFile *file,
- GMimeMessage *message,
- GMimePart *part,
- gchar **dirname,
- gchar **basename)
-{
- gint message_id;
- gchar *dir;
-
- message_id = get_mbox_message_id (message);
-
- if (message_id < 0) {
- *dirname = NULL;
- *basename = NULL;
- return;
- }
-
- dir = tracker_string_replace (file->path, local_dir, NULL);
- dir = tracker_string_remove (dir, ".sbd");
-
- *dirname = g_strdup_printf ("email://local local/%s;uid=%d",
- dir, message_id);
- *basename = g_strdup (g_mime_part_get_filename (part));
-
- g_free (dir);
-}
-
-static GList *
-get_mbox_recipient_list (GMimeMessage *message,
- const gchar *type)
-{
- GList *list = NULL;
- const InternetAddressList *addresses;
-
- addresses = g_mime_message_get_recipients (message, type);
-
- while (addresses) {
- InternetAddress *address;
- gchar *str;
-
- address = addresses->address;
-
- if (address->name && address->value.addr) {
- str = g_strdup_printf ("%s %s", address->name, address->value.addr);
- } else if (address->value.addr) {
- str = g_strdup (address->value.addr);
- } else if (address->name) {
- str = g_strdup (address->name);
- } else {
- str = NULL;
- }
-
- if (str) {
- list = g_list_prepend (list, str);
- }
-
- addresses = addresses->next;
- }
-
- return g_list_reverse (list);
-}
-
-static TrackerDataMetadata *
-get_metadata_for_data_wrapper (GMimeDataWrapper *wrapper)
-{
- TrackerDataMetadata *metadata;
- GMimeStream *stream;
- gchar *path;
- gint fd;
-
- path = g_build_filename (g_get_tmp_dir (), "tracker-evolution-module-XXXXXX", NULL);
- fd = g_mkstemp (path);
- metadata = NULL;
-
- stream = g_mime_stream_fs_new (fd);
-
- if (g_mime_data_wrapper_write_to_stream (wrapper, stream) != -1) {
- g_mime_stream_flush (stream);
-
- metadata = tracker_metadata_utils_get_data (path);
- g_unlink (path);
- }
-
- g_mime_stream_close (stream);
- g_object_unref (stream);
- g_free (path);
-
- return metadata;
-}
-
-static TrackerDataMetadata *
-get_metadata_for_mbox_attachment (TrackerFile *file,
- GMimeMessage *message,
- GMimePart *part)
-{
- TrackerDataMetadata *metadata;
- GMimeDataWrapper *content;
-
- content = g_mime_part_get_content_object (part);
-
- if (!content) {
- return NULL;
- }
-
- metadata = get_metadata_for_data_wrapper (content);
-
- if (metadata) {
- gchar *dirname, *basename;
-
- get_mbox_attachment_uri (file, message, part,
- &dirname, &basename);
-
- tracker_data_metadata_insert (metadata, METADATA_FILE_PATH, dirname);
- tracker_data_metadata_insert (metadata, METADATA_FILE_NAME, basename);
- }
-
- g_object_unref (content);
-
- return metadata;
-}
-
-static TrackerDataMetadata *
-get_metadata_for_mbox (TrackerFile *file)
-{
- EvolutionLocalData *data;
- GMimeMessage *message;
- TrackerDataMetadata *metadata;
- gchar *dirname, *basename;
- time_t date;
- GList *list;
- guint flags;
-
- data = file->data;
- message = data->message;
-
- if (!message) {
- return NULL;
- }
-
- flags = get_mbox_message_flags (message);
-
- if (flags & EVOLUTION_MESSAGE_JUNK ||
- flags & EVOLUTION_MESSAGE_DELETED) {
- return NULL;
- }
-
- if (data->current_mime_part) {
- /* We're processing an attachment */
- return get_metadata_for_mbox_attachment (file, message, data->current_mime_part->data);
- }
-
- metadata = tracker_data_metadata_new ();
-
- get_mbox_uri (file, message, &dirname, &basename);
- tracker_data_metadata_insert (metadata, METADATA_FILE_PATH, dirname);
- tracker_data_metadata_insert (metadata, METADATA_FILE_NAME, basename);
-
- g_mime_message_get_date (message, &date, NULL);
- tracker_data_metadata_insert (metadata, METADATA_EMAIL_DATE,
- tracker_guint_to_string (date));
-
- tracker_data_metadata_insert (metadata, METADATA_EMAIL_SENDER,
- g_strdup (g_mime_message_get_sender (message)));
- tracker_data_metadata_insert (metadata, METADATA_EMAIL_SUBJECT,
- g_strdup (g_mime_message_get_subject (message)));
-
- list = get_mbox_recipient_list (message, GMIME_RECIPIENT_TYPE_TO);
- tracker_data_metadata_insert_values (metadata, METADATA_EMAIL_SENT_TO, list);
-
- list = get_mbox_recipient_list (message, GMIME_RECIPIENT_TYPE_CC);
- tracker_data_metadata_insert_values (metadata, METADATA_EMAIL_CC, list);
-
- return metadata;
-}
-
-static 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);
- }
-}
-
-static gboolean
-get_imap_attachment_info (const gchar *mime_file,
- gchar **name,
- GMimePartEncodingType *encoding)
-{
- GMimeContentType *mime;
- gchar *tmp, *mime_content;
- const gchar *pos_content_type, *pos_encoding, *pos_end_encoding;
-
- if (name) {
- *name = NULL;
- }
-
- if (encoding) {
- *encoding = GMIME_PART_ENCODING_DEFAULT;
- }
-
- if (!g_file_get_contents (mime_file, &tmp, NULL, NULL)) {
- return FALSE;
- }
-
- /* all text content in lower case for comparisons */
- mime_content = g_ascii_strdown (tmp, -1);
- g_free (tmp);
-
- pos_content_type = strstr (mime_content, "content-type:");
-
- if (pos_content_type) {
- pos_encoding = strstr (pos_content_type, "content-transfer-encoding:");
- }
-
- if (!pos_content_type || !pos_encoding) {
- g_free (mime_content);
- return FALSE;
- }
-
- pos_content_type += strlen ("content-type:");
- pos_encoding += strlen ("content-transfer-encoding:");
-
- /* ignore spaces, tab or line returns */
- while (*pos_content_type != '\0' && (*pos_content_type == ' ' || *pos_content_type == '\t' || *pos_content_type == '\n')) {
- pos_content_type++;
- }
-
- while (*pos_encoding != '\0' && *pos_encoding == ' ') {
- pos_encoding++;
- }
-
- if (*pos_content_type == '\0' ||
- *pos_encoding == '\0') {
- g_free (mime_content);
- return FALSE;
- }
-
- mime = g_mime_content_type_new_from_string (pos_content_type);
-
- if (mime) {
- if (name) {
- *name = g_strdup (g_mime_content_type_get_parameter (mime, "name"));
- }
-
- g_mime_content_type_destroy (mime);
- }
-
- if (name && !*name) {
- g_free (mime_content);
- return FALSE;
- }
-
- /* Find end of encoding */
- pos_end_encoding = pos_encoding;
-
- while (*pos_end_encoding != '\0' &&
- *pos_end_encoding != ' ' &&
- *pos_end_encoding != '\n' &&
- *pos_end_encoding != '\t') {
- pos_end_encoding++;
- }
-
- if (encoding && pos_encoding != pos_end_encoding) {
- gchar *encoding_str = g_strndup (pos_encoding, pos_end_encoding - pos_encoding);
-
- if (strcmp (encoding_str, "7bit") == 0) {
- *encoding = GMIME_PART_ENCODING_7BIT;
- } else if (strcmp (encoding_str, "8bit") == 0) {
- *encoding = GMIME_PART_ENCODING_7BIT;
- } else if (strcmp (encoding_str, "binary") == 0) {
- *encoding = GMIME_PART_ENCODING_BINARY;
- } else if (strcmp (encoding_str, "base64") == 0) {
- *encoding = GMIME_PART_ENCODING_BASE64;
- } else if (strcmp (encoding_str, "quoted-printable") == 0) {
- *encoding = GMIME_PART_ENCODING_QUOTEDPRINTABLE;
- } else if (strcmp (encoding_str, "x-uuencode") == 0) {
- *encoding = GMIME_PART_ENCODING_UUENCODE;
- }
-
- g_free (encoding_str);
- }
-
- g_free (mime_content);
-
- return TRUE;
-}
-
-static void
-get_imap_uri (TrackerFile *file,
- const gchar *uid,
- gchar **uri_base,
- gchar **basename)
-{
- GList *keys, *k;
- gchar *path, *uri, *dir, *subdirs;
-
- path = file->path;
- keys = g_hash_table_get_keys (accounts);
- *uri_base = *basename = NULL;
-
- for (k = keys; k; k = k->next) {
- if (strstr (path, k->data)) {
- dir = g_build_filename (imap_dir, k->data, NULL);
-
- /* now remove all relevant info to create the email:// basename */
- subdirs = g_strdup (path);
- subdirs = tracker_string_remove (subdirs, dir);
- subdirs = tracker_string_remove (subdirs, "/folders/");
- subdirs = tracker_string_remove (subdirs, "/subfolders");
- subdirs = tracker_string_remove (subdirs, "/summary");
-
- uri = g_strdup_printf ("email://%s/%s;uid=%s",
- (gchar *) g_hash_table_lookup (accounts, k->data),
- subdirs, uid);
-
- tracker_file_get_path_and_name (uri, uri_base, basename);
-
- g_free (subdirs);
- g_free (dir);
- g_free (uri);
-
- break;
- }
- }
-
- g_list_free (keys);
-
- return;
-}
-
-static void
-get_imap_attachment_uri (TrackerFile *file,
- gchar **dirname,
- gchar **basename)
-{
- EvolutionImapData *data;
- gchar *message_dirname, *message_basename, *name;
-
- data = file->data;
-
- if (!get_imap_attachment_info (data->current_mime_part->data, &name, NULL)) {
- return;
- }
-
- get_imap_uri (file, data->cur_message_uid, &message_dirname, &message_basename);
- *dirname = g_strdup_printf ("%s/%s", message_dirname, message_basename);
- *basename = name;
-
- g_free (message_dirname);
- g_free (message_basename);
-}
-
-static GList *
-get_imap_recipient_list (const gchar *str)
-{
- GList *list = NULL;
- gchar **arr;
- gint i;
-
- if (!str) {
- return NULL;
- }
-
- arr = g_strsplit (str, ",", -1);
-
- for (i = 0; arr[i]; i++) {
- g_strstrip (arr[i]);
- list = g_list_prepend (list, g_strdup (arr[i]));
- }
-
- g_strfreev (arr);
-
- return g_list_reverse (list);
-}
-
-static gchar *
-get_imap_message_path (TrackerFile *file,
- const gchar *uid)
-{
- gchar *prefix, *message_path;
-
- prefix = g_strndup (file->path, strlen (file->path) - strlen ("summary"));
- message_path = g_strconcat (prefix, uid, ".", NULL);
- g_free (prefix);
-
- return message_path;
-}
-
-static TrackerDataMetadata *
-get_metadata_for_imap_attachment (TrackerFile *file,
- const gchar *mime_file)
-{
- TrackerDataMetadata *metadata;
- GMimeStream *stream;
- GMimeDataWrapper *wrapper;
- GMimePartEncodingType encoding;
- gchar *path, *name;
-
- if (!get_imap_attachment_info (mime_file, &name, &encoding)) {
- return NULL;
- }
-
- path = g_strdup (mime_file);
- path = tracker_string_remove (path, ".MIME");
-
-#if defined(__linux__)
- stream = email_get_stream (path, O_RDONLY | O_NOATIME, 0);
-#else
- stream = email_get_stream (path, O_RDONLY, 0);
-#endif
-
- if (!stream) {
- g_free (name);
- g_free (path);
- return NULL;
- }
-
- wrapper = g_mime_data_wrapper_new_with_stream (stream, encoding);
- metadata = get_metadata_for_data_wrapper (wrapper);
-
- if (metadata) {
- EvolutionImapData *data;
- gchar *dirname, *basename;
-
- data = file->data;
-
- get_imap_uri (file,
- data->cur_message_uid,
- &dirname, &basename);
-
- tracker_data_metadata_insert (metadata, METADATA_FILE_NAME, g_strdup (name));
- tracker_data_metadata_insert (metadata, METADATA_FILE_PATH,
- g_strdup_printf ("%s/%s", dirname, basename));
-
- g_free (dirname);
- g_free (basename);
- }
-
- g_object_unref (wrapper);
- g_object_unref (stream);
- g_free (name);
- g_free (path);
-
- return metadata;
-}
-
-static TrackerDataMetadata *
-get_metadata_for_imap (TrackerFile *file)
-{
- EvolutionImapData *data;
- TrackerDataMetadata *metadata = NULL;
- gchar *dirname, *basename;
- gchar *subject, *from, *to, *cc;
- gint32 i, count, flags;
- time_t date;
- GList *list;
- gboolean deleted;
-
- data = file->data;
-
- if (data->cur_message > data->n_messages) {
- return NULL;
- }
-
- if (data->current_mime_part) {
- return get_metadata_for_imap_attachment (file, data->current_mime_part->data);
- }
-
- if (!read_summary (data->summary,
- SUMMARY_TYPE_UINT32, &flags, /* flags */
- -1)) {
- return NULL;
- }
-
- deleted = ((flags & EVOLUTION_MESSAGE_JUNK) != 0 ||
- (flags & EVOLUTION_MESSAGE_DELETED) != 0);
-
- subject = NULL;
- from = NULL;
- to = NULL;
- cc = NULL;
-
- if (!read_summary (data->summary,
- 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, &cc, /* cc */
- SUMMARY_TYPE_STRING, NULL, /* mlist */
- -1)) {
- g_free (subject);
- g_free (from);
- g_free (to);
- g_free (cc);
- return NULL;
- }
-
- if (!deleted) {
- metadata = tracker_data_metadata_new ();
- get_imap_uri (file, data->cur_message_uid, &dirname, &basename);
-
- tracker_data_metadata_insert (metadata, METADATA_FILE_PATH, dirname);
- tracker_data_metadata_insert (metadata, METADATA_FILE_NAME, basename);
-
- tracker_data_metadata_insert (metadata, METADATA_EMAIL_DATE,
- tracker_guint_to_string (date));
-
- tracker_data_metadata_insert (metadata, METADATA_EMAIL_SENDER, from);
- tracker_data_metadata_insert (metadata, METADATA_EMAIL_SUBJECT, subject);
-
- list = get_imap_recipient_list (to);
- tracker_data_metadata_insert_values (metadata, METADATA_EMAIL_SENT_TO, list);
-
- list = get_imap_recipient_list (cc);
- tracker_data_metadata_insert_values (metadata, METADATA_EMAIL_CC, list);
- }
-
- g_free (to);
- g_free (cc);
-
- if (!read_summary (data->summary,
- SUMMARY_TYPE_INT32, NULL,
- SUMMARY_TYPE_INT32, NULL,
- SUMMARY_TYPE_UINT32, &count,
- -1)) {
- goto corruption;
- }
-
- /* references */
- for (i = 0; i < count; i++) {
- if (read_summary (data->summary,
- SUMMARY_TYPE_INT32, NULL,
- SUMMARY_TYPE_INT32, NULL,
- -1)) {
- continue;
- }
-
- goto corruption;
- }
-
- if (!read_summary (data->summary, SUMMARY_TYPE_UINT32, &count, -1)) {
- goto corruption;
- }
-
- /* user flags */
- for (i = 0; i < count; i++) {
- if (read_summary (data->summary, SUMMARY_TYPE_STRING, NULL, -1)) {
- continue;
- }
-
- goto corruption;
- }
-
- if (!read_summary (data->summary, SUMMARY_TYPE_UINT32, &count, -1)) {
- goto corruption;
- }
-
- /* user tags */
- for (i = 0; i < count; i++) {
- if (read_summary (data->summary,
- SUMMARY_TYPE_STRING, NULL,
- SUMMARY_TYPE_STRING, NULL,
- -1)) {
- continue;
- }
-
- goto corruption;
- }
-
- /* server flags */
- if (!read_summary (data->summary,
- SUMMARY_TYPE_UINT32, NULL,
- -1)) {
- goto corruption;
- }
-
- skip_content_info (data->summary);
-
- return metadata;
-
-corruption:
- /* assume corruption */
- if (metadata) {
- tracker_data_metadata_free (metadata);
- }
-
- return NULL;
-}
-
-void
-tracker_module_file_get_uri (TrackerFile *file,
- gchar **dirname,
- gchar **basename)
-{
- EvolutionFileData *file_data;
-
- file_data = file->data;
-
- if (!file_data) {
- /* It isn't any of the files the
- * module is interested for */
- return;
- }
-
- switch (file_data->type) {
- case MAIL_STORAGE_LOCAL: {
- EvolutionLocalData *data = file->data;
-
- if (!data->message) {
- return;
- }
-
- if (data->current_mime_part) {
- /* We're currently on an attachment */
- get_mbox_attachment_uri (file, data->message,
- data->current_mime_part->data,
- dirname, basename);
- } else {
- get_mbox_uri (file, data->message, dirname, basename);
- }
-
- break;
- }
- case MAIL_STORAGE_IMAP: {
- EvolutionImapData *data = file->data;
-
- if (data->current_mime_part) {
- /* We're currently on an attachment */
- get_imap_attachment_uri (file, dirname, basename);
- } else {
- get_imap_uri (file, data->cur_message_uid, dirname, basename);
- }
-
- break;
- }
- default:
- break;
- }
-}
-
-gchar *
-tracker_module_file_get_service_type (TrackerFile *file)
-{
- EvolutionFileData *data;
-
- data = file->data;
-
- if (!data) {
- /* It isn't any of the files the module handles */
- return NULL;
- }
-
- if (data->type == MAIL_STORAGE_LOCAL) {
- EvolutionLocalData *local_data = file->data;
-
- if (local_data->current_mime_part) {
- return g_strdup ("EvolutionAttachments");
- }
- } else if (data->type == MAIL_STORAGE_IMAP) {
- EvolutionImapData *imap_data = file->data;
-
- if (imap_data->current_mime_part) {
- return g_strdup ("EvolutionAttachments");
- }
- }
-
- return g_strdup ("EvolutionEmails");
-}
-
-TrackerDataMetadata *
-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;
-}
-
-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);
- }
-}
-
-static gchar *
-get_text_for_mbox (TrackerFile *file)
-{
- EvolutionLocalData *data;
- gboolean is_html;
- gchar *text, *encoding, *utf8_text;
-
- data = file->data;
-
- if (data->current_mime_part) {
- /* FIXME: Extract text from attachments */
- return NULL;
- }
-
- text = g_mime_message_get_body (data->message, TRUE, &is_html);
-
- if (!text) {
- return NULL;
- }
-
- encoding = get_object_encoding (GMIME_OBJECT (data->message));
-
- if (!encoding) {
- /* FIXME: could still puke on non-utf8
- * messages without proper content type
- */
- return text;
- }
-
- utf8_text = g_convert (text, -1, "utf8", encoding, NULL, NULL, NULL);
-
- g_free (encoding);
- g_free (text);
-
- return utf8_text;
-}
-
-static void
-extract_message_text (GMimeObject *object,
- gpointer user_data)
-{
- GString *body = (GString *) user_data;
- GMimePartEncodingType part_encoding;
- GMimePart *part;
- const gchar *content, *disposition, *filename;
- gchar *encoding, *part_body;
- gsize len;
-
- 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_message_text, user_data);
- g_object_unref (message);
- }
-
- return;
- } else if (GMIME_IS_MULTIPART (object)) {
- g_mime_multipart_foreach (GMIME_MULTIPART (object), extract_message_text, user_data);
- return;
- }
-
- part = GMIME_PART (object);
- filename = g_mime_part_get_filename (part);
- disposition = g_mime_part_get_content_disposition (part);
- part_encoding = g_mime_part_get_encoding (part);
-
- if (part_encoding == GMIME_PART_ENCODING_BINARY ||
- part_encoding == GMIME_PART_ENCODING_BASE64 ||
- part_encoding == GMIME_PART_ENCODING_UUENCODE) {
- return;
- }
-
- if (disposition &&
- strcmp (disposition, GMIME_DISPOSITION_ATTACHMENT) == 0) {
- return;
- }
-
- if (filename &&
- (strcmp (filename, "signature.asc") == 0 ||
- strcmp (filename, "signature.pgp") == 0)) {
- return;
- }
-
- content = g_mime_part_get_content (GMIME_PART (object), &len);
-
- if (!content) {
- return;
- }
-
- if (g_utf8_validate (content, len, NULL)) {
- g_string_append_len (body, content, (gssize) len);
- return;
- }
-
- encoding = get_object_encoding (object);
-
- if (!encoding) {
- /* FIXME: This will break for non-utf8 text without
- * the proper content type set
- */
- g_string_append_len (body, content, (gssize) len);
- } else {
- part_body = g_convert (content, (gssize) len, "utf8", encoding, NULL, NULL, NULL);
- g_string_append (body, part_body);
-
- g_free (part_body);
- g_free (encoding);
- }
-}
-
-static gchar *
-get_text_for_imap (TrackerFile *file)
-{
- EvolutionImapData *data;
- gchar *message_path;
- GMimeStream *stream;
- GMimeParser *parser;
- GMimeMessage *message;
- GString *body = NULL;
-
- data = file->data;
-
- if (data->current_mime_part) {
- /* FIXME: Extract text from attachments */
- return NULL;
- }
-
- message_path = get_imap_message_path (file, data->cur_message_uid);
-
-#if defined(__linux__)
- stream = email_get_stream (message_path, O_RDONLY | O_NOATIME, 0);
-#else
- stream = email_get_stream (message_path, O_RDONLY, 0);
-#endif
-
- if (!stream) {
- return NULL;
- }
-
- parser = g_mime_parser_new_with_stream (stream);
- g_mime_parser_set_scan_from (parser, FALSE);
- message = g_mime_parser_construct_message (parser);
-
- if (message) {
- body = g_string_new (NULL);
- g_mime_message_foreach_part (message, extract_message_text, body);
- g_object_unref (message);
- }
-
- g_object_unref (stream);
- g_object_unref (parser);
- g_free (message_path);
-
- return (body) ? g_string_free (body, FALSE) : NULL;
-}
-
-gchar *
-tracker_module_file_get_text (TrackerFile *file)
-{
- EvolutionFileData *data;
- gchar *text = NULL;
-
- data = file->data;
-
- if (!data) {
- /* It isn't any of the files the
- * module is interested in */
- return NULL;
- }
-
- if (data->type == MAIL_STORAGE_LOCAL) {
- text = get_text_for_mbox (file);
- } else if (data->type == MAIL_STORAGE_IMAP) {
- text = get_text_for_imap (file);
- }
-
- return text;
-}
-
-static GList *
-extract_imap_mime_parts (TrackerFile *file)
-{
- EvolutionImapData *data;
- gboolean has_attachment = TRUE;
- gint n_attachment = 0;
- gchar *message_path;
- GList *mime_parts = NULL;
-
- data = file->data;
- message_path = get_imap_message_path (file, data->cur_message_uid);
-
- while (has_attachment) {
- gchar *mime_file;
-
- n_attachment++;
- mime_file = g_strdup_printf ("%s%d.MIME", message_path, n_attachment);
-
- if (g_file_test (mime_file, G_FILE_TEST_EXISTS)) {
- mime_parts = g_list_prepend (mime_parts, mime_file);
- } else {
- g_free (mime_file);
- has_attachment = FALSE;
- }
- }
-
- g_free (message_path);
-
- return g_list_reverse (mime_parts);;
-}
-
-static void
-extract_mbox_mime_parts (GMimeObject *object,
- gpointer user_data)
-{
- GList **list = (GList **) user_data;
- GMimePart *part;
- const gchar *disposition, *filename;
-
- 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_mbox_mime_parts, user_data);
- g_object_unref (message);
- }
-
- return;
- } else if (GMIME_IS_MULTIPART (object)) {
- g_mime_multipart_foreach (GMIME_MULTIPART (object), extract_mbox_mime_parts, user_data);
- return;
- }
-
- part = GMIME_PART (object);
- disposition = g_mime_part_get_content_disposition (part);
-
- if (!disposition ||
- (strcmp (disposition, GMIME_DISPOSITION_ATTACHMENT) != 0 &&
- strcmp (disposition, GMIME_DISPOSITION_INLINE) != 0)) {
- return;
- }
-
- filename = g_mime_part_get_filename (GMIME_PART (object));
-
- if (!filename ||
- strcmp (filename, "signature.asc") == 0 ||
- strcmp (filename, "signature.pgp") == 0) {
- return;
- }
-
- *list = g_list_prepend (*list, g_object_ref (object));
-}
-
-gboolean
-tracker_module_file_iter_contents (TrackerFile *file)
-{
- EvolutionFileData *data;
-
- data = file->data;
-
- if (data->type == MAIL_STORAGE_IMAP) {
- EvolutionImapData *imap_data = file->data;
-
- /* Iterate through mime parts, if any */
- if (!imap_data->mime_parts) {
- imap_data->mime_parts = extract_imap_mime_parts (file);
- imap_data->current_mime_part = imap_data->mime_parts;
- } else {
- imap_data->current_mime_part = imap_data->current_mime_part->next;
- }
-
- if (imap_data->current_mime_part) {
- return TRUE;
- }
-
- g_list_foreach (imap_data->mime_parts, (GFunc) g_free, NULL);
- g_list_free (imap_data->mime_parts);
- imap_data->mime_parts = NULL;
-
- g_free (imap_data->cur_message_uid);
- imap_data->cur_message_uid = NULL;
-
- /* save current message uid */
- read_summary (imap_data->summary,
- SUMMARY_TYPE_STRING, &imap_data->cur_message_uid, /* message uid */
- -1);
-
- 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) {
- /* Iterate through mime parts, if any */
- if (!local_data->mime_parts) {
- g_mime_message_foreach_part (local_data->message,
- extract_mbox_mime_parts,
- &local_data->mime_parts);
- local_data->current_mime_part = local_data->mime_parts;
- } else {
- local_data->current_mime_part = local_data->current_mime_part->next;
- }
-
- if (local_data->current_mime_part) {
- return TRUE;
- }
-
- /* all possible mime parts have been already iterated, move on */
- g_object_unref (local_data->message);
-
- g_list_foreach (local_data->mime_parts, (GFunc) g_object_unref, NULL);
- g_list_free (local_data->mime_parts);
- local_data->mime_parts = NULL;
- }
-
- local_data->message = g_mime_parser_construct_message (local_data->parser);
-
- return (local_data->message != NULL);
- }
-
- return FALSE;
+ return NULL;
}
Modified: trunk/src/tracker-indexer/modules/files.c
==============================================================================
--- trunk/src/tracker-indexer/modules/files.c (original)
+++ trunk/src/tracker-indexer/modules/files.c Thu Nov 20 15:29:19 2008
@@ -25,22 +25,10 @@
#include <glib/gstdio.h>
#include <gio/gio.h>
-#include <libtracker-common/tracker-config.h>
#include <libtracker-common/tracker-file-utils.h>
-#include <libtracker-common/tracker-os-dependant.h>
#include <libtracker-common/tracker-ontology.h>
#include <tracker-indexer/tracker-metadata-utils.h>
-#include <tracker-indexer/tracker-module.h>
-
-#define METADATA_FILE_NAME_DELIMITED "File:NameDelimited"
-#define METADATA_FILE_EXT "File:Ext"
-#define METADATA_FILE_PATH "File:Path"
-#define METADATA_FILE_NAME "File:Name"
-#define METADATA_FILE_LINK "File:Link"
-#define METADATA_FILE_MIMETYPE "File:Mime"
-#define METADATA_FILE_SIZE "File:Size"
-#define METADATA_FILE_MODIFIED "File:Modified"
-#define METADATA_FILE_ACCESSED "File:Accessed"
+#include <tracker-indexer/tracker-module-file.h>
/* This is ONLY needed for the indexer to run standalone with
* the -p option, otherwise it will pick up all sorts of crap
@@ -49,22 +37,64 @@
*/
#undef ENABLE_FILE_EXCLUDE_CHECKING
-G_CONST_RETURN gchar *
-tracker_module_get_name (void)
+#define TRACKER_TYPE_REGULAR_FILE (tracker_regular_file_get_type ())
+#define TRACKER_REGULAR_FILE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), TRACKER_TYPE_REGULAR_FILE, TrackerRegularFile))
+
+typedef struct TrackerRegularFile TrackerRegularFile;
+typedef struct TrackerRegularFileClass TrackerRegularFileClass;
+
+struct TrackerRegularFile {
+ TrackerModuleFile parent_instance;
+};
+
+struct TrackerRegularFileClass {
+ TrackerModuleFileClass parent_class;
+};
+
+
+static const gchar * tracker_regular_file_get_service_type (TrackerModuleFile *file);
+static gchar * tracker_regular_file_get_text (TrackerModuleFile *file);
+static TrackerDataMetadata * tracker_regular_file_get_metadata (TrackerModuleFile *file);
+
+
+G_DEFINE_DYNAMIC_TYPE (TrackerRegularFile, tracker_regular_file, TRACKER_TYPE_MODULE_FILE);
+
+
+static void
+tracker_regular_file_class_init (TrackerRegularFileClass *klass)
+{
+ TrackerModuleFileClass *file_class = TRACKER_MODULE_FILE_CLASS (klass);
+
+ file_class->get_service_type = tracker_regular_file_get_service_type;
+ file_class->get_text = tracker_regular_file_get_text;
+ file_class->get_metadata = tracker_regular_file_get_metadata;
+}
+
+static void
+tracker_regular_file_class_finalize (TrackerRegularFileClass *klass)
{
- /* Return module name here */
- return "Files";
}
-gchar *
-tracker_module_file_get_service_type (TrackerFile *file)
+static void
+tracker_regular_file_init (TrackerRegularFile *file)
{
- gchar *mime_type;
- gchar *service_type;
+}
- mime_type = tracker_file_get_mime_type (file->path);
+static const gchar *
+tracker_regular_file_get_service_type (TrackerModuleFile *file)
+{
+ GFile *f;
+ const gchar *service_type;
+ gchar *mime_type, *path;
+
+ f = tracker_module_file_get_file (file);
+ path = g_file_get_path (f);
+
+ mime_type = tracker_file_get_mime_type (path);
service_type = tracker_ontology_get_service_by_mime (mime_type);
+
g_free (mime_type);
+ g_free (path);
return service_type;
}
@@ -139,26 +169,46 @@
#endif /* ENABLE_FILE_EXCLUDE_CHECKING */
-TrackerDataMetadata *
-tracker_module_file_get_metadata (TrackerFile *file)
+static TrackerDataMetadata *
+tracker_regular_file_get_metadata (TrackerModuleFile *file)
{
#ifdef ENABLE_FILE_EXCLUDE_CHECKING
if (check_exclude_file (file->path)) {
return NULL;
}
-#endif /* ENABLE_FILE_EXCLUDE_CHECKING */
+#endif
- return tracker_metadata_utils_get_data (file->path);
+ return tracker_metadata_utils_get_data (tracker_module_file_get_file (file));
}
-gchar *
-tracker_module_file_get_text (TrackerFile *file)
+static gchar *
+tracker_regular_file_get_text (TrackerModuleFile *file)
{
#ifdef ENABLE_FILE_EXCLUDE_CHECKING
if (check_exclude_file (file->path)) {
return NULL;
}
-#endif /* ENABLE_FILE_EXCLUDE_CHECKING */
+#endif
+
+ return tracker_metadata_utils_get_text (tracker_module_file_get_file (file));
+}
+
- return tracker_metadata_utils_get_text (file->path);
+void
+indexer_module_initialize (GTypeModule *module)
+{
+ tracker_regular_file_register_type (module);
+}
+
+void
+indexer_module_shutdown (void)
+{
+}
+
+TrackerModuleFile *
+indexer_module_create_file (GFile *file)
+{
+ return g_object_new (TRACKER_TYPE_REGULAR_FILE,
+ "file", file,
+ NULL);
}
Modified: trunk/src/tracker-indexer/tracker-indexer-module.c
==============================================================================
--- trunk/src/tracker-indexer/tracker-indexer-module.c (original)
+++ trunk/src/tracker-indexer/tracker-indexer-module.c Thu Nov 20 15:29:19 2008
@@ -20,196 +20,121 @@
*/
#include <gmodule.h>
-
#include "tracker-indexer-module.h"
-GModule *
-tracker_indexer_module_load (const gchar *module_name)
-{
- gchar *full_name, *path;
- GModule *module;
-
- g_return_val_if_fail (module_name != NULL, NULL);
- full_name = g_strdup_printf ("libtracker-indexer-%s", module_name);
- path = g_build_filename (INDEXER_MODULES_DIR, full_name, NULL);
+static gboolean tracker_indexer_module_load (GTypeModule *module);
+static void tracker_indexer_module_unload (GTypeModule *module);
- module = g_module_open (path, G_MODULE_BIND_LOCAL);
- if (!module) {
- g_warning ("Could not load indexer module '%s', %s\n", module_name, g_module_error ());
- } else {
- g_module_make_resident (module);
- }
-
- g_free (full_name);
- g_free (path);
-
- return module;
-}
+G_DEFINE_TYPE (TrackerIndexerModule, tracker_indexer_module, G_TYPE_TYPE_MODULE)
-void
-tracker_indexer_module_init (GModule *module)
+static void
+tracker_indexer_module_class_init (TrackerIndexerModuleClass *klass)
{
- TrackerModuleInit func;
+ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass);
- if (g_module_symbol (module, "tracker_module_init", (gpointer *) &func)) {
- (func) ();
- }
+ module_class->load = tracker_indexer_module_load;
+ module_class->unload = tracker_indexer_module_unload;
}
-void
-tracker_indexer_module_shutdown (GModule *module)
+static void
+tracker_indexer_module_init (TrackerIndexerModule *module)
{
- TrackerModuleShutdown func;
-
- if (g_module_symbol (module, "tracker_module_shutdown", (gpointer *) &func)) {
- (func) ();
- }
}
-G_CONST_RETURN gchar *
-tracker_indexer_module_get_name (GModule *module)
+static gboolean
+tracker_indexer_module_load (GTypeModule *module)
{
- TrackerModuleGetNameFunc func;
-
- if (g_module_symbol (module, "tracker_module_get_name", (gpointer *) &func)) {
- return (func) ();
- }
+ TrackerIndexerModule *indexer_module;
+ gchar *full_name, *path;
- return NULL;
-}
+ indexer_module = TRACKER_INDEXER_MODULE (module);
-TrackerFile *
-tracker_indexer_module_file_new (GModule *module,
- const gchar *path)
-{
- TrackerModuleFileGetDataFunc func;
- TrackerFile *file = NULL;
-
- file = g_slice_new0 (TrackerFile);
- file->path = g_strdup (path);
+ full_name = g_strdup_printf ("libtracker-indexer-%s", indexer_module->name);
+ path = g_build_filename (INDEXER_MODULES_DIR, full_name, NULL);
- if (g_module_symbol (module, "tracker_module_file_get_data", (gpointer *) &func)) {
- file->data = (func) (path);
- }
+ indexer_module->module = g_module_open (path, G_MODULE_BIND_LOCAL);
- return file;
-}
+ g_free (full_name);
+ g_free (path);
-void
-tracker_indexer_module_file_free (GModule *module,
- TrackerFile *file)
-{
- TrackerModuleFileFreeDataFunc func;
+ if (G_UNLIKELY (!indexer_module->module)) {
+ g_warning ("Could not load indexer module '%s': %s\n",
+ indexer_module->name,
+ g_module_error ());
- if (file->data &&
- g_module_symbol (module, "tracker_module_file_free_data", (gpointer *) &func)) {
- (func) (file->data);
+ return FALSE;
}
- g_free (file->path);
- g_slice_free (TrackerFile, file);
-}
-
-gboolean
-tracker_indexer_module_file_get_uri (GModule *module,
- TrackerFile *file,
- gchar **dirname,
- gchar **basename)
-{
- TrackerModuleFileGetUriFunc func;
- gchar *tmp_dirname;
- gchar *tmp_basename;
-
- tmp_dirname = tmp_basename = NULL;
-
- if (g_module_symbol (module, "tracker_module_file_get_uri", (gpointer *) &func)) {
- (func) (file, &tmp_dirname, &tmp_basename);
- } else {
- tmp_dirname = g_path_get_dirname (file->path);
- tmp_basename = g_path_get_basename (file->path);
- }
+ g_module_make_resident (indexer_module->module);
- if (tmp_dirname && tmp_basename) {
- if (dirname) {
- *dirname = tmp_dirname;
- } else {
- g_free (tmp_dirname);
- }
-
- if (basename) {
- *basename = tmp_basename;
- } else {
- g_free (tmp_basename);
- }
-
- return TRUE;
- } else {
- g_free (tmp_dirname);
- g_free (tmp_basename);
-
- if (dirname) {
- *dirname = NULL;
- }
-
- if (basename) {
- *basename = NULL;
- }
+ if (!g_module_symbol (indexer_module->module, "indexer_module_initialize",
+ (gpointer *) &indexer_module->initialize) ||
+ !g_module_symbol (indexer_module->module, "indexer_module_shutdown",
+ (gpointer *) &indexer_module->shutdown) ||
+ !g_module_symbol (indexer_module->module, "indexer_module_create_file",
+ (gpointer *) &indexer_module->create_file)) {
+ g_warning ("Could not load module symbols for '%s': %s",
+ indexer_module->name,
+ g_module_error ());
return FALSE;
}
-}
-gchar *
-tracker_indexer_module_file_get_service_type (GModule *module,
- TrackerFile *file)
-{
- TrackerModuleFileGetServiceTypeFunc func;
-
- if (g_module_symbol (module, "tracker_module_file_get_service_type", (gpointer *) &func)) {
- return (func) (file);
- } else {
- return g_strdup (tracker_indexer_module_get_name (module));
- }
+ indexer_module->initialize (module);
+ return TRUE;
}
-TrackerDataMetadata *
-tracker_indexer_module_file_get_metadata (GModule *module,
- TrackerFile *file)
+static void
+tracker_indexer_module_unload (GTypeModule *module)
{
- TrackerModuleFileGetMetadataFunc func;
+ TrackerIndexerModule *indexer_module;
- if (g_module_symbol (module, "tracker_module_file_get_metadata", (gpointer *) &func)) {
- return (func) (file);
- }
+ indexer_module = TRACKER_INDEXER_MODULE (module);
+ indexer_module->shutdown ();
+
+ g_module_close (indexer_module->module);
+ indexer_module->module = NULL;
- return NULL;
+ indexer_module->initialize = NULL;
+ indexer_module->shutdown = NULL;
+ indexer_module->create_file = NULL;
}
-gchar *
-tracker_indexer_module_file_get_text (GModule *module,
- TrackerFile *file)
+TrackerIndexerModule *
+tracker_indexer_module_get (const gchar *name)
{
- TrackerModuleFileGetText func;
+ static GHashTable *modules;
+ TrackerIndexerModule *module;
+
+ g_return_val_if_fail (name != NULL, NULL);
- if (g_module_symbol (module, "tracker_module_file_get_text", (gpointer *) &func)) {
- return (func) (file);
+ if (G_UNLIKELY (!modules)) {
+ modules = g_hash_table_new (g_str_hash, g_str_equal);
}
- return NULL;
-}
+ module = g_hash_table_lookup (modules, name);
-gboolean
-tracker_indexer_module_file_iter_contents (GModule *module,
- TrackerFile *file)
-{
- TrackerModuleFileIterContents func;
+ if (G_UNLIKELY (!module)) {
+ module = g_object_new (TRACKER_TYPE_INDEXER_MODULE, NULL);
+ g_type_module_set_name (G_TYPE_MODULE (module), name);
+ module->name = g_strdup (name);
- if (file->data && g_module_symbol (module, "tracker_module_file_iter_contents", (gpointer *) &func)) {
- return (func) (file);
+ g_hash_table_insert (modules, module->name, module);
}
- return FALSE;
+ if (!g_type_module_use (G_TYPE_MODULE (module))) {
+ return NULL;
+ }
+
+ return module;
+}
+
+TrackerModuleFile *
+tracker_indexer_module_create_file (TrackerIndexerModule *module,
+ GFile *file)
+{
+ return module->create_file (file);
}
Modified: trunk/src/tracker-indexer/tracker-indexer-module.h
==============================================================================
--- trunk/src/tracker-indexer/tracker-indexer-module.h (original)
+++ trunk/src/tracker-indexer/tracker-indexer-module.h Thu Nov 20 15:29:19 2008
@@ -23,36 +23,39 @@
#define __TRACKER_INDEXER_MODULE_H__
#include <glib.h>
-#include "tracker-module.h"
-#include <libtracker-data/tracker-data-metadata.h>
+#include "tracker-module-file.h"
+#include "tracker-module-iteratable.h"
G_BEGIN_DECLS
-GModule * tracker_indexer_module_load (const gchar *module_name);
+#define TRACKER_TYPE_INDEXER_MODULE (tracker_indexer_module_get_type ())
+#define TRACKER_INDEXER_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), TRACKER_TYPE_INDEXER_MODULE, TrackerIndexerModule))
-void tracker_indexer_module_init (GModule *module);
-void tracker_indexer_module_shutdown (GModule *module);
+typedef struct TrackerIndexerModule TrackerIndexerModule;
+typedef struct TrackerIndexerModuleClass TrackerIndexerModuleClass;
-G_CONST_RETURN gchar * tracker_indexer_module_get_name (GModule *module);
+struct TrackerIndexerModule {
+ GTypeModule parent_instance;
-TrackerFile * tracker_indexer_module_file_new (GModule *module,
- const gchar *path);
-void tracker_indexer_module_file_free (GModule *module,
- TrackerFile *file);
-
-gboolean tracker_indexer_module_file_get_uri (GModule *module,
- TrackerFile *file,
- gchar **dirname,
- gchar **basename);
-gchar * tracker_indexer_module_file_get_service_type (GModule *module,
- TrackerFile *file);
-TrackerDataMetadata * tracker_indexer_module_file_get_metadata (GModule *module,
- TrackerFile *file);
-gchar * tracker_indexer_module_file_get_text (GModule *module,
- TrackerFile *file);
+ GModule *module;
+ gchar *name;
+
+ void (* initialize) (GTypeModule *module);
+ void (* shutdown) (void);
+ TrackerModuleFile * (* create_file) (GFile *file);
+};
+
+struct TrackerIndexerModuleClass {
+ GTypeModuleClass parent_class;
+};
+
+
+GType tracker_indexer_module_get_type (void) G_GNUC_CONST;
+
+TrackerIndexerModule * tracker_indexer_module_get (const gchar *name);
+TrackerModuleFile * tracker_indexer_module_create_file (TrackerIndexerModule *module,
+ GFile *file);
-gboolean tracker_indexer_module_file_iter_contents (GModule *module,
- TrackerFile *file);
G_END_DECLS
Modified: trunk/src/tracker-indexer/tracker-indexer.c
==============================================================================
--- trunk/src/tracker-indexer/tracker-indexer.c (original)
+++ trunk/src/tracker-indexer/tracker-indexer.c Thu Nov 20 15:29:19 2008
@@ -74,7 +74,6 @@
#include "tracker-indexer.h"
#include "tracker-indexer-module.h"
#include "tracker-marshal.h"
-#include "tracker-module.h"
#define TRACKER_INDEXER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_INDEXER, TrackerIndexerPrivate))
@@ -153,10 +152,11 @@
};
struct PathInfo {
- GModule *module;
- TrackerFile *file;
- TrackerFile *other_file;
- gchar *module_name;
+ TrackerIndexerModule *module;
+ GFile *file;
+ GFile *other_file;
+ TrackerModuleFile *module_file;
+ TrackerModuleFile *other_module_file;
};
struct MetadataForeachData {
@@ -209,22 +209,24 @@
G_DEFINE_TYPE (TrackerIndexer, tracker_indexer, G_TYPE_OBJECT)
static PathInfo *
-path_info_new (GModule *module,
- const gchar *module_name,
- const gchar *path,
- const gchar *other_path)
+path_info_new (TrackerIndexerModule *module,
+ GFile *file,
+ GFile *other_file)
{
PathInfo *info;
info = g_slice_new (PathInfo);
info->module = module;
- info->module_name = g_strdup (module_name);
- info->file = tracker_indexer_module_file_new (module, path);
- if (G_UNLIKELY (other_path)) {
- info->other_file = tracker_indexer_module_file_new (module, other_path);
+ info->file = g_object_ref (file);
+ info->module_file = tracker_indexer_module_create_file (module, file);
+
+ if (G_UNLIKELY (other_file)) {
+ info->other_file = g_object_ref (other_file);
+ info->other_module_file = tracker_indexer_module_create_file (module, other_file);
} else {
info->other_file = NULL;
+ info->other_module_file = NULL;
}
return info;
@@ -234,11 +236,18 @@
path_info_free (PathInfo *info)
{
if (G_UNLIKELY (info->other_file)) {
- tracker_indexer_module_file_free (info->module, info->other_file);
+ g_object_unref (info->other_file);
+ }
+
+ if (G_UNLIKELY (info->other_module_file)) {
+ g_object_unref (info->other_module_file);
+ }
+
+ if (G_LIKELY (info->module_file)) {
+ g_object_unref (info->module_file);
}
- tracker_indexer_module_file_free (info->module, info->file);
- g_free (info->module_name);
+ g_object_unref (info->file);
g_slice_free (PathInfo, info);
}
@@ -634,13 +643,6 @@
}
static void
-close_module (GModule *module)
-{
- tracker_indexer_module_shutdown (module);
- g_module_close (module);
-}
-
-static void
check_started (TrackerIndexer *indexer)
{
TrackerIndexerState state;
@@ -859,23 +861,18 @@
g_quark_from_string (l->data);
}
- priv->indexer_modules = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- (GDestroyNotify) close_module);
+ priv->indexer_modules = g_hash_table_new (g_str_hash, g_str_equal);
for (l = priv->module_names; l; l = l->next) {
- GModule *module;
+ TrackerIndexerModule *module;
if (!tracker_module_config_get_enabled (l->data)) {
continue;
}
- module = tracker_indexer_module_load (l->data);
+ module = tracker_indexer_module_get (l->data);
if (module) {
- tracker_indexer_module_init (module);
-
g_hash_table_insert (priv->indexer_modules,
l->data, module);
}
@@ -1297,6 +1294,26 @@
g_hash_table_unref (new_words);
}
+static TrackerService *
+get_service_for_file (TrackerModuleFile *file,
+ TrackerIndexerModule *module)
+{
+ TrackerService *service;
+ const gchar *service_type;
+
+ service_type = tracker_module_file_get_service_type (file);
+
+ if (!service_type) {
+ service_type = tracker_module_config_get_index_service (module->name);
+ }
+
+ if (!service_type) {
+ return NULL;
+ }
+
+ return tracker_ontology_get_service_by_name (service_type);
+}
+
static gboolean
remove_existing_non_emb_metadata (TrackerField *field,
gpointer value,
@@ -1325,19 +1342,10 @@
TrackerDataMetadata *metadata)
{
TrackerService *service;
- gchar *service_type;
gchar *text;
guint32 id;
- service_type = tracker_indexer_module_file_get_service_type (info->module,
- info->file);
-
- if (!service_type) {
- return;
- }
-
- service = tracker_ontology_get_service_by_name (service_type);
- g_free (service_type);
+ service = get_service_for_file (info->module_file, info->module);
if (!service) {
return;
@@ -1377,7 +1385,7 @@
* difference and add the words.
*/
old_text = tracker_data_query_content (service, id);
- new_text = tracker_indexer_module_file_get_text (info->module, info->file);
+ new_text = tracker_module_file_get_text (info->module_file);
item_update_content (indexer, service, id, old_text, new_text);
g_free (old_text);
@@ -1406,7 +1414,7 @@
index_metadata (indexer, id, service, metadata);
- text = tracker_indexer_module_file_get_text (info->module, info->file);
+ text = tracker_module_file_get_text (info->module_file);
if (text) {
/* Save in the index */
@@ -1443,25 +1451,20 @@
TrackerDataMetadata *old_metadata, *new_metadata;
gchar *service_type;
gchar *new_path, *new_name, *ext;
+ GFile *file, *other_file;
+ gchar *path, *other_path;
guint32 id;
- service_type = tracker_indexer_module_file_get_service_type (info->module,
- info->other_file);
-
- if (!service_type) {
- return;
- }
-
- service = tracker_ontology_get_service_by_name (service_type);
- g_free (service_type);
+ service = get_service_for_file (info->other_module_file, info->module);
if (!service) {
return;
}
- g_debug ("Moving item from '%s' to '%s'",
- info->file->path,
- info->other_file->path);
+ path = g_file_get_path (info->file);
+ other_path = g_file_get_path (info->other_file);
+
+ g_debug ("Moving item from '%s' to '%s'", path, other_path);
/* Get 'source' ID */
if (!tracker_data_query_service_exists (service,
@@ -1469,37 +1472,36 @@
basename,
&id,
NULL)) {
- g_message ("Source file '%s' not found in database to move",
- info->file->path);
+ g_message ("Source file '%s' not found in database to move", path);
+ g_free (path);
+ g_free (other_path);
+
return;
}
- tracker_data_update_move_service (service,
- info->file->path,
- info->other_file->path);
+ tracker_data_update_move_service (service, path, other_path);
/*
* Updating what changes in move event (Path related properties)
*/
old_metadata = tracker_data_query_embedded_metadata (service, id);
- tracker_data_metadata_foreach_remove (old_metadata,
- filter_invalid_after_move_properties,
+ tracker_data_metadata_foreach_remove (old_metadata,
+ filter_invalid_after_move_properties,
NULL);
unindex_metadata (indexer, id, service, old_metadata);
-
new_metadata = tracker_data_metadata_new ();
- tracker_file_get_path_and_name (info->other_file->path, &new_path, &new_name);
+ tracker_file_get_path_and_name (other_path, &new_path, &new_name);
tracker_data_metadata_insert (new_metadata, METADATA_FILE_PATH, new_path);
tracker_data_metadata_insert (new_metadata, METADATA_FILE_NAME, new_name);
- tracker_data_metadata_insert (new_metadata,
- METADATA_FILE_NAME_DELIMITED,
- g_strdup (info->other_file->path));
+ tracker_data_metadata_insert (new_metadata,
+ METADATA_FILE_NAME_DELIMITED,
+ g_strdup (other_path));
- ext = strrchr (info->other_file->path, '.');
+ ext = strrchr (other_path, '.');
if (ext) {
tracker_data_metadata_insert (new_metadata, METADATA_FILE_EXT, g_strdup (ext + 1));
}
@@ -1510,6 +1512,9 @@
/* tracker_data_metadata_free frees the values */
tracker_data_metadata_free (old_metadata);
tracker_data_metadata_free (new_metadata);
+
+ g_free (path);
+ g_free (other_path);
}
static void
@@ -1524,7 +1529,7 @@
const gchar *service_type;
guint service_id, service_type_id;
- service_type = tracker_module_config_get_index_service (info->module_name);
+ service_type = tracker_module_config_get_index_service (info->module->name);
g_debug ("Removing item: '%s/%s' (no metadata was given by module)",
dirname,
@@ -1880,21 +1885,14 @@
const gchar *basename)
{
TrackerService *service;
- gchar *service_type;
+ gchar *path;
const gchar *str;
gboolean is_dir;
gboolean should_be_cached;
struct stat st;
time_t mtime;
- service_type = tracker_indexer_module_file_get_service_type (info->module, info->file);
-
- if (!service_type) {
- return FALSE;
- }
-
- service = tracker_ontology_get_service_by_name (service_type);
- g_free (service_type);
+ service = get_service_for_file (info->module_file, info->module);
if (!service) {
return TRUE;
@@ -1917,7 +1915,10 @@
* the database. If it does, then we can ignore any files
* immediately in this parent directory.
*/
- if (g_lstat (info->file->path, &st) == -1) {
+ path = g_file_get_path (info->file);
+
+ if (g_lstat (path, &st) == -1) {
+ g_free (path);
return TRUE;
}
@@ -1958,7 +1959,7 @@
* or not. All operations are done using the same string.
*/
if (is_dir) {
- str = info->file->path;
+ str = path;
} else {
str = dirname;
}
@@ -1982,6 +1983,8 @@
str,
should_index ? "should index" : "should not index");
+ g_free (path);
+
return should_index;
}
@@ -2010,6 +2013,7 @@
g_free (parent_basename);
g_free (parent_dirname);
+ g_free (path);
return TRUE;
}
@@ -2020,6 +2024,7 @@
g_free (parent_basename);
g_free (parent_dirname);
+ g_free (path);
return TRUE;
}
@@ -2032,6 +2037,7 @@
g_debug ("%s:'%s' has indifferent mtime and should not be indexed",
is_dir ? "Path" : "Parent path",
str);
+ g_free (path);
return FALSE;
}
@@ -2045,30 +2051,41 @@
g_strdup (str),
GINT_TO_POINTER (1));
+ g_free (path);
+
return TRUE;
}
+
static gboolean
process_file (TrackerIndexer *indexer,
PathInfo *info)
{
TrackerDataMetadata *metadata;
- gchar *dirname;
- gchar *basename;
+ gchar *uri, *dirname, *basename;
/* Note: If info->other_file is set, the PathInfo is for a
* MOVE event not for normal file event.
*/
+ if (!info->module_file) {
+ return TRUE;
+ }
+
/* Set the current module */
- indexer->private->current_module = g_quark_from_string (info->module_name);
+ indexer->private->current_module = g_quark_from_string (info->module->name);
+ uri = tracker_module_file_get_uri (info->module_file);
+
+ if (!uri) {
+ if (TRACKER_IS_MODULE_ITERATABLE (info->module_file)) {
+ return !tracker_module_iteratable_iter_contents (TRACKER_MODULE_ITERATABLE (info->module_file));
+ }
- if (!tracker_indexer_module_file_get_uri (info->module,
- info->file,
- &dirname,
- &basename)) {
- return !tracker_indexer_module_file_iter_contents (info->module, info->file);
+ return TRUE;
}
+ tracker_file_get_path_and_name (uri, &dirname, &basename);
+ g_free (uri);
+
/*
* FIRST:
* ======
@@ -2087,17 +2104,22 @@
* basename which are returned by the module are combined to
* look like:
*
- * email://1192717939 16218 20 petunia//INBOX;uid=1
+ * email://1192717939 16218 20 petunia/INBOX;uid=1
*
* We simply check the dirname[0] to make sure it isn't an
* email based dirname.
*/
if (G_LIKELY (!info->other_file) && dirname[0] == G_DIR_SEPARATOR) {
if (!should_index_file (indexer, info, dirname, basename)) {
- g_debug ("File is already up to date: '%s'", info->file->path);
+ gchar *path;
+
+ path = g_file_get_path (info->file);
+
+ g_debug ("File is already up to date: '%s'", path);
g_free (dirname);
g_free (basename);
+ g_free (path);
return TRUE;
}
@@ -2113,7 +2135,7 @@
if (G_UNLIKELY (info->other_file)) {
item_move (indexer, info, dirname, basename);
} else {
- metadata = tracker_indexer_module_file_get_metadata (info->module, info->file);
+ metadata = tracker_module_file_get_metadata (info->module_file);
if (metadata) {
item_add_or_update (indexer, info, dirname, basename, metadata);
@@ -2128,7 +2150,11 @@
g_free (dirname);
g_free (basename);
- return !tracker_indexer_module_file_iter_contents (info->module, info->file);
+ if (TRACKER_IS_MODULE_ITERATABLE (info->module_file)) {
+ return !tracker_module_iteratable_iter_contents (TRACKER_MODULE_ITERATABLE (info->module_file));
+ }
+
+ return TRUE;
}
static void
@@ -2136,39 +2162,48 @@
PathInfo *info,
gboolean recurse)
{
+ gchar *path;
const gchar *name;
GDir *dir;
- g_debug ("Processing directory:'%s'", info->file->path);
+ path = g_file_get_path (info->file);
+
+ /* FIXME: Use gio to iterate the directory */
+ g_debug ("Processing directory:'%s'", path);
- dir = g_dir_open (info->file->path, 0, NULL);
+ dir = g_dir_open (path, 0, NULL);
if (!dir) {
+ g_free (path);
return;
}
while ((name = g_dir_read_name (dir)) != NULL) {
PathInfo *new_info;
- gchar *path;
+ GFile *child;
+ gchar *child_path;
if (name[0] == '.') {
continue;
}
- path = g_build_filename (info->file->path, name, NULL);
+ child = g_file_get_child (info->file, name);
+ child_path = g_file_get_path (child);
- new_info = path_info_new (info->module, info->module_name, path, NULL);
+ new_info = path_info_new (info->module, child, NULL);
add_file (indexer, new_info);
- if (recurse && g_file_test (path, G_FILE_TEST_IS_DIR)) {
- new_info = path_info_new (info->module, info->module_name, path, NULL);
+ if (recurse && g_file_test (child_path, G_FILE_TEST_IS_DIR)) {
+ new_info = path_info_new (info->module, child, NULL);
add_directory (indexer, new_info);
}
- g_free (path);
+ g_object_unref (child);
+ g_free (child_path);
}
g_dir_close (dir);
+ g_free (path);
}
static void
@@ -2193,7 +2228,7 @@
process_module (TrackerIndexer *indexer,
const gchar *module_name)
{
- GModule *module;
+ TrackerIndexerModule *module;
GList *dirs, *d;
module = g_hash_table_lookup (indexer->private->indexer_modules, module_name);
@@ -2216,9 +2251,13 @@
for (d = dirs; d; d = d->next) {
PathInfo *info;
+ GFile *file;
- info = path_info_new (module, module_name, d->data, NULL);
+ file = g_file_new_for_path (d->data);
+ info = path_info_new (module, file, NULL);
add_directory (indexer, info);
+
+ g_object_unref (file);
}
g_list_free (dirs);
@@ -2562,7 +2601,7 @@
DBusGMethodInvocation *context,
GError **error)
{
- GModule *module;
+ TrackerIndexerModule *module;
guint request_id;
gint i;
GError *actual_error = NULL;
@@ -2591,9 +2630,13 @@
/* Add files to the queue */
for (i = 0; files[i]; i++) {
PathInfo *info;
+ GFile *file;
- info = path_info_new (module, module_name, files[i], NULL);
+ file = g_file_new_for_path (files[i]);
+ info = path_info_new (module, file, NULL);
add_file (indexer, info);
+
+ g_object_unref (file);
}
dbus_g_method_return (context);
@@ -2632,7 +2675,7 @@
DBusGMethodInvocation *context,
GError **error)
{
- GModule *module;
+ TrackerIndexerModule *module;
guint request_id;
GError *actual_error;
PathInfo *info;
@@ -2660,7 +2703,9 @@
}
/* Add files to the queue */
- info = path_info_new (module, module_name, from, to);
+ info = path_info_new (module,
+ g_file_new_for_path (from),
+ g_file_new_for_path (to));
add_file (indexer, info);
dbus_g_method_return (context);
Modified: trunk/src/tracker-indexer/tracker-metadata-utils.c
==============================================================================
--- trunk/src/tracker-indexer/tracker-metadata-utils.c (original)
+++ trunk/src/tracker-indexer/tracker-metadata-utils.c Thu Nov 20 15:29:19 2008
@@ -882,11 +882,11 @@
* Returns: A newly allocated string containing the file text, or %NULL.
**/
gchar *
-tracker_metadata_utils_get_text (const gchar *path)
+tracker_metadata_utils_get_text (GFile *file)
{
- gchar *mime_type;
- gchar *service_type;
- gchar *text;
+ gchar *path, *mime_type, *service_type, *text;
+
+ path = g_file_get_path (file);
mime_type = tracker_file_get_mime_type (path);
service_type = tracker_ontology_get_service_by_mime (mime_type);
@@ -902,6 +902,7 @@
g_free (service_type);
g_free (mime_type);
+ g_free (path);
return text;
}
@@ -916,14 +917,17 @@
* Returns: A newly created #TrackerDataMetadata, or %NULL if the file is not found.
**/
TrackerDataMetadata *
-tracker_metadata_utils_get_data (const gchar *path)
+tracker_metadata_utils_get_data (GFile *file)
{
TrackerDataMetadata *metadata;
struct stat st;
const gchar *ext;
- gchar *mime_type;
+ gchar *mime_type, *path;
+
+ path = g_file_get_path (file);
if (g_lstat (path, &st) < 0) {
+ g_free (path);
return NULL;
}
@@ -937,13 +941,13 @@
mime_type = tracker_file_get_mime_type (path);
tracker_data_metadata_insert (metadata, METADATA_FILE_NAME,
- g_filename_display_basename (path));
+ g_filename_display_basename (path));
tracker_data_metadata_insert (metadata, METADATA_FILE_PATH,
- g_path_get_dirname (path));
+ g_path_get_dirname (path));
tracker_data_metadata_insert (metadata, METADATA_FILE_NAME_DELIMITED,
- g_filename_to_utf8 (path, -1, NULL, NULL, NULL));
+ g_filename_to_utf8 (path, -1, NULL, NULL, NULL));
tracker_data_metadata_insert (metadata, METADATA_FILE_MIMETYPE,
- mime_type);
+ mime_type);
if (mime_type) {
/* FIXME:
@@ -958,19 +962,21 @@
link_path = g_file_read_link (path, NULL);
tracker_data_metadata_insert (metadata, METADATA_FILE_LINK,
- g_filename_to_utf8 (link_path, -1, NULL, NULL, NULL));
+ g_filename_to_utf8 (link_path, -1, NULL, NULL, NULL));
g_free (link_path);
}
/* FIXME: These should be dealt directly as integer/times/whatever, not strings */
tracker_data_metadata_insert (metadata, METADATA_FILE_SIZE,
- tracker_guint_to_string (st.st_size));
+ tracker_guint_to_string (st.st_size));
tracker_data_metadata_insert (metadata, METADATA_FILE_MODIFIED,
- tracker_date_to_string (st.st_mtime));
+ tracker_date_to_string (st.st_mtime));
tracker_data_metadata_insert (metadata, METADATA_FILE_ACCESSED,
- tracker_date_to_string (st.st_atime));
+ tracker_date_to_string (st.st_atime));
metadata_utils_get_embedded (path, mime_type, metadata);
+ g_free (path);
+
return metadata;
}
Modified: trunk/src/tracker-indexer/tracker-metadata-utils.h
==============================================================================
--- trunk/src/tracker-indexer/tracker-metadata-utils.h (original)
+++ trunk/src/tracker-indexer/tracker-metadata-utils.h Thu Nov 20 15:29:19 2008
@@ -23,11 +23,12 @@
#define __TRACKER_METADATA_UTILS_H__
#include <libtracker-data/tracker-data-metadata.h>
+#include <tracker-indexer/tracker-module-file.h>
G_BEGIN_DECLS
-TrackerDataMetadata *tracker_metadata_utils_get_data (const gchar *path);
-gchar * tracker_metadata_utils_get_text (const gchar *path);
+TrackerDataMetadata *tracker_metadata_utils_get_data (GFile *file);
+gchar * tracker_metadata_utils_get_text (GFile *file);
G_END_DECLS
Added: trunk/src/tracker-indexer/tracker-module-file.c
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/tracker-module-file.c Thu Nov 20 15:29:19 2008
@@ -0,0 +1,224 @@
+/* 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 <libtracker-common/tracker-file-utils.h>
+#include "tracker-module-file.h"
+
+#define METADATA_FILE_PATH "File:Path"
+#define METADATA_FILE_NAME "File:Name"
+
+#define TRACKER_MODULE_FILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MODULE_FILE, TrackerModuleFilePrivate))
+
+typedef struct TrackerModuleFilePrivate TrackerModuleFilePrivate;
+
+struct TrackerModuleFilePrivate {
+ GFile *file;
+};
+
+enum {
+ PROP_0,
+ PROP_FILE
+};
+
+
+static void tracker_module_file_finalize (GObject *object);
+static void tracker_module_file_constructed (GObject *object);
+static void tracker_module_file_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void tracker_module_file_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+
+
+G_DEFINE_ABSTRACT_TYPE (TrackerModuleFile, tracker_module_file, G_TYPE_OBJECT)
+
+static void
+tracker_module_file_class_init (TrackerModuleFileClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = tracker_module_file_finalize;
+ object_class->constructed = tracker_module_file_constructed;
+ object_class->set_property = tracker_module_file_set_property;
+ object_class->get_property = tracker_module_file_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_FILE,
+ g_param_spec_object ("file",
+ "File",
+ "File corresponding to the TrackerModuleFile",
+ G_TYPE_FILE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_type_class_add_private (object_class, sizeof (TrackerModuleFilePrivate));
+}
+
+static void
+tracker_module_file_init (TrackerModuleFile *file)
+{
+}
+
+static void
+tracker_module_file_finalize (GObject *object)
+{
+ TrackerModuleFilePrivate *priv;
+
+ priv = TRACKER_MODULE_FILE_GET_PRIVATE (object);
+
+ g_object_unref (priv->file);
+
+ G_OBJECT_CLASS (tracker_module_file_parent_class)->finalize (object);
+}
+
+static void
+tracker_module_file_constructed (GObject *object)
+{
+ if (TRACKER_MODULE_FILE_GET_CLASS (object)->initialize) {
+ TrackerModuleFile *file;
+
+ file = TRACKER_MODULE_FILE (object);
+ TRACKER_MODULE_FILE_GET_CLASS (object)->initialize (file);
+ }
+
+ if (G_OBJECT_CLASS (tracker_module_file_parent_class)->constructed) {
+ G_OBJECT_CLASS (tracker_module_file_parent_class)->constructed (object);
+ }
+}
+
+static void
+tracker_module_file_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerModuleFilePrivate *priv;
+
+ priv = TRACKER_MODULE_FILE_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_FILE:
+ priv->file = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+
+}
+
+static void
+tracker_module_file_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerModuleFilePrivate *priv;
+
+ priv = TRACKER_MODULE_FILE_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_FILE:
+ g_value_set_object (value, priv->file);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+GFile *
+tracker_module_file_get_file (TrackerModuleFile *file)
+{
+ TrackerModuleFilePrivate *priv;
+
+ priv = TRACKER_MODULE_FILE_GET_PRIVATE (file);
+
+ return priv->file;
+}
+
+G_CONST_RETURN gchar *
+tracker_module_file_get_service_type (TrackerModuleFile *file)
+{
+ if (TRACKER_MODULE_FILE_GET_CLASS (file)->get_service_type == NULL) {
+ return NULL;
+ }
+
+ return TRACKER_MODULE_FILE_GET_CLASS (file)->get_service_type (file);
+}
+
+gchar *
+tracker_module_file_get_uri (TrackerModuleFile *file)
+{
+ gchar *uri = NULL;
+
+ if (TRACKER_MODULE_FILE_GET_CLASS (file)->get_uri) {
+ uri = TRACKER_MODULE_FILE_GET_CLASS (file)->get_uri (file);
+ }
+
+ if (!uri) {
+ GFile *f;
+
+ f = tracker_module_file_get_file (file);
+
+ /* FIXME: When we agree on storing URIs in the
+ * database, this should stop returning the path
+ */
+ uri = g_file_get_path (f);
+ }
+
+ return uri;
+}
+
+gchar *
+tracker_module_file_get_text (TrackerModuleFile *file)
+{
+ if (TRACKER_MODULE_FILE_GET_CLASS (file)->get_text == NULL) {
+ return NULL;
+ }
+
+ return TRACKER_MODULE_FILE_GET_CLASS (file)->get_text (file);
+}
+
+TrackerDataMetadata *
+tracker_module_file_get_metadata (TrackerModuleFile *file)
+{
+ TrackerDataMetadata *metadata = NULL;
+
+ if (TRACKER_MODULE_FILE_GET_CLASS (file)->get_metadata != NULL) {
+ metadata = TRACKER_MODULE_FILE_GET_CLASS (file)->get_metadata (file);
+ }
+
+ if (metadata &&
+ !tracker_data_metadata_lookup (metadata, METADATA_FILE_PATH) &&
+ !tracker_data_metadata_lookup (metadata, METADATA_FILE_NAME)) {
+ gchar *uri, *dirname, *basename;
+
+ uri = tracker_module_file_get_uri (file);
+ tracker_file_get_path_and_name (uri, &dirname, &basename);
+
+ tracker_data_metadata_insert (metadata, METADATA_FILE_PATH, dirname);
+ tracker_data_metadata_insert (metadata, METADATA_FILE_NAME, basename);
+
+ g_free (uri);
+ }
+
+ return metadata;
+}
Added: trunk/src/tracker-indexer/tracker-module-file.h
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/tracker-module-file.h Thu Nov 20 15:29:19 2008
@@ -0,0 +1,66 @@
+/* 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.
+ */
+
+#ifndef __TRACKER_MODULE_FILE_H__
+#define __TRACKER_MODULE_FILE_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <libtracker-data/tracker-data-metadata.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_MODULE_FILE (tracker_module_file_get_type())
+#define TRACKER_MODULE_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MODULE_FILE, TrackerModuleFile))
+#define TRACKER_MODULE_FILE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_MODULE_FILE, TrackerModuleFileClass))
+#define TRACKER_IS_MODULE_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MODULE_FILE))
+#define TRACKER_IS_MODULE_FILE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_MODULE_FILE))
+#define TRACKER_MODULE_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_MODULE_FILE, TrackerModuleFileClass))
+
+
+typedef struct TrackerModuleFile TrackerModuleFile;
+typedef struct TrackerModuleFileClass TrackerModuleFileClass;
+
+struct TrackerModuleFile {
+ GObject parent_instance;
+};
+
+struct TrackerModuleFileClass {
+ GObjectClass parent_class;
+
+ void (* initialize) (TrackerModuleFile *file);
+ G_CONST_RETURN gchar * (* get_service_type) (TrackerModuleFile *file);
+ gchar * (* get_uri) (TrackerModuleFile *file);
+ gchar * (* get_text) (TrackerModuleFile *file);
+ TrackerDataMetadata * (* get_metadata) (TrackerModuleFile *file);
+};
+
+
+GType tracker_module_file_get_type (void) G_GNUC_CONST;
+
+GFile * tracker_module_file_get_file (TrackerModuleFile *file);
+G_CONST_RETURN gchar * tracker_module_file_get_service_type (TrackerModuleFile *file);
+gchar * tracker_module_file_get_uri (TrackerModuleFile *file);
+gchar * tracker_module_file_get_text (TrackerModuleFile *file);
+TrackerDataMetadata * tracker_module_file_get_metadata (TrackerModuleFile *file);
+
+
+G_END_DECLS
+
+#endif /* __TRACKER_MODULE_FILE_H__ */
Added: trunk/src/tracker-indexer/tracker-module-iteratable.c
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/tracker-module-iteratable.c Thu Nov 20 15:29:19 2008
@@ -0,0 +1,54 @@
+/* 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 "tracker-module-iteratable.h"
+#include "tracker-module-file.h"
+
+GType
+tracker_module_iteratable_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ type = g_type_register_static_simple (G_TYPE_INTERFACE,
+ "TrackerModuleIteratable",
+ sizeof (TrackerModuleIteratableIface),
+ NULL, 0, NULL, 0);
+
+ g_type_interface_add_prerequisite (type, TRACKER_TYPE_MODULE_FILE);
+ }
+
+ return type;
+}
+
+gboolean
+tracker_module_iteratable_iter_contents (TrackerModuleIteratable *iteratable)
+{
+ return TRACKER_MODULE_ITERATABLE_GET_IFACE (iteratable)->iter_contents (iteratable);
+}
+
+guint
+tracker_module_iteratable_get_count (TrackerModuleIteratable *iteratable)
+{
+ if (TRACKER_MODULE_ITERATABLE_GET_IFACE (iteratable)->get_count) {
+ return TRACKER_MODULE_ITERATABLE_GET_IFACE (iteratable)->get_count (iteratable);
+ }
+
+ return 0;
+}
Added: trunk/src/tracker-indexer/tracker-module-iteratable.h
==============================================================================
--- (empty file)
+++ trunk/src/tracker-indexer/tracker-module-iteratable.h Thu Nov 20 15:29:19 2008
@@ -0,0 +1,52 @@
+/* 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.
+ */
+
+#ifndef __TRACKER_MODULE_ITERATABLE_H__
+#define __TRACKER_MODULE_ITERATABLE_H__
+
+#include <glib-object.h>
+#include "tracker-module-file.h"
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_MODULE_ITERATABLE (tracker_module_iteratable_get_type ())
+#define TRACKER_MODULE_ITERATABLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MODULE_ITERATABLE, TrackerModuleIteratable))
+#define TRACKER_IS_MODULE_ITERATABLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MODULE_ITERATABLE))
+#define TRACKER_MODULE_ITERATABLE_GET_IFACE(i) (G_TYPE_INSTANCE_GET_INTERFACE ((i), TRACKER_TYPE_MODULE_ITERATABLE, TrackerModuleIteratableIface))
+
+typedef struct TrackerModuleIteratable TrackerModuleIteratable; /* dummy typedef */
+typedef struct TrackerModuleIteratableIface TrackerModuleIteratableIface;
+
+struct TrackerModuleIteratableIface {
+ GTypeInterface parent_iface;
+
+ gboolean (* iter_contents) (TrackerModuleIteratable *iteratable);
+ guint (* get_count) (TrackerModuleIteratable *iteratable);
+};
+
+
+GType tracker_module_iteratable_get_type (void) G_GNUC_CONST;
+
+gboolean tracker_module_iteratable_iter_contents (TrackerModuleIteratable *iteratable);
+guint tracker_module_iteratable_get_count (TrackerModuleIteratable *iteratable);
+
+
+G_END_DECLS
+
+#endif /* __TRACKER_MODULE_ITERATABLE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]