1 /** Google Calendar plugin
3 * Copyright (c) 2006 Eduardo Pereira Habkost <ehabkost@raisama.net>
4 * Copyright (c) 2008 Adenilson Cavalcanti da Silva <adenilson.silva@indt.org.br>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 * - commitchange/applychanges: report gdata entries directly and rely on
25 * gdata format plugin to do the conversion between formats.
26 * - commitchanges: report back updated fields, when ADDED (ID/updated/edit_url) or
27 * UPDATED (updated/edit_url)
28 * - review code for leaks (I'm not sure if I'm using opensync API correctly...)
32 #include <opensync/opensync.h>
33 #include <opensync/opensync-plugin.h>
34 #include <opensync/opensync-helper.h>
35 #include <opensync/opensync-merger.h>
36 #include <opensync/opensync-format.h>
37 #include <opensync/opensync-data.h>
38 #include <opensync/opensync-version.h>
42 #include <libxml/tree.h>
47 #include <sys/types.h>
50 #include <gcal_status.h>
51 #include <gcalendar.h>
60 char *gcal_anchor_path
;
61 char *gcont_anchor_path
;
64 /* libgcal resources */
69 struct gcal_event_array all_events
;
70 struct gcal_contact_array all_contacts
;
71 /* calendar sink/format */
72 OSyncObjTypeSink
*gcal_sink
;
73 OSyncObjFormat
*gcal_format
;
74 /* contact sink/format */
75 OSyncObjTypeSink
*gcont_sink
;
76 OSyncObjFormat
*gcont_format
;
77 /* XSLT context resource struct */
78 struct xslt_resources
*xslt_ctx_gcal
;
79 struct xslt_resources
*xslt_ctx_gcont
;
82 static void free_plg(struct gc_plgdata
*plgdata
)
84 if (plgdata
->calendar
) {
85 gcal_delete(plgdata
->calendar
);
86 gcal_cleanup_events(&(plgdata
->all_events
));
88 if (plgdata
->contacts
) {
89 gcal_delete(plgdata
->contacts
);
90 gcal_cleanup_contacts(&(plgdata
->all_contacts
));
93 if (plgdata
->gcal_anchor_path
)
94 free(plgdata
->gcal_anchor_path
);
95 if (plgdata
->gcont_anchor_path
)
96 free(plgdata
->gcont_anchor_path
);
97 if (plgdata
->xslt_path
)
98 free(plgdata
->xslt_path
);
99 if (plgdata
->xslt_ctx_gcal
)
100 xslt_delete(plgdata
->xslt_ctx_gcal
);
101 if (plgdata
->xslt_ctx_gcont
)
102 xslt_delete(plgdata
->xslt_ctx_gcont
);
103 if (plgdata
->cal_timestamp
)
104 free(plgdata
->cal_timestamp
);
105 if (plgdata
->cont_timestamp
)
106 free(plgdata
->cont_timestamp
);
107 if (plgdata
->timezone
)
108 free(plgdata
->timezone
);
110 xmlFree(plgdata
->url
);
111 if (plgdata
->username
)
112 xmlFree(plgdata
->username
);
113 if (plgdata
->password
)
114 xmlFree(plgdata
->password
);
115 if (plgdata
->gcal_sink
)
116 osync_objtype_sink_unref(plgdata
->gcal_sink
);
117 if (plgdata
->gcal_format
)
118 osync_objformat_unref(plgdata
->gcal_format
);
122 static void gc_connect(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
124 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
125 static int counter
= 0;
127 struct gc_plgdata
*plgdata
= data
;
128 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
129 OSyncError
*error
= NULL
;
132 if ((plgdata
->calendar
) && (counter
== 0)) {
133 result
= gcal_get_authentication(plgdata
->calendar
, plgdata
->username
,
139 snprintf(buffer
, sizeof(buffer
) - 1, "%s/gcal2osync.xslt",
141 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcal
, buffer
)))
143 osync_trace(TRACE_INTERNAL
, "\ndone calendar: %s\n", buffer
);
146 if (((plgdata
->contacts
) && (counter
== 1)) ||
147 ((plgdata
->gcont_sink
) && (!plgdata
->gcal_sink
))) {
148 result
= gcal_get_authentication(plgdata
->contacts
, plgdata
->username
,
154 snprintf(buffer
, sizeof(buffer
) - 1, "%s/gcont2osync.xslt",
156 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcont
, buffer
)))
158 osync_trace(TRACE_INTERNAL
, "\ndone contact: %s\n", buffer
);
161 osync_context_report_success(ctx
);
162 osync_trace(TRACE_EXIT
, "%s", __func__
);
166 osync_trace(TRACE_INTERNAL
, "\nGood bye, cruel world...\n");
167 osync_context_report_osyncerror(ctx
, &error
);
170 static void gc_get_changes_calendar(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
172 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
174 static int counter
= 0;
175 struct gc_plgdata
*plgdata
= data
;
176 char slow_sync_flag
= 0;
177 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
178 OSyncError
*error
= NULL
;
179 OSyncXMLFormat
*xmlformat
;
180 OSyncData
*odata
= NULL
;
181 OSyncChange
*chg
= NULL
;
183 char *timestamp
= NULL
, *msg
, *raw_xml
= NULL
;
186 if (!plgdata
->gcal_sink
)
188 timestamp
= osync_anchor_retrieve(plgdata
->gcal_anchor_path
, "gcalendar");
190 osync_trace(TRACE_INTERNAL
, "timestamp is: %s\n", timestamp
);
192 osync_trace(TRACE_INTERNAL
, "first sync!\n");
194 if (osync_objtype_sink_get_slowsync(plgdata
->gcal_sink
) || !timestamp
) {
195 osync_trace(TRACE_INTERNAL
, "\n\t\tgcal: Client asked for slow syncing...\n");
197 result
= gcal_get_events(plgdata
->calendar
, &(plgdata
->all_events
));
200 osync_trace(TRACE_INTERNAL
, "\n\t\tgcal: Client asked for fast syncing...\n");
201 result
= gcal_get_updated_events(plgdata
->calendar
,
202 &(plgdata
->all_events
),
207 msg
= "Failed getting events!";
211 /* Calendar returns most recently updated event as first element */
212 event
= gcal_event_element(&(plgdata
->all_events
), 0);
215 plgdata
->cont_timestamp
= strdup(gcal_event_get_updated(event
));
216 if (!plgdata
->cont_timestamp
) {
217 msg
= "Failed copying event timestamp!\n";
221 osync_trace(TRACE_INTERNAL
, "gcalendar: got then all!\n");
222 for (i
= 0; i
< plgdata
->all_events
.length
; ++i
) {
223 event
= gcal_event_element(&(plgdata
->all_events
), i
);
227 raw_xml
= gcal_event_get_xml(event
);
228 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcal
,
232 raw_xml
= plgdata
->xslt_ctx_gcal
->xml_str
;
233 xmlformat
= osync_xmlformat_parse(raw_xml
,
239 osync_xmlformat_sort(xmlformat
);
240 odata
= osync_data_new((char *)xmlformat
,
241 osync_xmlformat_size(),
242 plgdata
->gcal_format
, &error
);
246 if (!(chg
= osync_change_new(&error
)))
248 osync_data_set_objtype(odata
, osync_objtype_sink_get_name(plgdata
->gcal_sink
));
249 osync_change_set_data(chg
, odata
);
250 osync_data_unref(odata
);
252 osync_change_set_uid(chg
, gcal_event_get_url(event
));
255 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_ADDED
);
257 if (gcal_event_is_deleted(event
))
258 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_DELETED
);
260 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_MODIFIED
);
262 osync_context_report_change(ctx
, chg
);
263 osync_change_unref(chg
);
266 /* Load XSLT style to convert osync xmlformat-event --> gdata */
267 snprintf(buffer
, sizeof(buffer
) - 1, "%s/osync2gcal.xslt",
269 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcal
, buffer
)))
271 osync_trace(TRACE_INTERNAL
, "\ndone calendar: %s\n", buffer
);
275 osync_context_report_success(ctx
);
279 osync_error_unref(&error
);
280 osync_xmlformat_unref(&xmlformat
);
283 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
288 static void gc_get_changes_contact(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
290 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
292 static int counter
= 0;
293 struct gc_plgdata
*plgdata
= data
;
294 char slow_sync_flag
= 0;
295 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
296 OSyncError
*error
= NULL
;
297 OSyncXMLFormat
*xmlformat
;
298 OSyncData
*odata
= NULL
;
299 OSyncChange
*chg
= NULL
;
301 char *timestamp
= NULL
, *msg
, *raw_xml
= NULL
;
302 gcal_contact contact
;
305 if (!plgdata
->gcont_sink
)
307 timestamp
= osync_anchor_retrieve(plgdata
->gcal_anchor_path
, "gcontact");
308 if (osync_objtype_sink_get_slowsync(plgdata
->gcont_sink
) || !timestamp
) {
309 osync_trace(TRACE_INTERNAL
, "\n\t\tgcont: Client asked for slow syncing...\n");
311 result
= gcal_get_contacts(plgdata
->contacts
, &(plgdata
->all_contacts
));
314 osync_trace(TRACE_INTERNAL
, "\n\t\tgcont: Client asked for fast syncing...\n");
315 result
= gcal_get_updated_contacts(plgdata
->contacts
,
316 &(plgdata
->all_contacts
),
321 msg
= "Failed getting contacts!";
325 /* Contacts returns most recently updated entry as last element */
326 contact
= gcal_contact_element(&(plgdata
->all_contacts
),
327 (plgdata
->all_contacts
.length
- 1));
330 plgdata
->cont_timestamp
= strdup(gcal_contact_get_updated(contact
));
331 if (!plgdata
->cont_timestamp
) {
332 msg
= "Failed copying contact timestamp!\n";
336 osync_trace(TRACE_INTERNAL
, "gcontact: got then all!\n");
337 for (i
= 0; i
< plgdata
->all_contacts
.length
; ++i
) {
338 contact
= gcal_contact_element(&(plgdata
->all_contacts
), i
);
342 raw_xml
= gcal_contact_get_xml(contact
);
343 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcont
,
346 raw_xml
= plgdata
->xslt_ctx_gcont
->xml_str
;
347 xmlformat
= osync_xmlformat_parse(raw_xml
,
353 fprintf(stderr
, "gcont: %s\nosync: %s\n", gcal_contact_get_xml(contact
),
356 osync_xmlformat_sort(xmlformat
);
357 odata
= osync_data_new((char *)xmlformat
,
358 osync_xmlformat_size(),
359 plgdata
->gcont_format
, &error
);
363 if (!(chg
= osync_change_new(&error
)))
365 osync_data_set_objtype(odata
, osync_objtype_sink_get_name(plgdata
->gcont_sink
));
366 osync_change_set_data(chg
, odata
);
367 osync_data_unref(odata
);
369 osync_change_set_uid(chg
, gcal_contact_get_url(contact
));
372 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_ADDED
);
374 if (gcal_contact_is_deleted(contact
))
375 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_DELETED
);
377 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_MODIFIED
);
379 osync_context_report_change(ctx
, chg
);
380 osync_change_unref(chg
);
383 /* Load XSLT style to convert osync xmlformat-contact --> gdata */
384 snprintf(buffer
, sizeof(buffer
) - 1, "%s/osync2gcont.xslt",
386 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcont
, buffer
)))
388 osync_trace(TRACE_INTERNAL
, "\ndone contact: %s\n", buffer
);
392 osync_context_report_success(ctx
);
396 osync_error_unref(&error
);
397 osync_xmlformat_unref(&xmlformat
);
400 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
403 static void gc_commit_change_calendar(void *data
, OSyncPluginInfo
*info
,
404 OSyncContext
*ctx
, OSyncChange
*change
)
406 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
, change
);
407 osync_trace(TRACE_INTERNAL
, "hello, from calendar!\n");
408 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
409 struct gc_plgdata
*plgdata
= data
;
410 gcal_event event
= NULL
;
413 char *osync_xml
= NULL
, *msg
= NULL
, *raw_xml
= NULL
, *updated_event
= NULL
;
414 OSyncData
*odata
= NULL
;
416 if (!(odata
= osync_change_get_data(change
))) {
417 msg
= "Cannot get raw data from change obj!\n";
421 osync_data_get_data(odata
, &osync_xml
, &size
);
423 msg
= "Failed getting xml from change obj!\n";
427 /* Convert to gdata format */
428 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcal
, osync_xml
))) {
429 msg
= "Failed converting from osync xmlevent to gcalendar\n";
432 raw_xml
= plgdata
->xslt_ctx_gcal
->xml_str
;
434 switch (osync_change_get_changetype(change
)) {
435 case OSYNC_CHANGE_TYPE_ADDED
:
436 result
= gcal_add_xmlentry(plgdata
->calendar
, raw_xml
, &updated_event
);
438 msg
= "Failed adding new event!\n";
442 if (!(event
= gcal_event_new(updated_event
))) {
443 msg
= "Failed recovering updated fields!\n";
448 case OSYNC_CHANGE_TYPE_MODIFIED
:
449 result
= gcal_update_xmlentry(plgdata
->calendar
, raw_xml
, &updated_event
,
452 msg
= "Failed editing event!\n";
456 if (!(event
= gcal_event_new(updated_event
))) {
457 msg
= "Failed recovering updated fields!\n";
462 case OSYNC_CHANGE_TYPE_DELETED
:
463 result
= gcal_erase_xmlentry(plgdata
->calendar
, raw_xml
);
465 msg
= "Failed deleting event!\n";
471 osync_context_report_error(ctx
, OSYNC_ERROR_NOT_SUPPORTED
,
472 "Unknown change type");
484 /* Inform the new ID */
485 osync_change_set_uid(change
, gcal_event_get_url(event
));
486 gcal_event_delete(event
);
490 osync_context_report_success(ctx
);
492 osync_trace(TRACE_EXIT
, "%s", __func__
);
496 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
499 static void gc_commit_change_contact(void *data
, OSyncPluginInfo
*info
,
500 OSyncContext
*ctx
, OSyncChange
*change
)
502 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
, change
);
503 osync_trace(TRACE_INTERNAL
, "hello, from contacts!\n");
505 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
506 struct gc_plgdata
*plgdata
= data
;
507 gcal_contact contact
= NULL
;
509 char *osync_xml
= NULL
, *msg
= NULL
, *raw_xml
= NULL
, *updated_contact
= NULL
;
510 OSyncData
*odata
= NULL
;
512 if (!(odata
= osync_change_get_data(change
))) {
513 msg
= "Cannot get raw data from change obj!\n";
517 osync_data_get_data(odata
, &osync_xml
, &size
);
519 msg
= "Failed getting xml from change obj!\n";
523 /* Convert to gdata format */
524 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcont
, osync_xml
))) {
525 msg
= "Failed converting from osync xmlcontact to gcontact\n";
528 raw_xml
= plgdata
->xslt_ctx_gcont
->xml_str
;
530 fprintf(stderr
, "osync: %s\ngcont: %s\n\n", osync_xml
, raw_xml
);
532 switch (osync_change_get_changetype(change
)) {
533 case OSYNC_CHANGE_TYPE_ADDED
:
534 result
= gcal_add_xmlentry(plgdata
->contacts
, raw_xml
, &updated_contact
);
536 msg
= "Failed adding new contact!\n";
540 if (!(contact
= gcal_contact_new(updated_contact
))) {
541 msg
= "Failed recovering updated fields!\n";
546 case OSYNC_CHANGE_TYPE_MODIFIED
:
547 result
= gcal_update_xmlentry(plgdata
->contacts
, raw_xml
, &updated_contact
,
550 msg
= "Failed editing event!\n";
554 if (!(contact
= gcal_contact_new(updated_contact
))) {
555 msg
= "Failed recovering updated fields!\n";
560 case OSYNC_CHANGE_TYPE_DELETED
:
561 result
= gcal_erase_xmlentry(plgdata
->contacts
, raw_xml
);
563 msg
= "Failed deleting event!\n";
569 osync_context_report_error(ctx
, OSYNC_ERROR_NOT_SUPPORTED
,
570 "Unknown change type");
579 free(updated_contact
);
582 osync_change_set_uid(change
, gcal_contact_get_url(contact
));
583 gcal_contact_delete(contact
);
586 osync_context_report_success(ctx
);
587 osync_trace(TRACE_EXIT
, "%s", __func__
);
591 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
595 static void gc_sync_done(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
597 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
598 struct gc_plgdata
*plgdata
= NULL
;
602 osync_anchor_update(plgdata
->gcal_anchor_path
, "gcalendar", plgdata
->cal_timestamp
);
603 osync_anchor_update(plgdata
->gcont_anchor_path
, "gcontact", plgdata
->cont_timestamp
);
606 static void gc_disconnect(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
608 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
609 struct gc_plgdata
*plgdata
= data
;
611 osync_context_report_success(ctx
);
612 osync_trace(TRACE_EXIT
, "%s", __func__
);
615 static void gc_finalize(void *data
)
617 osync_trace(TRACE_ENTRY
, "%s(%p)", __func__
, data
);
618 struct gc_plgdata
*plgdata
= data
;
621 osync_trace(TRACE_EXIT
, "%s", __func__
);
624 static void *gc_initialize(OSyncPlugin
*plugin
,
625 OSyncPluginInfo
*info
,
628 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, plugin
, info
, error
);
629 struct gc_plgdata
*plgdata
;
630 OSyncPluginConfig
*config
;
631 OSyncPluginAuthentication
*auth
;
632 OSyncPluginAdvancedOption
*advanced
;
633 OSyncList
*resources
;
635 const char *objtype
, *tmp
;
638 plgdata
= osync_try_malloc0(sizeof(struct gc_plgdata
), error
);
639 config
= osync_plugin_info_get_config(info
);
640 if ((!plgdata
) || (!config
)) {
641 osync_error_set(error
, OSYNC_ERROR_GENERIC
,
642 "Unable to get config data.");
646 advanced
= osync_plugin_config_get_advancedoption_value_by_name(config
, "xslt");
648 osync_trace(TRACE_INTERNAL
, "Cannot locate xslt config!\n");
652 if (!(plgdata
->xslt_path
= strdup(osync_plugin_advancedoption_get_value(advanced
))))
655 resources
= osync_plugin_config_get_resources(config
);
656 numobjs
= osync_plugin_info_num_objtypes(info
);
658 for (i
= 1, r
= resources
; r
; r
= r
->next
, i
++) {
659 osync_trace(TRACE_INTERNAL
, "field: %s\n", osync_plugin_resource_get_objtype(r
->data
));
660 if (!(strcmp(osync_plugin_resource_get_objtype(r
->data
), "event")))
661 if (!(plgdata
->calendar
= gcal_new(GCALENDAR
)))
664 osync_trace(TRACE_INTERNAL
, "\tcreated calendar obj!\n");
665 gcal_set_store_xml(plgdata
->calendar
, 1);
668 if (!(strcmp(osync_plugin_resource_get_objtype(r
->data
), "contact")))
669 if (!(plgdata
->contacts
= gcal_new(GCONTACT
)))
672 osync_trace(TRACE_INTERNAL
, "\tcreated contact obj!\n");
673 gcal_set_store_xml(plgdata
->contacts
, 1);
679 /* TODO: how works resource policy? For while, copy everything... */
680 for (i
= 0; i
< numobjs
; i
++) {
682 if (!plgdata
->username
) {
683 auth
= osync_plugin_config_get_authentication(config
);
684 tmp
= osync_plugin_authentication_get_username(auth
);
688 if (!(plgdata
->username
= strdup(tmp
)))
693 if (!plgdata
->password
) {
694 tmp
= osync_plugin_authentication_get_password(auth
);
698 if (!(plgdata
->password
= strdup(tmp
)))
702 /* TODO: get proxy/calendar title/resources/etc */
706 OSyncObjTypeSinkFunctions functions_gcal
;
707 memset(&functions_gcal
, 0, sizeof(functions_gcal
));
708 functions_gcal
.connect
= gc_connect
;
709 functions_gcal
.get_changes
= gc_get_changes_calendar
;
710 functions_gcal
.commit
= gc_commit_change_calendar
;
711 functions_gcal
.disconnect
= gc_disconnect
;
712 functions_gcal
.sync_done
= gc_sync_done
;
715 if (plgdata
->calendar
) {
716 osync_trace(TRACE_INTERNAL
, "\tcreating calendar sink...\n");
717 OSyncFormatEnv
*formatenv1
= osync_plugin_info_get_format_env(info
);
718 plgdata
->gcal_format
= osync_format_env_find_objformat(formatenv1
, "xmlformat-event-doc");
719 if (!plgdata
->gcal_format
)
721 osync_objformat_ref(plgdata
->gcal_format
);
723 plgdata
->gcal_sink
= osync_plugin_info_find_objtype(info
, "event");
724 if (!plgdata
->gcal_sink
)
727 osync_objtype_sink_set_functions(plgdata
->gcal_sink
, functions_gcal
, plgdata
);
728 osync_plugin_info_add_objtype(info
, plgdata
->gcal_sink
);
732 OSyncObjTypeSinkFunctions functions_gcont
;
733 memset(&functions_gcont
, 0, sizeof(functions_gcont
));
734 functions_gcont
.connect
= gc_connect
;
735 functions_gcont
.get_changes
= gc_get_changes_contact
;
736 functions_gcont
.commit
= gc_commit_change_contact
;
737 functions_gcont
.disconnect
= gc_disconnect
;
738 functions_gcont
.sync_done
= gc_sync_done
;
740 if (plgdata
->contacts
) {
741 osync_trace(TRACE_INTERNAL
, "\tcreating contact sink...\n");
742 OSyncFormatEnv
*formatenv2
= osync_plugin_info_get_format_env(info
);
743 plgdata
->gcont_format
= osync_format_env_find_objformat(formatenv2
, "xmlformat-contact-doc");
744 if (!plgdata
->gcont_format
)
746 osync_objformat_ref(plgdata
->gcont_format
);
748 plgdata
->gcont_sink
= osync_plugin_info_find_objtype(info
, "contact");
749 if (!plgdata
->gcont_sink
)
752 osync_objtype_sink_set_functions(plgdata
->gcont_sink
, functions_gcont
, plgdata
);
753 osync_plugin_info_add_objtype(info
, plgdata
->gcont_sink
);
758 plgdata
->gcal_anchor_path
= g_strdup_printf("%s/calendar_anchor.db",
759 osync_plugin_info_get_configdir(info
));
760 if (!(plgdata
->gcal_anchor_path
))
763 osync_trace(TRACE_INTERNAL
, "\tanchor: %s\n", plgdata
->gcal_anchor_path
);
765 plgdata
->gcont_anchor_path
= g_strdup_printf("%s/contact_anchor.db",
766 osync_plugin_info_get_configdir(info
));
767 if (!(plgdata
->gcont_anchor_path
))
770 osync_trace(TRACE_INTERNAL
, "\tanchor: %s\n", plgdata
->gcont_anchor_path
);
772 if (plgdata
->calendar
)
773 if (!(plgdata
->xslt_ctx_gcal
= xslt_new()))
776 osync_trace(TRACE_INTERNAL
, "\tsucceed creating xslt_gcal!\n");
778 if (plgdata
->contacts
)
779 if (!(plgdata
->xslt_ctx_gcont
= xslt_new()))
782 osync_trace(TRACE_INTERNAL
, "\tsucceed creating xslt_gcont!\n");
784 osync_trace(TRACE_EXIT
, "%s", __func__
);
792 osync_trace(TRACE_EXIT_ERROR
, "%s: %s", __func__
, osync_error_print(error
));
796 static osync_bool
gc_discover(void *data
, OSyncPluginInfo
*info
, OSyncError
**error
)
798 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, error
);
800 struct gc_plgdata
*plgdata
= data
;
802 if (plgdata
->calendar
)
803 osync_objtype_sink_set_available(plgdata
->gcal_sink
, TRUE
);
804 if (plgdata
->contacts
)
805 osync_objtype_sink_set_available(plgdata
->gcont_sink
, TRUE
);
807 OSyncVersion
*version
= osync_version_new(error
);
808 osync_version_set_plugin(version
, "google-data");
809 osync_plugin_info_set_version(info
, version
);
810 osync_version_unref(version
);
812 osync_trace(TRACE_EXIT
, "%s", __func__
);
816 osync_bool
get_sync_info(OSyncPluginEnv
*env
, OSyncError
**error
)
818 osync_trace(TRACE_ENTRY
, "%s(%p, %p)", __func__
, env
, error
);
819 OSyncPlugin
*plugin
= osync_plugin_new(error
);
823 osync_plugin_set_name(plugin
, "google-data");
824 osync_plugin_set_longname(plugin
, "Google calendar/plugin");
825 osync_plugin_set_description(plugin
, "Google calendar and contacts plugin");
827 osync_plugin_set_initialize(plugin
, gc_initialize
);
828 osync_plugin_set_finalize(plugin
, gc_finalize
);
829 osync_plugin_set_discover(plugin
, gc_discover
);
831 osync_plugin_env_register_plugin(env
, plugin
);
832 osync_plugin_unref(plugin
);
834 osync_trace(TRACE_EXIT
, "%s", __func__
);
838 osync_trace(TRACE_EXIT_ERROR
, "Unable to register: %s", osync_error_print(error
));
839 osync_error_unref(error
);
843 int get_version(void)