Add some consts for TYPE and some common values for it for UrlFieldDetails.
Closes: bgo#653623
* Bug 658161 — Consistently use “contact” in translatable strings instead of
“persona”
* Bug 657738 — Favorite people are not always displayed
+* Bug 653623 — Would like a set of standard "type" parameters for UrlDetails
API changes:
* Individual.avatar is now settable using Individual.change_avatar() (not new
* In IndividualAggregator.ensure_individual_property_writeable we now throw
NO_PRIMARY_STORE instead of NO_WRITEABLE_STORE
* Add Folks.PersonaStore.user_set_default
+* Add AbstractFieldDetails.PARAM_TYPE, .PARAM_TYPE_HOME, .PARAM_TYPE_WORK,
+ .PARAM_TYPE_OTHER
+* Add UrlFieldDetails.PARAM_TYPE_HOMEPAGE, .PARAM_TYPE_BLOG,
+ .PARAM_TYPE_PROFILE, .PARAM_TYPE_FTP
Overview of changes from libfolks 0.6.2 to libfolks 0.6.2.1
===========================================================
foreach (var u in urls)
{
- bool homepage = false;
- bool blog = false;
- bool fburl = false;
- bool video = false;
+ /* A way to escape from the inner loop, since Vala doesn't have
+ * "continue 3". */
+ var set_attr_already = false;
var attr = new E.VCardAttribute (null, "X-URIS");
attr.add_value (u.value);
var param = new E.VCardAttributeParam (param_name.up ());
foreach (var param_val in u.parameters.get (param_name))
{
- if (param_name == "type")
+ if (param_name == AbstractFieldDetails.PARAM_TYPE)
{
- /* Keep in sync with Edsf.Persona.url_properties */
- if (param_val == "homepage_url")
+ /* Handle TYPEs which need mapping to custom vCard attrs
+ * for EDS. */
+ foreach (var mapping in Edsf.Persona._url_properties)
{
- homepage = true;
- }
- else if (param_val == "blog_url")
- {
- blog = true;
- }
- else if (param_val == "fburl")
- {
- fburl = true;
- }
- else if (param_val == "video_url")
- {
- video = true;
+ if (param_val.down () == mapping.folks_type)
+ {
+ contact.set (
+ E.Contact.field_id (mapping.vcard_field_name),
+ u.value);
+
+ set_attr_already = true;
+ break;
+ }
}
}
+
+ if (set_attr_already == true)
+ {
+ break;
+ }
+
param.add_value (param_val);
}
+
+ if (set_attr_already == true)
+ {
+ break;
+ }
+
attr.add_param (param);
}
- if (homepage)
- {
- contact.set (E.Contact.field_id ("homepage_url"), u.value);
- }
- else if (blog)
- {
- contact.set (E.Contact.field_id ("blog_url"), u.value);
- }
- else if (fburl)
- {
- contact.set (E.Contact.field_id ("fburl"), u.value);
- }
- else if (video)
+ if (set_attr_already == true)
{
- contact.set (E.Contact.field_id ("video_url"), u.value);
- }
- else
- {
- contact.add_attribute ((owned) attr);
+ continue;
}
+
+ contact.add_attribute ((owned) attr);
}
}
public static const string[] email_fields = {
"email_1", "email_2", "email_3", "email_4"
};
+
+ [Deprecated]
public static const string[] url_properties = {
"blog_url", "fburl", "homepage_url", "video_url"
};
+ /* Some types of URLs are represented in EDS using custom vCard fields rather
+ * than the X-URIS field. Here are mappings between the custom vCard field
+ * names which EDS uses, and the TYPE values which folks uses which map to
+ * them. */
+ private struct UrlTypeMapping
+ {
+ string vcard_field_name;
+ string folks_type;
+ }
+
+ internal static const UrlTypeMapping[] _url_properties =
+ {
+ { "homepage_url", UrlFieldDetails.PARAM_TYPE_HOMEPAGE },
+ { "blog_url", UrlFieldDetails.PARAM_TYPE_BLOG },
+ { "fburl", "x-free-busy" },
+ { "video_url", "x-video" }
+ };
+
/**
* The vCard attribute used to specify a Contact's gender
*
string param_name = param.get_name ().down ();
foreach (unowned string param_value in param.get_values ())
{
- details.add_parameter (param_name, param_value);
+ if (param_name == AbstractFieldDetails.PARAM_TYPE)
+ {
+ details.add_parameter (param_name, param_value.down ());
+ }
+ else
+ {
+ details.add_parameter (param_name, param_value);
+ }
}
}
}
var new_urls = new HashSet<UrlFieldDetails> ();
/* First we get the standard Evo urls.. */
- foreach (string url_property in this.url_properties)
+ foreach (var mapping in this._url_properties)
{
+ var url_property = mapping.vcard_field_name;
+ var folks_type = mapping.folks_type;
+
string u = (string) this._get_property (url_property);
if (u != null && u != "")
{
var fd_u = new UrlFieldDetails (u);
- fd_u.set_parameter("type", url_property);
+ fd_u.set_parameter (fd_u.PARAM_TYPE, folks_type);
new_urls.add (fd_u);
}
}
if (affl_info.website != null)
p._add_url (affl_info.website,
- affl_info.affl_tracker_id, "website");
+ affl_info.affl_tracker_id,
+ UrlFieldDetails.PARAM_TYPE_HOMEPAGE);
if (affl_info.blog != null)
p._add_url (affl_info.blog,
- affl_info.affl_tracker_id, "blog");
+ affl_info.affl_tracker_id, UrlFieldDetails.PARAM_TYPE_BLOG);
if (affl_info.url != null)
p._add_url (affl_info.url,
- affl_info.affl_tracker_id, "url");
+ affl_info.affl_tracker_id, null);
}
else
{
break;
case Trf.Attrib.URLS:
fd = (UrlFieldDetails) p;
- var type_p = fd.get_parameter_values ("type");
- if (type_p.contains ("blog"))
+ var type_p = fd.get_parameter_values (fd.PARAM_TYPE);
+
+ if (type_p != null &&
+ type_p.contains (UrlFieldDetails.PARAM_TYPE_BLOG))
{
related_connection = Trf.OntologyDefs.NCO_BLOG;
}
- else if (type_p.contains ("website"))
+ else if (type_p != null &&
+ type_p.contains (UrlFieldDetails.PARAM_TYPE_HOMEPAGE))
{
related_connection = Trf.OntologyDefs.NCO_WEBSITE;
}
- else if (type_p.contains ("url"))
+ else
{
related_connection = Trf.OntologyDefs.NCO_URL;
}
+
attr = "'%s'".printf (((UrlFieldDetails) fd).value);
break;
case Trf.Attrib.IM_ADDRESSES:
if (u[i] == null || u[i] == "")
continue;
- string type = "";
+ string? type = null;
switch (i)
{
case Trf.UrlsFields.BLOG:
- type = "blog";
+ type = UrlFieldDetails.PARAM_TYPE_BLOG;
break;
case Trf.UrlsFields.WEBSITE:
- type = "website";
+ type = UrlFieldDetails.PARAM_TYPE_HOMEPAGE;
break;
case Trf.UrlsFields.URL:
- type = "url";
+ /* No specific type is appropriate. */
break;
}
var url_fd = new UrlFieldDetails (u[i]);
url_fd.set_parameter ("tracker_id", tracker_id);
- url_fd.set_parameter ("type", type);
+
+ if (type != null)
+ {
+ url_fd.set_parameter (url_fd.PARAM_TYPE, type);
+ }
+
url_fds.add (url_fd);
}
}
this.notify_property ("urls");
}
- internal bool _add_url (string url, string tracker_id, string type = "")
+ internal bool _add_url (string url, string tracker_id, string? type = null)
{
bool found = false;
{
var url_fd = new UrlFieldDetails (url);
url_fd.set_parameter ("tracker_id", tracker_id);
- url_fd.set_parameter ("type", type);
+
+ if (type != null)
+ {
+ url_fd.set_parameter (url_fd.PARAM_TYPE, type);
+ }
+
this._urls.add (url_fd);
this.notify_property ("urls");
}
* a AbstractFieldDetails with value "(111) 555-1234" and with parameters
* `['type': ('work', 'voice')]`.
*
- * The parameter name "TYPE" with values "work", "home", or "other" are common
+ * The parameter name "type" with values "work", "home", or "other" are common
* amongst most vCard attributes (and thus most AbstractFieldDetails-derived
- * classes). A TYPE of "pref" may be used to indicate a preferred
+ * classes). A "type" of "pref" may be used to indicate a preferred
* {@link AbstractFieldDetails.value} amongst many. See specific classes for
* information on additional parameters and values specific to that class.
*
*/
public abstract class Folks.AbstractFieldDetails<T> : Object
{
+ /**
+ * Parameter name for classifying the type of value this field contains.
+ *
+ * For example, the value could be relevant to the contact's home life, or to
+ * their work life; values of {@link AbstractFieldDetails.PARAM_TYPE_HOME}
+ * and {@link AbstractFieldDetails.PARAM_TYPE_WORK} would be used for the
+ * {@link AbstractFieldDetails.PARAM_TYPE} parameter, respectively, in those
+ * cases.
+ *
+ * @since UNRELEASED
+ */
+ public static const string PARAM_TYPE = "type";
+
+ /**
+ * Parameter value for home-related field values.
+ *
+ * Value for a parameter with name {@link AbstractFieldDetails.PARAM_TYPE}.
+ *
+ * @since UNRELEASED
+ */
+ public static const string PARAM_TYPE_HOME = "home";
+
+ /**
+ * Parameter value for work-related field values.
+ *
+ * Value for a parameter with name {@link AbstractFieldDetails.PARAM_TYPE}.
+ *
+ * @since UNRELEASED
+ */
+ public static const string PARAM_TYPE_WORK = "work";
+
+ /**
+ * Parameter value for miscellaneous field values.
+ *
+ * Value for a parameter with name {@link AbstractFieldDetails.PARAM_TYPE}.
+ *
+ * @since UNRELEASED
+ */
+ public static const string PARAM_TYPE_OTHER = "other";
+
private T _value;
/**
* The value of the field.
public class Folks.UrlFieldDetails : AbstractFieldDetails<string>
{
/**
+ * Parameter value for URLs for the contact's home page.
+ *
+ * Value for a parameter with name {@link AbstractFieldDetails.PARAM_TYPE}.
+ *
+ * @since UNRELEASED
+ */
+ public static const string PARAM_TYPE_HOMEPAGE = "x-home-page";
+
+ /**
+ * Parameter value for URLs for the contact's personal or professional blog.
+ *
+ * Value for a parameter with name {@link AbstractFieldDetails.PARAM_TYPE}.
+ *
+ * @since UNRELEASED
+ */
+ public static const string PARAM_TYPE_BLOG = "x-blog";
+
+ /**
+ * Parameter value for URLs for the contact's social networking profile.
+ *
+ * Value for a parameter with name {@link AbstractFieldDetails.PARAM_TYPE}.
+ *
+ * @since UNRELEASED
+ */
+ public static const string PARAM_TYPE_PROFILE = "x-profile";
+
+ /**
+ * Parameter value for URLs for the contact's personal or professional FTP
+ * server.
+ *
+ * Value for a parameter with name {@link AbstractFieldDetails.PARAM_TYPE}.
+ *
+ * @since UNRELEASED
+ */
+ public static const string PARAM_TYPE_FTP = "x-ftp";
+
+ /**
* Create a new UrlFieldDetails.
*
* @param value the value of the field
this._extension, this._street, this._locality, this._region,
this._postal_code, this._country, null, null);
this._address = new PostalAddressFieldDetails (pa);
- this._address.add_parameter ("type", Edsf.Persona.address_fields[0]);
+ this._address.add_parameter (this._address.PARAM_TYPE,
+ Edsf.Persona.address_fields[0]);
this._properties_found = new HashTable<string, bool>
(str_hash, str_equal);
(GLib.HashFunc) EmailFieldDetails.hash,
(GLib.EqualFunc) EmailFieldDetails.equal);
var email_1 = new EmailFieldDetails (this._email_1);
- email_1.set_parameter ("type", Edsf.Persona.email_fields[0]);
+ email_1.set_parameter (email_1.PARAM_TYPE, Edsf.Persona.email_fields[0]);
emails.add (email_1);
v2.set_object (emails);
details.insert (
(GLib.EqualFunc) PhoneFieldDetails.equal);
var phone_1 = new PhoneFieldDetails (this._phone_1);
- phone_1.set_parameter ("type", Edsf.Persona.phone_fields[0]);
+ phone_1.set_parameter (phone_1.PARAM_TYPE, Edsf.Persona.phone_fields[0]);
phones.add (phone_1);
var phone_2 = new PhoneFieldDetails (this._phone_2);
- phone_2.set_parameter ("type", Edsf.Persona.phone_fields[1]);
+ phone_2.set_parameter (phone_2.PARAM_TYPE, Edsf.Persona.phone_fields[1]);
phones.add (phone_2);
v5.set_object (phones);
details.insert (
foreach (var pt in this._email_types)
{
- assert (pt == "OTHER");
+ assert (pt == AbstractFieldDetails.PARAM_TYPE_OTHER);
}
}
}
}
assert (found);
- foreach (var v in e.get_parameter_values("type"))
+ foreach (var v in e.get_parameter_values (e.PARAM_TYPE))
{
this._email_types.add (v);
}
foreach (var phone_fd in phone_numbers.phone_numbers)
{
this._phones_count++;
- foreach (var t in phone_fd.get_parameter_values ("type"))
+ foreach (var t in phone_fd.get_parameter_values (
+ phone_fd.PARAM_TYPE))
{
string? v = null;
- if (t == "CAR")
+ if (t == "car")
{
v = "car_phone";
}
- else if (t == "HOME")
+ else if (t == phone_fd.PARAM_TYPE_HOME)
{
v = "home_phone";
}
- else if (t == "X-EVOLUTION-COMPANY")
+ else if (t == "x-evolution-company")
{
v = "company_phone";
}
this._country,
null, "eds_id");
this._postal_address = new PostalAddressFieldDetails (pa);
- this._postal_address.add_parameter ("type",
+ this._postal_address.add_parameter (this._postal_address.PARAM_TYPE,
Edsf.Persona.address_fields[0]);
v = Value (typeof (string));
this._country,
null, "eds_id");
var pa_fd_copy = new PostalAddressFieldDetails (pa_copy);
- pa_fd_copy.add_parameter ("type", Edsf.Persona.address_fields[0]);
+ pa_fd_copy.add_parameter (pa_fd_copy.PARAM_TYPE,
+ Edsf.Persona.address_fields[0]);
v = Value (typeof (PostalAddressFieldDetails));
v.set_object (pa_fd_copy);
c1.set (Edsf.Persona.address_fields[0], (owned) v);
(GLib.HashFunc) EmailFieldDetails.hash,
(GLib.EqualFunc) EmailFieldDetails.equal);
var email_1 = new EmailFieldDetails ("bernie@example.org");
- email_1.set_parameter ("type", "OTHER");
+ email_1.set_parameter (email_1.PARAM_TYPE,
+ email_1.PARAM_TYPE_OTHER);
emails.add (email_1);
((EmailDetails) p).email_addresses = emails;
}
(GLib.HashFunc) PhoneFieldDetails.hash,
(GLib.EqualFunc) PhoneFieldDetails.equal);
var phone_1 = new PhoneFieldDetails ("1234");
- phone_1.set_parameter ("type", "HOME");
+ phone_1.set_parameter (phone_1.PARAM_TYPE,
+ phone_1.PARAM_TYPE_HOME);
phones.add (phone_1);
((PhoneDetails) p).phone_numbers = phones;
}
"locality", "region", "postal code", "country", "",
"123");
this._pa_fd = new PostalAddressFieldDetails (pa);
- this._pa_fd.add_parameter ("type", "address_other");
+ this._pa_fd.add_parameter (this._pa_fd.PARAM_TYPE,
+ this._pa_fd.PARAM_TYPE_OTHER);
this._found_before_update = false;
this._found_after_update = false;
"locality", "region", "postal code", "country", "format",
"123");
var pa_fd_1 = new PostalAddressFieldDetails (pa_1);
- pa_fd_1.add_parameter ("type", "address_other");
+ pa_fd_1.add_parameter (pa_fd_1.PARAM_TYPE,
+ pa_fd_1.PARAM_TYPE_OTHER);
pa_fds.add (pa_fd_1);
((PostalAddressDetails) p).postal_addresses = pa_fds;
}
"locality", "region", "postal code", "country", "",
"123");
this._pa_fd = new PostalAddressFieldDetails (pa);
- this._pa_fd.add_parameter ("type", "address_other");
+ this._pa_fd.add_parameter (this._pa_fd.PARAM_TYPE,
+ this._pa_fd.PARAM_TYPE_OTHER);
this._found_before_update = false;
this._found_after_update = false;
"locality", "region", "postal code", "country", "format",
"123");
var pa_fd_1 = new PostalAddressFieldDetails (pa_1);
- pa_fd_1.add_parameter ("type", "address_other");
+ pa_fd_1.add_parameter (pa_fd_1.PARAM_TYPE,
+ pa_fd_1.PARAM_TYPE_OTHER);
pa_fds.add (pa_fd_1);
((PostalAddressDetails) p).postal_addresses = pa_fds;
}
var p2 = new UrlFieldDetails (this._url_extra_2);
urls.add (p2);
var p3 = new UrlFieldDetails (this._url_home);
- p3.set_parameter("type", "homepage_url");
+ p3.set_parameter(p3.PARAM_TYPE, p3.PARAM_TYPE_HOMEPAGE);
urls.add (p3);
var p4 = new UrlFieldDetails (this._url_blog);
- p4.set_parameter("type", "blog_url");
+ p4.set_parameter(p3.PARAM_TYPE, p3.PARAM_TYPE_BLOG);
urls.add (p4);
((UrlDetails) p).urls = urls;
Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
this._persona_fullname = "persona #1";
this._urls = new Gee.HashMap<string, string> ();
- this._urls.set ("blog", "http://one.example.org");
- this._urls.set ("website", "http://two.example.org");
- this._urls.set ("url", "http://three.example.org");
+ this._urls.set (UrlFieldDetails.PARAM_TYPE_BLOG,
+ "http://one.example.org");
+ this._urls.set (UrlFieldDetails.PARAM_TYPE_HOMEPAGE,
+ "http://two.example.org");
+ this._urls.set (AbstractFieldDetails.PARAM_TYPE_OTHER,
+ "http://three.example.org");
c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
this._tracker_backend.add_contact (c1);
var url_fds = new HashSet<UrlFieldDetails> (
(GLib.HashFunc) UrlFieldDetails.hash,
(GLib.EqualFunc) UrlFieldDetails.equal);
- var p1 = new UrlFieldDetails (this._urls.get ("blog"));
- p1.set_parameter ("type", "blog");
+ var p1 = new UrlFieldDetails (
+ this._urls.get (UrlFieldDetails.PARAM_TYPE_BLOG));
+ p1.set_parameter (p1.PARAM_TYPE, p1.PARAM_TYPE_BLOG);
url_fds.add (p1);
- var p2 = new UrlFieldDetails (this._urls.get ("website"));
- p2.set_parameter ("type", "website");
+ var p2 = new UrlFieldDetails (
+ this._urls.get (UrlFieldDetails.PARAM_TYPE_HOMEPAGE));
+ p2.set_parameter (p1.PARAM_TYPE, p1.PARAM_TYPE_HOMEPAGE);
url_fds.add (p2);
- var p3 = new UrlFieldDetails (this._urls.get ("url"));
- p3.set_parameter ("type", "url");
+ var p3 = new UrlFieldDetails (
+ this._urls.get (AbstractFieldDetails.PARAM_TYPE_OTHER));
url_fds.add (p3);
foreach (var p in i.personas)
{
foreach (var p in i.urls)
{
- var type_p = p.get_parameter_values ("type");
+ var type_p = p.get_parameter_values (p.PARAM_TYPE);
- if (type_p.contains ("blog") &&
- p.value == this._urls.get ("blog"))
+ if (type_p != null &&
+ type_p.contains (p.PARAM_TYPE_BLOG) &&
+ p.value == this._urls.get (p.PARAM_TYPE_BLOG))
{
- this._urls.unset ("blog");
+ this._urls.unset (p.PARAM_TYPE_BLOG);
}
- else if (type_p.contains ("website") &&
- p.value == this._urls.get ("website"))
+ else if (type_p != null &&
+ type_p.contains (p.PARAM_TYPE_HOMEPAGE) &&
+ p.value == this._urls.get (p.PARAM_TYPE_HOMEPAGE))
{
- this._urls.unset ("website");
+ this._urls.unset (p.PARAM_TYPE_HOMEPAGE);
}
- else if (type_p.contains ("url") &&
- p.value == this._urls.get ("url"))
+ else if (type_p == null &&
+ p.value == this._urls.get (p.PARAM_TYPE_OTHER))
{
- this._urls.unset ("url");
+ this._urls.unset (p.PARAM_TYPE_OTHER);
}
}
}