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 * - commitchanges: report back updated fields, when ADDED (ID/updated/edit_url) or
25 * UPDATED (updated/edit_url)
26 * - review code for leaks (I'm not sure if I'm using opensync API correctly...)
30 #include <opensync/opensync.h>
31 #include <opensync/opensync-plugin.h>
32 #include <opensync/opensync-helper.h>
33 #include <opensync/opensync-merger.h>
34 #include <opensync/opensync-format.h>
35 #include <opensync/opensync-data.h>
36 #include <opensync/opensync-version.h>
40 #include <libxml/tree.h>
45 #include <sys/types.h>
48 #include <gcal_status.h>
49 #include <gcalendar.h>
58 char *gcal_anchor_path
;
59 char *gcont_anchor_path
;
62 /* libgcal resources */
67 struct gcal_event_array all_events
;
68 struct gcal_contact_array all_contacts
;
69 /* calendar sink/format */
70 OSyncObjTypeSink
*gcal_sink
;
71 OSyncObjFormat
*gcal_format
;
72 /* contact sink/format */
73 OSyncObjTypeSink
*gcont_sink
;
74 OSyncObjFormat
*gcont_format
;
75 /* XSLT context resource struct */
76 struct xslt_resources
*xslt_ctx_gcal
;
77 struct xslt_resources
*xslt_ctx_gcont
;
80 static void free_plg(struct gc_plgdata
*plgdata
)
82 if (plgdata
->calendar
) {
83 gcal_delete(plgdata
->calendar
);
84 gcal_cleanup_events(&(plgdata
->all_events
));
86 if (plgdata
->contacts
) {
87 gcal_delete(plgdata
->contacts
);
88 gcal_cleanup_contacts(&(plgdata
->all_contacts
));
91 if (plgdata
->gcal_anchor_path
)
92 free(plgdata
->gcal_anchor_path
);
93 if (plgdata
->gcont_anchor_path
)
94 free(plgdata
->gcont_anchor_path
);
95 if (plgdata
->xslt_path
)
96 free(plgdata
->xslt_path
);
97 if (plgdata
->xslt_ctx_gcal
)
98 xslt_delete(plgdata
->xslt_ctx_gcal
);
99 if (plgdata
->xslt_ctx_gcont
)
100 xslt_delete(plgdata
->xslt_ctx_gcont
);
101 if (plgdata
->cal_timestamp
)
102 free(plgdata
->cal_timestamp
);
103 if (plgdata
->cont_timestamp
)
104 free(plgdata
->cont_timestamp
);
105 if (plgdata
->timezone
)
106 free(plgdata
->timezone
);
108 xmlFree(plgdata
->url
);
109 if (plgdata
->username
)
110 xmlFree(plgdata
->username
);
111 if (plgdata
->password
)
112 xmlFree(plgdata
->password
);
113 if (plgdata
->gcal_sink
)
114 osync_objtype_sink_unref(plgdata
->gcal_sink
);
115 if (plgdata
->gcal_format
)
116 osync_objformat_unref(plgdata
->gcal_format
);
120 /** Run gchelper and return the file descriptors for its stdin/stdout
123 osync_bool
run_helper(struct gc_plgdata
*plgdata
, const char *operation
,
124 const char *arg
, int *in
, int *out
, pid_t
*ppid
,
128 osync_bool result
= FALSE
;
129 /* TODO: add calls to libgcal */
134 static void gc_connect(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
136 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
137 static int counter
= 0;
139 struct gc_plgdata
*plgdata
= data
;
140 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
141 OSyncError
*error
= NULL
;
144 if ((plgdata
->calendar
) && (counter
== 0)) {
145 result
= gcal_get_authentication(plgdata
->calendar
, plgdata
->username
,
151 snprintf(buffer
, sizeof(buffer
) - 1, "%s/gcal2osync.xslt",
153 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcal
, buffer
)))
155 osync_trace(TRACE_INTERNAL
, "\ndone calendar: %s\n", buffer
);
158 if (((plgdata
->contacts
) && (counter
== 1)) ||
159 ((plgdata
->gcont_sink
) && (!plgdata
->gcal_sink
))) {
160 result
= gcal_get_authentication(plgdata
->contacts
, plgdata
->username
,
166 snprintf(buffer
, sizeof(buffer
) - 1, "%s/gcont2osync.xslt",
168 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcont
, buffer
)))
170 osync_trace(TRACE_INTERNAL
, "\ndone contact: %s\n", buffer
);
173 osync_context_report_success(ctx
);
174 osync_trace(TRACE_EXIT
, "%s", __func__
);
178 osync_trace(TRACE_INTERNAL
, "\nGood bye, cruel world...\n");
179 osync_context_report_osyncerror(ctx
, &error
);
182 static void gc_get_changes(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
184 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
186 static int counter
= 0;
187 struct gc_plgdata
*plgdata
= data
;
188 char slow_sync_flag
= 0;
189 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
190 OSyncError
*error
= NULL
;
191 OSyncXMLFormat
*xmlformat
;
192 OSyncData
*odata
= NULL
;
193 OSyncChange
*chg
= NULL
;
195 char *timestamp
= NULL
, *msg
, *raw_xml
= NULL
;
197 gcal_contact contact
;
199 timestamp
= osync_anchor_retrieve(plgdata
->gcal_anchor_path
, "gcalendar");
201 osync_trace(TRACE_INTERNAL
, "timestamp is: %s\n", timestamp
);
203 osync_trace(TRACE_INTERNAL
, "first sync!\n");
205 if ((plgdata
->gcal_sink
) && (counter
== 0)) {
206 if (osync_objtype_sink_get_slowsync(plgdata
->gcal_sink
) || !timestamp
) {
207 osync_trace(TRACE_INTERNAL
, "\n\t\tgcal: Client asked for slow syncing...\n");
209 result
= gcal_get_events(plgdata
->calendar
, &(plgdata
->all_events
));
212 osync_trace(TRACE_INTERNAL
, "\n\t\tgcal: Client asked for fast syncing...\n");
213 result
= gcal_get_updated_events(plgdata
->calendar
,
214 &(plgdata
->all_events
),
219 msg
= "Failed getting events!";
223 /* Calendar returns most recently updated event as first element */
224 event
= gcal_event_element(&(plgdata
->all_events
), 0);
227 plgdata
->cont_timestamp
= strdup(gcal_event_get_updated(event
));
228 if (!plgdata
->cont_timestamp
) {
229 msg
= "Failed copying event timestamp!\n";
233 osync_trace(TRACE_INTERNAL
, "\tgot then all!\n");
234 for (i
= 0; i
< plgdata
->all_events
.length
; ++i
) {
235 event
= gcal_event_element(&(plgdata
->all_events
), i
);
239 raw_xml
= gcal_event_get_xml(event
);
240 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcal
,
244 raw_xml
= plgdata
->xslt_ctx_gcal
->xml_str
;
245 xmlformat
= osync_xmlformat_parse(raw_xml
,
251 osync_xmlformat_sort(xmlformat
);
252 odata
= osync_data_new((char *)xmlformat
,
253 osync_xmlformat_size(),
254 plgdata
->gcal_format
, &error
);
258 if (!(chg
= osync_change_new(&error
)))
260 osync_data_set_objtype(odata
, osync_objtype_sink_get_name(plgdata
->gcal_sink
));
261 osync_change_set_data(chg
, odata
);
262 osync_data_unref(odata
);
264 osync_change_set_uid(chg
, gcal_event_get_id(event
));
267 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_ADDED
);
269 if (gcal_event_is_deleted(event
))
270 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_DELETED
);
272 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_MODIFIED
);
274 osync_context_report_change(ctx
, chg
);
275 osync_change_unref(chg
);
278 /* Load XSLT style to convert osync xmlformat-event --> gdata */
279 snprintf(buffer
, sizeof(buffer
) - 1, "%s/osync2gcal.xslt",
281 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcal
, buffer
)))
283 osync_trace(TRACE_INTERNAL
, "\ndone calendar: %s\n", buffer
);
289 timestamp
= osync_anchor_retrieve(plgdata
->gcal_anchor_path
, "gcontact");
290 if (((plgdata
->gcont_sink
) && (counter
== 1)) ||
291 ((plgdata
->gcont_sink
) && (!plgdata
->gcal_sink
))) {
292 if (osync_objtype_sink_get_slowsync(plgdata
->gcont_sink
) || !timestamp
) {
293 osync_trace(TRACE_INTERNAL
, "\n\t\tgcont: Client asked for slow syncing...\n");
295 result
= gcal_get_contacts(plgdata
->contacts
, &(plgdata
->all_contacts
));
298 osync_trace(TRACE_INTERNAL
, "\n\t\tgcont: Client asked for fast syncing...\n");
299 result
= gcal_get_updated_contacts(plgdata
->contacts
,
300 &(plgdata
->all_contacts
),
306 msg
= "Failed getting contacts!";
310 /* Contacts returns most recently updated event as last element */
311 contact
= gcal_contact_element(&(plgdata
->all_contacts
),
312 (plgdata
->all_contacts
.length
- 1));
315 plgdata
->cont_timestamp
= strdup(gcal_contact_get_updated(contact
));
316 if (!plgdata
->cont_timestamp
) {
317 msg
= "Failed copying contact timestamp!\n";
321 osync_trace(TRACE_INTERNAL
, "\tgot then all!\n");
322 for (i
= 0; i
< plgdata
->all_contacts
.length
; ++i
) {
323 contact
= gcal_contact_element(&(plgdata
->all_contacts
), i
);
327 raw_xml
= gcal_contact_get_xml(contact
);
328 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcont
,
331 raw_xml
= plgdata
->xslt_ctx_gcal
->xml_str
;
332 xmlformat
= osync_xmlformat_parse(raw_xml
,
338 osync_xmlformat_sort(xmlformat
);
339 odata
= osync_data_new((char *)xmlformat
,
340 osync_xmlformat_size(),
341 plgdata
->gcont_format
, &error
);
345 if (!(chg
= osync_change_new(&error
)))
347 osync_data_set_objtype(odata
, osync_objtype_sink_get_name(plgdata
->gcont_sink
));
348 osync_change_set_data(chg
, odata
);
349 osync_data_unref(odata
);
351 osync_change_set_uid(chg
, gcal_contact_get_id(contact
));
354 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_ADDED
);
356 if (gcal_contact_is_deleted(contact
))
357 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_DELETED
);
359 osync_change_set_changetype(chg
, OSYNC_CHANGE_TYPE_MODIFIED
);
361 osync_context_report_change(ctx
, chg
);
362 osync_change_unref(chg
);
365 /* Load XSLT style to convert osync xmlformat-contact --> gdata */
366 snprintf(buffer
, sizeof(buffer
) - 1, "%s/osync2gcont.xslt",
368 if ((result
= xslt_initialize(plgdata
->xslt_ctx_gcont
, buffer
)))
370 osync_trace(TRACE_INTERNAL
, "\ndone contact: %s\n", buffer
);
376 osync_context_report_success(ctx
);
380 osync_error_unref(&error
);
381 osync_xmlformat_unref(&xmlformat
);
385 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
388 static void gc_commit_change_calendar(void *data
, OSyncPluginInfo
*info
,
389 OSyncContext
*ctx
, OSyncChange
*change
)
391 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
, change
);
392 osync_trace(TRACE_INTERNAL
, "hello, from calendar!\n");
393 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
394 struct gc_plgdata
*plgdata
= data
;
395 gcal_event event
= NULL
;
398 char *osync_xml
= NULL
, *msg
= NULL
, *raw_xml
= NULL
, *updated_event
= NULL
;
399 OSyncData
*odata
= NULL
;
401 if (!(odata
= osync_change_get_data(change
))) {
402 msg
= "Cannot get raw data from change obj!\n";
406 osync_data_get_data(odata
, &osync_xml
, &size
);
408 msg
= "Failed getting xml from change obj!\n";
412 /* Convert to gdata format */
413 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcal
, osync_xml
))) {
414 msg
= "Failed converting from osync xmlevent to gcalendar\n";
417 raw_xml
= plgdata
->xslt_ctx_gcal
->xml_str
;
419 switch (osync_change_get_changetype(change
)) {
420 case OSYNC_CHANGE_TYPE_ADDED
:
421 result
= gcal_add_xmlentry(plgdata
->calendar
, raw_xml
, &updated_event
);
423 msg
= "Failed adding new event!\n";
427 if (!(event
= gcal_event_new(updated_event
))) {
428 msg
= "Failed recovering updated fields!\n";
431 /* TODO: inform back the id/edit_url/last_updated */
434 case OSYNC_CHANGE_TYPE_MODIFIED
:
435 result
= gcal_update_xmlentry(plgdata
->calendar
, raw_xml
, &updated_event
,
438 msg
= "Failed editing event!\n";
442 if (!(event
= gcal_event_new(updated_event
))) {
443 msg
= "Failed recovering updated fields!\n";
446 /* TODO: inform back the edit_url/last_updated */
449 case OSYNC_CHANGE_TYPE_DELETED
:
450 result
= gcal_erase_xmlentry(plgdata
->calendar
, raw_xml
);
452 msg
= "Failed deleting event!\n";
458 osync_context_report_error(ctx
, OSYNC_ERROR_NOT_SUPPORTED
,
459 "Unknown change type");
471 gcal_event_delete(event
);
473 osync_context_report_success(ctx
);
475 osync_trace(TRACE_EXIT
, "%s", __func__
);
479 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
482 static void gc_commit_change_contact(void *data
, OSyncPluginInfo
*info
,
483 OSyncContext
*ctx
, OSyncChange
*change
)
485 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
, change
);
486 osync_trace(TRACE_INTERNAL
, "hello, from contacts!\n");
488 OSyncObjTypeSink
*sink
= osync_plugin_info_get_sink(info
);
489 struct gc_plgdata
*plgdata
= data
;
490 gcal_contact contact
= NULL
;
492 char *osync_xml
= NULL
, *msg
= NULL
, *raw_xml
= NULL
, *updated_contact
= NULL
;
493 OSyncData
*odata
= NULL
;
495 if (!(odata
= osync_change_get_data(change
))) {
496 msg
= "Cannot get raw data from change obj!\n";
500 osync_data_get_data(odata
, &osync_xml
, &size
);
502 msg
= "Failed getting xml from change obj!\n";
506 /* Convert to gdata format */
507 if ((result
= xslt_transform(plgdata
->xslt_ctx_gcont
, osync_xml
))) {
508 msg
= "Failed converting from osync xmlcontact to gcontact\n";
511 raw_xml
= plgdata
->xslt_ctx_gcal
->xml_str
;
513 switch (osync_change_get_changetype(change
)) {
514 case OSYNC_CHANGE_TYPE_ADDED
:
515 result
= gcal_add_xmlentry(plgdata
->contacts
, raw_xml
, &updated_contact
);
517 msg
= "Failed adding new contact!\n";
521 if (!(contact
= gcal_contact_new(updated_contact
))) {
522 msg
= "Failed recovering updated fields!\n";
525 /* TODO: inform back the id/edit_url/last_updated */
528 case OSYNC_CHANGE_TYPE_MODIFIED
:
529 result
= gcal_update_xmlentry(plgdata
->contacts
, raw_xml
, &updated_contact
,
532 msg
= "Failed editing event!\n";
536 if (!(contact
= gcal_contact_new(updated_contact
))) {
537 msg
= "Failed recovering updated fields!\n";
540 /* TODO: inform back the id/edit_url/last_updated */
543 case OSYNC_CHANGE_TYPE_DELETED
:
544 result
= gcal_erase_xmlentry(plgdata
->contacts
, raw_xml
);
546 msg
= "Failed deleting event!\n";
552 osync_context_report_error(ctx
, OSYNC_ERROR_NOT_SUPPORTED
,
553 "Unknown change type");
562 free(updated_contact
);
567 osync_context_report_success(ctx
);
568 osync_trace(TRACE_EXIT
, "%s", __func__
);
572 osync_context_report_error(ctx
, OSYNC_ERROR_GENERIC
, msg
);
576 static void gc_sync_done(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
578 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
579 struct gc_plgdata
*plgdata
= NULL
;
583 osync_anchor_update(plgdata
->gcal_anchor_path
, "gcalendar", plgdata
->cal_timestamp
);
584 osync_anchor_update(plgdata
->gcont_anchor_path
, "gcontact", plgdata
->cont_timestamp
);
587 static void gc_disconnect(void *data
, OSyncPluginInfo
*info
, OSyncContext
*ctx
)
589 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, ctx
);
590 struct gc_plgdata
*plgdata
= data
;
592 osync_context_report_success(ctx
);
593 osync_trace(TRACE_EXIT
, "%s", __func__
);
596 static void gc_finalize(void *data
)
598 osync_trace(TRACE_ENTRY
, "%s(%p)", __func__
, data
);
599 struct gc_plgdata
*plgdata
= data
;
602 osync_trace(TRACE_EXIT
, "%s", __func__
);
605 static void *gc_initialize(OSyncPlugin
*plugin
,
606 OSyncPluginInfo
*info
,
609 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, plugin
, info
, error
);
610 struct gc_plgdata
*plgdata
;
611 OSyncPluginConfig
*config
;
612 OSyncPluginAuthentication
*auth
;
613 OSyncPluginAdvancedOption
*advanced
;
614 OSyncList
*resources
;
616 const char *objtype
, *tmp
;
619 plgdata
= osync_try_malloc0(sizeof(struct gc_plgdata
), error
);
620 config
= osync_plugin_info_get_config(info
);
621 if ((!plgdata
) || (!config
)) {
622 osync_error_set(error
, OSYNC_ERROR_GENERIC
,
623 "Unable to get config data.");
627 advanced
= osync_plugin_config_get_advancedoption_value_by_name(config
, "xslt");
629 osync_trace(TRACE_INTERNAL
, "Cannot locate xslt config!\n");
633 if (!(plgdata
->xslt_path
= strdup(osync_plugin_advancedoption_get_value(advanced
))))
636 resources
= osync_plugin_config_get_resources(config
);
637 numobjs
= osync_plugin_info_num_objtypes(info
);
639 for (i
= 1, r
= resources
; r
; r
= r
->next
, i
++) {
640 osync_trace(TRACE_INTERNAL
, "field: %s\n", osync_plugin_resource_get_objtype(r
->data
));
641 if (!(strcmp(osync_plugin_resource_get_objtype(r
->data
), "event")))
642 if (!(plgdata
->calendar
= gcal_new(GCALENDAR
)))
645 osync_trace(TRACE_INTERNAL
, "\tcreated calendar obj!\n");
646 gcal_set_store_xml(plgdata
->calendar
, 1);
649 if (!(strcmp(osync_plugin_resource_get_objtype(r
->data
), "contact")))
650 if (!(plgdata
->contacts
= gcal_new(GCONTACT
)))
653 osync_trace(TRACE_INTERNAL
, "\tcreated contact obj!\n");
654 gcal_set_store_xml(plgdata
->contacts
, 1);
660 /* TODO: how works resource policy? For while, copy everything... */
661 for (i
= 0; i
< numobjs
; i
++) {
663 if (!plgdata
->username
) {
664 auth
= osync_plugin_config_get_authentication(config
);
665 tmp
= osync_plugin_authentication_get_username(auth
);
669 if (!(plgdata
->username
= strdup(tmp
)))
674 if (!plgdata
->password
) {
675 tmp
= osync_plugin_authentication_get_password(auth
);
679 if (!(plgdata
->password
= strdup(tmp
)))
683 /* TODO: get proxy/calendar title/resources/etc */
687 OSyncObjTypeSinkFunctions functions_gcal
;
688 memset(&functions_gcal
, 0, sizeof(functions_gcal
));
689 functions_gcal
.connect
= gc_connect
;
690 functions_gcal
.get_changes
= gc_get_changes
;
691 functions_gcal
.commit
= gc_commit_change_calendar
;
692 functions_gcal
.disconnect
= gc_disconnect
;
693 functions_gcal
.sync_done
= gc_sync_done
;
696 if (plgdata
->calendar
) {
697 osync_trace(TRACE_INTERNAL
, "\tcreating calendar sink...\n");
698 OSyncFormatEnv
*formatenv1
= osync_plugin_info_get_format_env(info
);
699 plgdata
->gcal_format
= osync_format_env_find_objformat(formatenv1
, "xmlformat-event");
700 if (!plgdata
->gcal_format
)
702 osync_objformat_ref(plgdata
->gcal_format
);
704 plgdata
->gcal_sink
= osync_plugin_info_find_objtype(info
, "event");
705 if (!plgdata
->gcal_sink
)
708 osync_objtype_sink_set_functions(plgdata
->gcal_sink
, functions_gcal
, plgdata
);
709 osync_plugin_info_add_objtype(info
, plgdata
->gcal_sink
);
713 OSyncObjTypeSinkFunctions functions_gcont
;
714 memset(&functions_gcont
, 0, sizeof(functions_gcont
));
715 functions_gcont
.connect
= gc_connect
;
716 functions_gcont
.get_changes
= gc_get_changes
;
717 functions_gcont
.commit
= gc_commit_change_contact
;
718 functions_gcont
.disconnect
= gc_disconnect
;
719 functions_gcont
.sync_done
= gc_sync_done
;
721 if (plgdata
->contacts
) {
722 osync_trace(TRACE_INTERNAL
, "\tcreating contact sink...\n");
723 OSyncFormatEnv
*formatenv2
= osync_plugin_info_get_format_env(info
);
724 plgdata
->gcont_format
= osync_format_env_find_objformat(formatenv2
, "xmlformat-contact");
725 if (!plgdata
->gcont_format
)
727 osync_objformat_ref(plgdata
->gcont_format
);
729 plgdata
->gcont_sink
= osync_plugin_info_find_objtype(info
, "contact");
730 if (!plgdata
->gcont_sink
)
733 osync_objtype_sink_set_functions(plgdata
->gcont_sink
, functions_gcont
, plgdata
);
734 osync_plugin_info_add_objtype(info
, plgdata
->gcont_sink
);
739 plgdata
->gcal_anchor_path
= g_strdup_printf("%s/calendar_anchor.db",
740 osync_plugin_info_get_configdir(info
));
741 if (!(plgdata
->gcal_anchor_path
))
744 osync_trace(TRACE_INTERNAL
, "\tanchor: %s\n", plgdata
->gcal_anchor_path
);
746 plgdata
->gcont_anchor_path
= g_strdup_printf("%s/contact_anchor.db",
747 osync_plugin_info_get_configdir(info
));
748 if (!(plgdata
->gcont_anchor_path
))
751 osync_trace(TRACE_INTERNAL
, "\tanchor: %s\n", plgdata
->gcont_anchor_path
);
753 if (plgdata
->calendar
)
754 if (!(plgdata
->xslt_ctx_gcal
= xslt_new()))
757 osync_trace(TRACE_INTERNAL
, "\tsucceed creating xslt_gcal!\n");
759 if (plgdata
->contacts
)
760 if (!(plgdata
->xslt_ctx_gcont
= xslt_new()))
763 osync_trace(TRACE_INTERNAL
, "\tsucceed creating xslt_gcont!\n");
765 osync_trace(TRACE_EXIT
, "%s", __func__
);
773 osync_trace(TRACE_EXIT_ERROR
, "%s: %s", __func__
, osync_error_print(error
));
777 static osync_bool
gc_discover(void *data
, OSyncPluginInfo
*info
, OSyncError
**error
)
779 osync_trace(TRACE_ENTRY
, "%s(%p, %p, %p)", __func__
, data
, info
, error
);
781 struct gc_plgdata
*plgdata
= data
;
783 if (plgdata
->calendar
)
784 osync_objtype_sink_set_available(plgdata
->gcal_sink
, TRUE
);
785 if (plgdata
->contacts
)
786 osync_objtype_sink_set_available(plgdata
->gcont_sink
, TRUE
);
788 OSyncVersion
*version
= osync_version_new(error
);
789 osync_version_set_plugin(version
, "google-data");
790 osync_plugin_info_set_version(info
, version
);
791 osync_version_unref(version
);
793 osync_trace(TRACE_EXIT
, "%s", __func__
);
797 osync_bool
get_sync_info(OSyncPluginEnv
*env
, OSyncError
**error
)
799 osync_trace(TRACE_ENTRY
, "%s(%p, %p)", __func__
, env
, error
);
800 OSyncPlugin
*plugin
= osync_plugin_new(error
);
804 osync_plugin_set_name(plugin
, "google-data");
805 osync_plugin_set_longname(plugin
, "Google calendar/plugin");
806 osync_plugin_set_description(plugin
, "Google calendar and contacts plugin");
808 osync_plugin_set_initialize(plugin
, gc_initialize
);
809 osync_plugin_set_finalize(plugin
, gc_finalize
);
810 osync_plugin_set_discover(plugin
, gc_discover
);
812 osync_plugin_env_register_plugin(env
, plugin
);
813 osync_plugin_unref(plugin
);
815 osync_trace(TRACE_EXIT
, "%s", __func__
);
819 osync_trace(TRACE_EXIT_ERROR
, "Unable to register: %s", osync_error_print(error
));
820 osync_error_unref(error
);
824 int get_version(void)