[Commits] [SCM] claws branch, master, updated. 3.14.1-175-g38131c9

ticho at claws-mail.org ticho at claws-mail.org
Sat Feb 4 17:35:15 CET 2017


The branch, master has been updated
       via  38131c96c146e1693fe7c4b90b4ca88d125c7a11 (commit)
      from  9200a687438aaaf0b18b448c6173c2fa0fd1b67b (commit)

Summary of changes:
 src/plugins/vcalendar/vcal_folder.c |  100 ++++++++++++++++-------------------
 1 file changed, 47 insertions(+), 53 deletions(-)


- Log -----------------------------------------------------------------
commit 38131c96c146e1693fe7c4b90b4ca88d125c7a11
Author: Andrej Kacian <ticho at claws-mail.org>
Date:   Sat Feb 4 17:33:07 2017 +0100

    Handle timezones correctly in vCalendar.
    
    We convert DTSTART and DTEND to UTC as soon as possible,
    using the VTIMEZONE info. The convert_to_utc() function
    should be able to handle several timezone definitions and
    events using those several different timezones in one ical
    file, picking the correct one for converting each event.

diff --git a/src/plugins/vcalendar/vcal_folder.c b/src/plugins/vcalendar/vcal_folder.c
index 9d3b8e2..a11ff96 100644
--- a/src/plugins/vcalendar/vcal_folder.c
+++ b/src/plugins/vcalendar/vcal_folder.c
@@ -131,6 +131,7 @@ static void update_subscription(const gchar *uri, gboolean verbose);
 static void vcal_folder_set_batch	(Folder		*folder,
 					 FolderItem	*item,
 					 gboolean	 batch);
+static void convert_to_utc(icalcomponent *calendar);
 
 gboolean vcal_subscribe_uri(Folder *folder, const gchar *uri);
 
@@ -1883,6 +1884,8 @@ static void update_subscription_finish(const gchar *uri, gchar *feed, gboolean v
 		/* if title differs, update it */
 	}
 	cal = icalparser_parse_string(feed);
+
+	convert_to_utc(cal);
 	
 	if (((VCalFolderItem *)item)->cal)
 		icalcomponent_free(((VCalFolderItem *)item)->cal);
@@ -2145,40 +2148,53 @@ static gchar *get_email_from_property(icalproperty *p)
 	return email;
 }
 
-static void adjust_for_local_time_zone(icalproperty *eventtime, icalproperty *tzoffsetto, int dtstart)
+static void convert_to_utc(icalcomponent *calendar)
 {
-	int tzoffset;
-	int loctzoffset;
-	time_t loctime, gmttime, evttime;
-	struct icaltimetype icaltime;
-
-	/* calculate local UTC offset */
-	loctime = time(NULL);
-	loctime = mktime(localtime(&loctime));
-	gmttime = mktime(gmtime(&loctime));
-	loctzoffset = loctime - gmttime;
-
-	if (eventtime && tzoffsetto) {
-		tzoffset = icalproperty_get_tzoffsetto(tzoffsetto);
-		if (dtstart) {
-			evttime = icaltime_as_timet(icalproperty_get_dtstart(eventtime));
-		}
-		else {
-			evttime = icaltime_as_timet(icalproperty_get_dtend(eventtime));
+	icalcomponent *event;
+	icaltimezone *tz, *tzutc = icaltimezone_get_utc_timezone();
+	icalproperty *prop;
+	icalparameter *tzid;
+
+	cm_return_if_fail(calendar != NULL);
+
+	for (
+			event = icalcomponent_get_first_component(calendar,
+				ICAL_VEVENT_COMPONENT);
+			event != NULL;
+			event = icalcomponent_get_next_component(calendar,
+				ICAL_VEVENT_COMPONENT)) {
+
+		/* DTSTART */
+		if ((prop = icalcomponent_get_first_property(event, ICAL_DTSTART_PROPERTY)) != NULL
+				&& (tzid = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER)) != NULL) {
+			/* Event has its DTSTART with a timezone specification, let's convert
+			 * to UTC and remove the TZID parameter. */
+
+			tz = icalcomponent_get_timezone(calendar, icalparameter_get_iana_value(tzid));
+			if (tz != NULL) {
+				debug_print("Converting DTSTART to UTC.\n");
+				icaltimetype t = icalproperty_get_dtstart(prop);
+				icaltimezone_convert_time(&t, tz, tzutc);
+				icalproperty_set_dtstart(prop, t);
+				icalproperty_remove_parameter_by_ref(prop, tzid);
+			}
 		}
 
-		/* convert to UTC */
-		evttime -= tzoffset;
-		/* and adjust for local time zone */
-		evttime += loctzoffset;
-		icaltime = icaltime_from_timet(evttime, 0);
-
-		if (dtstart) {
-			icalproperty_set_dtstart(eventtime, icaltime);
+		/* DTEND */
+		if ((prop = icalcomponent_get_first_property(event, ICAL_DTEND_PROPERTY)) != NULL
+				&& (tzid = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER)) != NULL) {
+			/* Event has its DTEND with a timezone specification, let's convert
+			 * to UTC and remove the TZID parameter. */
+
+			tz = icalcomponent_get_timezone(calendar, icalparameter_get_iana_value(tzid));
+			if (tz != NULL) {
+				debug_print("Converting DTEND to UTC.\n");
+				icaltimetype t = icalproperty_get_dtend(prop);
+				icaltimezone_convert_time(&t, tz, tzutc);
+				icalproperty_set_dtend(prop, t);
+				icalproperty_remove_parameter_by_ref(prop, tzid);
+			}
 		}
-		else {
-			icalproperty_set_dtend(eventtime, icaltime);
-		} 
 	}
 }
 
@@ -2265,31 +2281,9 @@ VCalEvent *vcal_get_event_from_ical(const gchar *ical, const gchar *charset)
 		TO_UTF8(summary);
 		icalproperty_free(prop);
 	}
-	tzcomp = icalcomponent_get_first_component(comp, ICAL_VTIMEZONE_COMPONENT);
-	if (tzcomp) {
-		icalproperty *evtstart = NULL;
-		icalproperty *evtend = NULL;
-		icalproperty *tzoffsetto = NULL;
-		icalcomponent *tzstd = NULL;
 
-		tzstd = icalcomponent_get_first_component(tzcomp, ICAL_XSTANDARD_COMPONENT);
-		tzoffsetto = icalcomponent_get_first_property(tzstd, ICAL_TZOFFSETTO_PROPERTY);
+	convert_to_utc(comp);
 
-		GET_PROP(comp, evtstart, ICAL_DTSTART_PROPERTY);
-		adjust_for_local_time_zone(evtstart, tzoffsetto, TRUE);
-
-		GET_PROP(comp, evtend, ICAL_DTEND_PROPERTY);
-		adjust_for_local_time_zone(evtend, tzoffsetto, FALSE);
-
-		if (tzoffsetto)
-			icalproperty_free(tzoffsetto);
-		if (evtstart)
-			icalproperty_free(evtstart);
-		if (evtend)
-			icalproperty_free(evtend);
-		if (tzstd)
-			icalcomponent_free(tzstd);
-	}
 	GET_PROP(comp, prop, ICAL_DTSTART_PROPERTY);
 	if (prop) {
 		dtstart = g_strdup(icaltime_as_ical_string(icalproperty_get_dtstart(prop)));

-----------------------------------------------------------------------


hooks/post-receive
-- 
Claws Mail


More information about the Commits mailing list