]> git.deb.at Git - pkg/abook.git/blob - vcard.c
vcard import: fixing the "ADR" field
[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 "xmalloc.h"
20
21 #include "vcard.h"
22
23 int vcard_parse_file_libvformat(char *filename) {
24   VF_OBJECT_T*  vfobj;
25   if (!vf_read_file(&vfobj, filename)) {
26     fprintf(stderr, "Could not read VCF file %s\n", filename);
27     return 1;
28   }
29
30   // a libvformat property
31   VF_PROP_T* prop;
32   // property number (used for multivalued properties)
33   int props = 0;
34   // temporary values
35   char *propval;
36   char multival[MAX_FIELD_LEN] = { 0 };
37   size_t available = MAX_FIELD_LEN;
38
39   do {
40     list_item item = item_create();
41
42     // fullname [ or struct-name [ or name ] ]
43     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "FN", NULL))
44       if ((propval = vf_get_prop_value_string(prop, 0)))
45         item_fput(item, NAME, xstrdup(propval));
46
47     if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "N", "*", NULL)) {
48       // TODO: GIVENNAME , FAMILYNAME
49       propval = vf_get_prop_value_string(prop, 0);
50       if(propval)
51         item_fput(item, NAME, xstrdup(propval));
52     }
53
54     if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NAME", NULL)) {
55       propval = vf_get_prop_value_string(prop, 0);
56       if(propval)
57         item_fput(item, NAME, xstrdup(propval));
58     }
59
60     // email(s)
61     // TODO: use our strconcat() ?
62     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "EMAIL", NULL)) {
63       props = 0;
64       available = MAX_FIELD_LEN;
65       while (available > 0 && props < 5) {
66         propval = vf_get_prop_value_string(prop, props++);
67         if(!propval) continue;
68         if (available > 0 && *multival != 0)
69           strncat(multival, ",", available--);
70         strncat(multival, propval, available);
71         available -= strlen(propval);
72       }
73       if (available < MAX_FIELD_LEN)
74         item_fput(item, EMAIL, xstrdup(multival));
75     }
76
77     // format for ADR:
78     // PO Box, Extended Addr, Street, Locality, Region, Postal Code, Country
79     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", NULL)) {
80       props = 0;
81       // PO Box: abook ignores
82       vf_get_prop_value_string(prop, props++);
83
84       // ext-address
85       propval = vf_get_prop_value_string(prop, props++);
86       if(propval) item_fput(item, ADDRESS2, xstrdup(propval));
87       // address (street)
88       propval = vf_get_prop_value_string(prop, props++);
89       if(propval) item_fput(item, ADDRESS, xstrdup(propval));
90       // locality (city)
91       propval = vf_get_prop_value_string(prop, props++);
92       if(propval) item_fput(item, CITY, xstrdup(propval));
93       // region (state)
94       propval = vf_get_prop_value_string(prop, props++);
95       if(propval) item_fput(item, STATE, xstrdup(propval));
96       // postal-code (zip)
97       propval = vf_get_prop_value_string(prop, props++);
98       if(propval) item_fput(item, ZIP, xstrdup(propval));
99       // country
100       propval = vf_get_prop_value_string(prop, props++);
101       if(propval) item_fput(item, COUNTRY, xstrdup(propval));
102     }
103
104
105     /*
106     // city: not in libvformat
107     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", "CITY", NULL)) {
108       propval = vf_get_prop_value_string(prop, 0);
109       item_fput(item, CITY, xstrdup(propval));
110     }
111     // state
112     // zip
113     // country
114     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "C", NULL)) {
115       propval = vf_get_prop_value_string(prop, 0);
116       item_fput(item, COUNTRY, xstrdup(propval));
117     }
118     */
119
120     // phone
121     // check for HOME
122     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "HOME")) {
123       propval = vf_get_prop_value_string(prop, 0);
124       item_fput(item, PHONE, xstrdup(propval));
125     }
126     // or grab a more generic one otherwise
127     else if(vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", NULL)) {
128       propval = vf_get_prop_value_string(prop, 0);
129       item_fput(item, PHONE, xstrdup(propval));
130     }
131
132     // workphone
133     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "WORK", NULL)) {
134       propval = vf_get_prop_value_string(prop, 0);
135       item_fput(item, WORKPHONE, xstrdup(propval));
136     }
137
138     // fax
139     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "FAX", NULL)) {
140       propval = vf_get_prop_value_string(prop, 0);
141       item_fput(item, FAX, xstrdup(propval));
142     }
143
144     // cellphone
145     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "CELL", NULL)) {
146       propval = vf_get_prop_value_string(prop, 0);
147       item_fput(item, MOBILEPHONE, xstrdup(propval));
148     }
149
150     // nick
151     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NICKNAME", NULL)) {
152       propval = vf_get_prop_value_string(prop, 0);
153       item_fput(item, NICK, xstrdup(propval));
154     }
155
156     // url
157     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "URL", NULL)) {
158       propval = vf_get_prop_value_string(prop, 0);
159       item_fput(item, URL, xstrdup(propval));
160     }
161
162     // notes
163     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NOTE", NULL)) {
164       propval = vf_get_prop_value_string(prop, 0);
165       item_fput(item, NOTES, xstrdup(propval));
166     }
167
168     // anniversary
169     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "BDAY", NULL)) {
170       propval = vf_get_prop_value_string(prop, 0);
171       item_fput(item, ANNIVERSARY, xstrdup(propval));
172     }
173
174     // (mutt) groups
175     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "CATEGORIES", NULL)) {
176         props = 0;
177         available = MAX_FIELD_LEN;
178         *multival = 0;
179         while (available > 0 && props < 5) {
180           propval = vf_get_prop_value_string(prop, props++);
181           if(!propval) continue;
182           if (available > 0 && *multival != 0)
183             strncat(multival, ",", available--);
184           strncat(multival, propval, available);
185           available -= strlen(propval);
186         }
187         if (available < MAX_FIELD_LEN)
188           item_fput(item, GROUPS, xstrdup(multival));
189     }
190
191     add_item2database(item);
192     item_free(&item);
193   } while (vf_get_next_object(&vfobj));
194
195   return 0;
196 }