]> git.deb.at Git - pkg/abook.git/blob - vcard.c
reformat changelog entry
[pkg/abook.git] / vcard.c
1
2 /*
3  * Copyright 2012, RaphaĆ«l Droz <raphael.droz+floss@gmail.com>
4  *
5  * abook's wrapper for libvformat:
6  * fits a vcard parsed by libvformat into a usable abook item list
7  *
8  * see:
9  * libvformat's vf_iface.h
10  * http://www.imc.org/pdi/vcard-21.txt
11  * rfc 2426
12  * rfc 2739
13  */
14
15 #include <stdio.h>
16 #include <string.h>
17
18 #include "database.h"
19 #include "options.h" // bool
20 #include "misc.h" // abook_list_to_csv
21 #include "xmalloc.h"
22
23 #include "vcard.h"
24
25 int vcard_parse_file_libvformat(char *filename) {
26   VF_OBJECT_T*  vfobj;
27   if (!vf_read_file(&vfobj, filename)) {
28     fprintf(stderr, "Could not read VCF file %s\n", filename);
29     return 1;
30   }
31
32   // a libvformat property
33   VF_PROP_T* prop;
34   // property number (used for multivalued properties)
35   int props = 0;
36   // temporary values
37   abook_list *multivalues = NULL;
38   char *propval = 0;
39   bool phone_found;
40
41   do {
42     list_item item = item_create();
43     phone_found = false;
44     /* Note: libvformat use va_args, we *must* cast the last
45        NULL argument to (char*) for arch where
46        sizeof(int) != sizeof(char *) */
47
48     // fullname [ or struct-name [ or name ] ]
49     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "FN", (char*)0))
50       if ((propval = vf_get_prop_value_string(prop, 0)))
51         item_fput(item, NAME, xstrdup(propval));
52
53     if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "N", (char*)0)) {
54       // TODO: GIVENNAME, FAMILYNAME
55       propval = vf_get_prop_value_string(prop, 0);
56       if(propval)
57         item_fput(item, NAME, xstrdup(propval));
58     }
59
60     if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NAME", (char*)0)) {
61       propval = vf_get_prop_value_string(prop, 0);
62       if(propval)
63         item_fput(item, NAME, xstrdup(propval));
64     }
65
66     // email(s). (TODO: EMAIL;PREF: should be abook's first)
67     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "EMAIL", (char*)0)) {
68             do {
69                     props = 0;
70                     while ((propval = vf_get_prop_value_string(prop, props++))) {
71                             abook_list_append(&multivalues, propval);
72                     }
73             } while (vf_get_next_property(&prop));
74             item_fput(item, EMAIL, abook_list_to_csv(multivalues));
75             abook_list_free(&multivalues);
76     }
77
78     // format for ADR:
79     // PO Box, Extended Addr, Street, Locality, Region, Postal Code, Country
80     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", (char*)0)) {
81       props = 0;
82       // PO Box: abook ignores
83       vf_get_prop_value_string(prop, props++);
84
85       // ext-address
86       propval = vf_get_prop_value_string(prop, props++);
87       if(propval) item_fput(item, ADDRESS2, xstrdup(propval));
88       // address (street)
89       propval = vf_get_prop_value_string(prop, props++);
90       if(propval) item_fput(item, ADDRESS, xstrdup(propval));
91       // locality (city)
92       propval = vf_get_prop_value_string(prop, props++);
93       if(propval) item_fput(item, CITY, xstrdup(propval));
94       // region (state)
95       propval = vf_get_prop_value_string(prop, props++);
96       if(propval) item_fput(item, STATE, xstrdup(propval));
97       // postal-code (zip)
98       propval = vf_get_prop_value_string(prop, props++);
99       if(propval) item_fput(item, ZIP, xstrdup(propval));
100       // country
101       propval = vf_get_prop_value_string(prop, props++);
102       if(propval) item_fput(item, COUNTRY, xstrdup(propval));
103     }
104
105     // phone numbers
106     // home
107     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "HOME", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
108             item_fput(item, PHONE, xstrdup(propval)); phone_found = true;
109     }
110     // workphone
111     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "WORK", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
112             item_fput(item, WORKPHONE, xstrdup(propval)); phone_found = true;
113     }
114
115     // fax
116     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "FAX", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
117             item_fput(item, FAX, xstrdup(propval)); phone_found = true;
118     }
119
120     // cellphone
121     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "CELL", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
122             item_fput(item, MOBILEPHONE, xstrdup(propval)); phone_found = true;
123     }
124
125     // or grab any other one as default
126     if(! phone_found && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
127             item_fput(item, PHONE, xstrdup(propval));
128     }
129
130     // nick
131     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NICKNAME", (char*)0)) {
132             propval = vf_get_prop_value_string(prop, 0);
133             item_fput(item, NICK, xstrdup(propval));
134     }
135
136     // url
137     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "URL", (char*)0)) {
138       propval = vf_get_prop_value_string(prop, 0);
139       item_fput(item, URL, xstrdup(propval));
140     }
141
142     // notes
143     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NOTE", (char*)0)) {
144       propval = vf_get_prop_value_string(prop, 0);
145       item_fput(item, NOTES, xstrdup(propval));
146     }
147
148     // anniversary
149     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "BDAY", (char*)0)) {
150       propval = vf_get_prop_value_string(prop, 0);
151       item_fput(item, ANNIVERSARY, xstrdup(propval));
152     }
153
154     // (mutt) groups
155     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "CATEGORIES", (char*)0)) {
156             do {
157                     props = 0;
158                     while ((propval = vf_get_prop_value_string(prop, props++))) {
159                             abook_list_append(&multivalues, propval);
160                     }
161             } while (vf_get_next_property(&prop));
162             item_fput(item, GROUPS, abook_list_to_csv(multivalues));
163             abook_list_free(&multivalues);
164     }
165
166     add_item2database(item);
167     item_free(&item);
168   } while (vf_get_next_object(&vfobj));
169
170   return 0;
171 }