/* we try to be as forgiving as we possibly can here - this isn't a
 * validator.  Almost nothing is considered a fatal error.  We always
 * try to return *something*.
 */
static void
parse (EVCard *evc, const char *str)
{
	char *buf ;
	char *p;
	EVCardAttribute *attr;

	buf = make_valid_utf8 (str);

	//buf = fold_lines (buf);

	d(printf ("BEFORE FOLDING:\n"));
	d(printf (str));
	d(printf ("\n\nAFTER FOLDING:\n"));
	d(printf (buf));

	p = buf;

	attr = read_attribute (&p);
	if (!attr || attr->group || g_ascii_strcasecmp (attr->name, "begin")) {
		g_warning ("vcard began without a BEGIN:VCARD\n");
	}
	if (attr && !g_ascii_strcasecmp (attr->name, "begin")) {
		e_vcard_attribute_free (attr);
		attr = NULL;
	} else if (attr)
		e_vcard_add_attribute (evc, attr);

	while (*p) {
		EVCardAttribute *next_attr = read_attribute (&p);

		if (next_attr) {
			attr = next_attr;

			if (g_ascii_strcasecmp (next_attr->name, "end"))
				e_vcard_add_attribute (evc, next_attr);
			else
				break;
		}
	}

	if (!attr || attr->group || g_ascii_strcasecmp (attr->name, "end")) {
		g_warning ("vcard ended without END:VCARD\n");
	}

	if (attr && !g_ascii_strcasecmp (attr->name, "end"))
		e_vcard_attribute_free (attr);

	g_free (buf);

	evc->priv->attributes = g_list_reverse (evc->priv->attributes);
}
/**
 * e_vcard_remove_attributes:
 * @evc: vcard object
 * @attr_group: group name of attributes to be removed
 * @attr_name: name of the arributes to be removed
 *
 * Removes all the attributes with group name and attribute name equal to
 * passed in values. If @attr_group is %NULL or an empty string,
 * it removes all the attributes with passed in name irrespective of
 * their group names.
 **/
void
e_vcard_remove_attributes (EVCard *evc, const char *attr_group, const char *attr_name)
{
	GList *attr;

	g_return_if_fail (E_IS_VCARD (evc));
	g_return_if_fail (attr_name != NULL);

	attr = evc->priv->attributes;
	while (attr) {
		GList *next_attr;
		EVCardAttribute *a = attr->data;

		next_attr = attr->next;

		if (((!attr_group || *attr_group == '\0') ||
		     (attr_group && !g_ascii_strcasecmp (attr_group, a->group))) &&
		    ((!attr_name && !a->name) || !g_ascii_strcasecmp (attr_name, a->name))) {

			/* matches, remove/delete the attribute */
			evc->priv->attributes = g_list_delete_link (evc->priv->attributes, attr);

			e_vcard_attribute_free (a);
		}

		attr = next_attr;
	}
}
/**
 * e_vcard_remove_attribute:
 * @evc: an #EVCard
 * @attr: an #EVCardAttribute to remove
 *
 * Removes @attr from @evc and frees it.
 **/
