Added/fixed support for some fields.
[libgcal.git] / src / gcontact.c
blob657731df7bb94b8ea0150151405d5c1a5dc6fad5
1 /*
2 Copyright (c) 2008 Instituto Nokia de Tecnologia
3 All rights reserved.
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of the INdT nor the names of its contributors
14 may be used to endorse or promote products derived from this software
15 without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE.
29 /**
30 * @file gcontact.c
31 * @author Adenilson Cavalcanti da Silva <adenilson.silva@indt.org.br>
32 * @date Thu Jun 26 07:37:03 2008
34 * @brief libgcal google contacts user public API.
36 * Use this functions to handle common tasks when dealing with google contacts.
39 #ifdef HAVE_CONFIG_H
40 #include "config.h"
41 #else
42 #define _GNU_SOURCE
43 #endif
45 #include <string.h>
46 #include <stdio.h>
47 #include "gcontact.h"
48 #include "gcal_parser.h"
49 #include "internal_gcal.h"
52 /** Strings associated with phone number types */
53 const char* gcal_phone_type_str[] = {
54 "assistant", // P_ASSISTANT
55 "callback", // P_CALLBACK
56 "car", // P_CAR
57 "company_main", // P_COMPANY_MAIN
58 "fax", // P_FAX
59 "home", // P_HOME
60 "home_fax", // P_HOME_FAX
61 "isdn", // P_ISDN
62 "main", // P_MAIN
63 "mobile", // P_MOBILE
64 "other", // P_OTHER
65 "other_fax", // P_OTHER_FAX
66 "pager", // P_PAGER
67 "radio", // P_RADIO
68 "telex", // P_TELEX
69 "tty_tdd", // P_TTY_TDD
70 "work", // P_WORK
71 "work_fax", // P_WORK_FAX
72 "work_mobile", // P_WORK_MOBILE
73 "work_pager" // P_WORK_PAGER
76 /** Strings associated with email types */
77 const char* gcal_email_type_str[] = {
78 "home", // E_HOME
79 "other", // E_OTHER
80 "work" // E_WORK
83 gcal_contact_t gcal_contact_new(char *raw_xml)
85 gcal_contact_t contact = NULL;
86 dom_document *doc;
87 int result = -1;
89 contact = (gcal_contact_t) malloc(sizeof(struct gcal_contact));
90 if (!contact)
91 goto exit;
93 gcal_init_contact(contact);
94 if (!raw_xml)
95 goto exit;
97 /* Builds a doc, parse and init object */
98 doc = build_dom_document(raw_xml);
99 if (!doc)
100 goto cleanup;
102 result = extract_all_contacts(doc, contact, 1);
103 clean_dom_document(doc);
105 cleanup:
106 if (result) {
107 free(contact);
108 contact = NULL;
110 exit:
111 return contact;
114 void gcal_contact_delete(gcal_contact_t contact)
116 if (!contact)
117 return;
119 gcal_destroy_contact(contact);
120 free(contact);
124 int gcal_get_contacts(gcal_t gcalobj, struct gcal_contact_array *contact_array)
126 int result = -1;
127 if (contact_array)
128 contact_array->length = 0;
130 if ((!gcalobj) || (!contact_array))
131 return result;
133 result = gcal_dump(gcalobj, "GData-Version: 3.0");
134 if (result == -1) {
135 contact_array->entries = NULL;
136 contact_array->length = 0;
137 return result;
140 contact_array->entries = gcal_get_all_contacts(gcalobj,
141 &contact_array->length);
142 if (!contact_array->entries)
143 return result;
145 result = 0;
147 return result;
151 void gcal_cleanup_contacts(struct gcal_contact_array *contacts)
153 if (!contacts)
154 return;
156 gcal_destroy_contacts(contacts->entries, contacts->length);
157 contacts->length = 0;
158 contacts->entries = NULL;
163 int gcal_add_contact(gcal_t gcalobj, gcal_contact_t contact)
165 int result = -1;
166 struct gcal_contact updated;
167 gcal_init_contact(&updated);
169 if ((!gcalobj) || (!contact))
170 goto exit;
173 result = gcal_create_contact(gcalobj, contact, &updated);
174 if (result)
175 goto exit;
177 /* Swap updated fields: id, updated, edit_uri, etag, photo url */
178 if (contact->common.id)
179 free(contact->common.id);
180 contact->common.id = updated.common.id;
181 updated.common.id = NULL;
183 if (contact->common.updated)
184 free(contact->common.updated);
185 contact->common.updated = updated.common.updated;
186 updated.common.updated = NULL;
188 if (contact->common.edit_uri)
189 free(contact->common.edit_uri);
190 contact->common.edit_uri = updated.common.edit_uri;
191 updated.common.edit_uri = NULL;
193 if (contact->common.etag)
194 free(contact->common.etag);
195 contact->common.etag = updated.common.etag;
196 updated.common.etag = NULL;
198 if (contact->photo)
199 free(contact->photo);
200 contact->photo = updated.photo;
201 updated.photo = NULL;
203 /* Cleanup updated contact */
204 gcal_destroy_contact(&updated);
206 exit:
207 return result;
210 int gcal_update_contact(gcal_t gcalobj, gcal_contact_t contact)
212 int result = -1;
213 struct gcal_contact updated;
214 gcal_init_contact(&updated);
216 if ((!gcalobj) || (!contact))
217 goto exit;
220 result = gcal_edit_contact(gcalobj, contact, &updated);
221 if (result)
222 goto exit;
224 /* Swap updated fields: updated, edit_uri, etag */
225 if (contact->common.updated)
226 free(contact->common.updated);
227 contact->common.updated = updated.common.updated;
228 updated.common.updated = NULL;
230 if (contact->common.edit_uri)
231 free(contact->common.edit_uri);
232 contact->common.edit_uri = updated.common.edit_uri;
233 updated.common.edit_uri = NULL;
235 if (contact->common.etag)
236 free(contact->common.etag);
237 contact->common.etag = updated.common.etag;
238 updated.common.etag = NULL;
240 if (contact->photo)
241 free(contact->photo);
242 contact->photo = updated.photo;
243 updated.photo = NULL;
245 /* Cleanup updated contact */
246 gcal_destroy_contact(&updated);
248 exit:
249 return result;
252 int gcal_erase_contact(gcal_t gcalobj, gcal_contact_t contact)
254 int result = -1;
255 if ((!gcalobj) || (!contact))
256 goto exit;
258 result = gcal_delete_contact(gcalobj, contact);
259 exit:
260 return result;
263 int gcal_get_updated_contacts(gcal_t gcal_obj,
264 struct gcal_contact_array *contacts,
265 char *timestamp)
267 int result = -1;
268 if (contacts)
269 contacts->length = 0;
271 if ((!gcal_obj) || (!contacts))
272 return result;
274 result = gcal_query_updated(gcal_obj, timestamp, "GData-Version: 3.0");
275 if (result) {
276 contacts->entries = NULL;
277 contacts->length = 0;
278 return result;
281 contacts->entries = gcal_get_all_contacts(gcal_obj, &contacts->length);
282 if (contacts->entries)
283 result = 0;
285 return result;
288 gcal_contact_t gcal_contact_element(struct gcal_contact_array *contacts,
289 size_t _index)
292 struct gcal_contact *contact = NULL;
293 if ((!contacts) || (_index > (contacts->length - 1)) ||
294 (contacts->length == 0))
295 return contact;
297 contact = &contacts->entries[_index];
298 return contact;
301 char *gcal_contact_get_xml(gcal_contact_t contact)
303 if ((!contact))
304 return NULL;
305 return gcal_get_xml(&(contact->common));
308 char *gcal_contact_get_id(gcal_contact_t contact)
310 if ((!contact))
311 return NULL;
312 return gcal_get_id(&(contact->common));
315 char *gcal_contact_get_updated(gcal_contact_t contact)
317 if ((!contact))
318 return NULL;
319 return gcal_get_updated(&(contact->common));
322 char *gcal_contact_get_title(gcal_contact_t contact)
324 if ((!contact))
325 return NULL;
326 return gcal_get_title(&(contact->common));
329 char *gcal_contact_get_url(gcal_contact_t contact)
331 if ((!contact))
332 return NULL;
333 return gcal_get_url(&(contact->common));
336 char *gcal_contact_get_etag(gcal_contact_t contact)
338 if ((!contact))
339 return NULL;
340 return gcal_get_etag(&(contact->common));
343 char gcal_contact_is_deleted(gcal_contact_t contact)
345 if ((!contact))
346 return -1;
347 return gcal_get_deleted(&(contact->common));
351 /* This are the fields unique to calendar contacts */
352 int gcal_contact_get_emails_count(gcal_contact_t contact)
354 if ((!contact))
355 return -1;
356 return contact->emails_nr;
359 int gcal_contact_get_pref_email(gcal_contact_t contact)
361 if ((!contact))
362 return -1;
363 return contact->pref_email;
366 char *gcal_contact_get_email_address(gcal_contact_t contact, int i)
368 if ((!contact))
369 return NULL;
370 if (!(contact->emails_field) || (i >= contact->emails_nr))
371 return NULL;
372 return contact->emails_field[i];
375 gcal_email_type gcal_contact_get_email_address_type(gcal_contact_t contact, int i)
377 gcal_email_type result = E_INVALID;
378 int j;
380 if ((!contact))
381 return result;
382 if (!(contact->emails_type) || (i >= contact->emails_nr))
383 return result;
384 for (j = 0; j < E_ITEMS_COUNT; j++)
385 if (!strcmp(contact->emails_type[i], gcal_email_type_str[j]))
386 result = j;
387 return result;
390 char *gcal_contact_get_content(gcal_contact_t contact)
392 if ((!contact))
393 return NULL;
394 return contact->content;
397 char *gcal_contact_get_organization(gcal_contact_t contact)
399 if ((!contact))
400 return NULL;
401 return contact->org_name;
404 char *gcal_contact_get_profission(gcal_contact_t contact)
406 if ((!contact))
407 return NULL;
408 return contact->org_title;
411 char *gcal_contact_get_im(gcal_contact_t contact)
413 if ((!contact))
414 return NULL;
415 return contact->im;
418 char *gcal_contact_get_homepage(gcal_contact_t contact)
420 if ((!contact))
421 return NULL;
422 return contact->homepage;
425 char *gcal_contact_get_blog(gcal_contact_t contact)
427 if ((!contact))
428 return NULL;
429 return contact->blog;
432 int gcal_contact_get_phone_numbers_count(gcal_contact_t contact)
434 if ((!contact))
435 return -1;
436 return contact->phone_numbers_nr;
439 char *gcal_contact_get_phone_number(gcal_contact_t contact, int i)
441 if ((!contact))
442 return NULL;
443 if (!(contact->phone_numbers_field) || (i >= contact->phone_numbers_nr))
444 return NULL;
445 return contact->phone_numbers_field[i];
448 gcal_phone_type gcal_contact_get_phone_number_type(gcal_contact_t contact, int i)
450 gcal_phone_type result = P_INVALID;
451 int j;
453 if ((!contact))
454 return result;
455 if (!(contact->phone_numbers_type) || (i >= contact->phone_numbers_nr))
456 return result;
457 for (j = 0; j < P_ITEMS_COUNT; j++)
458 if (!strcmp(contact->phone_numbers_type[i], gcal_phone_type_str[j]))
459 result = j;
460 return result;
463 char *gcal_contact_get_address(gcal_contact_t contact)
465 if ((!contact))
466 return NULL;
467 return contact->post_address;
470 char *gcal_contact_get_structured_address(gcal_contact_t contact, const char *address_field_key)
472 struct gcal_structured_postal_address *temp_structured_address;
474 if ((!contact))
475 return NULL;
477 for(temp_structured_address = contact->structured_address; temp_structured_address != NULL; temp_structured_address = temp_structured_address->next_address_field)
479 if(!strcmp(address_field_key,temp_structured_address->address_field_key))
480 return temp_structured_address->address_field_value;
482 return NULL;
485 int gcal_contact_get_groupMembership_count(gcal_contact_t contact)
487 if ((!contact))
488 return -1;
489 return contact->groupMembership_nr;
492 char *gcal_contact_get_groupMembership(gcal_contact_t contact, int i)
494 if ((!contact))
495 return NULL;
496 if (!(contact->groupMembership) || (i >= contact->groupMembership_nr))
497 return NULL;
498 return contact->groupMembership[i];
501 char *gcal_contact_get_photo(gcal_contact_t contact)
503 if ((!contact))
504 return NULL;
506 return contact->photo_data;
509 unsigned int gcal_contact_get_photolength(gcal_contact_t contact)
511 if ((!contact))
512 return -1;
514 return contact->photo_length;
517 char *gcal_contact_get_birthday(gcal_contact_t contact)
519 if ((!contact))
520 return NULL;
521 return contact->birthday;
524 /* Here starts the gcal_contact setters */
525 int gcal_contact_set_title(gcal_contact_t contact, const char *field)
527 int result = -1;
529 if ((!contact) || (!field))
530 return result;
532 if (contact->common.title)
533 free(contact->common.title);
535 contact->common.title = strdup(field);
536 if (contact->common.title)
537 result = 0;
539 return result;
542 int gcal_contact_delete_email_addresses(gcal_contact_t contact)
544 int result = -1;
545 int temp;
547 if (!contact)
548 return result;
550 if (contact->emails_nr > 0) {
551 for (temp = 0; temp < contact->emails_nr; temp++) {
552 if (contact->emails_field[temp])
553 free(contact->emails_field[temp]);
554 if (contact->emails_type[temp])
555 free(contact->emails_type[temp]);
557 free(contact->emails_field);
558 free(contact->emails_type);
561 contact->emails_nr = contact->pref_email = 0;
562 contact->emails_field = contact->emails_type = 0;
564 result = 0;
566 return result;
569 int gcal_contact_add_email_address(gcal_contact_t contact, const char *field, gcal_email_type type, int pref)
571 int result = -1;
573 if ((!contact) || (!field) || (type<0) || (type>=E_ITEMS_COUNT))
574 return result;
576 contact->emails_field = (char**) realloc(contact->emails_field, (contact->emails_nr+1) * sizeof(char*));
577 contact->emails_field[contact->emails_nr] = strdup(field);
579 contact->emails_type = (char**) realloc(contact->emails_type, (contact->emails_nr+1) * sizeof(char*));
580 contact->emails_type[contact->emails_nr] = strdup(gcal_email_type_str[type]);
582 if (pref)
583 contact->pref_email = contact->emails_nr;
585 contact->emails_nr++;
587 result = 0;
589 return result;
592 int gcal_contact_set_url(gcal_contact_t contact, const char *field)
594 int result = -1;
596 if ((!contact) || (!field))
597 return result;
599 if (contact->common.edit_uri)
600 free(contact->common.edit_uri);
602 contact->common.edit_uri = strdup(field);
603 if (contact->common.edit_uri)
604 result = 0;
606 return result;
610 int gcal_contact_set_id(gcal_contact_t contact, const char *field)
612 int result = -1;
614 if ((!contact) || (!field))
615 return result;
617 if (contact->common.id)
618 free(contact->common.id);
620 contact->common.id = strdup(field);
621 if (contact->common.id)
622 result = 0;
624 return result;
628 int gcal_contact_set_etag(gcal_contact_t contact, const char *field)
630 int result = -1;
632 if ((!contact) || (!field))
633 return result;
635 if (contact->common.etag)
636 free(contact->common.etag);
638 contact->common.etag = strdup(field);
639 if (contact->common.etag)
640 result = 0;
642 return result;
645 int gcal_contact_delete_phone_numbers(gcal_contact_t contact)
647 int result = -1;
648 int temp;
650 if (!contact)
651 return result;
653 if (contact->phone_numbers_nr > 0) {
654 for (temp = 0; temp < contact->phone_numbers_nr; temp++) {
655 if (contact->phone_numbers_field[temp])
656 free(contact->phone_numbers_field[temp]);
657 if (contact->phone_numbers_type[temp])
658 free(contact->phone_numbers_type[temp]);
660 free(contact->phone_numbers_field);
661 free(contact->phone_numbers_type);
664 contact->phone_numbers_nr = 0;
666 result = 0;
668 return result;
671 int gcal_contact_add_phone_number(gcal_contact_t contact, const char *field, gcal_phone_type type)
673 int result = -1;
675 if ((!contact) || (!field) || (type<0) || (type>=P_ITEMS_COUNT))
676 return result;
678 contact->phone_numbers_field = (char**) realloc(contact->phone_numbers_field, (contact->phone_numbers_nr+1) * sizeof(char*));
679 contact->phone_numbers_field[contact->phone_numbers_nr] = strdup(field);
681 contact->phone_numbers_type = (char**) realloc(contact->phone_numbers_type, (contact->phone_numbers_nr+1) * sizeof(char*));
682 contact->phone_numbers_type[contact->phone_numbers_nr] = strdup(gcal_phone_type_str[type]);
684 contact->phone_numbers_nr++;
686 result = 0;
688 return result;
691 int gcal_contact_set_address(gcal_contact_t contact, const char *field)
693 int result = -1;
695 if ((!contact) || (!field))
696 return result;
698 if (contact->post_address)
699 free(contact->post_address);
701 contact->post_address = strdup(field);
702 if (contact->post_address)
703 result = 0;
705 return result;
708 int gcal_contact_set_structured_address(gcal_contact_t contact, const char *address_field_key, const char *address_field_value )
710 struct gcal_structured_postal_address *temp_structured_address;
712 if (!contact)
713 return -1;
715 if(address_field_value == NULL)
716 address_field_value = "";
718 if(contact->structured_address->address_field_key == NULL) {
719 contact->structured_address->address_field_key = (char *)malloc(strlen(address_field_key)+1);
720 strcpy(contact->structured_address->address_field_key,address_field_key);
722 contact->structured_address->address_field_value = (char *)malloc(strlen(address_field_value)+1);
723 strcpy(contact->structured_address->address_field_value,address_field_value);
725 contact->structured_address->next_address_field = NULL;
726 return 0;
728 for(temp_structured_address = contact->structured_address; ; temp_structured_address = temp_structured_address->next_address_field) {
729 if(!strcmp(address_field_key,temp_structured_address->address_field_key)) {
730 if(temp_structured_address->address_field_value != NULL) {
731 free(temp_structured_address->address_field_value);
732 temp_structured_address->address_field_value = (char *)malloc(strlen(address_field_value)+1);
733 strcpy(temp_structured_address->address_field_value,address_field_value);
734 return 0;
737 if(temp_structured_address->next_address_field == NULL) {
738 temp_structured_address->next_address_field = (struct gcal_structured_postal_address *)malloc(sizeof(struct gcal_structured_postal_address));
739 temp_structured_address = temp_structured_address->next_address_field;
741 temp_structured_address->address_field_key = (char *)malloc(strlen(address_field_key)+1);
742 strcpy(temp_structured_address->address_field_key,address_field_key);
744 temp_structured_address->address_field_value = (char *)malloc(strlen(address_field_value)+1);
745 strcpy(temp_structured_address->address_field_value,address_field_value);
747 temp_structured_address->next_address_field = NULL;
748 return 0;
752 return -1;
755 int gcal_contact_delete_groupMembership(gcal_contact_t contact)
757 int result = -1;
758 int temp;
760 if (!contact)
761 return result;
763 if (contact->groupMembership_nr > 0) {
764 for (temp = 0; temp < contact->groupMembership_nr; temp++) {
765 if (contact->groupMembership[temp])
766 free(contact->groupMembership[temp]);
768 free(contact->groupMembership);
771 contact->groupMembership_nr = 0;
773 result = 0;
775 return result;
778 int gcal_contact_add_groupMembership(gcal_contact_t contact, char *field)
780 int result = -1;
782 if ((!contact) || (!field))
783 return result;
785 contact->groupMembership = (char**) realloc(contact->groupMembership, (contact->groupMembership_nr+1) * sizeof(char*));
786 contact->groupMembership[contact->groupMembership_nr] = strdup(field);
788 contact->groupMembership_nr++;
790 result = 0;
792 return result;
795 int gcal_contact_set_profission(gcal_contact_t contact, const char *field)
797 int result = -1;
799 if ((!contact) || (!field))
800 return result;
802 if (contact->org_title)
803 free(contact->org_title);
805 contact->org_title = strdup(field);
806 if (contact->org_title)
807 result = 0;
809 return result;
813 int gcal_contact_set_organization(gcal_contact_t contact, const char *field)
815 int result = -1;
817 if ((!contact) || (!field))
818 return result;
820 if (contact->org_name)
821 free(contact->org_name);
823 contact->org_name = strdup(field);
824 if (contact->org_name)
825 result = 0;
827 return result;
830 int gcal_contact_set_content(gcal_contact_t contact, const char *field)
832 int result = -1;
834 if ((!contact) || (!field))
835 return result;
837 if (contact->content)
838 free(contact->content);
840 contact->content = strdup(field);
841 if (contact->content)
842 result = 0;
844 return result;
848 int gcal_contact_set_photo(gcal_contact_t contact, const char *field,
849 int length)
851 int result = -1;
853 if ((!contact) || (!field))
854 return result;
856 if (contact->photo_data)
857 if (contact->photo_length > 1)
858 free(contact->photo_data);
860 if (!(contact->photo_data = malloc(length * sizeof(unsigned char))))
861 return result;
863 memcpy(contact->photo_data, field, length);
864 contact->photo_length = length;
865 result = 0;
867 return result;
870 int gcal_contact_set_birthday(gcal_contact_t contact, const char *field)
872 int result = -1;
874 if ((!contact) || (!field))
875 return result;
877 if (contact->birthday)
878 free(contact->birthday);
880 contact->birthday = strdup(field);
881 if (contact->birthday)
882 result = 0;
884 return result;
887 int gcal_contact_set_homepage(gcal_contact_t contact, const char *field)
889 int result = -1;
891 if ((!contact) || (!field))
892 return result;
894 if (contact->homepage)
895 free(contact->homepage);
897 contact->homepage = strdup(field);
898 if (contact->homepage)
899 result = 0;
901 return result;
904 int gcal_contact_set_blog(gcal_contact_t contact, const char *field)
906 int result = -1;
908 if ((!contact) || (!field))
909 return result;
911 if (contact->blog)
912 free(contact->blog);
914 contact->blog = strdup(field);
915 if (contact->blog)
916 result = 0;
918 return result;