Attachment 'implementation.diff'
Download 1 Index: src/plugins/evolution/tracker-evolution-indexer.h
2 ===================================================================
3 --- src/plugins/evolution/tracker-evolution-indexer.h (revision 0)
4 +++ src/plugins/evolution/tracker-evolution-indexer.h (revision 0)
5 @@ -0,0 +1,100 @@
6 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
7 +/*
8 + * Copyright (C) 2008, Nokia
9 + *
10 + * This library is free software; you can redistribute it and/or
11 + * modify it under the terms of the GNU General Public
12 + * License as published by the Free Software Foundation; either
13 + * version 2 of the License, or (at your option) any later version.
14 + *
15 + * This library is distributed in the hope that it will be useful,
16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 + * General Public License for more details.
19 + *
20 + * You should have received a copy of the GNU General Public
21 + * License along with this library; if not, write to the
22 + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 + * Boston, MA 02110-1301, USA.
24 + *
25 + * Authors:
26 + * Philip Van Hoof <philip@codeminded.be>
27 + */
28 +
29 +#ifndef __LIBTRACKER_EVOLUTION_H__
30 +#define __LIBTRACKER_EVOLUTION_H__
31 +
32 +#if !defined (TRACKER_ENABLE_INTERNALS) && !defined (TRACKER_COMPILATION)
33 +#error "TRACKER_ENABLE_INTERNALS not defined, this must be defined to use tracker's internal functions"
34 +#endif
35 +
36 +#include <glib.h>
37 +
38 +#include <libtracker-common/tracker-common.h>
39 +
40 +G_BEGIN_DECLS
41 +
42 +#if !defined (TRACKER_ENABLE_INTERNALS) && !defined (TRACKER_COMPILATION)
43 +#error "TRACKER_ENABLE_INTERNALS not defined, this must be defined to use tracker's internal functions"
44 +#endif
45 +
46 +#include <glib.h>
47 +#include <dbus/dbus-glib-bindings.h>
48 +
49 +#include <tracker-indexer/tracker-indexer.h>
50 +
51 +#include "tracker-evolution-common.h"
52 +
53 +G_BEGIN_DECLS
54 +
55 +#define TRACKER_TYPE_EVOLUTION_INDEXER (tracker_evolution_indexer_get_type())
56 +#define TRACKER_EVOLUTION_INDEXER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_EVOLUTION_INDEXER, TrackerEvolutionIndexer))
57 +#define TRACKER_EVOLUTION_INDEXER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_EVOLUTION_INDEXER, TrackerEvolutionIndexerClass))
58 +#define TRACKER_EVOLUTION_INDEXER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_EVOLUTION_INDEXER, TrackerEvolutionIndexerClass))
59 +
60 +G_BEGIN_DECLS
61 +
62 +typedef struct TrackerEvolutionIndexer TrackerEvolutionIndexer;
63 +typedef struct TrackerEvolutionIndexerClass TrackerEvolutionIndexerClass;
64 +
65 +struct TrackerEvolutionIndexer {
66 + GObject parent;
67 +};
68 +
69 +struct TrackerEvolutionIndexerClass {
70 + GObjectClass parent;
71 +};
72 +
73 +GType tracker_evolution_indexer_get_type (void);
74 +
75 +void tracker_evolution_indexer_set (TrackerEvolutionIndexer *object,
76 + const gchar *subject,
77 + const GStrv predicates,
78 + const GStrv values,
79 + DBusGMethodInvocation *context,
80 + GError *derror);
81 +void tracker_evolution_indexer_set_many (TrackerEvolutionIndexer *object,
82 + const GStrv subjects,
83 + const GPtrArray *predicates,
84 + const GPtrArray *values,
85 + DBusGMethodInvocation *context,
86 + GError *derror);
87 +void tracker_evolution_indexer_unset_many (TrackerEvolutionIndexer *object,
88 + const GStrv subjects,
89 + DBusGMethodInvocation *context,
90 + GError *derror);
91 +void tracker_evolution_indexer_unset (TrackerEvolutionIndexer *object,
92 + const gchar *subject,
93 + DBusGMethodInvocation *context,
94 + GError *derror);
95 +void tracker_evolution_indexer_cleanup (TrackerEvolutionIndexer *object,
96 + DBusGMethodInvocation *context,
97 + GError *derror);
98 +
99 +void tracker_evolution_storer_init (TrackerConfig *config,
100 + TrackerIndexer *indexer);
101 +void tracker_evolution_storer_shutdown (void);
102 +
103 +G_END_DECLS
104 +
105 +#endif /* __LIBTRACKER_EVOLUTION_H__ */
106 Index: src/plugins/evolution/tracker-evolution-plugin.h
107 ===================================================================
108 --- src/plugins/evolution/tracker-evolution-plugin.h (revision 0)
109 +++ src/plugins/evolution/tracker-evolution-plugin.h (revision 0)
110 @@ -0,0 +1,60 @@
111 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
112 +/*
113 + * Copyright (C) 2008, Nokia
114 + *
115 + * This library is free software; you can redistribute it and/or
116 + * modify it under the terms of the GNU General Public
117 + * License as published by the Free Software Foundation; either
118 + * version 2 of the License, or (at your option) any later version.
119 + *
120 + * This library is distributed in the hope that it will be useful,
121 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
122 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
123 + * General Public License for more details.
124 + *
125 + * You should have received a copy of the GNU General Public
126 + * License along with this library; if not, write to the
127 + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
128 + * Boston, MA 02110-1301, USA.
129 + *
130 + * Authors:
131 + * Philip Van Hoof <philip@codeminded.be>
132 + */
133 +
134 +#ifndef __TRACKER_EVOLUTION_PLUGIN_H__
135 +#define __TRACKER_EVOLUTION_PLUGIN_H__
136 +
137 +#include <dbus/dbus-glib-bindings.h>
138 +#include <dbus/dbus-glib-lowlevel.h>
139 +
140 +#include "tracker-evolution-common.h"
141 +
142 +#define TRACKER_TYPE_EVOLUTION_PLUGIN (tracker_evolution_plugin_get_type())
143 +#define TRACKER_EVOLUTION_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_EVOLUTION_PLUGIN, TrackerEvolutionPlugin))
144 +#define TRACKER_EVOLUTION_PLUGIN_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_EVOLUTION_PLUGIN, TrackerEvolutionPluginClass))
145 +#define TRACKER_EVOLUTION_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_EVOLUTION_PLUGIN, TrackerEvolutionPluginClass))
146 +
147 +G_BEGIN_DECLS
148 +
149 +typedef struct TrackerEvolutionPlugin TrackerEvolutionPlugin;
150 +typedef struct TrackerEvolutionPluginClass TrackerEvolutionPluginClass;
151 +
152 +struct TrackerEvolutionPlugin {
153 + GObject parent;
154 +};
155 +
156 +struct TrackerEvolutionPluginClass {
157 + GObjectClass parent;
158 +};
159 +
160 +GType tracker_evolution_plugin_get_type (void);
161 +
162 +void tracker_evolution_plugin_register (TrackerEvolutionPlugin *object,
163 + gchar *registrar_path,
164 + guint last_checkout,
165 + DBusGMethodInvocation *context,
166 + GError *derror);
167 +
168 +G_END_DECLS
169 +
170 +#endif /* __TRACKER_EVOLUTION_PLUGIN_H__ */
171 Index: src/plugins/evolution/org-freedesktop-Tracker-evolution-plugin.eplug.xml
172 ===================================================================
173 --- src/plugins/evolution/org-freedesktop-Tracker-evolution-plugin.eplug.xml (revision 0)
174 +++ src/plugins/evolution/org-freedesktop-Tracker-evolution-plugin.eplug.xml (revision 0)
175 @@ -0,0 +1,15 @@
176 +<?xml version="1.0"?>
177 +<e-plugin-list>
178 + <e-plugin id="org.freedesktop.Tracker.evolution_plugin"
179 + type="shlib"
180 + location="+PLUGIN_INSTALL_DIR+/liborg-freedesktop-Tracker-evolution-plugin.so"
181 + domain="+GETTEXT_PACKAGE+"
182 + localedir="+LOCALEDIR+"
183 + _name="TrackerEvolutionPlugin"
184 + load-on-startup="after-ui">
185 +
186 + <_description>Support for Tracker.</_description>
187 +
188 + <author name="Philip Van Hoof" email="philip@codeminded.be"/>
189 + </e-plugin>
190 +</e-plugin-list>
191 Index: src/plugins/evolution/tracker-evolution.h
192 ===================================================================
193 --- src/plugins/evolution/tracker-evolution.h (revision 0)
194 +++ src/plugins/evolution/tracker-evolution.h (revision 0)
195 @@ -0,0 +1,42 @@
196 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
197 +/*
198 + * Copyright (C) 2008, Nokia
199 + *
200 + * This library is free software; you can redistribute it and/or
201 + * modify it under the terms of the GNU General Public
202 + * License as published by the Free Software Foundation; either
203 + * version 2 of the License, or (at your option) any later version.
204 + *
205 + * This library is distributed in the hope that it will be useful,
206 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
207 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
208 + * General Public License for more details.
209 + *
210 + * You should have received a copy of the GNU General Public
211 + * License along with this library; if not, write to the
212 + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
213 + * Boston, MA 02110-1301, USA.
214 + *
215 + * Authors:
216 + * Philip Van Hoof <philip@codeminded.be>
217 + */
218 +
219 +#ifndef __LIBTRACKER_EVOLUTION_H__
220 +#define __LIBTRACKER_EVOLUTION_H__
221 +
222 +#if !defined (TRACKER_ENABLE_INTERNALS) && !defined (TRACKER_COMPILATION)
223 +#error "TRACKER_ENABLE_INTERNALS not defined, this must be defined to use tracker's internal functions"
224 +#endif
225 +
226 +#include <glib.h>
227 +
228 +#include <libtracker-common/tracker-common.h>
229 +
230 +G_BEGIN_DECLS
231 +
232 +void tracker_evolution_init (TrackerConfig *config);
233 +void tracker_evolution_shutdown (void);
234 +
235 +G_END_DECLS
236 +
237 +#endif /* __LIBTRACKER_EVOLUTION_H__ */
238 Index: src/plugins/evolution/tracker-evolution-registrar.h
239 ===================================================================
240 --- src/plugins/evolution/tracker-evolution-registrar.h (revision 0)
241 +++ src/plugins/evolution/tracker-evolution-registrar.h (revision 0)
242 @@ -0,0 +1,88 @@
243 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
244 +/*
245 + * Copyright (C) 2008, Nokia
246 + *
247 + * This library is free software; you can redistribute it and/or
248 + * modify it under the terms of the GNU General Public
249 + * License as published by the Free Software Foundation; either
250 + * version 2 of the License, or (at your option) any later version.
251 + *
252 + * This library is distributed in the hope that it will be useful,
253 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
254 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
255 + * General Public License for more details.
256 + *
257 + * You should have received a copy of the GNU General Public
258 + * License along with this library; if not, write to the
259 + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
260 + * Boston, MA 02110-1301, USA.
261 + *
262 + * Authors:
263 + * Philip Van Hoof <philip@codeminded.be>
264 + */
265 +
266 +#ifndef __LIBTRACKER_EVOLUTION_REGISTRAR_H__
267 +#define __LIBTRACKER_EVOLUTION_REGISTRAR_H__
268 +
269 +#if !defined (TRACKER_ENABLE_INTERNALS) && !defined (TRACKER_COMPILATION)
270 +#error "TRACKER_ENABLE_INTERNALS not defined, this must be defined to use tracker's internal functions"
271 +#endif
272 +
273 +#include <dbus/dbus-glib-bindings.h>
274 +
275 +#include "tracker-evolution-common.h"
276 +
277 +G_BEGIN_DECLS
278 +
279 +#define TRACKER_TYPE_EVOLUTION_REGISTRAR (tracker_evolution_registrar_get_type())
280 +#define TRACKER_EVOLUTION_REGISTRAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_EVOLUTION_REGISTRAR, TrackerEvolutionRegistrar))
281 +#define TRACKER_EVOLUTION_REGISTRAR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_EVOLUTION_REGISTRAR, TrackerEvolutionRegistrarClass))
282 +#define TRACKER_EVOLUTION_REGISTRAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_EVOLUTION_REGISTRAR, TrackerEvolutionRegistrarClass))
283 +
284 +G_BEGIN_DECLS
285 +
286 +#ifndef __TRACKER_EVOLUTION_REGISTRAR_C__
287 +extern const DBusGMethodInfo *registrar_methods;
288 +#endif
289 +
290 +typedef struct TrackerEvolutionRegistrar TrackerEvolutionRegistrar;
291 +typedef struct TrackerEvolutionRegistrarClass TrackerEvolutionRegistrarClass;
292 +
293 +struct TrackerEvolutionRegistrar {
294 + GObject parent;
295 +};
296 +
297 +struct TrackerEvolutionRegistrarClass {
298 + GObjectClass parent;
299 +};
300 +
301 +GType tracker_evolution_registrar_get_type (void);
302 +
303 +void tracker_evolution_registrar_set (TrackerEvolutionRegistrar *object,
304 + const gchar *subject,
305 + const GStrv predicates,
306 + const GStrv values,
307 + DBusGMethodInvocation *context,
308 + GError *derror);
309 +void tracker_evolution_registrar_set_many (TrackerEvolutionRegistrar *object,
310 + const GStrv subjects,
311 + const GPtrArray *predicates,
312 + const GPtrArray *values,
313 + DBusGMethodInvocation *context,
314 + GError *derror);
315 +void tracker_evolution_registrar_unset_many (TrackerEvolutionRegistrar *object,
316 + const GStrv subjects,
317 + DBusGMethodInvocation *context,
318 + GError *derror);
319 +void tracker_evolution_registrar_unset (TrackerEvolutionRegistrar *object,
320 + const gchar *subject,
321 + DBusGMethodInvocation *context,
322 + GError *derror);
323 +void tracker_evolution_registrar_cleanup (TrackerEvolutionRegistrar *object,
324 + DBusGMethodInvocation *context,
325 + GError *derror);
326 +
327 +
328 +G_END_DECLS
329 +
330 +#endif /* __LIBTRACKER_EVOLUTION_REGISTRAR_H__ */
331 Index: src/plugins/evolution/tracker-evolution-plugin.xml
332 ===================================================================
333 --- src/plugins/evolution/tracker-evolution-plugin.xml (revision 0)
334 +++ src/plugins/evolution/tracker-evolution-plugin.xml (revision 0)
335 @@ -0,0 +1,11 @@
336 +<?xml version="1.0" encoding="UTF-8"?>
337 +<node name="/">
338 + <interface name="org.gnome.evolution.metadata.Manager">
339 + <method name="Register">
340 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
341 + <arg type="o" name="registrar_path" direction="in" />
342 + <arg type="u" name="last_checkout" direction="in" />
343 + </method>
344 + </interface>
345 +</node>
346 +
347 Index: src/plugins/evolution/tracker-evolution-common.h
348 ===================================================================
349 --- src/plugins/evolution/tracker-evolution-common.h (revision 0)
350 +++ src/plugins/evolution/tracker-evolution-common.h (revision 0)
351 @@ -0,0 +1,76 @@
352 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
353 +/*
354 + * Copyright (C) 2008, Nokia
355 + *
356 + * This library is free software; you can redistribute it and/or
357 + * modify it under the terms of the GNU General Public
358 + * License as published by the Free Software Foundation; either
359 + * version 2 of the License, or (at your option) any later version.
360 + *
361 + * This library is distributed in the hope that it will be useful,
362 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
363 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
364 + * General Public License for more details.
365 + *
366 + * You should have received a copy of the GNU General Public
367 + * License along with this library; if not, write to the
368 + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
369 + * Boston, MA 02110-1301, USA.
370 + *
371 + * Authors:
372 + * Philip Van Hoof <philip@codeminded.be>
373 + */
374 +
375 +#ifndef __TRACKER_EVOLUTION_COMMON_H__
376 +#define __TRACKER_EVOLUTION_COMMON_H__
377 +
378 +#define TRACKER_EVOLUTION_INDEXER_PATH "/org/freedesktop/Tracker/Indexer/Evolution/Registrar"
379 +
380 +#define TRACKER_EVOLUTION_REGISTRAR_SERVICE "org.freedesktop.Tracker"
381 +#define TRACKER_EVOLUTION_REGISTRAR_PATH "/org/freedesktop/Tracker/Evolution/Registrar"
382 +#define TRACKER_EVOLUTION_REGISTRAR_INTERFACE "org.gnome.evolution.metadata.Registrar"
383 +
384 +#define TRACKER_EVOLUTION_MANAGER_SERVICE "org.gnome.evolution"
385 +#define TRACKER_EVOLUTION_MANAGER_PATH "/org/gnome/evolution/metadata/Manager"
386 +#define TRACKER_EVOLUTION_MANAGER_INTERFACE "org.gnome.evolution.metadata.Manager"
387 +
388 +#define DBUS_ERROR_DOMAIN "TrackerEvolution"
389 +#define DBUS_ERROR g_quark_from_static_string (DBUS_ERROR_DOMAIN)
390 +
391 +#define TRACKER_EVOLUTION_PREDICATE_SUBJECT "Evolution:MessageSubject"
392 +#define TRACKER_EVOLUTION_PREDICATE_SENT "Evolution:MessageSent"
393 +#define TRACKER_EVOLUTION_PREDICATE_FROM "Evolution:MessageFrom"
394 +#define TRACKER_EVOLUTION_PREDICATE_TO "Evolution:MessageTo"
395 +#define TRACKER_EVOLUTION_PREDICATE_FILE "Evolution:MessageFile"
396 +#define TRACKER_EVOLUTION_PREDICATE_CC "Evolution:MessageCc"
397 +#define TRACKER_EVOLUTION_PREDICATE_UID "Evolution:MessageUid"
398 +#define TRACKER_EVOLUTION_PREDICATE_SEEN "Evolution:MessageSeen"
399 +#define TRACKER_EVOLUTION_PREDICATE_JUNK "Evolution:MessageJunk"
400 +#define TRACKER_EVOLUTION_PREDICATE_ANSWERED "Evolution:MessageAnswered"
401 +#define TRACKER_EVOLUTION_PREDICATE_FLAGGED "Evolution:MessageFlagged"
402 +#define TRACKER_EVOLUTION_PREDICATE_TAG "Evolution:MessageTag"
403 +#define TRACKER_EVOLUTION_PREDICATE_FORWARDED "Evolution:MessageForwarded"
404 +#define TRACKER_EVOLUTION_PREDICATE_DELETED "Evolution:MessageDeleted"
405 +#define TRACKER_EVOLUTION_PREDICATE_SIZE "Evolution:MessageSize"
406 +
407 +#define TRACKER_TYPE_G_STRV_ARRAY (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRV))
408 +
409 +#define dbus_async_return_if_fail(expr,context) \
410 + G_STMT_START { \
411 + if G_LIKELY(expr) { } else { \
412 + GError *error = NULL; \
413 + \
414 + g_set_error (&error, \
415 + DBUS_ERROR, \
416 + 0, \
417 + "Assertion `%s' failed", \
418 + #expr); \
419 + \
420 + dbus_g_method_return_error (context, error); \
421 + g_error_free (error); \
422 + \
423 + return; \
424 + }; \
425 + } G_STMT_END
426 +
427 +#endif /* __TRACKER_EVOLUTION_COMMON_H__ */
428 Index: src/plugins/evolution/Makefile.am
429 ===================================================================
430 --- src/plugins/evolution/Makefile.am (revision 0)
431 +++ src/plugins/evolution/Makefile.am (revision 0)
432 @@ -0,0 +1,89 @@
433 +INCLUDES = \
434 + -I$(top_srcdir)/src \
435 + -DGETTEXT_PACKAGE="\"$(GETTEXT_PACKAGE)\"" \
436 + -DLOCALEDIR="\"$(LOCALEDIR)\"" \
437 + -DTRACKER_COMPILATION \
438 + $(DBUS_CFLAGS) \
439 + $(GMIME_CFLAGS) \
440 + $(EVOPLUG_CFLAGS)
441 +
442 +%.eplug.in: %.eplug.xml
443 + LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@
444 +
445 +%.eplug: %.eplug.in
446 + sed -e "s%+PLUGIN_INSTALL_DIR+%$(EVOPLUG_INSTALL_DIR)%" \
447 + -e "s%+GETTEXT_PACKAGE+%$(GETTEXT_PACKAGE)%" \
448 + -e "s%+LOCALEDIR+%$(LOCALEDIR)%" \
449 + $< > $@
450 +
451 +eplugindir = $(EVOLUTION_PLUGIN_INSTALL_DIR)
452 +
453 +eplugin_DATA = org-freedesktop-Tracker-evolution-plugin.eplug
454 +
455 +eplugin_LTLIBRARIES = liborg-freedesktop-Tracker-evolution-plugin.la
456 +
457 +noinst_LTLIBRARIES = libtracker-evolution.la libtracker-evolution-indexer.la
458 +
459 +libtracker_evolution_indexer_la_SOURCES = \
460 + tracker-evolution-indexer.c \
461 + tracker-evolution-indexer.h \
462 + tracker-evolution-registrar-glue.h \
463 + tracker-evolution-common.h
464 +
465 +libtracker_evolution_la_SOURCES = \
466 + tracker-evolution.c \
467 + tracker-evolution.h \
468 + tracker-evolution-registrar.c \
469 + tracker-evolution-registrar.h \
470 + tracker-evolution-common.h \
471 + tracker-evolution-registrar-glue.h
472 +
473 +libtracker_evolution_la_LIBADD = \
474 + $(top_builddir)/src/libtracker-data/libtracker-data.la \
475 + $(top_builddir)/src/libtracker-db/libtracker-db.la \
476 + $(top_builddir)/src/libtracker-common/libtracker-common.la \
477 + $(DBUS_LIBS) \
478 + $(GTHREAD_LIBS) \
479 + $(GIO_LIBS) \
480 + $(GLIB2_LIBS) \
481 + $(RAPTOR_LIBS)
482 +
483 +libtracker_evolution_indexer_la_LIBADD = \
484 + $(top_builddir)/src/libtracker-data/libtracker-data.la \
485 + $(top_builddir)/src/libtracker-db/libtracker-db.la \
486 + $(top_builddir)/src/libtracker-common/libtracker-common.la \
487 + $(DBUS_LIBS) \
488 + $(GTHREAD_LIBS) \
489 + $(GIO_LIBS) \
490 + $(GLIB2_LIBS) \
491 + $(RAPTOR_LIBS) \
492 + $(GMIME_LIBS)
493 +
494 +liborg_freedesktop_Tracker_evolution_plugin_la_SOURCES = \
495 + tracker-evolution-plugin.c \
496 + tracker-evolution-plugin.h \
497 + tracker-evolution-common.h \
498 + tracker-evolution-plugin-glue.h
499 +
500 +liborg_freedesktop_Tracker_evolution_plugin_la_LDFLAGS = -module -avoid-version
501 +liborg_freedesktop_Tracker_evolution_plugin_la_LDLIBS = \
502 + $(EVOPLUG_LIBS) \
503 + $(DBUS_LIBS)
504 +
505 +dbus_sources = \
506 + tracker-evolution-plugin-glue.h \
507 + tracker-evolution-registrar-glue.h
508 +
509 +%-glue.h: %.xml
510 + $(DBUSBINDINGTOOL) --mode=glib-server --output=$@ --prefix=$(subst -,_,$*) $^
511 +
512 +BUILT_SOURCES = \
513 + $(dbus_sources) \
514 + $(eplugin_DATA)
515 +
516 +CLEANFILES = $(BUILT_SOURCES) \
517 + org-freedesktop-Tracker-evolution-plugin.eplug
518 +
519 +EXTRA_DIST = \
520 + $(BUILT_SOURCES) \
521 + org-freedesktop-Tracker-evolution-plugin.eplug.xml
522 Index: src/plugins/evolution/tracker-evolution-plugin.c
523 ===================================================================
524 --- src/plugins/evolution/tracker-evolution-plugin.c (revision 0)
525 +++ src/plugins/evolution/tracker-evolution-plugin.c (revision 0)
526 @@ -0,0 +1,1732 @@
527 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
528 +/*
529 + * Copyright (C) 2008, Nokia
530 + *
531 + * This library is free software; you can redistribute it and/or
532 + * modify it under the terms of the GNU General Public
533 + * License as published by the Free Software Foundation; either
534 + * version 2 of the License, or (at your option) any later version.
535 + *
536 + * This library is distributed in the hope that it will be useful,
537 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
538 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
539 + * General Public License for more details.
540 + *
541 + * You should have received a copy of the GNU General Public
542 + * License along with this library; if not, write to the
543 + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
544 + * Boston, MA 02110-1301, USA.
545 + *
546 + * Authors:
547 + * Philip Van Hoof <philip@codeminded.be>
548 + */
549 +
550 +#include "config.h"
551 +
552 +#include <sys/types.h>
553 +#include <sys/stat.h>
554 +#include <sys/wait.h>
555 +#include <fcntl.h>
556 +#include <errno.h>
557 +#include <signal.h>
558 +#include <string.h>
559 +#include <pthread.h>
560 +#include <signal.h>
561 +#include <time.h>
562 +#include <inttypes.h>
563 +
564 +#include <sqlite3.h>
565 +
566 +#include <camel/camel-mime-message.h>
567 +#include <camel/camel-i18n.h>
568 +#include <camel/camel-store.h>
569 +#include <camel/camel-folder.h>
570 +#include <camel/camel-db.h>
571 +#include <camel/camel-offline-store.h>
572 +#include <camel/camel-session.h>
573 +
574 +#include <mail/mail-config.h>
575 +#include <mail/mail-session.h>
576 +#include <mail/em-utils.h>
577 +#include <mail/mail-ops.h>
578 +
579 +#include <e-util/e-config.h>
580 +
581 +#include <libedataserver/e-account.h>
582 +#include <libedataserver/e-account-list.h>
583 +
584 +#include "tracker-evolution-plugin.h"
585 +#include "tracker-evolution-plugin-glue.h"
586 +
587 +/* This runs in-process of evolution (in the mailer, as a EPlugin). It has
588 + * access to the CamelSession using the external variable 'session'. The header
589 + * mail/mail-session.h makes this variable public */
590 +
591 +#define MAX_BEFORE_SEND 2000
592 +
593 +G_DEFINE_TYPE (TrackerEvolutionPlugin, tracker_evolution_plugin, G_TYPE_OBJECT)
594 +
595 +#define TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_EVOLUTION_PLUGIN, TrackerEvolutionPluginPrivate))
596 +
597 +/* Some helper-defines */
598 +#define CAMEL_CALLBACK(func) ((CamelObjectEventHookFunc) func)
599 +#define EXTRACT_STRING(val) if (*part) part++; len=strtoul (part, &part, 10); if (*part) part++; val=g_strndup (part, len); part+=len;
600 +#define EXTRACT_FIRST_DIGIT(val) val=strtoul (part, &part, 10);
601 +
602 +/* About the locks being used: Camel's API must be used in a multi-threaded
603 + * fashion. Therefore it's necessary to guard against concurrent access of
604 + * memory. Especially given that both the mainloop and the Camel-threads will
605 + * be accessing the memory (mainloop for DBus calls, and Camel-threads mostly
606 + * during registration of accounts and folders) */
607 +
608 +typedef struct {
609 + guint64 last_checkout;
610 + DBusGProxy *registrar;
611 + guint signal;
612 +} ClientRegistry;
613 +
614 +typedef struct {
615 + TrackerEvolutionPlugin *self;
616 + gchar *account_uri;
617 + guint hook_id;
618 +} OnSummaryChangedInfo;
619 +
620 +typedef struct {
621 + OnSummaryChangedInfo *hook_info;
622 + CamelFolder *folder;
623 +} FolderRegistry;
624 +
625 +typedef struct {
626 + EAccount *account;
627 + TrackerEvolutionPlugin *self;
628 + guint hook_id;
629 + CamelStore *store;
630 +} StoreRegistry;
631 +
632 +typedef struct {
633 + TrackerEvolutionPlugin *self;
634 + gchar *account_uri;
635 + ClientRegistry *info;
636 +} IntroductionInfo;
637 +
638 +typedef struct {
639 + TrackerEvolutionPlugin *self;
640 + gchar *uri;
641 + gboolean old_state;
642 + EAccount *account;
643 +} RegisterInfo;
644 +
645 +typedef struct {
646 + DBusGConnection *connection;
647 + GHashTable *registrars;
648 + GStaticRecMutex *mutex;
649 + GHashTable *registered_folders;
650 + GHashTable *cached_folders;
651 + GHashTable *registered_stores;
652 + GList *registered_clients;
653 + EAccountList *accounts;
654 +} TrackerEvolutionPluginPrivate;
655 +
656 +enum {
657 + PROP_0,
658 + PROP_CONNECTION
659 +};
660 +
661 +static DBusGProxy *dbus_proxy = NULL;
662 +static TrackerEvolutionPlugin *manager = NULL;
663 +static GStaticRecMutex glock = G_STATIC_REC_MUTEX_INIT;
664 +
665 +/* Prototype declarations */
666 +static void register_account (TrackerEvolutionPlugin *self, EAccount *account);
667 +static void unregister_account (TrackerEvolutionPlugin *self, EAccount *account);
668 +int e_plugin_lib_enable (EPluginLib *ep, int enable);
669 +static void metadata_set_many (TrackerEvolutionPlugin *self, GStrv subjects, GPtrArray *predicates, GPtrArray *values);
670 +static void metadata_unset_many (TrackerEvolutionPlugin *self, GStrv subjects);
671 +
672 +static GList *
673 +get_recipient_list (const gchar *str)
674 +{
675 + GList *list = NULL;
676 + gchar **arr;
677 + gint i;
678 +
679 + if (!str) {
680 + return NULL;
681 + }
682 +
683 + arr = g_strsplit (str, ",", -1);
684 +
685 + for (i = 0; arr[i]; i++) {
686 + g_strstrip (arr[i]);
687 + list = g_list_prepend (list, g_strdup (arr[i]));
688 + }
689 +
690 + g_strfreev (arr);
691 +
692 + return g_list_reverse (list);
693 +}
694 +
695 +static void
696 +folder_registry_free (FolderRegistry *registry)
697 +{
698 + camel_object_remove_event (registry->folder, registry->hook_info->hook_id);
699 + camel_object_unref (registry->folder);
700 + g_free (registry->hook_info->account_uri);
701 + g_slice_free (OnSummaryChangedInfo, registry->hook_info);
702 + g_slice_free (FolderRegistry, registry);
703 +}
704 +
705 +static FolderRegistry*
706 +folder_registry_new (const gchar *account_uri,
707 + CamelFolder *folder,
708 + TrackerEvolutionPlugin *self)
709 +{
710 + FolderRegistry *registry = g_slice_new (FolderRegistry);
711 +
712 + registry->hook_info = g_slice_new (OnSummaryChangedInfo);
713 + registry->hook_info->account_uri = g_strdup (account_uri);
714 + registry->hook_info->self = self; /* weak */
715 + registry->hook_info->hook_id = 0;
716 + camel_object_ref (folder);
717 + registry->folder = folder;
718 +
719 + return registry;
720 +}
721 +
722 +static void
723 +process_fields (GPtrArray *predicates_temp,
724 + GPtrArray *values_temp,
725 + gchar *uid,
726 + guint flags,
727 + gchar *sent,
728 + gchar *subject,
729 + gchar *from,
730 + gchar *to,
731 + gchar *cc,
732 + gchar *size,
733 + CamelFolder *folder)
734 +{
735 + GList *list, *l;
736 +
737 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_UID));
738 + g_ptr_array_add (values_temp, g_strdup (uid));
739 +
740 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_SEEN));
741 + g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_SEEN) ? "True" : "False"));
742 +
743 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_JUNK));
744 + g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_JUNK) ? "True" : "False"));
745 +
746 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_DELETED));
747 + g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_DELETED) ? "True" : "False"));
748 +
749 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_ANSWERED));
750 + g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_ANSWERED) ? "True" : "False"));
751 +
752 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_FLAGGED));
753 + g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_FLAGGED) ? "True" : "False"));
754 +
755 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_FORWARDED));
756 + g_ptr_array_add (values_temp, g_strdup ((flags & CAMEL_MESSAGE_FORWARDED) ? "True" : "False"));
757 +
758 +
759 + if (subject && g_utf8_validate (subject, -1, NULL)) {
760 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_SUBJECT));
761 + g_ptr_array_add (values_temp, g_strdup (subject));
762 + }
763 +
764 + list = get_recipient_list (to);
765 + for (l = list; l; l = l->next) {
766 + if (l->data && g_utf8_validate (l->data, -1, NULL)) {
767 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TO));
768 + g_ptr_array_add (values_temp, l->data);
769 + } else
770 + g_free (l->data);
771 + }
772 + g_list_free (list);
773 +
774 + if (from && g_utf8_validate (from, -1, NULL)) {
775 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_FROM));
776 + g_ptr_array_add (values_temp, g_strdup (from));
777 + }
778 +
779 + if (size && g_utf8_validate (size, -1, NULL)) {
780 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_SIZE));
781 + g_ptr_array_add (values_temp, g_strdup (size));
782 + }
783 +
784 + list = get_recipient_list (cc);
785 + for (l = list; l; l = l->next) {
786 + if (l->data && g_utf8_validate (l->data, -1, NULL)) {
787 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_CC));
788 + g_ptr_array_add (values_temp, l->data);
789 + } else
790 + g_free (l->data);
791 + }
792 + g_list_free (list);
793 +
794 + if (sent && g_utf8_validate (sent, -1, NULL)) {
795 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_SENT));
796 + g_ptr_array_add (values_temp, g_strdup (sent));
797 + }
798 +
799 + if (folder) {
800 + gchar *filen = camel_folder_get_filename (folder, uid, NULL);
801 + if (filen) {
802 + if (g_file_test (filen, G_FILE_TEST_EXISTS)) {
803 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_FILE));
804 + g_ptr_array_add (values_temp, filen);
805 + } else
806 + g_free (filen);
807 + }
808 + }
809 +}
810 +
811 +/* When new messages arrive to- or got deleted from the summary, called in
812 + * mainloop or by a thread (unknown, depends on Camel and Evolution code that
813 + * executes the reason why this signal gets emitted) */
814 +
815 +static void
816 +on_folder_summary_changed (CamelFolder *folder,
817 + CamelFolderChangeInfo *changes,
818 + gpointer user_data)
819 +{
820 + OnSummaryChangedInfo *info = user_data;
821 + TrackerEvolutionPlugin *self = info->self;
822 + CamelFolderSummary *summary;
823 + gchar *account_uri = info->account_uri;
824 + GPtrArray *merged;
825 + guint i;
826 + gchar *em_uri;
827 +
828 + if (!folder)
829 + return;
830 +
831 + summary = folder->summary;
832 + em_uri = em_uri_from_camel (account_uri);
833 +
834 + merged = g_ptr_array_new ();
835 +
836 + /* the uid_added member contains the added-to-the-summary items */
837 +
838 + if (changes->uid_added && changes->uid_added->len > 0) {
839 + for (i = 0; i < changes->uid_added->len; i++)
840 + g_ptr_array_add (merged, changes->uid_added->pdata[i]);
841 + }
842 +
843 + /* the uid_changed member contains the changed-in-the-summary items */
844 +
845 + if (changes->uid_changed && changes->uid_changed->len > 0) {
846 + gboolean found = FALSE;
847 + guint y;
848 +
849 + for (i = 0; i < changes->uid_changed->len; i++) {
850 + for (y = 0; y < merged->len; y++) {
851 + if (strcmp (merged->pdata[y], changes->uid_changed->pdata[i]) == 0) {
852 + found = TRUE;
853 + break;
854 + }
855 + }
856 +
857 + if (!found)
858 + g_ptr_array_add (merged, changes->uid_changed->pdata[i]);
859 + }
860 + }
861 +
862 + if (merged->len > 0) {
863 + GPtrArray *predicates_array = g_ptr_array_new ();
864 + GPtrArray *values_array = g_ptr_array_new ();
865 + gchar **subjects = (gchar **) g_malloc0 (sizeof (gchar *) * merged->len + 1);
866 + guint y;
867 +
868 + y = 0;
869 +
870 + for (i = 0; i< merged->len; i++) {
871 + gchar *subject, *to, *from, *cc, *uid = NULL, *sent, *size;
872 + guint flags;
873 + gchar **values, **predicates;
874 + CamelMessageInfo *linfo;
875 + GPtrArray *values_temp = g_ptr_array_new ();
876 + GPtrArray *predicates_temp = g_ptr_array_new ();
877 + const CamelTag *ctags;
878 + const CamelFlag *cflags;
879 +
880 + linfo = camel_folder_summary_uid (summary, merged->pdata[i]);
881 +
882 + if (linfo)
883 + uid = (gchar *) camel_message_info_uid (linfo);
884 +
885 + if (linfo && uid) {
886 + guint j, max;
887 +
888 + subject = (gchar *) camel_message_info_subject (linfo);
889 + to = (gchar *) camel_message_info_to (linfo);
890 + from = (gchar *) camel_message_info_from (linfo);
891 + cc = (gchar *) camel_message_info_cc (linfo);
892 + flags = (guint) camel_message_info_flags (linfo);
893 +
894 + /* Camel returns a time_t, I think a uint64 is the best fit here */
895 + sent = g_strdup_printf ("%"PRIu64, (unsigned long long) camel_message_info_date_sent (linfo));
896 +
897 + /* Camel returns a uint32, so %u */
898 + size = g_strdup_printf ("%u", camel_message_info_size (linfo));
899 +
900 + process_fields (predicates_temp, values_temp, uid,
901 + flags, sent, subject, from, to, cc,
902 + size, folder);
903 +
904 + cflags = camel_message_info_user_flags (linfo);
905 + while (cflags) {
906 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
907 + g_ptr_array_add (values_temp, g_strdup_printf ("%s=True", cflags->name));
908 + cflags = cflags->next;
909 + }
910 +
911 + ctags = camel_message_info_user_tags (linfo);
912 + while (ctags) {
913 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
914 + g_ptr_array_add (values_temp, g_strdup_printf ("%s=%s", ctags->name, ctags->value));
915 + ctags = ctags->next;
916 + }
917 +
918 + if (values_temp->len != predicates_temp->len)
919 + g_critical ("values_temp->len != predicates_temp->len");
920 +
921 + max = MIN (values_temp->len, predicates_temp->len);
922 +
923 + values = (gchar **) g_malloc0 (sizeof (gchar*) * max + 1);
924 + predicates = (gchar **) g_malloc0 (sizeof (gchar*) * max + 1);
925 +
926 + for (j = 0; j < max; j++) {
927 + predicates[j] = predicates_temp->pdata[j];
928 + values[j] = values_temp->pdata[j];
929 + }
930 +
931 + predicates[j] = NULL;
932 + values[j] = NULL;
933 +
934 + g_ptr_array_add (values_array, values);
935 + g_ptr_array_add (predicates_array, predicates);
936 +
937 + /* This is not a path but a URI, don't use the
938 + * OS's directory separator here */
939 +
940 + subjects[y] = g_strdup_printf ("%s%s/%s",
941 + em_uri,
942 + camel_folder_get_full_name (folder),
943 + uid);
944 +
945 + g_ptr_array_free (predicates_temp, TRUE);
946 + g_ptr_array_free (values_temp, TRUE);
947 +
948 + y++;
949 + }
950 +
951 + if (linfo)
952 + camel_message_info_free (linfo);
953 + }
954 +
955 + subjects[y] = NULL;
956 +
957 + /* This goes to all currently registered registrars */
958 +
959 + metadata_set_many (self, subjects, predicates_array, values_array);
960 +
961 + g_strfreev (subjects);
962 + for (i = 0; i < values_array->len; i++)
963 + g_strfreev (values_array->pdata[i]);
964 + g_ptr_array_free (values_array, TRUE);
965 + for (i = 0; i < predicates_array->len; i++)
966 + g_strfreev (predicates_array->pdata[i]);
967 + g_ptr_array_free (predicates_array, TRUE);
968 + }
969 +
970 + g_ptr_array_free (merged, TRUE);
971 +
972 + /* the uid_removed member contains the removed-from-the-summary items */
973 +
974 + if (changes->uid_removed && changes->uid_removed->len > 0) {
975 + gchar **subjects = (gchar **) g_malloc0 (sizeof (gchar *) * changes->uid_removed->len + 1);
976 +
977 + for (i = 0; i< changes->uid_removed->len; i++) {
978 +
979 + /* This is not a path but a URI, don't use the OS's
980 + * directory separator here */
981 +
982 + subjects[i] = g_strdup_printf ("%s%s/%s", em_uri,
983 + camel_folder_get_full_name (folder),
984 + (char*) changes->uid_removed->pdata[i]);
985 + }
986 +
987 + subjects[i] = NULL;
988 +
989 + /* This goes to all currently registered registrars */
990 +
991 + metadata_unset_many (self, subjects);
992 +
993 + g_strfreev (subjects);
994 + }
995 + g_free (em_uri);
996 +}
997 +
998 +/* Initial upload of more recent than last_checkout items, called in the mainloop */
999 +static void
1000 +introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
1001 + CamelFolderInfo *iter,
1002 + CamelStore *store,
1003 + gchar *account_uri,
1004 + ClientRegistry *info)
1005 +{
1006 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1007 + gchar *em_uri = em_uri_from_camel (account_uri);
1008 +
1009 + while (iter) {
1010 + guint i, ret = SQLITE_OK;
1011 + CamelDB *cdb_r = store->cdb_r;
1012 + gchar *query;
1013 + sqlite3_stmt *stmt = NULL;
1014 + gboolean more = TRUE;
1015 +
1016 + query = sqlite3_mprintf ("SELECT uid, flags, read, deleted, " /* 0 - 3 */
1017 + "replied, important, junk, attachment, " /* 4 - 7 */
1018 + "size, dsent, dreceived, subject, " /* 8 - 11 */
1019 + "mail_from, mail_to, mail_cc, mlist, " /* 12 - 15 */
1020 + "labels, usertags " /* 16 - 17 */
1021 + "FROM %Q "
1022 + "WHERE modified > %"PRIu64,
1023 +
1024 + iter->full_name,
1025 + info->last_checkout);
1026 +
1027 + g_mutex_lock (cdb_r->lock);
1028 +
1029 + ret = sqlite3_prepare_v2 (cdb_r->db, query, -1, &stmt, NULL);
1030 +
1031 + while (more) {
1032 + GPtrArray *subjects_a = g_ptr_array_new ();
1033 + GPtrArray *predicates_array = g_ptr_array_new ();
1034 + GPtrArray *values_array = g_ptr_array_new ();
1035 + guint count = 0;
1036 +
1037 + more = FALSE;
1038 +
1039 + while (ret == SQLITE_OK || ret == SQLITE_BUSY || ret == SQLITE_ROW) {
1040 + gchar **values, **predicates;
1041 + gchar *subject, *to, *from, *cc, *sent, *uid, *size;
1042 + gchar *part, *label, *p;
1043 + guint flags;
1044 +
1045 + ret = sqlite3_step (stmt);
1046 +
1047 + if (ret == SQLITE_BUSY) {
1048 + usleep (10);
1049 + continue;
1050 + }
1051 +
1052 + if ((ret != SQLITE_OK && ret != SQLITE_ROW) || ret == SQLITE_DONE) {
1053 + more = FALSE;
1054 + break;
1055 + }
1056 +
1057 + uid = (gchar *) sqlite3_column_text (stmt, 0);
1058 +
1059 + if (uid) {
1060 + GPtrArray *predicates_temp = g_ptr_array_new ();
1061 + GPtrArray *values_temp = g_ptr_array_new ();
1062 + CamelFolder *folder;
1063 + guint max = 0, j;
1064 +
1065 + flags = (guint ) sqlite3_column_int (stmt, 1);
1066 + size = (gchar *) sqlite3_column_text (stmt, 8);
1067 + sent = (gchar *) sqlite3_column_text (stmt, 9);
1068 + subject = (gchar *) sqlite3_column_text (stmt, 11);
1069 + from = (gchar *) sqlite3_column_text (stmt, 12);
1070 + to = (gchar *) sqlite3_column_text (stmt, 13);
1071 + cc = (gchar *) sqlite3_column_text (stmt, 14);
1072 +
1073 + g_static_rec_mutex_lock (priv->mutex);
1074 +
1075 + folder = g_hash_table_lookup (priv->cached_folders, iter->full_name);
1076 +
1077 + process_fields (predicates_temp, values_temp, uid, flags, sent,
1078 + subject, from, to, cc, size, folder);
1079 +
1080 + g_static_rec_mutex_unlock (priv->mutex);
1081 +
1082 + /* Extract User flags/labels */
1083 + p = part = g_strdup ((const gchar *) sqlite3_column_text (stmt, 16));
1084 + if (part) {
1085 + label = part;
1086 + for (j=0; part[j]; j++) {
1087 +
1088 + if (part[j] == ' ') {
1089 + part[j] = 0;
1090 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
1091 + g_ptr_array_add (values_temp, g_strdup_printf ("%s=True", label));
1092 + label = &(part[j+1]);
1093 + }
1094 + }
1095 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
1096 + g_ptr_array_add (values_temp, g_strdup (label));
1097 + }
1098 + g_free (p);
1099 +
1100 + /* Extract User tags */
1101 + p = part = g_strdup ((const gchar *) sqlite3_column_text (stmt, 17));
1102 + EXTRACT_FIRST_DIGIT (max)
1103 + for (j = 0; j < max; j++) {
1104 + int len;
1105 + char *name, *value;
1106 + EXTRACT_STRING (name)
1107 + EXTRACT_STRING (value)
1108 + if (name && g_utf8_validate (name, -1, NULL) &&
1109 + value && g_utf8_validate (value, -1, NULL)) {
1110 + g_ptr_array_add (predicates_temp, g_strdup (TRACKER_EVOLUTION_PREDICATE_TAG));
1111 + g_ptr_array_add (values_temp, g_strdup_printf ("%s=%s", name, value));
1112 + }
1113 + g_free(name);
1114 + g_free(value);
1115 + }
1116 + g_free (p);
1117 +
1118 + if (values_temp->len != predicates_temp->len)
1119 + g_critical ("values_temp->len != predicates_temp->len");
1120 +
1121 + max = MIN (values_temp->len, predicates_temp->len);
1122 +
1123 + values = (gchar **) g_malloc0 (sizeof (gchar*) * max + 1);
1124 + predicates = (gchar **) g_malloc0 (sizeof (gchar*) * max + 1);
1125 +
1126 + for (j = 0; j < max; j++) {
1127 + predicates[j] = predicates_temp->pdata[j];
1128 + values[j] = values_temp->pdata[j];
1129 + }
1130 +
1131 + predicates[j] = NULL;
1132 + values[j] = NULL;
1133 +
1134 + /* This is not a path but a URI, don't use the
1135 + * OS's directory separator here */
1136 +
1137 + g_ptr_array_add (subjects_a, g_strdup_printf ("%s%s/%s", em_uri,
1138 + iter->full_name, uid));
1139 +
1140 + g_ptr_array_add (predicates_array, predicates);
1141 + g_ptr_array_add (values_array, values);
1142 +
1143 + g_ptr_array_free (predicates_temp, TRUE);
1144 + g_ptr_array_free (values_temp, TRUE);
1145 +
1146 + count++;
1147 + }
1148 +
1149 + if (count > MAX_BEFORE_SEND) {
1150 +
1151 + /* Yield per MAX_BEFORE_SEND. This function is
1152 + * called as a result of a DBus call, so it runs
1153 + * in the mainloop. Therefore, yield he mainloop
1154 + * sometimes, indeed */
1155 +
1156 + g_main_context_iteration (NULL, TRUE);
1157 +
1158 + more = TRUE;
1159 + break;
1160 + }
1161 +
1162 + more = FALSE;
1163 + }
1164 +
1165 +
1166 + if (count > 0) {
1167 + gchar **subjects;
1168 +
1169 + subjects = (gchar **) g_malloc0 (sizeof (gchar *) * subjects_a->len + 1);
1170 + for (i = 0; i < subjects_a->len; i++)
1171 + subjects[i] = g_ptr_array_index (subjects_a, i);
1172 + subjects[i] = NULL;
1173 +
1174 + dbus_g_proxy_call_no_reply (info->registrar,
1175 + "SetMany",
1176 + G_TYPE_STRV, subjects,
1177 + TRACKER_TYPE_G_STRV_ARRAY, predicates_array,
1178 + TRACKER_TYPE_G_STRV_ARRAY, values_array,
1179 + G_TYPE_INVALID,
1180 + G_TYPE_INVALID);
1181 +
1182 + g_strfreev (subjects);
1183 + }
1184 +
1185 + g_ptr_array_free (subjects_a, TRUE);
1186 +
1187 + for (i = 0; i < values_array->len; i++)
1188 + g_strfreev (values_array->pdata[i]);
1189 + g_ptr_array_free (values_array, TRUE);
1190 +
1191 + for (i = 0; i < predicates_array->len; i++)
1192 + g_strfreev (predicates_array->pdata[i]);
1193 + g_ptr_array_free (predicates_array, TRUE);
1194 + }
1195 +
1196 + sqlite3_finalize (stmt);
1197 + sqlite3_free (query);
1198 +
1199 + g_mutex_unlock (cdb_r->lock);
1200 +
1201 + if (iter->child) {
1202 + introduce_walk_folders_in_folder (self, iter->child, store, account_uri, info);
1203 + }
1204 +
1205 + iter = iter->next;
1206 + }
1207 +
1208 + g_free (em_uri);
1209 +}
1210 +
1211 +/* Initial notify of deletes that are more recent than last_checkout, called in
1212 + * the mainloop */
1213 +
1214 +static void
1215 +introduce_store_deal_with_deleted (TrackerEvolutionPlugin *self,
1216 + CamelStore *store,
1217 + char *account_uri,
1218 + gpointer user_data)
1219 +{
1220 + ClientRegistry *info = user_data;
1221 + gboolean more = TRUE;
1222 + gchar *query;
1223 + sqlite3_stmt *stmt = NULL;
1224 + CamelDB *cdb_r;
1225 + guint i, ret;
1226 + gchar *em_uri = em_uri_from_camel (account_uri);
1227 +
1228 + query = sqlite3_mprintf ("SELECT uid, mailbox FROM Deletes WHERE modified > %" PRIu64,
1229 + info->last_checkout);
1230 +
1231 + cdb_r = store->cdb_r;
1232 +
1233 + g_mutex_lock (cdb_r->lock);
1234 +
1235 + sqlite3_prepare_v2 (cdb_r->db, query, -1, &stmt, NULL);
1236 +
1237 + ret = SQLITE_OK;
1238 +
1239 + while (more) {
1240 + GPtrArray *subjects_a = g_ptr_array_new ();
1241 + guint count = 0;
1242 +
1243 + more = FALSE;
1244 +
1245 + while (ret == SQLITE_OK || ret == SQLITE_BUSY || ret == SQLITE_ROW) {
1246 + const gchar *uid;
1247 + const gchar *mailbox;
1248 +
1249 + ret = sqlite3_step (stmt);
1250 +
1251 + if (ret == SQLITE_BUSY) {
1252 + usleep (10);
1253 + continue;
1254 + }
1255 +
1256 + if ((ret != SQLITE_OK && ret != SQLITE_ROW) || ret == SQLITE_DONE) {
1257 + more = FALSE;
1258 + break;
1259 + }
1260 +
1261 + uid = (const gchar *) sqlite3_column_text (stmt, 0);
1262 + mailbox = (const gchar *) sqlite3_column_text (stmt, 1);
1263 +
1264 + /* This is not a path but a URI, don't use the OS's
1265 + * directory separator here */
1266 +
1267 + g_ptr_array_add (subjects_a, g_strdup_printf ("%s%s/%s", em_uri,
1268 + mailbox, uid));
1269 +
1270 + if (count > MAX_BEFORE_SEND) {
1271 +
1272 + /* Yield per MAX_BEFORE_SEND. This function is
1273 + * called as a result of a DBus call, so it runs
1274 + * in the mainloop. Therefore, yield he mainloop
1275 + * sometimes, indeed */
1276 +
1277 + g_main_context_iteration (NULL, TRUE);
1278 +
1279 + more = TRUE;
1280 + break;
1281 + }
1282 +
1283 + count++;
1284 +
1285 + more = FALSE;
1286 + }
1287 +
1288 + if (count > 0) {
1289 + gchar **subjects;
1290 +
1291 + subjects = (gchar **) g_malloc0 (sizeof (gchar *) * subjects_a->len + 1);
1292 + for (i = 0; i < subjects_a->len; i++)
1293 + subjects[i] = g_ptr_array_index (subjects_a, i);
1294 + subjects[i] = NULL;
1295 +
1296 + dbus_g_proxy_call_no_reply (info->registrar,
1297 + "UnsetMany",
1298 + G_TYPE_STRV, subjects,
1299 + G_TYPE_INVALID,
1300 + G_TYPE_INVALID);
1301 +
1302 + g_strfreev (subjects);
1303 + }
1304 +
1305 + g_ptr_array_free (subjects_a, TRUE);
1306 +
1307 + }
1308 +
1309 + sqlite3_finalize (stmt);
1310 + sqlite3_free (query);
1311 +
1312 + g_mutex_unlock (cdb_r->lock);
1313 +
1314 + g_free (em_uri);
1315 +}
1316 +
1317 +/* Get the oldest date in all of the deleted-tables, called in the mainloop */
1318 +
1319 +static guint64
1320 +get_last_deleted_time (TrackerEvolutionPlugin *self)
1321 +{
1322 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1323 + guint64 smallest = (guint64) time (NULL);
1324 +
1325 + if (priv->accounts) {
1326 + EIterator *it;
1327 +
1328 + for (it = e_list_get_iterator (E_LIST (priv->accounts)); e_iterator_is_valid (it); e_iterator_next (it)) {
1329 + EAccount *account = (EAccount *) e_iterator_get (it);
1330 + CamelProvider *provider;
1331 + CamelStore *store;
1332 + CamelException ex;
1333 + char *uri;
1334 + CamelDB *cdb_r;
1335 + sqlite3_stmt *stmt = NULL;
1336 + gchar *query;
1337 + guint ret = SQLITE_OK;
1338 + guint64 latest = smallest;
1339 +
1340 + camel_exception_init (&ex);
1341 +
1342 + if (!account->enabled || !(uri = account->source->url))
1343 + continue;
1344 +
1345 + if (!(provider = camel_provider_get(uri, NULL))) {
1346 + camel_exception_clear (&ex);
1347 + continue;
1348 + }
1349 +
1350 + if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
1351 + continue;
1352 +
1353 + if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
1354 + camel_exception_clear (&ex);
1355 + continue;
1356 + }
1357 +
1358 + cdb_r = store->cdb_r;
1359 +
1360 + query = sqlite3_mprintf ("SELECT time FROM Deletes ORDER BY time LIMIT 1");
1361 +
1362 + g_mutex_lock (cdb_r->lock);
1363 +
1364 + ret = sqlite3_prepare_v2 (cdb_r->db, query, -1, &stmt, NULL);
1365 +
1366 + ret = sqlite3_step (stmt);
1367 + if (ret == SQLITE_OK || ret == SQLITE_ROW)
1368 + latest = sqlite3_column_int64 (stmt, 0);
1369 +
1370 + if (latest < smallest)
1371 + smallest = latest;
1372 +
1373 + sqlite3_finalize (stmt);
1374 + sqlite3_free (query);
1375 +
1376 + g_mutex_unlock (cdb_r->lock);
1377 +
1378 + }
1379 +
1380 + g_object_unref (it);
1381 + }
1382 +
1383 + return smallest;
1384 +}
1385 +
1386 +
1387 +static void
1388 +register_walk_folders_in_folder (TrackerEvolutionPlugin *self,
1389 + CamelFolderInfo *iter,
1390 + CamelStore *store,
1391 + gchar *account_uri)
1392 +{
1393 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1394 +
1395 + while (iter) {
1396 + CamelFolder *folder;
1397 +
1398 + folder = camel_store_get_folder (store, iter->full_name, 0, NULL);
1399 +
1400 + if (folder) {
1401 + guint hook_id;
1402 + FolderRegistry *registry;
1403 +
1404 + registry = folder_registry_new (account_uri, folder, self);
1405 +
1406 + g_static_rec_mutex_lock (priv->mutex);
1407 +
1408 + if (!priv->registered_folders) {
1409 + priv->registered_folders = g_hash_table_new_full (g_int_hash, g_int_equal,
1410 + (GDestroyNotify) NULL,
1411 + (GDestroyNotify) folder_registry_free);
1412 + priv->cached_folders = g_hash_table_new_full (g_str_hash, g_str_equal,
1413 + (GDestroyNotify) g_free,
1414 + (GDestroyNotify) NULL);
1415 + }
1416 +
1417 + hook_id = camel_object_hook_event (folder, "folder_changed",
1418 + CAMEL_CALLBACK (on_folder_summary_changed),
1419 + registry->hook_info);
1420 + registry->hook_info->hook_id = hook_id;
1421 +
1422 + g_hash_table_replace (priv->registered_folders, &hook_id,
1423 + registry);
1424 + g_hash_table_replace (priv->cached_folders, g_strdup (iter->full_name),
1425 + folder);
1426 +
1427 + g_static_rec_mutex_unlock (priv->mutex);
1428 +
1429 + camel_object_unref (folder);
1430 + }
1431 +
1432 + if (iter->child) {
1433 + register_walk_folders_in_folder (self, iter->child, store,
1434 + account_uri);
1435 + }
1436 +
1437 + iter = iter->next;
1438 + }
1439 +}
1440 +
1441 +
1442 +static void
1443 +unregister_walk_folders_in_folder (TrackerEvolutionPlugin *self,
1444 + CamelFolderInfo *titer,
1445 + CamelStore *store,
1446 + gchar *account_uri)
1447 +{
1448 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1449 +
1450 + while (titer) {
1451 + CamelFolder *folder;
1452 + GHashTableIter iter;
1453 + gpointer key, value;
1454 +
1455 + folder = camel_store_get_folder (store, titer->full_name, 0, NULL);
1456 +
1457 + if (folder) {
1458 + g_static_rec_mutex_lock (priv->mutex);
1459 +
1460 + g_hash_table_iter_init (&iter, priv->registered_folders);
1461 + while (g_hash_table_iter_next (&iter, &key, &value)) {
1462 + FolderRegistry *registry = value;
1463 +
1464 + if (folder == registry->folder) {
1465 + g_hash_table_remove (priv->cached_folders, titer->full_name);
1466 + g_hash_table_iter_remove (&iter);
1467 + break;
1468 + }
1469 + }
1470 +
1471 + camel_object_unref (folder);
1472 +
1473 + g_static_rec_mutex_unlock (priv->mutex);
1474 + }
1475 +
1476 + if (titer->child) {
1477 + unregister_walk_folders_in_folder (self, titer->child, store,
1478 + account_uri);
1479 + }
1480 +
1481 + titer = titer->next;
1482 + }
1483 +}
1484 +
1485 +static void
1486 +client_registry_info_free (ClientRegistry *info)
1487 +{
1488 + if (info->signal != 0) /* known (see below) */
1489 + g_signal_handler_disconnect (info->registrar, info->signal);
1490 + g_object_unref (info->registrar);
1491 + g_slice_free (ClientRegistry, info);
1492 +}
1493 +
1494 +static ClientRegistry*
1495 +client_registry_info_copy (ClientRegistry *info)
1496 +{
1497 + ClientRegistry *ninfo = g_slice_new0 (ClientRegistry);
1498 +
1499 + ninfo->signal = 0; /* known */
1500 + ninfo->last_checkout = info->last_checkout;
1501 + ninfo->registrar = g_object_ref (info->registrar);
1502 +
1503 + return ninfo;
1504 +}
1505 +
1506 +static gboolean
1507 +on_got_folderinfo_introduce (CamelStore *store,
1508 + CamelFolderInfo *iter,
1509 + void *data)
1510 +{
1511 + IntroductionInfo *intro_info = data;
1512 +
1513 + introduce_walk_folders_in_folder (intro_info->self, iter, store,
1514 + intro_info->account_uri,
1515 + intro_info->info);
1516 +
1517 + client_registry_info_free (intro_info->info);
1518 + g_free (intro_info->account_uri);
1519 + g_object_unref (intro_info->self);
1520 + g_free (intro_info);
1521 +
1522 + return TRUE;
1523 +}
1524 +
1525 +static void
1526 +introduce_account_to (TrackerEvolutionPlugin *self,
1527 + EAccount *account,
1528 + ClientRegistry *info)
1529 +{
1530 + CamelProvider *provider;
1531 + CamelStore *store;
1532 + CamelException ex;
1533 + char *uri, *account_uri, *ptr;
1534 + IntroductionInfo *intro_info;
1535 +
1536 + if (!account->enabled || !(uri = account->source->url))
1537 + return;
1538 +
1539 + camel_exception_init (&ex);
1540 + if (!(provider = camel_provider_get(uri, &ex))) {
1541 + camel_exception_clear (&ex);
1542 + return;
1543 + }
1544 +
1545 + if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
1546 + return;
1547 +
1548 + if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
1549 + camel_exception_clear (&ex);
1550 + return;
1551 + }
1552 +
1553 + account_uri = g_strdup (uri);
1554 +
1555 + ptr = strchr (account_uri, ';');
1556 +
1557 + if (ptr)
1558 + *ptr = '\0';
1559 +
1560 + introduce_store_deal_with_deleted (self, store, account_uri, info);
1561 +
1562 + intro_info = g_new0 (IntroductionInfo, 1);
1563 +
1564 + intro_info->self = g_object_ref (self);
1565 + intro_info->info = client_registry_info_copy (info);
1566 + intro_info->account_uri = account_uri; /* is freed in on_got above */
1567 +
1568 + mail_get_folderinfo (store, NULL, on_got_folderinfo_introduce, intro_info);
1569 +
1570 + camel_object_unref (store);
1571 +
1572 +}
1573 +
1574 +
1575 +static void
1576 +introduce_account_to_all (TrackerEvolutionPlugin *self,
1577 + EAccount *account)
1578 +{
1579 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1580 + GList *copy = priv->registered_clients;
1581 +
1582 + while (copy) {
1583 + ClientRegistry *info = copy->data;
1584 + introduce_account_to (self, account, info);
1585 + copy = g_list_next (copy);
1586 + }
1587 +
1588 +}
1589 +
1590 +static void
1591 +introduce_accounts_to (TrackerEvolutionPlugin *self,
1592 + ClientRegistry *info)
1593 +{
1594 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1595 + EIterator *it;
1596 +
1597 + for (it = e_list_get_iterator (E_LIST (priv->accounts)); e_iterator_is_valid (it); e_iterator_next (it))
1598 + introduce_account_to (self, (EAccount *) e_iterator_get (it), info);
1599 +
1600 + g_object_unref (it);
1601 +}
1602 +
1603 +
1604 +static void
1605 +register_client (TrackerEvolutionPlugin *self,
1606 + guint64 last_checkout,
1607 + DBusGProxy *registrar,
1608 + guint dsignal)
1609 +{
1610 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1611 + guint64 too_old = get_last_deleted_time (self);
1612 + ClientRegistry *info = g_slice_new (ClientRegistry);
1613 +
1614 + info->signal = dsignal;
1615 + info->registrar = g_object_ref (registrar);
1616 +
1617 + if (last_checkout < too_old) {
1618 + dbus_g_proxy_call_no_reply (registrar,
1619 + "Cleanup",
1620 + G_TYPE_INVALID,
1621 + G_TYPE_INVALID);
1622 + info->last_checkout = 0;
1623 + } else
1624 + info->last_checkout = last_checkout;
1625 +
1626 + introduce_accounts_to (self, info);
1627 +
1628 + priv->registered_clients =
1629 + g_list_prepend (priv->registered_clients, info);
1630 +
1631 +}
1632 +
1633 +
1634 +static void
1635 +metadata_set_many (TrackerEvolutionPlugin *self,
1636 + GStrv subjects,
1637 + GPtrArray *predicates,
1638 + GPtrArray *values)
1639 +{
1640 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1641 + GHashTableIter iter;
1642 + gpointer key, value;
1643 +
1644 + g_static_rec_mutex_lock (priv->mutex);
1645 +
1646 + g_hash_table_iter_init (&iter, priv->registrars);
1647 +
1648 + while (g_hash_table_iter_next (&iter, &key, &value)) {
1649 + DBusGProxy *registrar = value;
1650 +
1651 + dbus_g_proxy_call_no_reply (registrar,
1652 + "SetMany",
1653 + G_TYPE_STRV, subjects,
1654 + TRACKER_TYPE_G_STRV_ARRAY, predicates,
1655 + TRACKER_TYPE_G_STRV_ARRAY, values,
1656 + G_TYPE_INVALID,
1657 + G_TYPE_INVALID);
1658 + }
1659 +
1660 + g_static_rec_mutex_unlock (priv->mutex);
1661 +}
1662 +
1663 +static void
1664 +metadata_unset_many (TrackerEvolutionPlugin *self,
1665 + GStrv subjects)
1666 +{
1667 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1668 + GHashTableIter iter;
1669 + gpointer key, value;
1670 +
1671 + g_static_rec_mutex_lock (priv->mutex);
1672 +
1673 + g_hash_table_iter_init (&iter, priv->registrars);
1674 +
1675 + while (g_hash_table_iter_next (&iter, &key, &value)) {
1676 + DBusGProxy *registrar = value;
1677 +
1678 + dbus_g_proxy_call_no_reply (registrar,
1679 + "UnsetMany",
1680 + G_TYPE_STRV, subjects,
1681 + G_TYPE_INVALID,
1682 + G_TYPE_INVALID);
1683 + }
1684 +
1685 + g_static_rec_mutex_unlock (priv->mutex);
1686 +
1687 +}
1688 +
1689 +static void
1690 +on_folder_created (CamelStore *store, void *event_data,
1691 + StoreRegistry *registry)
1692 +{
1693 + unregister_account (registry->self, registry->account);
1694 + register_account (registry->self, registry->account);
1695 + introduce_account_to_all (registry->self, registry->account);
1696 +}
1697 +
1698 +static void
1699 +on_folder_deleted (CamelStore *store,
1700 + void *event_data,
1701 + StoreRegistry *registry)
1702 +{
1703 + unregister_account (registry->self, registry->account);
1704 + register_account (registry->self, registry->account);
1705 + introduce_account_to_all (registry->self, registry->account);
1706 +}
1707 +
1708 +static void
1709 +on_folder_renamed (CamelStore *store,
1710 + CamelRenameInfo *info,
1711 + StoreRegistry *registry)
1712 +{
1713 + unregister_account (registry->self, registry->account);
1714 + register_account (registry->self, registry->account);
1715 + introduce_account_to_all (registry->self, registry->account);
1716 +}
1717 +
1718 +static StoreRegistry*
1719 +store_registry_new (gpointer co,
1720 + EAccount *account,
1721 + TrackerEvolutionPlugin *self)
1722 +{
1723 + StoreRegistry *registry = g_slice_new (StoreRegistry);
1724 +
1725 + registry->store = co;
1726 + registry->account = account; /* weak */
1727 + registry->self = self; /* weak */
1728 + camel_object_ref (co);
1729 +
1730 + return registry;
1731 +}
1732 +
1733 +static void
1734 +store_registry_free (StoreRegistry *registry)
1735 +{
1736 + camel_object_remove_event (registry->store, registry->hook_id);
1737 + camel_object_unref (registry->store);
1738 + g_slice_free (StoreRegistry, registry);
1739 +}
1740 +
1741 +
1742 +static gboolean
1743 +on_got_folderinfo_register (CamelStore *store,
1744 + CamelFolderInfo *iter,
1745 + void *data)
1746 +{
1747 + RegisterInfo *reg_info = data;
1748 + TrackerEvolutionPlugin *self = reg_info->self;
1749 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1750 + EAccount *account = reg_info->account;
1751 + StoreRegistry *registry;
1752 + gchar *uri = reg_info->uri;
1753 + guint hook_id;
1754 +
1755 + g_static_rec_mutex_lock (priv->mutex);
1756 +
1757 + if (!priv->registered_stores)
1758 + priv->registered_stores = g_hash_table_new_full (g_int_hash, g_int_equal,
1759 + (GDestroyNotify) NULL,
1760 + (GDestroyNotify) store_registry_free);
1761 +
1762 + /* Hook up catching folder changes in the store */
1763 + registry = store_registry_new (store, account, self);
1764 + hook_id = camel_object_hook_event (store, "folder_created",
1765 + CAMEL_CALLBACK (on_folder_created),
1766 + registry);
1767 + registry->hook_id = hook_id;
1768 + g_hash_table_replace (priv->registered_stores, &hook_id, registry);
1769 +
1770 + registry = store_registry_new (store, account, self);
1771 + hook_id = camel_object_hook_event (store, "folder_renamed",
1772 + CAMEL_CALLBACK (on_folder_renamed),
1773 + registry);
1774 + registry->hook_id = hook_id;
1775 + g_hash_table_replace (priv->registered_stores, &hook_id, registry);
1776 +
1777 + registry = store_registry_new (store, account, self);
1778 + hook_id = camel_object_hook_event (store, "folder_deleted",
1779 + CAMEL_CALLBACK (on_folder_deleted),
1780 + registry);
1781 + registry->hook_id = hook_id;
1782 + g_hash_table_replace (priv->registered_stores, &hook_id, registry);
1783 +
1784 + g_static_rec_mutex_unlock (priv->mutex);
1785 +
1786 + /* Register each folder to hook folder_changed everywhere */
1787 + register_walk_folders_in_folder (self, iter, store, uri);
1788 +
1789 + g_object_unref (reg_info->account);
1790 + g_object_unref (reg_info->self);
1791 + g_free (reg_info->uri);
1792 + g_free (reg_info);
1793 +
1794 + return TRUE;
1795 +}
1796 +
1797 +static void
1798 +register_account (TrackerEvolutionPlugin *self,
1799 + EAccount *account)
1800 +{
1801 + CamelProvider *provider;
1802 + CamelStore *store;
1803 + CamelException ex;
1804 + char *uri;
1805 + RegisterInfo *reg_info;
1806 +
1807 + if (!account->enabled || !(uri = account->source->url))
1808 + return;
1809 +
1810 + camel_exception_init (&ex);
1811 + if (!(provider = camel_provider_get(uri, &ex))) {
1812 + camel_exception_clear (&ex);
1813 + return;
1814 + }
1815 +
1816 + if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
1817 + return;
1818 +
1819 + if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
1820 + camel_exception_clear (&ex);
1821 + return;
1822 + }
1823 +
1824 + reg_info = g_new0 (RegisterInfo, 1);
1825 +
1826 + reg_info->self = g_object_ref (self);
1827 + reg_info->uri = g_strdup (uri);
1828 + reg_info->account = g_object_ref (account);
1829 +
1830 + /* Get the account's folder-info and register it asynchronously */
1831 + mail_get_folderinfo (store, NULL, on_got_folderinfo_register, reg_info);
1832 +
1833 + camel_object_unref (store);
1834 +}
1835 +
1836 +static gboolean
1837 +on_got_folderinfo_unregister (CamelStore *store,
1838 + CamelFolderInfo *titer,
1839 + void *data)
1840 +{
1841 + RegisterInfo *reg_info = data;
1842 + TrackerEvolutionPlugin *self = reg_info->self;
1843 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
1844 + gchar *uri = reg_info->uri;
1845 + GHashTableIter iter;
1846 + gpointer key, value;
1847 +
1848 + unregister_walk_folders_in_folder (self, titer, store, uri);
1849 +
1850 + g_static_rec_mutex_lock (priv->mutex);
1851 +
1852 + if (priv->registered_stores) {
1853 + g_hash_table_iter_init (&iter, priv->registered_stores);
1854 +
1855 + while (g_hash_table_iter_next (&iter, &key, &value)) {
1856 + if (value == store)
1857 + g_hash_table_iter_remove (&iter);
1858 + }
1859 + }
1860 +
1861 + g_static_rec_mutex_unlock (priv->mutex);
1862 +
1863 + g_object_unref (reg_info->self);
1864 + g_free (reg_info->uri);
1865 + g_free (reg_info);
1866 +
1867 + return TRUE;
1868 +}
1869 +
1870 +static void
1871 +unregister_account (TrackerEvolutionPlugin *self,
1872 + EAccount *account)
1873 +{
1874 + CamelProvider *provider;
1875 + CamelStore *store;
1876 + CamelException ex;
1877 + char *uri;
1878 + RegisterInfo *reg_info;
1879 +
1880 +
1881 + camel_exception_init (&ex);
1882 + if (!(provider = camel_provider_get(uri, &ex))) {
1883 + camel_exception_clear (&ex);
1884 + return;
1885 + }
1886 +
1887 + if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
1888 + return;
1889 +
1890 + if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
1891 + camel_exception_clear (&ex);
1892 + return;
1893 + }
1894 +
1895 + reg_info = g_new0 (RegisterInfo, 1);
1896 +
1897 + reg_info->self = g_object_ref (self);
1898 + reg_info->uri = g_strdup (uri);
1899 + reg_info->account = NULL;
1900 +
1901 + /* Get the account's folder-info and unregister asynchronously */
1902 + mail_get_folderinfo (store, NULL, on_got_folderinfo_unregister, reg_info);
1903 +
1904 + camel_object_unref (store);
1905 +}
1906 +
1907 +static void
1908 +on_account_added (EAccountList *list,
1909 + EAccount *account,
1910 + TrackerEvolutionPlugin *self)
1911 +{
1912 + register_account (self, account);
1913 + introduce_account_to_all (self, account);
1914 +}
1915 +
1916 +static void
1917 +on_account_removed (EAccountList *list,
1918 + EAccount *account,
1919 + TrackerEvolutionPlugin *self)
1920 +{
1921 + unregister_account (self, account);
1922 +}
1923 +
1924 +static void
1925 +on_account_changed (EAccountList *list,
1926 + EAccount *account,
1927 + TrackerEvolutionPlugin *self)
1928 +{
1929 + unregister_account (self, account);
1930 + register_account (self, account);
1931 + introduce_account_to_all (self, account);
1932 +}
1933 +
1934 +static void
1935 +disable_plugin (void)
1936 +{
1937 + GError *error = NULL;
1938 + guint result;
1939 +
1940 + org_freedesktop_DBus_release_name (dbus_proxy, TRACKER_EVOLUTION_MANAGER_SERVICE,
1941 + &result, &error);
1942 +
1943 + if (!error) {
1944 + if (manager) {
1945 + g_object_unref (manager);
1946 + manager = NULL;
1947 + }
1948 +
1949 + if (dbus_proxy) {
1950 + g_object_unref (dbus_proxy);
1951 + dbus_proxy = NULL;
1952 + }
1953 + } else {
1954 + g_warning ("Could not setup DBus, ReleaseName of %s: %s\n",
1955 + TRACKER_EVOLUTION_MANAGER_SERVICE, error->message);
1956 +
1957 + g_error_free (error);
1958 + }
1959 +}
1960 +
1961 +static void
1962 +enable_plugin (void)
1963 +{
1964 + DBusGConnection *connection;
1965 + GError *error = NULL;
1966 + guint result;
1967 +
1968 + if (dbus_proxy && manager)
1969 + return;
1970 +
1971 + if ((dbus_proxy && !manager) || (!dbus_proxy && manager))
1972 + disable_plugin ();
1973 +
1974 + if ((dbus_proxy && !manager) || (!dbus_proxy && manager))
1975 + return;
1976 +
1977 + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
1978 +
1979 + if (error)
1980 + goto error_handler;
1981 +
1982 + dbus_proxy = dbus_g_proxy_new_for_name (connection,
1983 + DBUS_SERVICE_DBUS,
1984 + DBUS_PATH_DBUS,
1985 + DBUS_INTERFACE_DBUS);
1986 +
1987 + if (!org_freedesktop_DBus_request_name (dbus_proxy, TRACKER_EVOLUTION_MANAGER_SERVICE,
1988 + DBUS_NAME_FLAG_DO_NOT_QUEUE,
1989 + &result, &error)) {
1990 +
1991 + g_warning ("Could not setup DBus, failed at RequestName for %s\n",
1992 + TRACKER_EVOLUTION_MANAGER_SERVICE);
1993 +
1994 + goto error_handler;
1995 + }
1996 +
1997 + if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
1998 +
1999 + g_warning ("Could not setup DBus, can't become primary owner of %s\n",
2000 + TRACKER_EVOLUTION_MANAGER_SERVICE);
2001 +
2002 + goto error_handler;
2003 + }
2004 +
2005 + if (error)
2006 + goto error_handler;
2007 +
2008 + manager = g_object_new (TRACKER_TYPE_EVOLUTION_PLUGIN,
2009 + "connection", connection, NULL);
2010 +
2011 + dbus_g_object_type_install_info (G_OBJECT_TYPE (manager),
2012 + &dbus_glib_tracker_evolution_plugin_object_info);
2013 +
2014 + dbus_g_connection_register_g_object (connection,
2015 + TRACKER_EVOLUTION_MANAGER_PATH,
2016 + G_OBJECT (manager));
2017 +
2018 + error_handler:
2019 +
2020 + if (error) {
2021 + g_warning ("Could not setup DBus, %s\n", error->message);
2022 + disable_plugin();
2023 + g_error_free (error);
2024 + }
2025 +}
2026 +
2027 +static gboolean
2028 +do_remove_or_not (gpointer key, gpointer value, gpointer user_data)
2029 +{
2030 + if (user_data == value)
2031 + return TRUE;
2032 +
2033 + return FALSE;
2034 +}
2035 +
2036 +static void
2037 +service_gone (DBusGProxy *lproxy, TrackerEvolutionPlugin *plugin)
2038 +{
2039 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
2040 + GList *copy = priv->registered_clients;
2041 + GList *to_delete = NULL;
2042 +
2043 + g_static_rec_mutex_lock (priv->mutex);
2044 +
2045 + g_hash_table_foreach_remove (priv->registrars,
2046 + do_remove_or_not,
2047 + lproxy);
2048 +
2049 + while (copy) {
2050 + ClientRegistry *creg = copy->data;
2051 + if (creg->registrar == lproxy)
2052 + to_delete = g_list_prepend (to_delete, copy);
2053 + copy = g_list_next (copy);
2054 + }
2055 +
2056 + copy = to_delete;
2057 + while (copy) {
2058 + GList *node = copy->data;
2059 + ClientRegistry *creg = node->data;
2060 + priv->registered_clients = g_list_delete_link (priv->registered_clients, node);
2061 + client_registry_info_free (creg);
2062 + copy = g_list_next (copy);
2063 + }
2064 +
2065 + g_list_free (to_delete);
2066 +
2067 + g_static_rec_mutex_unlock (priv->mutex);
2068 +}
2069 +
2070 +void
2071 +tracker_evolution_plugin_register (TrackerEvolutionPlugin *plugin,
2072 + gchar *registrar_path,
2073 + guint last_checkout,
2074 + DBusGMethodInvocation *context,
2075 + GError *derror)
2076 +{
2077 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
2078 + gchar *sender;
2079 + DBusGProxy *registrar;
2080 + guint dsignal;
2081 +
2082 + g_static_rec_mutex_lock (priv->mutex);
2083 +
2084 + sender = dbus_g_method_get_sender (context);
2085 +
2086 + registrar = dbus_g_proxy_new_for_name (priv->connection, sender,
2087 + registrar_path,
2088 + TRACKER_EVOLUTION_REGISTRAR_INTERFACE);
2089 +
2090 + g_hash_table_replace (priv->registrars, g_strdup (sender),
2091 + registrar);
2092 +
2093 + dsignal = g_signal_connect (registrar, "destroy",
2094 + G_CALLBACK (service_gone),
2095 + plugin);
2096 +
2097 + g_static_rec_mutex_unlock (priv->mutex);
2098 +
2099 + /* Passing uint64 over DBus ain't working :-\ */
2100 + register_client (plugin, (guint64) last_checkout, registrar, dsignal);
2101 +
2102 + dbus_g_method_return (context);
2103 +}
2104 +
2105 +
2106 +int
2107 +e_plugin_lib_enable (EPluginLib *ep, int enabled)
2108 +{
2109 + g_static_rec_mutex_lock (&glock);
2110 +
2111 + if (enabled)
2112 + enable_plugin ();
2113 + else
2114 + disable_plugin ();
2115 +
2116 + g_static_rec_mutex_unlock (&glock);
2117 +
2118 + return 0;
2119 +}
2120 +
2121 +
2122 +static void
2123 +tracker_evolution_plugin_finalize (GObject *plugin)
2124 +{
2125 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
2126 +
2127 + g_static_rec_mutex_lock (priv->mutex);
2128 +
2129 + g_list_foreach (priv->registered_clients,
2130 + (GFunc) client_registry_info_free,
2131 + NULL);
2132 + g_list_free (priv->registered_clients);
2133 +
2134 + g_list_free (priv->registered_clients);
2135 +
2136 + if (priv->registered_folders) {
2137 + g_hash_table_destroy (priv->registered_folders);
2138 + g_hash_table_destroy (priv->cached_folders);
2139 + priv->cached_folders = NULL;
2140 + priv->registered_folders = NULL;
2141 + }
2142 +
2143 + if (priv->registered_stores) {
2144 + g_hash_table_destroy (priv->registered_stores);
2145 + priv->registered_stores = NULL;
2146 + }
2147 +
2148 + g_object_unref (priv->accounts);
2149 +
2150 + g_hash_table_destroy (priv->registrars);
2151 +
2152 + g_static_rec_mutex_unlock (priv->mutex);
2153 +
2154 + g_slice_free (GStaticRecMutex, priv->mutex);
2155 +
2156 + G_OBJECT_CLASS (tracker_evolution_plugin_parent_class)->finalize (plugin);
2157 +}
2158 +
2159 +static void
2160 +tracker_evolution_plugin_set_connection (TrackerEvolutionPlugin *plugin,
2161 + DBusGConnection *connection)
2162 +{
2163 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
2164 + priv->connection = connection;
2165 +}
2166 +
2167 +static void
2168 +tracker_evolution_plugin_set_property (GObject *plugin,
2169 + guint prop_id,
2170 + const GValue *value,
2171 + GParamSpec *pspec)
2172 +{
2173 + switch (prop_id) {
2174 + case PROP_CONNECTION:
2175 + tracker_evolution_plugin_set_connection (TRACKER_EVOLUTION_PLUGIN (plugin),
2176 + g_value_get_pointer (value));
2177 + break;
2178 + default:
2179 + G_OBJECT_WARN_INVALID_PROPERTY_ID (plugin, prop_id, pspec);
2180 + }
2181 +}
2182 +
2183 +static void
2184 +tracker_evolution_plugin_get_property (GObject *plugin,
2185 + guint prop_id,
2186 + GValue *value,
2187 + GParamSpec *pspec)
2188 +{
2189 + TrackerEvolutionPluginPrivate *priv;
2190 +
2191 + priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
2192 +
2193 + switch (prop_id) {
2194 + case PROP_CONNECTION:
2195 + g_value_set_pointer (value, priv->connection);
2196 + break;
2197 + default:
2198 + G_OBJECT_WARN_INVALID_PROPERTY_ID (plugin, prop_id, pspec);
2199 + }
2200 +}
2201 +
2202 +static void
2203 +tracker_evolution_plugin_class_init (TrackerEvolutionPluginClass *klass)
2204 +{
2205 + GObjectClass *object_class = G_OBJECT_CLASS (klass);
2206 +
2207 + object_class->finalize = tracker_evolution_plugin_finalize;
2208 + object_class->set_property = tracker_evolution_plugin_set_property;
2209 + object_class->get_property = tracker_evolution_plugin_get_property;
2210 +
2211 + g_object_class_install_property (object_class,
2212 + PROP_CONNECTION,
2213 + g_param_spec_pointer ("connection",
2214 + "DBus connection",
2215 + "DBus connection",
2216 + G_PARAM_READWRITE |
2217 + G_PARAM_CONSTRUCT));
2218 +
2219 + g_type_class_add_private (object_class, sizeof (TrackerEvolutionPluginPrivate));
2220 +}
2221 +
2222 +static void
2223 +tracker_evolution_plugin_init (TrackerEvolutionPlugin *plugin)
2224 +{
2225 + TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (plugin);
2226 + EIterator *it;
2227 +
2228 + priv->mutex = g_slice_new0 (GStaticRecMutex);
2229 + g_static_rec_mutex_init (priv->mutex);
2230 +
2231 + g_static_rec_mutex_lock (priv->mutex);
2232 +
2233 + priv->registrars = g_hash_table_new_full (g_str_hash, g_str_equal,
2234 + (GDestroyNotify) g_free,
2235 + (GDestroyNotify) g_object_unref);
2236 +
2237 +
2238 + priv->cached_folders = NULL;
2239 + priv->registered_folders = NULL;
2240 + priv->registered_stores = NULL;
2241 + priv->registered_clients = NULL;
2242 +
2243 + g_static_rec_mutex_unlock (priv->mutex);
2244 +
2245 + priv->accounts = g_object_ref (mail_config_get_accounts ());
2246 +
2247 + for (it = e_list_get_iterator (E_LIST (priv->accounts)); e_iterator_is_valid (it); e_iterator_next (it))
2248 + register_account (plugin, (EAccount *) e_iterator_get (it));
2249 +
2250 + g_object_unref (it);
2251 +
2252 + g_signal_connect (priv->accounts, "account-added",
2253 + G_CALLBACK (on_account_added), plugin);
2254 + g_signal_connect (priv->accounts, "account-removed",
2255 + G_CALLBACK (on_account_removed), plugin);
2256 + g_signal_connect (priv->accounts, "account-changed",
2257 + G_CALLBACK (on_account_changed), plugin);
2258 +}
2259 Index: src/plugins/evolution/tracker-evolution-indexer.c
2260 ===================================================================
2261 --- src/plugins/evolution/tracker-evolution-indexer.c (revision 0)
2262 +++ src/plugins/evolution/tracker-evolution-indexer.c (revision 0)
2263 @@ -0,0 +1,603 @@
2264 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2265 +/*
2266 + * Copyright (C) 2008, Nokia
2267 + *
2268 + * This library is free software; you can redistribute it and/or
2269 + * modify it under the terms of the GNU General Public
2270 + * License as published by the Free Software Foundation; either
2271 + * version 2 of the License, or (at your option) any later version.
2272 + *
2273 + * This library is distributed in the hope that it will be useful,
2274 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2275 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2276 + * General Public License for more details.
2277 + *
2278 + * You should have received a copy of the GNU General Public
2279 + * License along with this library; if not, write to the
2280 + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2281 + * Boston, MA 02110-1301, USA.
2282 + *
2283 + * Authors:
2284 + * Philip Van Hoof <philip@codeminded.be>
2285 + */
2286 +
2287 +#include "config.h"
2288 +
2289 +#include <string.h>
2290 +#include <fcntl.h>
2291 +#include <sys/types.h>
2292 +#include <sys/stat.h>
2293 +#include <glib.h>
2294 +#include <gio/gio.h>
2295 +#include <glib/gstdio.h>
2296 +#include <stdlib.h>
2297 +#include <stdio.h>
2298 +
2299 +#include <gmime/gmime.h>
2300 +
2301 +#include <libtracker-data/tracker-data-update.h>
2302 +
2303 +/* This is okay, we run in-process of the indexer: we can access its symbols */
2304 +#include <tracker-indexer/tracker-module.h>
2305 +#include <tracker-indexer/tracker-module-metadata-private.h>
2306 +
2307 +#include "tracker-evolution-indexer.h"
2308 +
2309 +/* These defines/renames are necessary for -glue.h */
2310 +#define tracker_evolution_registrar_set tracker_evolution_indexer_set
2311 +#define tracker_evolution_registrar_set_many tracker_evolution_indexer_set_many
2312 +#define tracker_evolution_registrar_unset_many tracker_evolution_indexer_unset_many
2313 +#define tracker_evolution_registrar_unset tracker_evolution_indexer_unset
2314 +#define tracker_evolution_registrar_cleanup tracker_evolution_indexer_cleanup
2315 +#define dbus_glib_tracker_evolution_indexer_object_info dbus_glib_tracker_evolution_registrar_object_info
2316 +
2317 +#include "tracker-evolution-registrar-glue.h"
2318 +
2319 +/* Based on data/services/email.metadata */
2320 +
2321 +#define METADATA_EMAIL_RECIPIENT "Email:Recipient"
2322 +#define METADATA_EMAIL_DATE "Email:Date"
2323 +#define METADATA_EMAIL_SENDER "Email:Sender"
2324 +#define METADATA_EMAIL_SUBJECT "Email:Subject"
2325 +#define METADATA_EMAIL_SENT_TO "Email:SentTo"
2326 +#define METADATA_EMAIL_CC "Email:CC"
2327 +#define METADATA_EMAIL_TEXT "Email:Body"
2328 +#define METADATA_EMAIL_TAG "User:Keywords"
2329 +
2330 +#define TRACKER_EVOLUTION_INDEXER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_EVOLUTION_INDEXER, TrackerEvolutionIndexerPrivate))
2331 +
2332 +G_DEFINE_TYPE (TrackerEvolutionIndexer, tracker_evolution_indexer, G_TYPE_OBJECT)
2333 +
2334 +/* This runs in-process of tracker-indexer */
2335 +
2336 +static GObject *idx_indexer = NULL;
2337 +
2338 +typedef struct {
2339 + TrackerIndexer *indexer;
2340 +} TrackerEvolutionIndexerPrivate;
2341 +
2342 +enum {
2343 + PROP_0,
2344 + PROP_INDEXER
2345 +};
2346 +
2347 +static void
2348 +tracker_evolution_indexer_finalize (GObject *object)
2349 +{
2350 + TrackerEvolutionIndexerPrivate *priv = TRACKER_EVOLUTION_INDEXER_GET_PRIVATE (object);
2351 +
2352 + if (priv->indexer)
2353 + g_object_unref (priv->indexer);
2354 +
2355 + G_OBJECT_CLASS (tracker_evolution_indexer_parent_class)->finalize (object);
2356 +}
2357 +
2358 +static void
2359 +tracker_evolution_indexer_set_property (GObject *object,
2360 + guint prop_id,
2361 + const GValue *value,
2362 + GParamSpec *pspec)
2363 +{
2364 + TrackerEvolutionIndexerPrivate *priv = TRACKER_EVOLUTION_INDEXER_GET_PRIVATE (object);
2365 +
2366 + switch (prop_id) {
2367 +
2368 + case PROP_INDEXER:
2369 + priv->indexer = g_value_dup_object (value);
2370 + break;
2371 +
2372 + default:
2373 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2374 + break;
2375 + }
2376 +}
2377 +
2378 +static void
2379 +tracker_evolution_indexer_get_property (GObject *object,
2380 + guint prop_id,
2381 + GValue *value,
2382 + GParamSpec *pspec)
2383 +{
2384 + TrackerEvolutionIndexerPrivate *priv;
2385 +
2386 + priv = TRACKER_EVOLUTION_INDEXER_GET_PRIVATE (object);
2387 +
2388 + switch (prop_id) {
2389 + case PROP_INDEXER:
2390 + g_value_set_object (value, priv->indexer);
2391 + break;
2392 + default:
2393 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2394 + break;
2395 + }
2396 +}
2397 +
2398 +static void
2399 +tracker_evolution_indexer_class_init (TrackerEvolutionIndexerClass *klass)
2400 +{
2401 + GObjectClass *object_class = G_OBJECT_CLASS (klass);
2402 +
2403 + object_class->finalize = tracker_evolution_indexer_finalize;
2404 + object_class->set_property = tracker_evolution_indexer_set_property;
2405 + object_class->get_property = tracker_evolution_indexer_get_property;
2406 +
2407 + g_object_class_install_property (object_class,
2408 + PROP_INDEXER,
2409 + g_param_spec_object ("indexer",
2410 + "Indexer",
2411 + "Indexer",
2412 + tracker_indexer_get_type (),
2413 + G_PARAM_READWRITE |
2414 + G_PARAM_CONSTRUCT));
2415 +
2416 + g_type_class_add_private (object_class, sizeof (TrackerEvolutionIndexerPrivate));
2417 +}
2418 +
2419 +static void
2420 +tracker_evolution_indexer_init (TrackerEvolutionIndexer *object)
2421 +{
2422 + TrackerEvolutionIndexerPrivate *priv = TRACKER_EVOLUTION_INDEXER_GET_PRIVATE (object);
2423 +
2424 + priv->indexer = NULL;
2425 +}
2426 +
2427 +
2428 +#if 0
2429 +static void
2430 +extract_mime_parts (GMimeObject *object,
2431 + gpointer user_data)
2432 +{
2433 + const gchar *message_subject = user_data;
2434 + gchar *subject = NULL;
2435 + const gchar *disposition, *filename;
2436 + GMimePart *part;
2437 +
2438 + if (GMIME_IS_MESSAGE_PART (object)) {
2439 + GMimeMessage *message;
2440 +
2441 + message = g_mime_message_part_get_message (GMIME_MESSAGE_PART (object));
2442 +
2443 + if (message) {
2444 + g_mime_message_foreach_part (message, extract_mime_parts, user_data);
2445 + g_object_unref (message);
2446 + }
2447 +
2448 + return;
2449 + } else if (GMIME_IS_MULTIPART (object)) {
2450 + g_mime_multipart_foreach (GMIME_MULTIPART (object), extract_mime_parts, user_data);
2451 + return;
2452 + }
2453 +
2454 + part = GMIME_PART (object);
2455 + disposition = g_mime_part_get_content_disposition (part);
2456 +
2457 + if (!disposition ||
2458 + (g_strcmp0 (disposition, GMIME_DISPOSITION_ATTACHMENT) != 0 &&
2459 + g_strcmp0 (disposition, GMIME_DISPOSITION_INLINE) != 0)) {
2460 + return;
2461 + }
2462 +
2463 + filename = g_mime_part_get_filename (GMIME_PART (object));
2464 +
2465 + if (!filename ||
2466 + g_strcmp0 (filename, "signature.asc") == 0 ||
2467 + g_strcmp0 (filename, "signature.pgp") == 0) {
2468 + return;
2469 + }
2470 +
2471 + if (filename) {
2472 + GHashTable *data;
2473 + TrackerModuleMetadata *metadata;
2474 + gchar *subject;
2475 +
2476 + /* This is not a path but a URI: don't use the OS's dir separator
2477 + * here, use the '/'. Another option is to use '#' instead of '/'
2478 + * here. This depends on how we want to format the URI and what
2479 + * Evolution can cope with as URI for an attachment (I don't
2480 + * think it can cope with any attachment URI, btw). */
2481 +
2482 + subject = g_strdup_printf ("%s/%s", message_subject,
2483 + filename);
2484 +
2485 + metadata = tracker_module_metadata_new ();
2486 +
2487 + tracker_module_metadata_add_string (metadata,
2488 + "File:Path",
2489 + subject);
2490 +
2491 + tracker_module_metadata_add_string (metadata,
2492 + "File:Name",
2493 + filename);
2494 +
2495 + data = tracker_module_metadata_get_hash_table (metadata);
2496 +
2497 + tracker_data_update_replace_service (subject, "EvolutionEmails", data);
2498 +
2499 + g_hash_table_destroy (data);
2500 + g_object_unref (metadata);
2501 + g_free (subject);
2502 + }
2503 +}
2504 +
2505 +static gchar *
2506 +get_object_encoding (GMimeObject *object)
2507 +{
2508 + const gchar *start_encoding, *end_encoding;
2509 + const gchar *content_type = NULL;
2510 +
2511 + if (GMIME_IS_MESSAGE (object)) {
2512 + content_type = g_mime_message_get_header (GMIME_MESSAGE (object), "Content-Type");
2513 + } else if (GMIME_IS_PART (object)) {
2514 + content_type = g_mime_part_get_content_header (GMIME_PART (object), "Content-Type");
2515 + }
2516 +
2517 + if (!content_type) {
2518 + return NULL;
2519 + }
2520 +
2521 + start_encoding = strstr (content_type, "charset=");
2522 +
2523 + if (!start_encoding) {
2524 + return NULL;
2525 + }
2526 +
2527 + start_encoding += strlen ("charset=");
2528 +
2529 + if (start_encoding[0] == '"') {
2530 + /* encoding is quoted */
2531 + start_encoding++;
2532 + end_encoding = strstr (start_encoding, "\"");
2533 + } else {
2534 + end_encoding = strstr (start_encoding, ";");
2535 + }
2536 +
2537 + if (end_encoding) {
2538 + return g_strndup (start_encoding, end_encoding - start_encoding);
2539 + } else {
2540 + return g_strdup (start_encoding);
2541 + }
2542 +}
2543 +#endif
2544 +
2545 +static void
2546 +perform_set (TrackerEvolutionIndexer *object,
2547 + const gchar *subject,
2548 + const GStrv predicates,
2549 + const GStrv values)
2550 +{
2551 + guint i = 0;
2552 + TrackerModuleMetadata *metadata;
2553 + GHashTable *data;
2554 +
2555 + metadata = tracker_module_metadata_new ();
2556 +
2557 + while (predicates [i] != NULL && values[i] != NULL) {
2558 +
2559 + /* TODO: TRACKER_EVOLUTION_PREDICATE_SEEN (!)
2560 + * TRACKER_EVOLUTION_PREDICATE_JUNK (!)
2561 + * TRACKER_EVOLUTION_PREDICATE_ANSWERED
2562 + * TRACKER_EVOLUTION_PREDICATE_FLAGGED
2563 + * TRACKER_EVOLUTION_PREDICATE_FORWARDED
2564 + * TRACKER_EVOLUTION_PREDICATE_DELETED (!)
2565 + * TRACKER_EVOLUTION_PREDICATE_SIZE (!) :
2566 + *
2567 + * I don't have predicates in Tracker's ontology for these. In
2568 + * Jürg's vstore branch we are working with Nepomuk as ontology-
2569 + * set. Perhaps when we merge this to that branch that we can
2570 + * improve this situation. */
2571 +
2572 +
2573 +#if 0
2574 +
2575 + /* Disabling this as I can't find any version of GMime-2.0 that
2576 + * wont crash on any of my test E-mails. Going to ask Garnacho
2577 + * to migrate to GMime-2.4 with his old Evolution support. */
2578 +
2579 + if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_FILE) == 0) {
2580 + GMimeStream *stream;
2581 + GMimeParser *parser;
2582 + GMimeMessage *message;
2583 + gint fd;
2584 + gchar *text, *orig_text, *ptr, *encoding;
2585 + gchar *path = g_strdup (values[i]);
2586 + off_t offset = 0;
2587 + gboolean is_html;
2588 +
2589 + ptr = strstr (path, "/!");
2590 + if (ptr) {
2591 + offset = (off_t) atol (ptr+2);
2592 + *ptr = '\0';
2593 + }
2594 +
2595 + fd = tracker_file_open (path, FALSE);
2596 +
2597 + g_free (path);
2598 +
2599 + if (fd == -1)
2600 + goto cont;
2601 +
2602 + stream = g_mime_stream_fs_new_with_bounds (fd, offset, -1);
2603 +
2604 + if (!stream) {
2605 + close (fd);
2606 + goto cont;
2607 + }
2608 +
2609 + parser = g_mime_parser_new_with_stream (stream);
2610 +
2611 + if (!parser) {
2612 + g_object_unref (stream);
2613 + goto cont;
2614 + }
2615 +
2616 + g_mime_parser_set_scan_from (parser, FALSE);
2617 +
2618 + message = g_mime_parser_construct_message (parser);
2619 +
2620 + if (!message) {
2621 + g_object_unref (parser);
2622 + g_object_unref (stream);
2623 + goto cont;
2624 + }
2625 +
2626 + g_mime_message_foreach_part (message,
2627 + extract_mime_parts,
2628 + subject);
2629 +
2630 + orig_text = g_mime_message_get_body (message, TRUE, &is_html);
2631 +
2632 + if (orig_text) {
2633 +
2634 + encoding = get_object_encoding (GMIME_OBJECT (message));
2635 +
2636 + if (encoding) {
2637 + text = g_convert (text, -1, "utf8", encoding, NULL, NULL, NULL);
2638 + g_free (orig_text);
2639 + } else
2640 + text = orig_text;
2641 +
2642 + tracker_module_metadata_add_string (metadata,
2643 + METADATA_EMAIL_TEXT,
2644 + text);
2645 +
2646 + g_free (text);
2647 + g_free (encoding);
2648 + }
2649 +
2650 + g_object_unref (message);
2651 + g_object_unref (parser);
2652 + g_object_unref (stream);
2653 + }
2654 +#endif
2655 +
2656 + if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_TAG) == 0) {
2657 + gchar *key, *value;
2658 +
2659 + if (!values[i] || strlen (values[i]) < 1)
2660 + goto cont;
2661 +
2662 + key = g_strdup (values[i]);
2663 +
2664 + value = strchr (key, '=');
2665 +
2666 + if (value) {
2667 + *value = '\0';
2668 + value++;
2669 + }
2670 +
2671 + /* TODO: what about value? The format of Evolution is
2672 + * key=value, so we can store a value too here. Is this
2673 + * something Nepomuk can someday save us with? */
2674 +
2675 + tracker_module_metadata_add_string (metadata,
2676 + METADATA_EMAIL_TAG,
2677 + key);
2678 +
2679 + g_free (key);
2680 + }
2681 +
2682 + if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_SUBJECT) == 0) {
2683 + tracker_module_metadata_add_string (metadata,
2684 + METADATA_EMAIL_SUBJECT,
2685 + values[i]);
2686 + }
2687 +
2688 + if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_SENT) == 0) {
2689 + tracker_module_metadata_add_string (metadata,
2690 + METADATA_EMAIL_DATE,
2691 + values[i]);
2692 + }
2693 +
2694 + if (g_strcmp0 (predicates[i], METADATA_EMAIL_SENDER) == 0) {
2695 + tracker_module_metadata_add_string (metadata,
2696 + METADATA_EMAIL_SENDER,
2697 + values[i]);
2698 + }
2699 +
2700 + if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_TO) == 0) {
2701 + tracker_module_metadata_add_string (metadata,
2702 + METADATA_EMAIL_SENT_TO,
2703 + values[i]);
2704 + }
2705 +
2706 + if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_CC) == 0) {
2707 + tracker_module_metadata_add_string (metadata,
2708 + METADATA_EMAIL_CC,
2709 + values[i]);
2710 + }
2711 +
2712 + cont:
2713 +
2714 + i++;
2715 + }
2716 +
2717 + data = tracker_module_metadata_get_hash_table (metadata);
2718 +
2719 + tracker_data_update_replace_service (subject, "EvolutionEmails", data);
2720 +
2721 + g_hash_table_destroy (data);
2722 + g_object_unref (metadata);
2723 +}
2724 +
2725 +static void
2726 +perform_unset (TrackerEvolutionIndexer *object,
2727 + const gchar *subject)
2728 +{
2729 + tracker_data_update_delete_service_by_path (subject, "EvolutionEmails");
2730 +}
2731 +
2732 +static void
2733 +perform_cleanup (TrackerEvolutionIndexer *object)
2734 +{
2735 + tracker_data_update_delete_service_all ("EvolutionEmails");
2736 +}
2737 +
2738 +void
2739 +tracker_evolution_indexer_set (TrackerEvolutionIndexer *object,
2740 + const gchar *subject,
2741 + const GStrv predicates,
2742 + const GStrv values,
2743 + DBusGMethodInvocation *context,
2744 + GError *derror)
2745 +{
2746 + dbus_async_return_if_fail (subject != NULL, context);
2747 +
2748 + if (predicates && values) {
2749 +
2750 + dbus_async_return_if_fail (g_strv_length (predicates) ==
2751 + g_strv_length (values), context);
2752 +
2753 + perform_set (object, subject, predicates, values);
2754 + }
2755 +
2756 + dbus_g_method_return (context);
2757 +}
2758 +
2759 +void
2760 +tracker_evolution_indexer_set_many (TrackerEvolutionIndexer *object,
2761 + const GStrv subjects,
2762 + const GPtrArray *predicates,
2763 + const GPtrArray *values,
2764 + DBusGMethodInvocation *context,
2765 + GError *derror)
2766 +{
2767 + guint len;
2768 + guint i = 0;
2769 +
2770 + dbus_async_return_if_fail (subjects != NULL, context);
2771 + dbus_async_return_if_fail (predicates != NULL, context);
2772 + dbus_async_return_if_fail (values != NULL, context);
2773 +
2774 + len = g_strv_length (subjects);
2775 +
2776 + dbus_async_return_if_fail (len == predicates->len, context);
2777 + dbus_async_return_if_fail (len == values->len, context);
2778 +
2779 + while (subjects[i] != NULL) {
2780 + GStrv preds = g_ptr_array_index (predicates, i);
2781 + GStrv vals = g_ptr_array_index (values, i);
2782 +
2783 + perform_set (object, subjects[i], preds, vals);
2784 +
2785 + i++;
2786 + }
2787 +
2788 + dbus_g_method_return (context);
2789 +}
2790 +
2791 +void
2792 +tracker_evolution_indexer_unset_many (TrackerEvolutionIndexer *object,
2793 + const GStrv subjects,
2794 + DBusGMethodInvocation *context,
2795 + GError *derror)
2796 +{
2797 + guint i = 0;
2798 +
2799 + dbus_async_return_if_fail (subjects != NULL, context);
2800 +
2801 + while (subjects[i] != NULL) {
2802 +
2803 + perform_unset (object, subjects[i]);
2804 +
2805 + i++;
2806 + }
2807 +
2808 + dbus_g_method_return (context);
2809 +}
2810 +
2811 +void
2812 +tracker_evolution_indexer_unset (TrackerEvolutionIndexer *object,
2813 + const gchar *subject,
2814 + DBusGMethodInvocation *context,
2815 + GError *derror)
2816 +{
2817 + dbus_async_return_if_fail (subject != NULL, context);
2818 +
2819 + perform_unset (object, subject);
2820 +
2821 + dbus_g_method_return (context);
2822 +}
2823 +
2824 +void
2825 +tracker_evolution_indexer_cleanup (TrackerEvolutionIndexer *object,
2826 + DBusGMethodInvocation *context,
2827 + GError *derror)
2828 +{
2829 + perform_cleanup (object);
2830 +
2831 + dbus_g_method_return (context);
2832 +}
2833 +
2834 +void
2835 +tracker_evolution_storer_init (TrackerConfig *config,
2836 + TrackerIndexer *indexer)
2837 +{
2838 + GError *error = NULL;
2839 + DBusGConnection *connection;
2840 +
2841 + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
2842 +
2843 + if (!error) {
2844 + idx_indexer = g_object_new (TRACKER_TYPE_EVOLUTION_INDEXER,
2845 + "indexer", indexer, NULL);
2846 +
2847 + dbus_g_object_type_install_info (G_OBJECT_TYPE (idx_indexer),
2848 + &dbus_glib_tracker_evolution_indexer_object_info);
2849 +
2850 + dbus_g_connection_register_g_object (connection,
2851 + TRACKER_EVOLUTION_INDEXER_PATH,
2852 + idx_indexer);
2853 + }
2854 +
2855 + if (error) {
2856 + g_critical ("Can't init DBus for Evolution support: %s", error->message);
2857 + g_error_free (error);
2858 + }
2859 +}
2860 +
2861 +void
2862 +tracker_evolution_storer_shutdown (void)
2863 +{
2864 + if (idx_indexer)
2865 + g_object_unref (idx_indexer);
2866 +}
2867 Index: src/plugins/evolution/tracker-evolution-registrar.xml
2868 ===================================================================
2869 --- src/plugins/evolution/tracker-evolution-registrar.xml (revision 0)
2870 +++ src/plugins/evolution/tracker-evolution-registrar.xml (revision 0)
2871 @@ -0,0 +1,34 @@
2872 +<?xml version="1.0" encoding="UTF-8"?>
2873 +<node name="/">
2874 + <interface name="org.gnome.evolution.metadata.Registrar">
2875 +
2876 + <method name="Set">
2877 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
2878 + <arg type="s" name="subject" direction="in" />
2879 + <arg type="as" name="predicates" direction="in" />
2880 + <arg type="as" name="values" direction="in" />
2881 + </method>
2882 +
2883 + <method name="SetMany">
2884 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
2885 + <arg type="as" name="subjects" direction="in" />
2886 + <arg type="aas" name="predicates" direction="in" />
2887 + <arg type="aas" name="values" direction="in" />
2888 + </method>
2889 +
2890 + <method name="Unset">
2891 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
2892 + <arg type="s" name="subject" direction="in" />
2893 + </method>
2894 +
2895 + <method name="UnsetMany">
2896 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
2897 + <arg type="as" name="subjects" direction="in" />
2898 + </method>
2899 +
2900 + <method name="Cleanup">
2901 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
2902 + </method>
2903 +
2904 + </interface>
2905 +</node>
2906 Index: src/plugins/evolution/tracker-evolution.c
2907 ===================================================================
2908 --- src/plugins/evolution/tracker-evolution.c (revision 0)
2909 +++ src/plugins/evolution/tracker-evolution.c (revision 0)
2910 @@ -0,0 +1,357 @@
2911 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2912 +/*
2913 + * Copyright (C) 2008, Nokia
2914 + *
2915 + * This library is free software; you can redistribute it and/or
2916 + * modify it under the terms of the GNU General Public
2917 + * License as published by the Free Software Foundation; either
2918 + * version 2 of the License, or (at your option) any later version.
2919 + *
2920 + * This library is distributed in the hope that it will be useful,
2921 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2922 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2923 + * General Public License for more details.
2924 + *
2925 + * You should have received a copy of the GNU General Public
2926 + * License along with this library; if not, write to the
2927 + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2928 + * Boston, MA 02110-1301, USA.
2929 + *
2930 + * Authors:
2931 + * Philip Van Hoof <philip@codeminded.be>
2932 + */
2933 +
2934 +#include "config.h"
2935 +
2936 +#include <string.h>
2937 +#include <time.h>
2938 +
2939 +#include <libtracker-data/tracker-data-manager.h>
2940 +
2941 +#include "tracker-evolution.h"
2942 +#include "tracker-evolution-registrar.h"
2943 +
2944 +typedef struct {
2945 + TrackerConfig *config;
2946 + DBusGConnection *connection;
2947 + gboolean is_enabled;
2948 + DBusGProxy *dbus_proxy;
2949 + DBusGProxy *manager_proxy;
2950 + GObject *object;
2951 + gboolean deactivating;
2952 +} EvolutionSupportPrivate;
2953 +
2954 +static GStaticPrivate private_key = G_STATIC_PRIVATE_INIT;
2955 +
2956 +static guint
2957 +get_stored_last_checkout (void)
2958 +{
2959 + return (guint) tracker_data_manager_get_db_option_int ("EvolutionLastCheckout");
2960 +}
2961 +
2962 +static void
2963 +set_stored_last_checkout (guint last_checkout)
2964 +{
2965 + tracker_data_manager_set_db_option_int ("EvolutionLastCheckout", (gint) last_checkout);
2966 +}
2967 +
2968 +static void
2969 +deactivate_registrar (void)
2970 +{
2971 + EvolutionSupportPrivate *private;
2972 +
2973 + private = g_static_private_get (&private_key);
2974 + g_return_if_fail (private != NULL);
2975 +
2976 + set_stored_last_checkout (time(NULL));
2977 +
2978 + if (private->object) {
2979 + g_object_unref (private->object);
2980 + private->object = NULL;
2981 + }
2982 +
2983 + if (private->manager_proxy && !private->deactivating)
2984 + g_object_unref (private->manager_proxy);
2985 +
2986 + private->manager_proxy = NULL;
2987 +}
2988 +
2989 +static void
2990 +deactivate_dbus_client (void)
2991 +{
2992 + EvolutionSupportPrivate *private;
2993 +
2994 + private = g_static_private_get (&private_key);
2995 + g_return_if_fail (private != NULL);
2996 +
2997 + deactivate_registrar ();
2998 +
2999 + if (private->dbus_proxy) {
3000 + g_object_unref (private->dbus_proxy);
3001 + private->dbus_proxy = NULL;
3002 + }
3003 +}
3004 +
3005 +static void
3006 +on_manager_destroy (DBusGProxy *proxy, gpointer user_data)
3007 +{
3008 + EvolutionSupportPrivate *private;
3009 + gboolean old_setting;
3010 +
3011 + private = g_static_private_get (&private_key);
3012 + g_return_if_fail (private != NULL);
3013 +
3014 + old_setting = private->deactivating;
3015 +
3016 + private->deactivating = TRUE;
3017 + deactivate_registrar ();
3018 + private->deactivating = old_setting;
3019 +}
3020 +
3021 +
3022 +static void
3023 +activate_registrar (void)
3024 +{
3025 + EvolutionSupportPrivate *private;
3026 +
3027 + private = g_static_private_get (&private_key);
3028 + g_return_if_fail (private != NULL);
3029 +
3030 + if (private->object)
3031 + return;
3032 +
3033 + private->manager_proxy =
3034 + dbus_g_proxy_new_for_name (private->connection,
3035 + TRACKER_EVOLUTION_MANAGER_SERVICE,
3036 + TRACKER_EVOLUTION_MANAGER_PATH,
3037 + TRACKER_EVOLUTION_MANAGER_INTERFACE);
3038 +
3039 + /* If while we had a proxy for the manager the manager shut itself down,
3040 + * then we'll get rid of our registrar too, in on_manager_destroy */
3041 +
3042 + g_signal_connect (private->manager_proxy, "destroy",
3043 + G_CALLBACK (on_manager_destroy), NULL);
3044 +
3045 + if (private->manager_proxy) {
3046 + GError *error = NULL;
3047 + guint result;
3048 +
3049 + /* Creation of the registrar */
3050 + if (!org_freedesktop_DBus_request_name (private->dbus_proxy,
3051 + TRACKER_EVOLUTION_REGISTRAR_SERVICE,
3052 + DBUS_NAME_FLAG_DO_NOT_QUEUE,
3053 + &result, &error)) {
3054 + g_critical ("Could not setup DBus, %s in use\n", TRACKER_EVOLUTION_REGISTRAR_SERVICE);
3055 + goto error_handler;
3056 + }
3057 +
3058 + if (error)
3059 + goto error_handler;
3060 +
3061 + private->object = g_object_new (TRACKER_TYPE_EVOLUTION_REGISTRAR,
3062 + "connection", private->connection,
3063 + NULL);
3064 +
3065 + dbus_g_object_type_install_info (G_OBJECT_TYPE (private->object),
3066 + ®istrar_methods);
3067 + dbus_g_connection_register_g_object (private->connection,
3068 + TRACKER_EVOLUTION_REGISTRAR_PATH,
3069 + private->object);
3070 +
3071 + /* Registration of the registrar to the manager */
3072 + dbus_g_proxy_call_no_reply (private->manager_proxy, "Register",
3073 + G_TYPE_OBJECT, private->object, /* TRACKER_EVOLUTION_REGISTRAR_PATH, */
3074 + G_TYPE_UINT, get_stored_last_checkout (),
3075 + G_TYPE_INVALID,
3076 + G_TYPE_INVALID);
3077 +
3078 + error_handler:
3079 +
3080 + if (error) {
3081 + g_critical ("Could not setup DBus, %s\n", error->message);
3082 + g_error_free (error);
3083 + }
3084 + }
3085 +}
3086 +
3087 +static void
3088 +name_owner_changed_cb (DBusGProxy *proxy,
3089 + gchar *name,
3090 + gchar *old_owner,
3091 + gchar *new_owner,
3092 + gpointer user_data)
3093 +{
3094 +
3095 + /* If we receive a NameOwnerChanged about the manager's service */
3096 +
3097 + if (g_strcmp0 (name, TRACKER_EVOLUTION_MANAGER_SERVICE) == 0) {
3098 + if (tracker_is_empty_string (new_owner) && !tracker_is_empty_string (old_owner))
3099 + deactivate_registrar ();
3100 + if (tracker_is_empty_string (old_owner) && !tracker_is_empty_string (new_owner))
3101 + activate_registrar ();
3102 + }
3103 +}
3104 +
3105 +static void
3106 +list_names_reply_cb (DBusGProxy *proxy,
3107 + DBusGProxyCall *call,
3108 + gpointer user_data)
3109 +{
3110 + GError *error = NULL;
3111 + GStrv names = NULL;
3112 + guint i = 0;
3113 +
3114 + dbus_g_proxy_end_call (proxy, call, &error,
3115 + G_TYPE_STRV, &names,
3116 + G_TYPE_INVALID);
3117 +
3118 + if (error) {
3119 + g_warning ("%s", error->message);
3120 + g_error_free (error);
3121 + if (names)
3122 + g_strfreev (names);
3123 + return;
3124 + }
3125 +
3126 + while (names[i] != NULL) {
3127 + /* If the manager's service is found, start the registrar */
3128 + if (g_strcmp0 (names[i], TRACKER_EVOLUTION_MANAGER_SERVICE) == 0) {
3129 + activate_registrar ();
3130 + break;
3131 + }
3132 + i++;
3133 + }
3134 +
3135 + g_strfreev (names);
3136 +}
3137 +
3138 +static void
3139 +activate_dbus_client (void)
3140 +{
3141 + EvolutionSupportPrivate *private;
3142 +
3143 + private = g_static_private_get (&private_key);
3144 + g_return_if_fail (private != NULL);
3145 +
3146 + private->dbus_proxy = dbus_g_proxy_new_for_name (private->connection,
3147 + DBUS_SERVICE_DBUS,
3148 + DBUS_PATH_DBUS,
3149 + DBUS_INTERFACE_DBUS);
3150 +
3151 + /* We listen for NameOwnerChanged to know when the manager's service
3152 + * comes up and to know when it goes down */
3153 +
3154 + dbus_g_proxy_add_signal (private->dbus_proxy, "NameOwnerChanged",
3155 + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
3156 + G_TYPE_INVALID);
3157 +
3158 + dbus_g_proxy_connect_signal (private->dbus_proxy, "NameOwnerChanged",
3159 + G_CALLBACK (name_owner_changed_cb),
3160 + NULL, NULL);
3161 +
3162 + /* If the manager service is up and running, then list_names_reply_cb
3163 + * will execute activate_registrar, as it'll appear in the results of
3164 + * the ListNames DBus function. If not then we will just wait for the
3165 + * NameOwnerChanged to emit that the manager's service has came up. */
3166 +
3167 + dbus_g_proxy_begin_call (private->dbus_proxy, "ListNames",
3168 + list_names_reply_cb, NULL, NULL,
3169 + G_TYPE_INVALID,
3170 + G_TYPE_INVALID);
3171 +}
3172 +
3173 +static gboolean
3174 +is_enabled (TrackerConfig *config)
3175 +{
3176 + /* If none of the disabled modules include the Evolution module,
3177 + * we assume we are enabled in the configuration. */
3178 +
3179 + return (g_slist_find_custom (tracker_config_get_disabled_modules (config),
3180 + "Evolution",
3181 + (GCompareFunc) g_strcmp0) != NULL);
3182 +}
3183 +
3184 +static void
3185 +disabled_notify (GObject *pspec,
3186 + GParamSpec *gobject,
3187 + gpointer user_data)
3188 +{
3189 + EvolutionSupportPrivate *private;
3190 + gboolean new_value;
3191 +
3192 + private = g_static_private_get (&private_key);
3193 + g_return_if_fail (private != NULL);
3194 +
3195 + new_value = is_enabled (private->config);
3196 +
3197 + if (private->is_enabled != new_value) {
3198 + if (private->is_enabled) {
3199 + /* If we were enabled, disable */
3200 + deactivate_dbus_client ();
3201 + } else {
3202 + /* If we were disabled, enable */
3203 + activate_dbus_client ();
3204 + }
3205 + private->is_enabled = new_value;
3206 + }
3207 +
3208 + g_message ("Evolution support service %s",
3209 + private->is_enabled ? "enabled" : "disabled");
3210 +}
3211 +
3212 +static void
3213 +free_private (EvolutionSupportPrivate *private)
3214 +{
3215 + g_object_unref (private->config);
3216 + g_free (private);
3217 +}
3218 +
3219 +void
3220 +tracker_evolution_init (TrackerConfig *config)
3221 +{
3222 + DBusGConnection *connection;
3223 + GError *error = NULL;
3224 +
3225 + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
3226 +
3227 + if (!error) {
3228 + EvolutionSupportPrivate *private;
3229 +
3230 + private = g_new0 (EvolutionSupportPrivate, 1);
3231 +
3232 + private->deactivating = FALSE;
3233 + private->config = g_object_ref (config);
3234 + private->is_enabled = is_enabled (config);
3235 + private->connection = connection;
3236 +
3237 + g_static_private_set (&private_key,
3238 + private,
3239 + (GDestroyNotify) free_private);
3240 +
3241 + /* Hook configuration changes */
3242 + g_signal_connect (private->config, "notify::disabled-modules",
3243 + G_CALLBACK (disabled_notify),
3244 + NULL);
3245 +
3246 + /* If in configuration we are enabled now */
3247 + if (private->is_enabled)
3248 + activate_dbus_client ();
3249 + } else {
3250 + g_critical ("Could not setup DBus, %s\n", error->message);
3251 + g_error_free (error);
3252 + }
3253 +}
3254 +
3255 +void
3256 +tracker_evolution_shutdown ()
3257 +{
3258 + EvolutionSupportPrivate *private;
3259 +
3260 + private = g_static_private_get (&private_key);
3261 + g_return_if_fail (private != NULL);
3262 +
3263 + if (private->is_enabled)
3264 + deactivate_dbus_client ();
3265 +
3266 + g_static_private_set (&private_key, NULL, NULL);
3267 +}
3268 Index: src/plugins/evolution/tracker-evolution-registrar.c
3269 ===================================================================
3270 --- src/plugins/evolution/tracker-evolution-registrar.c (revision 0)
3271 +++ src/plugins/evolution/tracker-evolution-registrar.c (revision 0)
3272 @@ -0,0 +1,245 @@
3273 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3274 +/*
3275 + * Copyright (C) 2008, Nokia
3276 + *
3277 + * This library is free software; you can redistribute it and/or
3278 + * modify it under the terms of the GNU General Public
3279 + * License as published by the Free Software Foundation; either
3280 + * version 2 of the License, or (at your option) any later version.
3281 + *
3282 + * This library is distributed in the hope that it will be useful,
3283 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3284 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3285 + * General Public License for more details.
3286 + *
3287 + * You should have received a copy of the GNU General Public
3288 + * License along with this library; if not, write to the
3289 + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3290 + * Boston, MA 02110-1301, USA.
3291 + *
3292 + * Authors:
3293 + * Philip Van Hoof <philip@codeminded.be>
3294 + */
3295 +
3296 +#include "config.h"
3297 +
3298 +#include <libtracker-data/tracker-data-update.h>
3299 +#define __TRACKER_EVOLUTION_REGISTRAR_C__
3300 +#include "tracker-evolution-registrar.h"
3301 +#include "tracker-evolution-registrar-glue.h"
3302 +
3303 +const DBusGMethodInfo *registrar_methods = dbus_glib_tracker_evolution_registrar_methods;
3304 +
3305 +#define TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_EVOLUTION_REGISTRAR, TrackerEvolutionRegistrarPrivate))
3306 +
3307 +G_DEFINE_TYPE (TrackerEvolutionRegistrar, tracker_evolution_registrar, G_TYPE_OBJECT)
3308 +
3309 +/* This runs in-process of trackerd. It simply proxies everything to the indexer
3310 + * who wont always be running. Which is why this is needed (trackerd is always
3311 + * running, so it's more suitable to respond to Evolution's requests). */
3312 +
3313 +typedef struct {
3314 + DBusGProxy *idx_proxy;
3315 + DBusGConnection *connection;
3316 +} TrackerEvolutionRegistrarPrivate;
3317 +
3318 +enum {
3319 + PROP_0,
3320 + PROP_CONNECTION
3321 +};
3322 +
3323 +static void
3324 +tracker_evolution_registrar_finalize (GObject *object)
3325 +{
3326 + TrackerEvolutionRegistrarPrivate *priv = TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE (object);
3327 +
3328 + if (priv->idx_proxy)
3329 + g_object_unref (priv->idx_proxy);
3330 +
3331 + G_OBJECT_CLASS (tracker_evolution_registrar_parent_class)->finalize (object);
3332 +}
3333 +
3334 +static void
3335 +tracker_evolution_registrar_set_connection (TrackerEvolutionRegistrar *object,
3336 + DBusGConnection *connection)
3337 +{
3338 + TrackerEvolutionRegistrarPrivate *priv = TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE (object);
3339 +
3340 + priv->connection = connection; /* weak */
3341 +
3342 + priv->idx_proxy = dbus_g_proxy_new_for_name (priv->connection,
3343 + "org.freedesktop.Tracker.Indexer",
3344 + TRACKER_EVOLUTION_INDEXER_PATH,
3345 + TRACKER_EVOLUTION_REGISTRAR_INTERFACE);
3346 +}
3347 +
3348 +static void
3349 +tracker_evolution_registrar_set_property (GObject *object,
3350 + guint prop_id,
3351 + const GValue *value,
3352 + GParamSpec *pspec)
3353 +{
3354 + switch (prop_id) {
3355 + case PROP_CONNECTION:
3356 + tracker_evolution_registrar_set_connection (TRACKER_EVOLUTION_REGISTRAR (object),
3357 + g_value_get_pointer (value));
3358 + break;
3359 + default:
3360 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3361 + }
3362 +}
3363 +
3364 +static void
3365 +tracker_evolution_registrar_get_property (GObject *object,
3366 + guint prop_id,
3367 + GValue *value,
3368 + GParamSpec *pspec)
3369 +{
3370 + TrackerEvolutionRegistrarPrivate *priv = TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE (object);
3371 +
3372 + switch (prop_id) {
3373 + case PROP_CONNECTION:
3374 + g_value_set_pointer (value, priv->connection);
3375 + break;
3376 + default:
3377 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3378 + }
3379 +}
3380 +
3381 +static void
3382 +tracker_evolution_registrar_class_init (TrackerEvolutionRegistrarClass *klass)
3383 +{
3384 + GObjectClass *object_class = G_OBJECT_CLASS (klass);
3385 +
3386 + object_class->finalize = tracker_evolution_registrar_finalize;
3387 + object_class->set_property = tracker_evolution_registrar_set_property;
3388 + object_class->get_property = tracker_evolution_registrar_get_property;
3389 +
3390 + g_object_class_install_property (object_class,
3391 + PROP_CONNECTION,
3392 + g_param_spec_pointer ("connection",
3393 + "DBus connection",
3394 + "DBus connection",
3395 + G_PARAM_READWRITE |
3396 + G_PARAM_CONSTRUCT));
3397 +
3398 + g_type_class_add_private (object_class, sizeof (TrackerEvolutionRegistrarPrivate));
3399 +}
3400 +
3401 +static void
3402 +tracker_evolution_registrar_init (TrackerEvolutionRegistrar *object)
3403 +{
3404 +}
3405 +
3406 +void
3407 +tracker_evolution_registrar_set (TrackerEvolutionRegistrar *object,
3408 + const gchar *subject,
3409 + const GStrv predicates,
3410 + const GStrv values,
3411 + DBusGMethodInvocation *context,
3412 + GError *derror)
3413 +{
3414 + TrackerEvolutionRegistrarPrivate *priv = TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE (object);
3415 +
3416 + dbus_async_return_if_fail (subject != NULL, context);
3417 +
3418 + if (predicates && values) {
3419 +
3420 + dbus_async_return_if_fail (g_strv_length (predicates) ==
3421 + g_strv_length (values), context);
3422 +
3423 + dbus_g_proxy_call_no_reply (priv->idx_proxy,
3424 + "Set",
3425 + G_TYPE_STRING, subject,
3426 + G_TYPE_STRV, predicates,
3427 + G_TYPE_STRV, values,
3428 + G_TYPE_INVALID,
3429 + G_TYPE_INVALID);
3430 + }
3431 +
3432 + dbus_g_method_return (context);
3433 +}
3434 +
3435 +void
3436 +tracker_evolution_registrar_set_many (TrackerEvolutionRegistrar *object,
3437 + const GStrv subjects,
3438 + const GPtrArray *predicates,
3439 + const GPtrArray *values,
3440 + DBusGMethodInvocation *context,
3441 + GError *derror)
3442 +{
3443 + TrackerEvolutionRegistrarPrivate *priv = TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE (object);
3444 + guint len;
3445 +
3446 + dbus_async_return_if_fail (subjects != NULL, context);
3447 + dbus_async_return_if_fail (predicates != NULL, context);
3448 + dbus_async_return_if_fail (values != NULL, context);
3449 +
3450 + len = g_strv_length (subjects);
3451 +
3452 + dbus_async_return_if_fail (len == predicates->len, context);
3453 + dbus_async_return_if_fail (len == values->len, context);
3454 +
3455 + dbus_g_proxy_call_no_reply (priv->idx_proxy,
3456 + "SetMany",
3457 + G_TYPE_STRV, subjects,
3458 + TRACKER_TYPE_G_STRV_ARRAY, predicates,
3459 + TRACKER_TYPE_G_STRV_ARRAY, values,
3460 + G_TYPE_INVALID,
3461 + G_TYPE_INVALID);
3462 +
3463 + dbus_g_method_return (context);
3464 +}
3465 +
3466 +void
3467 +tracker_evolution_registrar_unset_many (TrackerEvolutionRegistrar *object,
3468 + const GStrv subjects,
3469 + DBusGMethodInvocation *context,
3470 + GError *derror)
3471 +{
3472 + TrackerEvolutionRegistrarPrivate *priv = TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE (object);
3473 +
3474 + dbus_async_return_if_fail (subjects != NULL, context);
3475 +
3476 + dbus_g_proxy_call_no_reply (priv->idx_proxy,
3477 + "UnsetMany",
3478 + G_TYPE_STRV, subjects,
3479 + G_TYPE_INVALID,
3480 + G_TYPE_INVALID);
3481 +
3482 + dbus_g_method_return (context);
3483 +}
3484 +
3485 +void
3486 +tracker_evolution_registrar_unset (TrackerEvolutionRegistrar *object,
3487 + const gchar *subject,
3488 + DBusGMethodInvocation *context,
3489 + GError *derror)
3490 +{
3491 + TrackerEvolutionRegistrarPrivate *priv = TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE (object);
3492 +
3493 + dbus_async_return_if_fail (subject != NULL, context);
3494 +
3495 + dbus_g_proxy_call_no_reply (priv->idx_proxy,
3496 + "Unset",
3497 + G_TYPE_STRING, subject,
3498 + G_TYPE_INVALID,
3499 + G_TYPE_INVALID);
3500 +
3501 + dbus_g_method_return (context);
3502 +}
3503 +
3504 +void
3505 +tracker_evolution_registrar_cleanup (TrackerEvolutionRegistrar *object,
3506 + DBusGMethodInvocation *context,
3507 + GError *derror)
3508 +{
3509 + TrackerEvolutionRegistrarPrivate *priv = TRACKER_EVOLUTION_REGISTRAR_GET_PRIVATE (object);
3510 +
3511 + dbus_g_proxy_call_no_reply (priv->idx_proxy,
3512 + "Cleanup",
3513 + G_TYPE_INVALID,
3514 + G_TYPE_INVALID);
3515 +
3516 + dbus_g_method_return (context);
3517 +}
3518 Index: src/plugins/Makefile.am
3519 ===================================================================
3520 --- src/plugins/Makefile.am (revision 0)
3521 +++ src/plugins/Makefile.am (revision 0)
3522 @@ -0,0 +1,6 @@
3523 +SUBDIRS = .
3524 +
3525 +if HAVE_EVOLUTION_PLUGIN
3526 +SUBDIRS += evolution
3527 +endif
3528 +
3529 Index: src/tracker-indexer/tracker-main.c
3530 ===================================================================
3531 --- src/tracker-indexer/tracker-main.c (revision 2782)
3532 +++ src/tracker-indexer/tracker-main.c (working copy)
3533 @@ -44,7 +44,10 @@
3534
3535 #include <libtracker-data/tracker-data-update.h>
3536 #include <libtracker-data/tracker-turtle.h>
3537 +#include <libtracker-data/tracker-data-manager.h>
3538
3539 +#include <plugins/evolution/tracker-evolution-indexer.h>
3540 +
3541 #include "tracker-dbus.h"
3542 #include "tracker-indexer.h"
3543
3544 @@ -254,11 +257,14 @@
3545 main (gint argc, gchar *argv[])
3546 {
3547 TrackerConfig *config;
3548 + TrackerLanguage *language;
3549 TrackerIndexer *indexer;
3550 TrackerDBManagerFlags flags = 0;
3551 GOptionContext *context;
3552 GError *error = NULL;
3553 gchar *filename;
3554 + TrackerDBIndex *file_index;
3555 + TrackerDBIndex *email_index;
3556
3557 g_type_init ();
3558
3559 @@ -296,6 +302,7 @@
3560
3561 /* Initialize logging */
3562 config = tracker_config_new ();
3563 + language = tracker_language_new (config);
3564
3565 if (verbosity > -1) {
3566 tracker_config_set_verbosity (config, verbosity);
3567 @@ -371,6 +378,15 @@
3568 tracker_indexer_process_modules (indexer, modules);
3569 }
3570
3571 + file_index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_FILE);
3572 + email_index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_EMAIL);
3573 +
3574 + tracker_data_manager_init (config, language, file_index, email_index);
3575 +
3576 +#ifdef HAVE_EVOLUTION_PLUGIN
3577 + tracker_evolution_storer_init (config, indexer);
3578 +#endif
3579 +
3580 tracker_turtle_init ();
3581
3582 g_message ("Starting...");
3583 @@ -383,15 +399,24 @@
3584
3585 tracker_turtle_shutdown ();
3586
3587 +
3588 if (quit_timeout_id) {
3589 g_source_remove (quit_timeout_id);
3590 }
3591
3592 g_main_loop_unref (main_loop);
3593 g_object_unref (indexer);
3594 +
3595 g_object_unref (config);
3596 + g_object_unref (language);
3597
3598 - tracker_thumbnailer_shutdown ();
3599 + tracker_data_manager_shutdown ();
3600 +
3601 +#ifdef HAVE_EVOLUTION_PLUGIN
3602 + tracker_evolution_storer_shutdown ();
3603 +#endif
3604 +
3605 + tracker_thumbnailer_shutdown ();
3606 tracker_dbus_shutdown ();
3607 tracker_db_index_manager_shutdown ();
3608 tracker_db_manager_shutdown ();
3609 Index: src/tracker-indexer/modules/evolution.c
3610 ===================================================================
3611 --- src/tracker-indexer/modules/evolution.c (revision 2782)
3612 +++ src/tracker-indexer/modules/evolution.c (working copy)
3613 @@ -26,7 +26,10 @@
3614
3615 #include "evolution-pop.h"
3616 #include "evolution-imap.h"
3617 +
3618 +#ifndef HAVE_EVOLUTION_PLUGIN
3619 #include "evolution-imap-db.h"
3620 +#endif
3621
3622 typedef enum MailStorageType MailStorageType;
3623
3624 @@ -34,7 +37,9 @@
3625 MAIL_STORAGE_NONE,
3626 MAIL_STORAGE_LOCAL,
3627 MAIL_STORAGE_IMAP,
3628 +#ifndef HAVE_EVOLUTION_PLUGIN
3629 MAIL_STORAGE_IMAP_DB
3630 +#endif
3631 };
3632
3633 static gchar *local_dir = NULL;
3634 @@ -76,9 +81,12 @@
3635 } else if (g_str_has_prefix (path, imap_dir)) {
3636 if (strcmp (basenam, "summary") == 0) {
3637 type = MAIL_STORAGE_IMAP;
3638 - } else if (strcmp (basenam, "folders.db") == 0) {
3639 + }
3640 +#ifndef HAVE_EVOLUTION_PLUGIN
3641 + else if (strcmp (basenam, "folders.db") == 0) {
3642 type = MAIL_STORAGE_IMAP_DB;
3643 }
3644 +#endif
3645 }
3646
3647 /* Exclude non wanted folders */
3648 @@ -110,9 +118,12 @@
3649 return tracker_evolution_pop_file_new (file);
3650 } else if (type == MAIL_STORAGE_IMAP) {
3651 return tracker_evolution_imap_file_new (file);
3652 - } else if (type == MAIL_STORAGE_IMAP_DB) {
3653 + }
3654 +#ifndef HAVE_EVOLUTION_PLUGIN
3655 + else if (type == MAIL_STORAGE_IMAP_DB) {
3656 return tracker_evolution_imap_db_file_new (file);
3657 }
3658 +#endif
3659
3660 return NULL;
3661 }
3662 Index: src/tracker-indexer/Makefile.am
3663 ===================================================================
3664 --- src/tracker-indexer/Makefile.am (revision 2782)
3665 +++ src/tracker-indexer/Makefile.am (working copy)
3666 @@ -17,6 +17,7 @@
3667 $(RAPTOR_CFLAGS) \
3668 $(GMODULE_CFLAGS)
3669
3670 +
3671 libtracker_moduledir = $(libdir)/tracker
3672 libtracker_moduleincludedir=$(includedir)/tracker-1.0/libtracker-module/
3673 libtracker_module_LTLIBRARIES = libtracker-module.la
3674 @@ -55,6 +56,7 @@
3675 $(top_builddir)/src/libtracker-db/libtracker-db.la \
3676 $(top_builddir)/src/libtracker-common/libtracker-common.la \
3677 $(top_builddir)/src/libstemmer/libstemmer.la \
3678 + $(top_builddir)/src/plugins/evolution/libtracker-evolution-indexer.la \
3679 $(trackerd_win_libs) \
3680 $(DBUS_LIBS) \
3681 $(GMODULE_LIBS) \
3682 Index: src/libtracker-data/tracker-data-update.c
3683 ===================================================================
3684 --- src/libtracker-data/tracker-data-update.c (revision 2782)
3685 +++ src/libtracker-data/tracker-data-update.c (working copy)
3686 @@ -607,6 +607,35 @@
3687 }
3688 }
3689
3690 +
3691 +void
3692 +tracker_data_update_delete_service_all (const gchar *rdf_type)
3693 +{
3694 + TrackerService *service;
3695 + gchar *service_type_id;
3696 + TrackerDBInterface *iface;
3697 +
3698 + if (!rdf_type)
3699 + return;
3700 +
3701 + service = tracker_ontology_get_service_by_name (rdf_type);
3702 +
3703 + g_return_if_fail (TRACKER_IS_SERVICE (service));
3704 +
3705 + service_type_id = tracker_gint_to_string (tracker_service_get_id (service));
3706 +
3707 + iface = tracker_db_manager_get_db_interface_by_type (tracker_service_get_name (service),
3708 + TRACKER_DB_CONTENT_TYPE_METADATA);
3709 +
3710 + tracker_db_interface_execute_procedure (iface,
3711 + NULL,
3712 + "DeleteServiceAll",
3713 + service_type_id,
3714 + NULL);
3715 +
3716 + g_free (service_type_id);
3717 +}
3718 +
3719 static void
3720 set_metadata (TrackerField *field,
3721 gpointer value,
3722 Index: src/libtracker-data/tracker-data-update.h
3723 ===================================================================
3724 --- src/libtracker-data/tracker-data-update.h (revision 2782)
3725 +++ src/libtracker-data/tracker-data-update.h (working copy)
3726 @@ -58,7 +58,9 @@
3727 GHashTable *metadata);
3728 void tracker_data_update_delete_service_by_path (const gchar *path,
3729 const gchar *rdf_type);
3730 +void tracker_data_update_delete_service_all (const gchar *rdf_type);
3731
3732 +
3733 /* Metadata */
3734 void tracker_data_update_set_metadata (TrackerService *service,
3735 guint32 service_id,
3736 Index: src/trackerd/tracker-main.c
3737 ===================================================================
3738 --- src/trackerd/tracker-main.c (revision 2782)
3739 +++ src/trackerd/tracker-main.c (working copy)
3740 @@ -53,8 +53,11 @@
3741 #include <libtracker-db/tracker-db-index.h>
3742 #include <libtracker-db/tracker-db-index-manager.h>
3743
3744 +#include <libtracker-data/tracker-data-manager.h>
3745 #include <libtracker-data/tracker-turtle.h>
3746
3747 +#include <plugins/evolution/tracker-evolution.h>
3748 +
3749 #include "tracker-crawler.h"
3750 #include "tracker-dbus.h"
3751 #include "tracker-indexer-client.h"
3752 @@ -1030,11 +1033,11 @@
3753 return EXIT_FAILURE;
3754 }
3755
3756 + tracker_module_config_init ();
3757 +
3758 tracker_turtle_init ();
3759 tracker_thumbnailer_init (config);
3760
3761 - tracker_module_config_init ();
3762 -
3763 flags |= TRACKER_DB_MANAGER_REMOVE_CACHE;
3764 index_flags |= TRACKER_DB_INDEX_MANAGER_READONLY;
3765
3766 @@ -1132,6 +1135,10 @@
3767 return EXIT_FAILURE;
3768 }
3769
3770 +#ifdef HAVE_EVOLUTION_PLUGIN
3771 + tracker_evolution_init (config);
3772 +#endif
3773 +
3774 g_message ("Waiting for DBus requests...");
3775
3776 /* Set our status as running, if this is FALSE, threads stop
3777 @@ -1202,6 +1209,11 @@
3778 shutdown_directories ();
3779
3780 /* Shutdown major subsystems */
3781 +
3782 +#ifdef HAVE_EVOLUTION_PLUGIN
3783 + tracker_evolution_shutdown ();
3784 +#endif
3785 +
3786 tracker_cleanup_shutdown ();
3787 tracker_xesam_manager_shutdown ();
3788 tracker_dbus_shutdown ();
3789 Index: src/trackerd/Makefile.am
3790 ===================================================================
3791 --- src/trackerd/Makefile.am (revision 2782)
3792 +++ src/trackerd/Makefile.am (working copy)
3793 @@ -77,6 +77,7 @@
3794 $(top_builddir)/src/libtracker-db/libtracker-db.la \
3795 $(top_builddir)/src/libtracker-common/libtracker-common.la \
3796 $(top_builddir)/src/libstemmer/libstemmer.la \
3797 + $(top_builddir)/src/plugins/evolution/libtracker-evolution.la \
3798 $(inotify_libs) \
3799 $(GMIME_LIBS) \
3800 $(FAM_LIBS) \
3801 Index: src/Makefile.am
3802 ===================================================================
3803 --- src/Makefile.am (revision 2782)
3804 +++ src/Makefile.am (working copy)
3805 @@ -37,6 +37,7 @@
3806 libtracker-data \
3807 libtracker \
3808 $(build_sqlite_fts) \
3809 + plugins \
3810 trackerd \
3811 tracker-utils \
3812 tracker-extract \
3813 @@ -62,4 +63,5 @@
3814 libtracker-gtk \
3815 tracker-applet \
3816 tracker-search-tool \
3817 - tracker-preferences
3818 + tracker-preferences \
3819 + plugins
3820 Index: configure.ac
3821 ===================================================================
3822 --- configure.ac (revision 2782)
3823 +++ configure.ac (working copy)
3824 @@ -120,6 +120,8 @@
3825 LIBGSF_REQUIRED=1.13
3826 EXEMPI_REQUIRED=1.99.2
3827 HILDON_THUMBNAIL_REQUIRED=3.0.10
3828 +EVO_REQUIRED=2.25.5
3829 +EDS_REQUIRED=2.25.5
3830
3831 # Library Checks
3832 PKG_CHECK_MODULES(GLIB2, [glib-2.0 >= $GLIB_REQUIRED])
3833 @@ -181,6 +183,28 @@
3834 AC_DEFINE(HAVE_RAPTOR, 1, [Raptor RDF parsers])
3835 fi
3836
3837 +# Check for Evolution's plugin system
3838 +PKG_CHECK_MODULES(EVOPLUG, [
3839 + evolution-plugin >= $EVO_REQUIRED
3840 + evolution-data-server-1.2 >= $EDS_REQUIRED],
3841 + have_evoplug=yes, have_evoplug=no)
3842 +AC_SUBST(EVOPLUG_CFLAGS)
3843 +AC_SUBST(EVOPLUG_LIBS)
3844 +
3845 +if test x$have_evoplug == "xyes"; then
3846 +EVOLUTION_PLUGIN_INSTALL_DIR=`$PKG_CONFIG evolution-plugin --variable=plugindir`
3847 +else
3848 +EVOLUTION_PLUGIN_INSTALL_DIR=/dev/null
3849 +fi
3850 +
3851 +AC_SUBST(EVOLUTION_PLUGIN_INSTALL_DIR)
3852 +
3853 +if test x$have_evoplug == "xyes"; then
3854 + AC_DEFINE(HAVE_EVOLUTION_PLUGIN, 1, [Evolution plugin])
3855 +fi
3856 +
3857 +AM_CONDITIONAL(HAVE_EVOLUTION_PLUGIN, test "$have_evoplug" = "yes")
3858 +
3859 # Check we have the DBUS binding tool we need
3860 AC_PATH_PROG(DBUSBINDINGTOOL, dbus-binding-tool)
3861 if test -z $DBUSBINDINGTOOL; then
3862 @@ -1199,6 +1223,8 @@
3863 src/tracker-search-tool/Makefile
3864 src/tracker-search-tool/tracker-search-tool.desktop.in
3865 src/tracker-utils/Makefile
3866 + src/plugins/Makefile
3867 + src/plugins/evolution/Makefile
3868 tests/common/Makefile
3869 tests/libtracker-common/Makefile
3870 tests/libtracker-db/Makefile
3871 @@ -1256,6 +1282,11 @@
3872 Support MP3 album art (w/ GdkPixbuf): $have_gdkpixbuf
3873 Support Playlists (w/ Totem): $have_playlist
3874
3875 +Plugins:
3876 +
3877 + Evolution support (old): yes
3878 + Evolution plugin: $have_evoplug
3879 +
3880 Warning:
3881
3882 You must make sure SQLite is compiled with --enable-threadsafe
3883 Index: data/db/sqlite-stored-procs.sql
3884 ===================================================================
3885 --- data/db/sqlite-stored-procs.sql (revision 2782)
3886 +++ data/db/sqlite-stored-procs.sql (working copy)
3887 @@ -171,6 +171,11 @@
3888 GetXesamMimePrefixForServiceId SELECT MimePrefix FROM XesamFileMimePrefixes WHERE ServiceTypeId = ?;
3889
3890 /*
3891 + * Turtle importing
3892 + */
3893 +DeleteServiceAll DELETE FROM Services WHERE ServiceTypeID = ?;
3894 +
3895 +/*
3896 * Deprecated
3897 */
3898 GetNewID SELECT OptionValue FROM Options WHERE OptionKey = 'Sequence';
3899 Index: data/db/sqlite-tracker.sql
3900 ===================================================================
3901 --- data/db/sqlite-tracker.sql (revision 2782)
3902 +++ data/db/sqlite-tracker.sql (working copy)
3903 @@ -8,6 +8,7 @@
3904 insert Into Options (OptionKey, OptionValue) values ('Sequence', '1');
3905 insert Into Options (OptionKey, OptionValue) values ('EventSequence', '1');
3906 insert Into Options (OptionKey, OptionValue) values ('UpdateCount', '0');
3907 +insert Into Options (OptionKey, OptionValue) values ('EvolutionLastCheckout', '0');
3908
3909
3910 /* store volume and HAL info here for files */
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.