void
e_vcard_remove_attribute (EVCard *evc, EVCardAttribute *attr)
{
	g_return_if_fail (E_IS_VCARD (evc));
	g_return_if_fail (attr != NULL);

	evc->priv->attributes = g_list_remove (evc->priv->attributes, attr);
	e_vcard_attribute_free (attr);
}
Ejemplo n.º 4
0
/* utility functions shared between all contact importers */
static void
preview_contact (EWebViewPreview *preview,
                 EContact *contact)
{
	gint idx;
	gboolean had_value = FALSE;

	const gint fields[] = {
		E_CONTACT_FILE_AS,
		E_CONTACT_CATEGORIES,

		E_CONTACT_IS_LIST,
		E_CONTACT_LIST_SHOW_ADDRESSES,
		E_CONTACT_WANTS_HTML,

		E_CONTACT_FULL_NAME,
		E_CONTACT_GIVEN_NAME,
		E_CONTACT_FAMILY_NAME,
		E_CONTACT_NICKNAME,
		E_CONTACT_SPOUSE,
		E_CONTACT_BIRTH_DATE,
		E_CONTACT_ANNIVERSARY,
		E_CONTACT_MAILER,
		E_CONTACT_EMAIL,

		-1,

		E_CONTACT_ORG,
		E_CONTACT_ORG_UNIT,
		E_CONTACT_OFFICE,
		E_CONTACT_TITLE,
		E_CONTACT_ROLE,
		E_CONTACT_MANAGER,
		E_CONTACT_ASSISTANT,

		-1,

		E_CONTACT_PHONE_ASSISTANT,
		E_CONTACT_PHONE_BUSINESS,
		E_CONTACT_PHONE_BUSINESS_2,
		E_CONTACT_PHONE_BUSINESS_FAX,
		E_CONTACT_PHONE_CALLBACK,
		E_CONTACT_PHONE_CAR,
		E_CONTACT_PHONE_COMPANY,
		E_CONTACT_PHONE_HOME,
		E_CONTACT_PHONE_HOME_2,
		E_CONTACT_PHONE_HOME_FAX,
		E_CONTACT_PHONE_ISDN,
		E_CONTACT_PHONE_MOBILE,
		E_CONTACT_PHONE_OTHER,
		E_CONTACT_PHONE_OTHER_FAX,
		E_CONTACT_PHONE_PAGER,
		E_CONTACT_PHONE_PRIMARY,
		E_CONTACT_PHONE_RADIO,
		E_CONTACT_PHONE_TELEX,
		E_CONTACT_PHONE_TTYTDD,

		-1,

		E_CONTACT_ADDRESS_HOME,
		E_CONTACT_ADDRESS_WORK,
		E_CONTACT_ADDRESS_OTHER,

		-1,

		E_CONTACT_HOMEPAGE_URL,
		E_CONTACT_BLOG_URL,
		E_CONTACT_CALENDAR_URI,
		E_CONTACT_FREEBUSY_URL,
		E_CONTACT_ICS_CALENDAR,
		E_CONTACT_VIDEO_URL,

		-1,

		E_CONTACT_IM_AIM,
		E_CONTACT_IM_GROUPWISE,
		E_CONTACT_IM_JABBER,
		E_CONTACT_IM_YAHOO,
		E_CONTACT_IM_MSN,
		E_CONTACT_IM_ICQ,
		E_CONTACT_IM_GADUGADU,
		E_CONTACT_IM_SKYPE,

		-1,

		E_CONTACT_NOTE
	};

	g_return_if_fail (preview != NULL);
	g_return_if_fail (contact != NULL);

	for (idx = 0; idx < G_N_ELEMENTS (fields); idx++) {
		EContactField field;

		if (fields[idx] == -1) {
			if (had_value)
				e_web_view_preview_add_empty_line (preview);
			had_value = FALSE;
			continue;
		}

		field = fields[idx];

		if (field == E_CONTACT_BIRTH_DATE || field == E_CONTACT_ANNIVERSARY) {
			EContactDate *dt = e_contact_get (contact, field);
			if (dt) {
				GDate gd = { 0 };
				struct tm tm;
				gchar *value;

				g_date_set_dmy (&gd, dt->day, dt->month, dt->year);
				g_date_to_struct_tm (&gd, &tm);

				value = e_datetime_format_format_tm (
					"addressbook", "table",
					DTFormatKindDate, &tm);
				if (value) {
					e_web_view_preview_add_section (
						preview,
						e_contact_pretty_name (field),
						value);
					had_value = TRUE;
				}

				g_free (value);
				e_contact_date_free (dt);
			}
		} else if (field == E_CONTACT_IS_LIST ||
			   field == E_CONTACT_WANTS_HTML ||
			   field == E_CONTACT_LIST_SHOW_ADDRESSES) {
			if (e_contact_get (contact, field)) {
				e_web_view_preview_add_text (
					preview, e_contact_pretty_name (field));
				had_value = TRUE;
			}
		} else if (field == E_CONTACT_ADDRESS_HOME ||
			   field == E_CONTACT_ADDRESS_WORK ||
			   field == E_CONTACT_ADDRESS_OTHER) {
			EContactAddress *addr = e_contact_get (contact, field);
			if (addr) {
				gboolean have = FALSE;

				#define add_it(_what)	\
					if (addr->_what && *addr->_what) {	\
						e_web_view_preview_add_section ( \
							preview, have ? NULL : \
							e_contact_pretty_name (field), addr->_what);	\
						have = TRUE;	\
						had_value = TRUE;	\
					}

				add_it (po);
				add_it (ext);
				add_it (street);
				add_it (locality);
				add_it (region);
				add_it (code);
				add_it (country);

				#undef add_it

				e_contact_address_free (addr);
			}
		} else if (field == E_CONTACT_IM_AIM ||
			   field == E_CONTACT_IM_GROUPWISE ||
			   field == E_CONTACT_IM_JABBER ||
			   field == E_CONTACT_IM_YAHOO ||
			   field == E_CONTACT_IM_MSN ||
			   field == E_CONTACT_IM_ICQ ||
			   field == E_CONTACT_IM_GADUGADU ||
			   field == E_CONTACT_IM_SKYPE ||
			   field == E_CONTACT_EMAIL) {
			GList *attrs, *a;
			gboolean have = FALSE;
			const gchar *pretty_name;

			pretty_name = e_contact_pretty_name (field);

			attrs = e_contact_get_attributes (contact, field);
			for (a = attrs; a; a = a->next) {
				EVCardAttribute *attr = a->data;
				GList *value;

				if (!attr)
					continue;

				value = e_vcard_attribute_get_values (attr);

				while (value != NULL) {
					const gchar *str = value->data;

					if (str && *str) {
						e_web_view_preview_add_section (
							preview, have ? NULL :
							pretty_name, str);
						have = TRUE;
						had_value = TRUE;
					}

					value = value->next;
				}

				e_vcard_attribute_free (attr);
			}

			g_list_free (attrs);

		} else if (field == E_CONTACT_CATEGORIES) {
			const gchar *pretty_name;
			const gchar *value;

			pretty_name = e_contact_pretty_name (field);
			value = e_contact_get_const (contact, field);

			if (value != NULL && *value != '\0') {
				e_web_view_preview_add_section (
					preview, pretty_name, value);
				had_value = TRUE;
			}

		} else {
			const gchar *pretty_name;
			const gchar *value;

			pretty_name = e_contact_pretty_name (field);
			value = e_contact_get_const (contact, field);

			if (value != NULL && *value != '\0') {
				e_web_view_preview_add_section (
					preview, pretty_name, value);
				had_value = TRUE;
			}
		}
	}
}
/* reads an entire attribute from the input buffer, leaving p pointing
   at the start of the next line (past the \r\n) */
