[california/wip/731543-attendees] Component.Attendee -> Component.Person
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/731543-attendees] Component.Attendee -> Component.Person
- Date: Thu, 6 Nov 2014 00:35:39 +0000 (UTC)
commit dbae8c470806033a4d5920a03b0745f4816d2842
Author: Jim Nelson <jim yorba org>
Date: Wed Nov 5 12:37:52 2014 -0800
Component.Attendee -> Component.Person
src/Makefile.am | 2 +-
src/component/component-attendee.vala | 108 -------------------------
src/component/component-instance.vala | 20 +++---
src/component/component-person.vala | 139 +++++++++++++++++++++++++++++++++
4 files changed, 150 insertions(+), 119 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index c4d6bdf..d4dc27a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -85,13 +85,13 @@ california_VALASOURCES = \
collection/collection-simple-iterable.vala \
\
component/component.vala \
- component/component-attendee.vala \
component/component-date-time.vala \
component/component-details-parser.vala \
component/component-error.vala \
component/component-event.vala \
component/component-icalendar.vala \
component/component-instance.vala \
+ component/component-person.vala \
component/component-recurrence-rule.vala \
component/component-uid.vala \
component/component-vtype.vala \
diff --git a/src/component/component-instance.vala b/src/component/component-instance.vala
index 1002fa6..0a12044 100644
--- a/src/component/component-instance.vala
+++ b/src/component/component-instance.vala
@@ -183,7 +183,7 @@ public abstract class Instance : BaseObject, Gee.Hashable<Instance> {
*
* See [[https://tools.ietf.org/html/rfc5545#section-3.8.4.1]]
*/
- public Gee.Set<Attendee> attendees { get; private set; default = new Gee.HashSet<Attendee>(); }
+ public Gee.Set<Person> attendees { get; private set; default = new Gee.HashSet<Person>(); }
/**
* The iCal component being represented by this { link Instance}.
@@ -372,7 +372,7 @@ public abstract class Instance : BaseObject, Gee.Hashable<Instance> {
iCal.icalproperty_kind.ATTENDEE_PROPERTY);
while (attendee_prop != null) {
try {
- attendees.add(new Attendee.from_property(attendee_prop));
+ attendees.add(new Person.from_property(attendee_prop));
} catch (ComponentError comperr) {
debug("Unable to parse ATTENDEE for %s: %s", to_string(), comperr.message);
}
@@ -428,7 +428,7 @@ public abstract class Instance : BaseObject, Gee.Hashable<Instance> {
case PROP_ATTENDEES:
remove_all_properties(iCal.icalproperty_kind.ATTENDEE_PROPERTY);
- foreach (Attendee attendee in attendees)
+ foreach (Person attendee in attendees)
ical_component.add_property(attendee.as_ical_property());
break;
@@ -488,8 +488,8 @@ public abstract class Instance : BaseObject, Gee.Hashable<Instance> {
* No URI-format checking is performed here; it is up to the caller to convert and deal with
* formatting issues. Also note that duplicates are allowed in the attendees list.
*/
- public void add_attendees(Gee.Collection<Attendee> to_add) {
- Gee.Set<Attendee> copy = traverse<Attendee>(attendees).to_hash_set();
+ public void add_attendees(Gee.Collection<Person> to_add) {
+ Gee.Set<Person> copy = traverse<Person>(attendees).to_hash_set();
copy.add_all(to_add);
attendees = copy;
@@ -500,8 +500,8 @@ public abstract class Instance : BaseObject, Gee.Hashable<Instance> {
*
* See { link add_attendees} for notes about data validity and checking.
*/
- public void remove_attendees(Gee.Collection<Attendee> to_remove) {
- attendees = traverse<Attendee>(attendees)
+ public void remove_attendees(Gee.Collection<Person> to_remove) {
+ attendees = traverse<Person>(attendees)
.filter(attendee => !to_remove.contains(attendee))
.to_hash_set();
}
@@ -510,7 +510,7 @@ public abstract class Instance : BaseObject, Gee.Hashable<Instance> {
* Removes all { link attendees}.
*/
public void clear_attendees() {
- attendees = new Gee.HashSet<Attendee>();
+ attendees = new Gee.HashSet<Person>();
}
/**
@@ -519,10 +519,10 @@ public abstract class Instance : BaseObject, Gee.Hashable<Instance> {
* Returns null if no attendees are associated with this { link Instance}.
*/
public string? attendees_to_string() {
- return traverse<Attendee>(attendees).to_string(stringify_attendee);
+ return traverse<Person>(attendees).to_string(stringify_attendee);
}
- private static string? stringify_attendee(Attendee attendee, bool is_first, bool is_last) {
+ private static string? stringify_attendee(Person attendee, bool is_first, bool is_last) {
// A common separator for email addresses followed by an email address itself.
return is_first ? attendee.mailbox : _(", %s").printf(attendee.mailbox);
}
diff --git a/src/component/component-person.vala b/src/component/component-person.vala
new file mode 100644
index 0000000..e2d5404
--- /dev/null
+++ b/src/component/component-person.vala
@@ -0,0 +1,139 @@
+/* Copyright 2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+namespace California.Component {
+
+/**
+ * An immutable representation of an iCalendar CAL-ADDRESS (ATTENDEE, ORGANIZER, etc.)
+ *
+ * Person is not guaranteed to represent an individual per se, but it always represents an RFC822
+ * mailbox (i.e. email address), which may include a group list address, multiuser mailbox, etc.
+ *
+ * For equality purposes, only the { link mailto} is used. All other parameters are ignored when
+ * comparing Persons.
+ *
+ * See [[https://tools.ietf.org/html/rfc5545#section-3.3.3]],
+ * [[https://tools.ietf.org/html/rfc5545#section-3.8.4.1]],
+ * [[https://tools.ietf.org/html/rfc5545#section-3.8.4.3]],
+ * [[https://tools.ietf.org/html/rfc5545#section-3.2.2]], and more.
+ */
+
+public class Person : BaseObject, Gee.Hashable<Person> {
+ /**
+ * The mailto: of the { link Person}, the only required value for the property.
+ */
+ public Soup.URI mailto { get; private set; }
+
+ /**
+ * The CN (common name) for the { link Person}.
+ */
+ public string? common_name { get; private set; default = null; }
+
+ /**
+ * The { link mailto} URI as a text string.
+ *
+ * @see mailbox
+ */
+ public string mailto_text { owned get { return mailto.to_string(false); } }
+
+ /**
+ * The { link mailto} as a simple (unadorned) RFC822 mailbox (i.e. email address).
+ *
+ * This does not include the "mailto:" scheme nor the { link common_name}, i.e.
+ * "bob example com"
+ */
+ public string mailbox { get { return mailto.path; } }
+
+ /**
+ * The { link mailto} as a complete (adorned) RFC822 mailbox (i.e. email address) with
+ * user-readable name, if supplied.
+ *
+ * This does not include the "mailto:" scheme but it will include the { link common_name} if
+ * present, i.e. "Bob Jones <bob example com>".
+ */
+ public string rfc822_mailbox { owned get {
+ return String.is_empty(common_name) ? "<%s>".printf(mailbox) : "%s <%s>".printf(common_name,
mailbox);
+ } }
+
+ private Gee.HashSet<string> parameters = new Gee.HashSet<string>(String.ci_hash, String.ci_equal);
+
+ /**
+ * Create an { link Person} with the required { link mailto} and optional { link common_name}.
+ */
+ public Person(Soup.URI mailto, string? common_name) throws ComponentError {
+ validate_mailto(mailto);
+
+ this.mailto = mailto;
+ this.common_name = common_name;
+ }
+
+ internal Person.from_property(iCal.icalproperty prop) throws Error {
+ unowned iCal.icalvalue? prop_value = prop.get_value();
+ if (prop_value == null || prop_value.is_valid() == 0) {
+ throw new ComponentError.INVALID("Property of kind %s has no associated value",
+ prop.isa().to_string());
+ }
+
+ if (prop_value.isa() != iCal.icalvalue_kind.CALADDRESS_VALUE) {
+ throw new ComponentError.INVALID("Property of kind %s has value of kind %s",
+ prop.isa().to_string(), prop_value.isa().to_string());
+ }
+
+ string uri = prop_value.get_caladdress();
+ if (String.is_empty(uri))
+ throw new ComponentError.INVALID("Invalid Person property: no CAL-ADDRESS value");
+
+ mailto = URI.parse(uri);
+ validate_mailto(mailto);
+
+ // load parameters into local table
+ unowned iCal.icalparameter? param = prop.get_first_parameter(iCal.icalparameter_kind.ANY_PARAMETER);
+ while (param != null) {
+ parameters.add(param.as_ical_string());
+
+ // parse parameter into well-known (common) property
+ switch (param.isa()) {
+ case iCal.icalparameter_kind.CN_PARAMETER:
+ common_name = param.get_cn();
+ break;
+
+ default:
+ // fall-through
+ break;
+ }
+
+ param = prop.get_next_parameter(iCal.icalparameter_kind.ANY_PARAMETER);
+ }
+ }
+
+ private static void validate_mailto(Soup.URI uri) throws ComponentError {
+ if (uri.scheme != "mailto" || String.is_empty(uri.path))
+ throw new ComponentError.INVALID("Invalid mailto: %s", uri.to_string(false));
+ }
+
+ internal iCal.icalproperty as_ical_property() {
+ iCal.icalproperty prop = new iCal.icalproperty.attendee(mailto_text);
+ foreach (string parameter in parameters)
+ prop.add_parameter(new iCal.icalparameter.from_string(parameter));
+
+ return prop;
+ }
+
+ public uint hash() {
+ return String.ci_hash(mailto_text);
+ }
+
+ public bool equal_to(Person other) {
+ return (this != other) ? mailto.equal(other.mailto) : true;
+ }
+
+ public override string to_string() {
+ return mailto_text;
+ }
+}
+
+}
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]