extern abook_field_list *fields_list;
extern int fields_count;
+// see also enum field_types @database.h
+extern abook_field standard_fields[];
/*
* function declarations
* csv import filter
*/
+/* This is used by both allcsv_export_database() and csv_export_common()
+ to distinguish between standard and defined fields.
+ To avoid confusions this should stay > ITEM_FIELDS */
+#define CUSTOM_FIELD_START_INDEX (ITEM_FIELDS + 10)
+
/* FIXME
* these files should be parsed according to a certain
* lay out, or the default if layout is not given, at
"FN", /* FORMATTED NAME */
"EMAIL", /* EMAIL */
"ADR", /* ADDRESS */
- "ADR", /* ADDRESS2 - not used */
+ "ADR", /* ADDRESS2 */
"ADR", /* CITY */
"ADR", /* STATE */
"ADR", /* ZIP */
NULL /* not implemented: ANNIVERSARY, ITEM_FIELDS */
};
-/*
- * mappings between vCard ADR field and abook's ADDRESS
- * see rfc2426 section 3.2.1
- */
-static int vcard_address_fields[] = {
- -1, /* vCard(post office box) - not used */
- -1, /* vCard(the extended address) - not used */
- 2, /* vCard(the street address) - ADDRESS */
- 4, /* vCard(the locality) - CITY */
- 5, /* vCard(the region) - STATE */
- 6, /* vCard(the postal code) - ZIP */
- 7 /* vCard(the country name) - COUNTRY */
-};
-
enum {
VCARD_KEY = 0,
VCARD_KEY_ATTRIBUTE,
}
}
+
+/*
+ * mappings between vCard ADR field and abook's ADDRESS
+ * see rfc2426 section 3.2.1
+ */
static void
vcard_parse_address(list_item item, char *line)
{
- int i;
- int k;
char *value;
- char *address_field;
value = vcard_get_line_element(line, VCARD_VALUE);
if(!value)
return;
- address_field = value;
- for(i=k=0; value[i]; i++) {
- if(value[i] == ';') {
- value[i] = '\0';
- if(vcard_address_fields[k] >= 0) {
- item[vcard_address_fields[k]] = xstrdup(address_field);
- }
- address_field = &value[i+1];
- k++;
- if((k+1)==(sizeof(vcard_address_fields)/sizeof(*vcard_address_fields)))
- break;
- }
- }
- item[vcard_address_fields[k]] = xstrdup(address_field);
- xfree(value);
+ // vCard(post office box) - not used
+ strsep(&value, ";");
+ // vCard(the extended address)
+ item_fput(item, ADDRESS2, xstrdup(strsep(&value, ";")));
+ // vCard(the street address)
+ item_fput(item, ADDRESS, xstrdup(strsep(&value, ";")));
+ // vCard(the locality)
+ item_fput(item, CITY, xstrdup(strsep(&value, ";")));
+ // vCard(the region)
+ item_fput(item, STATE, xstrdup(strsep(&value, ";")));
+ // vCard(the postal code)
+ item_fput(item, ZIP, xstrdup(strsep(&value, ";")));
+ // vCard(the country name)
+ item_fput(item, COUNTRY, xstrdup(strsep(&value, ";")));
+
+ if(*value) xfree(value);
}
static void
else if(CSV_IS_SPECIAL(fields[i])) {
if(special_func)
(*special_func)(out, e.item, fields[i]);
- } else
+ }
+ else if(fields[i] >= CUSTOM_FIELD_START_INDEX) {
+ fprintf(out, "\"%s\"",
+ safe_str(db_fget_byid(e.item, fields[i] - CUSTOM_FIELD_START_INDEX)));
+ }
+ else
/*fprintf(out,(
strchr(safe_str(database[e.item][field_idx(fields[i])]), ',') ||
strchr(safe_str(database[e.item][field_idx(fields[i])]), '\"')) ?
* TODO: Should get these atomatically from abook_fileds
* - JH
*/
- int allcsv_export_fields[] = {
+ int allcsv_export_fields[ITEM_FIELDS + 6] = { // only the 5 custom fields are allowed so far
NAME,
EMAIL,
ADDRESS,
PHONE,
WORKPHONE,
FAX,
- MOBILEPHONE,
+ MOBILEPHONE, // spelt "mobile" in standard_fields
NICK,
URL,
NOTES,
};
fprintf(out, "#");
- fprintf(out, "\"NAME\",");
- fprintf(out, "\"EMAIL\",");
- fprintf(out, "\"ADDRESS\",");
- fprintf(out, "\"ADDRESS2\",");
- fprintf(out, "\"CITY\",");
- fprintf(out, "\"STATE\",");
- fprintf(out, "\"ZIP\",");
- fprintf(out, "\"COUNTRY\",");
- fprintf(out, "\"PHONE\",");
- fprintf(out, "\"WORKPHONE\",");
- fprintf(out, "\"FAX\",");
- fprintf(out, "\"MOBILEPHONE\",");
- fprintf(out, "\"NICK\",");
- fprintf(out, "\"URL\",");
- fprintf(out, "\"NOTES\",");
- fprintf(out, "\"ANNIVERSARY\",");
- fprintf(out, "\"GROUPS\"\n");
+ int i = 0;
+ while(allcsv_export_fields[i+1] != CSV_LAST) {
+ fprintf(out, "\"%s\",", standard_fields[i++].key);
+ }
+ fprintf(out, "\"%s\"", standard_fields[i].key);
+
+ /*
+ Custom fields handling:
+ This loop appends custom fields' id at the end of allcsv_export_fields and shift
+ the CSV_LAST sentinel value each time one is found.
+ CUSTOM_FIELD_START_INDEX is added to these index values so csv_export_common()
+ can later recognize them and call db_fget_byid() instead of the traditional db_fget()
+
+ It only search for defined the [legacy?] "custom" fields.
+ */
+
+ // pointer to the end of the field list
+ int append_field = ITEM_FIELDS;
+ // custom field's trailing number (between 1 and 5)
+ int j;
+ // full custom field name, eg "custom4"
+ char custom_field_key[8];
+ // index used by custom_field_key
+ int field_no;
+ // name of the defined field <field_no> as chosen by the user
+ char *custom_field_name;
+
+ for (j = 1; j <= 5; j++) {
+ snprintf(custom_field_key, 8, "custom%d", j++);
+ if(find_declared_field(custom_field_key)) {
+ find_field_number(custom_field_key, &field_no);
+ get_field_info(field_no, NULL, &custom_field_name, NULL);
+ // append the field to the list
+ allcsv_export_fields[append_field] = field_no + CUSTOM_FIELD_START_INDEX;
+ allcsv_export_fields[++append_field] = CSV_LAST;
+ // print column name
+ fprintf(out, ",\"%s\"", custom_field_name);
+ }
+ }
+ free(custom_field_name);
+ fprintf(out, "\n");
csv_export_common(out, e, allcsv_export_fields, NULL);
void
vcard_export_item(FILE *out, int item)
{
- int j;
+ int j, email_no;
char *name, *tmp;
abook_list *emails, *em;
fprintf(out, "BEGIN:VCARD\r\nFN:%s\r\n",
tmp = db_email_get(item);
if(*tmp) {
emails = csv_to_abook_list(tmp);
-
- for(em = emails; em; em = em->next)
- fprintf(out, "EMAIL;INTERNET:%s\r\n", em->data);
+ fprintf(out, "EMAIL;PREF;INTERNET:%s\r\n", emails->data);
+ email_no = 1;
+ for(em = emails->next; em; em = em->next, email_no++ )
+ fprintf(out, "EMAIL;%d;INTERNET:%s\r\n", email_no, em->data);
abook_list_free(&emails);
}
return 0;
}
-// see also enum field_types @database.h
-extern abook_field standard_fields[];
static int
find_field_enum(char *s) {
int i = -1;