static EVCardAttribute*
read_attribute (char **p)
{
	char *attr_group = NULL;
	char *attr_name = NULL;
	EVCardAttribute *attr = NULL;
	GString *str;
	char *lp;
	gboolean is_qp = FALSE;

	/* first read in the group/name */
	str = g_string_new ("");
	for( lp =  skip_newline( *p, is_qp );
	     *lp != '\n' && *lp != '\r' && *lp != '\0';
	     lp = skip_newline( lp, is_qp ) ) {

		if (*lp == ':' || *lp == ';') {
			if (str->len != 0) {
				/* we've got a name, break out to the value/attribute parsing */
				attr_name = g_string_free (str, FALSE);
				break;
			}
			else {
				/* a line of the form:
				 * (group.)?[:;]
				 *
				 * since we don't have an attribute
				 * name, skip to the end of the line
				 * and try again.
				 */
				g_string_free (str, TRUE);
				*p = lp;
				skip_to_next_line(p);
				goto lose;
			}
		}
		else if (*lp == '.') {
			if (attr_group) {
				g_warning ("extra `.' in attribute specification.  ignoring extra group `%s'",
					   str->str);
				g_string_free (str, TRUE);
				str = g_string_new ("");
			}
			if (str->len != 0) {
				attr_group = g_string_free (str, FALSE);
				str = g_string_new ("");
			}
		}
		else if (g_unichar_isalnum (g_utf8_get_char (lp)) || *lp == '-' || *lp == '_') {
			g_string_append_unichar (str, g_utf8_get_char (lp));
		}
		else {
			g_warning ("invalid character found in attribute group/name");
			g_string_free (str, TRUE);
			*p = lp;
			skip_to_next_line(p);
			goto lose;
		}

		lp = g_utf8_next_char(lp);
	}

	if (!attr_name) {
		skip_to_next_line (p);
		goto lose;
	}

	attr = e_vcard_attribute_new (attr_group, attr_name);
	g_free (attr_group);
	g_free (attr_name);

	if (*lp == ';') {
		/* skip past the ';' */
		lp = g_utf8_next_char(lp);
		read_attribute_params (attr, &lp, &is_qp);
		if (is_qp)
			attr->encoding = EVC_ENCODING_RAW;
	}
	if (*lp == ':') {
		/* skip past the ':' */
		lp = g_utf8_next_char(lp);
		read_attribute_value (attr, &lp, is_qp);
	}

	*p = lp;

	if (!attr->values)
		goto lose;

	return attr;
 lose:
	if (attr)
		e_vcard_attribute_free (attr);
	return NULL;
}