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 * - find a way to report changes to opensync and make it work
25 * - review code for leaks (I'm not sure if I'm using opensync API correctly...)
29 #include <opensync/opensync.h>
30 #include <opensync/opensync-plugin.h>
31 #include <opensync/opensync-helper.h>
32 #include <opensync/opensync-merger.h>
33 #include <opensync/opensync-format.h>
34 #include <opensync/opensync-data.h>
35 #include <opensync/opensync-version.h>
39 #include <libxml/tree.h>
44 #include <sys/types.h>
47 #include <gcal_status.h>
48 #include <gcalendar.h>
57 char *gcal_anchor_path
;
58 char *gcont_anchor_path
;
61 /* libgcal resources */
66 struct gcal_event_array all_events
;
67 struct gcal_contact_array all_contacts
;
68 /* calendar sink/format */
69 OSyncObjTypeSink
*gcal_sink
;
70 OSyncObjFormat
*gcal_format
;
71 /* contact sink/format */
72 OSyncObjTypeSink
*gcont_sink
;
73 OSyncObjFormat
*gcont_format
;
74 /* XSLT context resource struct */
75 struct xslt_resources
*xslt_ctx_gcal
;
76 struct xslt_resources
*xslt_ctx_gcont
;
79 static void free_plg(struct gc_plgdata
*plgdata
)
81 if (plgdata
->calendar
) {
82 gcal_delete(plgdata
->calendar
);
83 gcal_cleanup_events(&(plgdata
->all_events
));
85 if (plgdata
->contacts
) {
86 gcal_delete(plgdata
->contacts
);
87 gcal_cleanup_contacts(&(plgdata
->all_contacts
));
90 if (plgdata
->gcal_anchor_path
)
91 free(plgdata
->gcal_anchor_path
);
92 if (plgdata
->gcont_anchor_path
)
93 free(plgdata
->gcont_anchor_path
);
94 if (plgdata
->xslt_path
)
95 free(plgdata
->xslt_path
);
96 if (plgdata
->xslt_ctx_gcal
)
97 xslt_delete(plgdata
->xslt_ctx_gcal
);
98 if (plgdata
->xslt_ctx_gcont
)
99 xslt_delete(plgdata
->xslt_ctx_gcont
);
100 if (plgdata
->cal_timestamp
)
101 free(plgdata
->cal_timestamp
);
102 if (plgdata
->cont_timestamp
)
103 free(plgdata
->cont_timestamp
);
104 if (plgdata
->timezone
)
105 free(plgdata
->timezone
);
107 xmlFree(plgdata
->url
);
108 if (plgdata
->username
)
109 xmlFree(plgdata
->username
);
110 if (plgdata
->password
)
111 xmlFree(plgdata
->password
);
112 if (plgdata
->gcal_sink
)
113 osync_objtype_sink_unref(plgdata
->gcal_sink
);
114 if (plgdata
->gcal_format
)
115 osync_objformat_unref(plgdata
->gcal_format
);
119 static void gc_connect(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
121 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
122 static int counter
= 0;
124 struct gc_plgdata
*plgdata
= data
;
125 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
126 OSyncError
*error
= NULL
;
129 if ((plgdata
->calendar
) && (counter
== 0)) {
130 result
= gcal_get_authentication(plgdata
->calendar
, plgdata
->username
,
136 snprintf(buffer
, sizeof(buffer
) - 1, "%s/gcal2osync.xslt",
138 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcal
, buffer
)))
140 osync_trace(TRACE_INTERNAL
, "\ndone calendar: %s\n", buffer
);
143 if (((plgdata
->contacts
) && (counter
== 1)) ||
144 ((plgdata
->gcont_sink
) && (!plgdata
->gcal_sink
))) {
145 result
= gcal_get_authentication(plgdata
->contacts
, plgdata
->username
,
151 snprintf(buffer
, sizeof(buffer
) - 1, "%s/gcont2osync.xslt",
153 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcont
, buffer
)))
155 osync_trace(TRACE_INTERNAL
, "\ndone contact: %s\n", buffer
);
158 osync_context_report_success(ctx
);
159 osync_trace(TRACE_EXIT
, "%s", __func__
);
163 osync_trace(TRACE_INTERNAL
, "\nGood bye, cruel world...\n");
164 osync_context_report_osyncerror(ctx
, &error
);
167 static void gc_get_changes_calendar(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
169 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
171 static int counter
= 0;
172 struct gc_plgdata
*plgdata
= data
;
173 char slow_sync_flag
= 0;
174 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
175 OSyncError
*error
= NULL
;
176 OSyncXMLFormat
*xmlformat
;
177 OSyncData
*odata
= NULL
;
178 OSyncChange
*chg
= NULL
;
180 char *timestamp
= NULL
, *msg
, *raw_xml
= NULL
;
183 if (!plgdata
->gcal_sink
)
185 timestamp
= osync_anchor_retrieve(plgdata
->gcal_anchor_path
, "gcalendar");
187 osync_trace(TRACE_INTERNAL
, "timestamp is: %s\n", timestamp
);
189 osync_trace(TRACE_INTERNAL
, "first sync!\n");
191 if (osync_objtype_sink_get_slowsync(plgdata
->gcal_sink
) || !timestamp
) {
192 osync_trace(TRACE_INTERNAL
, "\n\t\tgcal: Client asked for slow syncing...\n");
194 result
= gcal_get_events(plgdata
->calendar
, &(plgdata
->all_events
));
197 osync_trace(TRACE_INTERNAL
, "\n\t\tgcal: Client asked for fast syncing...\n");
198 result
= gcal_get_updated_events(plgdata
->calendar
,
199 &(plgdata
->all_events
),
204 msg
= "Failed getting events!";
208 /* Calendar returns most recently updated event as first element */
209 event
= gcal_event_element(&(plgdata
->all_events
), 0);
212 plgdata
->cont_timestamp
= strdup(gcal_event_get_updated(event
));
213 if (!plgdata
->cont_timestamp
) {
214 msg
= "Failed copying event timestamp!\n";
218 osync_trace(TRACE_INTERNAL
, "gcalendar: got then all!\n");
219 for (i
= 0; i
< plgdata
->all_events
.length
; ++i
) {
220 event
= gcal_event_element(&(plgdata
->all_events
), i
);
224 raw_xml
= gcal_event_get_xml(event
);
225 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcal
,
229 raw_xml
= plgdata
->xslt_ctx_gcal
->xml_str
;
230 xmlformat
= osync_xmlformat_parse(raw_xml
,
236 osync_trace(TRACE_INTERNAL
, "gevent: %s\nosync: %s\n",
237 gcal_event_get_xml(event
), raw_xml
);
239 osync_xmlformat_sort(xmlformat
);
240 odata
= osync_data_new(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 osync_trace(TRACE_INTERNAL
, "gcont: %s\nosync: %s\n",
354 gcal_contact_get_xml(contact
), raw_xml
);
356 osync_xmlformat_sort(xmlformat
);
358 odata
= osync_data_new(xmlformat
,
359 osync_xmlformat_size(),
360 plgdata
->gcont_format
, &error
);
365 if (!(chg
= osync_change_new(&error
)))
367 osync_data_set_objtype(odata
, osync_objtype_sink_get_name(plgdata
->gcont_sink
));
368 osync_change_set_data(chg
, odata
);
369 osync_data_unref(odata
);
371 osync_change_set_uid(chg
, gcal_contact_get_url(contact
));
374 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_ADDED
);
376 if (gcal_contact_is_deleted(contact
))
377 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_DELETED
);
379 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_MODIFIED
);
381 osync_context_report_change(ctx
, chg
);
382 osync_change_unref(chg
);
385 /* Load XSLT style to convert osync xmlformat-contact --> gdata */
386 snprintf(buffer
, sizeof(buffer
) - 1, "%s/osync2gcont.xslt",
388 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcont
, buffer
)))
390 osync_trace(TRACE_INTERNAL
, "\ndone contact: %s\n", buffer
);
394 osync_context_report_success(ctx
);
398 osync_error_unref(&error
);
399 osync_xmlformat_unref(&xmlformat
);
402 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
405 static void gc_commit_change_calendar(void *data
, OSyncPluginInfo
*info
,
406 OSyncContext
*ctx
, OSyncChange
*change
)
408 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
, change
);
409 osync_trace(TRACE_INTERNAL
, "hello, from calendar!\n");
410 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
411 struct gc_plgdata
*plgdata
= data
;
412 gcal_event event
= NULL
;
415 char *osync_xml
= NULL
, *msg
= NULL
, *raw_xml
= NULL
, *updated_event
= NULL
;
416 OSyncData
*odata
= NULL
;
418 if (!(odata
= osync_change_get_data(change
))) {
419 msg
= "Cannot get raw data from change obj!\n";
423 osync_data_get_data(odata
, &osync_xml
, &size
);
425 msg
= "Failed getting xml from change obj!\n";
429 /* Convert to gdata format */
430 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcal
, osync_xml
))) {
431 msg
= "Failed converting from osync xmlevent to gcalendar\n";
434 raw_xml
= plgdata
->xslt_ctx_gcal
->xml_str
;
436 osync_trace(TRACE_EXIT
, "osync: %s\ngcont: %s\n\n", osync_xml
, raw_xml
);
438 switch (osync_change_get_changetype(change
)) {
439 case OSYNC_CHANGE_TYPE_ADDED
:
440 result
= gcal_add_xmlentry(plgdata
->calendar
, raw_xml
, &updated_event
);
442 msg
= "Failed adding new event!\n";
443 result
= gcal_status_httpcode(plgdata
->calendar
);
447 if (!(event
= gcal_event_new(updated_event
))) {
448 msg
= "Failed recovering updated fields!\n";
453 case OSYNC_CHANGE_TYPE_MODIFIED
:
454 result
= gcal_update_xmlentry(plgdata
->calendar
, raw_xml
, &updated_event
,
457 msg
= "Failed editing event!\n";
461 if (!(event
= gcal_event_new(updated_event
))) {
462 msg
= "Failed recovering updated fields!\n";
467 case OSYNC_CHANGE_TYPE_DELETED
:
468 result
= gcal_erase_xmlentry(plgdata
->calendar
, raw_xml
);
470 msg
= "Failed deleting event!\n";
476 osync_context_report_error(ctx
, OSYNC_ERROR_NOT_SUPPORTED
,
477 "Unknown change type");
486 /* update the timestamp */
487 if (plgdata
->cal_timestamp
)
488 free(plgdata
->cal_timestamp
);
489 plgdata
->cal_timestamp
= strdup(gcal_event_get_updated(event
));
490 if (!plgdata
->cal_timestamp
) {
491 msg
= "Failed copying contact timestamp!\n";
495 /* FIXME: not sure if this works */
496 /* Inform the new ID */
497 osync_change_set_uid(change
, gcal_event_get_url(event
));
498 gcal_event_delete(event
);
502 osync_context_report_success(ctx
);
504 osync_trace(TRACE_EXIT
, "%s", __func__
);
508 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
509 osync_trace(TRACE_EXIT
, "%s:%sHTTP code: %d", __func__
, msg
, result
);
512 static void gc_commit_change_contact(void *data
, OSyncPluginInfo
*info
,
513 OSyncContext
*ctx
, OSyncChange
*change
)
515 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
, change
);
516 osync_trace(TRACE_INTERNAL
, "hello, from contacts!\n");
518 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
519 struct gc_plgdata
*plgdata
= data
;
520 gcal_contact contact
= NULL
;
522 char *osync_xml
= NULL
, *msg
= NULL
, *raw_xml
= NULL
, *updated_contact
= NULL
;
523 OSyncData
*odata
= NULL
;
525 if (!(odata
= osync_change_get_data(change
))) {
526 msg
= "Cannot get raw data from change obj!\n";
530 osync_data_get_data(odata
, &osync_xml
, &size
);
532 msg
= "Failed getting xml from change obj!\n";
536 /* Convert to gdata format */
537 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcont
, osync_xml
))) {
538 msg
= "Failed converting from osync xmlcontact to gcontact\n";
541 raw_xml
= plgdata
->xslt_ctx_gcont
->xml_str
;
543 osync_trace(TRACE_INTERNAL
, "osync: %s\ngcont: %s\n\n", osync_xml
, raw_xml
);
545 switch (osync_change_get_changetype(change
)) {
546 case OSYNC_CHANGE_TYPE_ADDED
:
547 result
= gcal_add_xmlentry(plgdata
->contacts
, raw_xml
, &updated_contact
);
549 msg
= "Failed adding new contact!\n";
550 result
= gcal_status_httpcode(plgdata
->contacts
);
554 if (!(contact
= gcal_contact_new(updated_contact
))) {
555 msg
= "Failed recovering updated fields!\n";
560 case OSYNC_CHANGE_TYPE_MODIFIED
:
561 result
= gcal_update_xmlentry(plgdata
->contacts
, raw_xml
, &updated_contact
,
564 msg
= "Failed editing event!\n";
568 if (!(contact
= gcal_contact_new(updated_contact
))) {
569 msg
= "Failed recovering updated fields!\n";
574 case OSYNC_CHANGE_TYPE_DELETED
:
575 result
= gcal_erase_xmlentry(plgdata
->contacts
, raw_xml
);
577 msg
= "Failed deleting event!\n";
583 osync_context_report_error(ctx
, OSYNC_ERROR_NOT_SUPPORTED
,
584 "Unknown change type");
590 free(updated_contact
);
593 /* update the timestamp */
594 if (plgdata
->cont_timestamp
)
595 free(plgdata
->cont_timestamp
);
596 plgdata
->cont_timestamp
= strdup(gcal_contact_get_updated(contact
));
597 if (!plgdata
->cont_timestamp
) {
598 msg
= "Failed copying contact timestamp!\n";
602 /* FIXME: not sure if this works */
603 /* Inform the new ID */
604 osync_change_set_uid(change
, gcal_contact_get_url(contact
));
605 gcal_contact_delete(contact
);
608 osync_context_report_success(ctx
);
609 osync_trace(TRACE_EXIT
, "%s", __func__
);
613 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
614 osync_trace(TRACE_EXIT
, "%s:%sHTTP code: %d", __func__
, msg
, result
);
617 static void gc_sync_done(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
619 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
620 struct gc_plgdata
*plgdata
= NULL
;
624 if (plgdata
->calendar
&& plgdata
->cal_timestamp
)
625 osync_anchor_update(plgdata
->gcal_anchor_path
, "gcalendar",
626 plgdata
->cal_timestamp
);
627 if (plgdata
->contacts
&& plgdata
->cont_timestamp
)
628 osync_anchor_update(plgdata
->gcont_anchor_path
, "gcontact",
629 plgdata
->cont_timestamp
);
632 static void gc_disconnect(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
634 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
635 struct gc_plgdata
*plgdata
= data
;
637 osync_context_report_success(ctx
);
638 osync_trace(TRACE_EXIT
, "%s", __func__
);
641 static void gc_finalize(void *data
)
643 osync_trace(TRACE_ENTRY
, "%s(%p)", __func__
, data
);
644 struct gc_plgdata
*plgdata
= data
;
647 osync_trace(TRACE_EXIT
, "%s", __func__
);
650 static void *gc_initialize(OSyncPlugin
*plugin
,
651 OSyncPluginInfo
*info
,
654 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, plugin
, info
, error
);
655 struct gc_plgdata
*plgdata
;
656 OSyncPluginConfig
*config
;
657 OSyncPluginAuthentication
*auth
;
658 OSyncPluginAdvancedOption
*advanced
;
659 OSyncList
*resources
;
661 const char *objtype
, *tmp
;
664 plgdata
= osync_try_malloc0(sizeof(struct gc_plgdata
), error
);
665 config
= osync_plugin_info_get_config(info
);
666 if ((!plgdata
) || (!config
)) {
667 osync_error_set(error
, OSYNC_ERROR_GENERIC
,
668 "Unable to get config data.");
672 advanced
= osync_plugin_config_get_advancedoption_value_by_name(config
, "xslt");
674 osync_trace(TRACE_INTERNAL
, "Cannot locate xslt config!\n");
678 if (!(plgdata
->xslt_path
= strdup(osync_plugin_advancedoption_get_value(advanced
))))
681 resources
= osync_plugin_config_get_resources(config
);
682 numobjs
= osync_plugin_info_num_objtypes(info
);
684 for (i
= 1, r
= resources
; r
; r
= r
->next
, i
++) {
685 osync_trace(TRACE_INTERNAL
, "field: %s\n", osync_plugin_resource_get_objtype(r
->data
));
686 if (!(strcmp(osync_plugin_resource_get_objtype(r
->data
), "event")))
687 if (!(plgdata
->calendar
= gcal_new(GCALENDAR
)))
690 osync_trace(TRACE_INTERNAL
, "\tcreated calendar obj!\n");
691 gcal_set_store_xml(plgdata
->calendar
, 1);
694 if (!(strcmp(osync_plugin_resource_get_objtype(r
->data
), "contact")))
695 if (!(plgdata
->contacts
= gcal_new(GCONTACT
)))
698 osync_trace(TRACE_INTERNAL
, "\tcreated contact obj!\n");
699 gcal_set_store_xml(plgdata
->contacts
, 1);
705 /* TODO: how works resource policy? For while, copy everything... */
706 for (i
= 0; i
< numobjs
; i
++) {
708 if (!plgdata
->username
) {
709 auth
= osync_plugin_config_get_authentication(config
);
710 tmp
= osync_plugin_authentication_get_username(auth
);
714 if (!(plgdata
->username
= strdup(tmp
)))
719 if (!plgdata
->password
) {
720 tmp
= osync_plugin_authentication_get_password(auth
);
724 if (!(plgdata
->password
= strdup(tmp
)))
728 /* TODO: get proxy/calendar title/resources/etc */
732 OSyncObjTypeSinkFunctions functions_gcal
;
733 memset(&functions_gcal
, 0, sizeof(functions_gcal
));
734 functions_gcal
.connect
= gc_connect
;
735 functions_gcal
.get_changes
= gc_get_changes_calendar
;
736 functions_gcal
.commit
= gc_commit_change_calendar
;
737 functions_gcal
.disconnect
= gc_disconnect
;
738 functions_gcal
.sync_done
= gc_sync_done
;
741 if (plgdata
->calendar
) {
742 osync_trace(TRACE_INTERNAL
, "\tcreating calendar sink...\n");
743 OSyncFormatEnv
*formatenv1
= osync_plugin_info_get_format_env(info
);
744 plgdata
->gcal_format
= osync_format_env_find_objformat(formatenv1
, "xmlformat-event");
745 if (!plgdata
->gcal_format
)
747 osync_objformat_ref(plgdata
->gcal_format
);
749 plgdata
->gcal_sink
= osync_plugin_info_find_objtype(info
, "event");
750 if (!plgdata
->gcal_sink
)
753 osync_objtype_sink_set_functions(plgdata
->gcal_sink
, functions_gcal
, plgdata
);
754 osync_plugin_info_add_objtype(info
, plgdata
->gcal_sink
);
758 OSyncObjTypeSinkFunctions functions_gcont
;
759 memset(&functions_gcont
, 0, sizeof(functions_gcont
));
760 functions_gcont
.connect
= gc_connect
;
761 functions_gcont
.get_changes
= gc_get_changes_contact
;
762 functions_gcont
.commit
= gc_commit_change_contact
;
763 functions_gcont
.disconnect
= gc_disconnect
;
764 functions_gcont
.sync_done
= gc_sync_done
;
766 if (plgdata
->contacts
) {
767 osync_trace(TRACE_INTERNAL
, "\tcreating contact sink...\n");
768 OSyncFormatEnv
*formatenv2
= osync_plugin_info_get_format_env(info
);
769 plgdata
->gcont_format
= osync_format_env_find_objformat(formatenv2
, "xmlformat-contact");
770 if (!plgdata
->gcont_format
)
772 osync_objformat_ref(plgdata
->gcont_format
);
774 plgdata
->gcont_sink
= osync_plugin_info_find_objtype(info
, "contact");
775 if (!plgdata
->gcont_sink
)
778 osync_objtype_sink_set_functions(plgdata
->gcont_sink
, functions_gcont
, plgdata
);
779 osync_plugin_info_add_objtype(info
, plgdata
->gcont_sink
);
784 plgdata
->gcal_anchor_path
= g_strdup_printf("%s/calendar_anchor.db",
785 osync_plugin_info_get_configdir(info
));
786 if (!(plgdata
->gcal_anchor_path
))
789 osync_trace(TRACE_INTERNAL
, "\tanchor: %s\n", plgdata
->gcal_anchor_path
);
791 plgdata
->gcont_anchor_path
= g_strdup_printf("%s/contact_anchor.db",
792 osync_plugin_info_get_configdir(info
));
793 if (!(plgdata
->gcont_anchor_path
))
796 osync_trace(TRACE_INTERNAL
, "\tanchor: %s\n", plgdata
->gcont_anchor_path
);
798 if (plgdata
->calendar
)
799 if (!(plgdata
->xslt_ctx_gcal
= xslt_new()))
802 osync_trace(TRACE_INTERNAL
, "\tsucceed creating xslt_gcal!\n");
804 if (plgdata
->contacts
)
805 if (!(plgdata
->xslt_ctx_gcont
= xslt_new()))
808 osync_trace(TRACE_INTERNAL
, "\tsucceed creating xslt_gcont!\n");
810 osync_trace(TRACE_EXIT
, "%s", __func__
);
818 osync_trace(TRACE_EXIT_ERROR
, "%s: %s", __func__
, osync_error_print(error
));
822 static osync_bool
gc_discover(void *data
, OSyncPluginInfo
*info
, OSyncError
**error
)
824 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, error
);
826 struct gc_plgdata
*plgdata
= data
;
828 if (plgdata
->calendar
)
829 osync_objtype_sink_set_available(plgdata
->gcal_sink
, TRUE
);
830 if (plgdata
->contacts
)
831 osync_objtype_sink_set_available(plgdata
->gcont_sink
, TRUE
);
833 OSyncVersion
*version
= osync_version_new(error
);
834 osync_version_set_plugin(version
, "google-data");
835 osync_plugin_info_set_version(info
, version
);
836 osync_version_unref(version
);
838 osync_trace(TRACE_EXIT
, "%s", __func__
);
842 osync_bool
get_sync_info(OSyncPluginEnv
*env
, OSyncError
**error
)
844 osync_trace(TRACE_ENTRY
, "%s(%p, %p)", __func__
, env
, error
);
845 OSyncPlugin
*plugin
= osync_plugin_new(error
);
849 osync_plugin_set_name(plugin
, "google-data");
850 osync_plugin_set_longname(plugin
, "Google calendar/plugin");
851 osync_plugin_set_description(plugin
, "Google calendar and contacts plugin");
853 osync_plugin_set_initialize(plugin
, gc_initialize
);
854 osync_plugin_set_finalize(plugin
, gc_finalize
);
855 osync_plugin_set_discover(plugin
, gc_discover
);
857 osync_plugin_env_register_plugin(env
, plugin
);
858 osync_plugin_unref(plugin
);
860 osync_trace(TRACE_EXIT
, "%s", __func__
);
864 osync_trace(TRACE_EXIT_ERROR
, "Unable to register: %s", osync_error_print(error
));
865 osync_error_unref(error
);
869 int get_version(void)