aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/engine-eds.cpp268
-rw-r--r--tests/test-eds-tasks-config-files/.local/share/evolution/tasks/system/tasks.ics18
-rw-r--r--tests/test-eds-tasks.cpp19
3 files changed, 94 insertions, 211 deletions
diff --git a/src/engine-eds.cpp b/src/engine-eds.cpp
index 5d423da..e49ba63 100644
--- a/src/engine-eds.cpp
+++ b/src/engine-eds.cpp
@@ -533,6 +533,7 @@ private:
e_cal_free_alarms(comp_alarms);
g_list_free(comps_list);
e_cal_client_free_ecalcomp_slist(comps_slist);
+ delete subtask;
}
else if (error != nullptr)
{
@@ -641,50 +642,91 @@ private:
AppointmentSubtask * subtask,
GTimeZone * gtz)
{
+ /**
+ *** Filter out components that we're not interested in
+ **/
+
+ auto& component = comp_alarms->comp;
+
// we only want calendar events and vtodos
- const auto vtype = e_cal_component_get_vtype(comp_alarms->comp);
+ const auto vtype = e_cal_component_get_vtype(component);
if ((vtype != E_CAL_COMPONENT_EVENT) && (vtype != E_CAL_COMPONENT_TODO))
return;
- // FIXME: leaks
- g_message("%s --> %s", G_STRLOC, e_cal_component_get_as_string (comp_alarms->comp));
+ // we're not interested in completed or cancelled components
+ auto status = ICAL_STATUS_NONE;
+ e_cal_component_get_status(component, &status);
+ if ((status == ICAL_STATUS_COMPLETED) || (status == ICAL_STATUS_CANCELLED))
+ return;
- // get uid
const gchar* uid = nullptr;
- e_cal_component_get_uid(comp_alarms->comp, &uid);
+ e_cal_component_get_uid(component, &uid);
+ if (uid == nullptr)
+ return;
- // get status
- auto status = ICAL_STATUS_NONE;
- e_cal_component_get_status(comp_alarms->comp, &status);
+ // walk through the cattegories list to look for our in-house tags
+ bool disabled = false;
+ Appointment::Type type = Appointment::EVENT;
+ GSList * categ_list = nullptr;
+ e_cal_component_get_categories_list (component, &categ_list);
+ for (GSList * l=categ_list; l!=nullptr; l=l->next) {
+ auto tag = static_cast<const char*>(l->data);
+ if (!g_strcmp0(tag, TAG_ALARM))
+ type = Appointment::UBUNTU_ALARM;
+ if (!g_strcmp0(tag, TAG_DISABLED))
+ disabled = true;
+ }
+ e_cal_component_free_categories_list(categ_list);
+ if (disabled) // don't notify users about disabled alarms...
+ return;
+
+ /**
+ *** This looks like a component that we should notify users about.
+ *** Let's add it.
+ **/
+
+ Appointment appointment;
+ appointment.uid = uid;
+ appointment.color = subtask->color;
+ appointment.type = type;
+
+ // get appointment.summary
+ ECalComponentText text {};
+ e_cal_component_get_summary(component, &text);
+ if (text.value)
+ appointment.summary = text.value;
// get dtstart as a DateTime
ECalComponentDateTime eccdt_tmp;
- e_cal_component_get_dtstart(comp_alarms->comp, &eccdt_tmp);
- const auto begin = datetime_from_component_date_time(eccdt_tmp, gtz);
+ e_cal_component_get_dtstart(component, &eccdt_tmp);
+ //const auto begin = datetime_from_component_date_time(eccdt_tmp, gtz);
+ appointment.begin = datetime_from_component_date_time(eccdt_tmp, gtz);
e_cal_component_free_datetime(&eccdt_tmp);
// get dtend as a DateTime
- e_cal_component_get_dtend(comp_alarms->comp, &eccdt_tmp);
- DateTime end = eccdt_tmp.value != nullptr ? datetime_from_component_date_time(eccdt_tmp, gtz) : begin;
+ e_cal_component_get_dtend(component, &eccdt_tmp);
+ //DateTime end = eccdt_tmp.value != nullptr ? datetime_from_component_date_time(eccdt_tmp, gtz) : begin;
+ appointment.end = eccdt_tmp.value != nullptr ? datetime_from_component_date_time(eccdt_tmp, gtz) : appointment.begin;
e_cal_component_free_datetime(&eccdt_tmp);
g_debug("got appointment from %s to %s, uid %s status %d",
- begin.format("%F %T %z").c_str(),
- end.format("%F %T %z").c_str(),
+ appointment.begin.format("%F %T %z").c_str(),
+ appointment.end.format("%F %T %z").c_str(),
uid,
(int)status);
+ // build our Alarm map from the comp_alarms
+ std::map<DateTime,Alarm> alarms;
for (auto l=comp_alarms->alarms; l!=nullptr; l=l->next)
{
auto ai = static_cast<ECalComponentAlarmInstance*>(l->data);
- auto a = e_cal_component_get_alarm(comp_alarms->comp, ai->auid);
+ auto a = e_cal_component_get_alarm(component, ai->auid);
if (a != nullptr)
{
g_message("%s creating alarm_begin from ai->trigger %zu", G_STRLOC, (size_t)ai->trigger);
const DateTime alarm_begin{gtz, ai->trigger};
-g_message("%s alarm_begin is %s", alarm_begin.format("%F %T %z").c_str());
-#if 0
+g_message("%s alarm_begin is %s", G_STRLOC, alarm_begin.format("%F %T %z").c_str());
auto& alarm = alarms[alarm_begin];
if (alarm.text.empty())
@@ -693,195 +735,37 @@ g_message("%s alarm_begin is %s", alarm_begin.format("%F %T %z").c_str());
alarm.audio_url = get_alarm_sound_url(a);
if (!alarm.time.is_set())
alarm.time = alarm_begin;
-#endif
e_cal_component_alarm_free(a);
}
}
-#if 0
- auto instance_callback = [](icalcomponent *comp, struct icaltime_span *span, void *vsubtask) {
- auto instance = icalcomponent_new_clone(comp);
- auto subtask = static_cast<AppointmentSubtask*>(vsubtask);
- icalcomponent_set_dtstart(instance, icaltime_from_timet(span->start, false));
- icalcomponent_set_dtend(instance, icaltime_from_timet(span->end, false));
- g_debug("instance %s", icalcomponent_as_ical_string(instance));
-
- auto valarm = icalcomponent_get_first_component(instance, ICAL_VALARM_COMPONENT);
- while (valarm != nullptr) {
- g_debug("valarm %s", icalcomponent_as_ical_string(valarm));
- auto trigger_property = icalcomponent_get_first_property(valarm, ICAL_TRIGGER_PROPERTY);
- if (trigger_property != nullptr)
- {
- auto trigger = icalproperty_get_trigger(trigger_property);
- g_debug("%s found a trigger", G_STRLOC);
- g_debug("%s trigger time is %s", G_STRLOC, icaltime_as_ical_string(trigger.time));
- g_debug("%s trigger duration is %s", G_STRLOC, icaldurationtype_as_ical_string(trigger.duration));
- if(!icaltime_is_null_time(trigger.time))
- g_debug("value=DATE-TIME:%s\n", icaltime_as_ical_string(trigger.time));
- else
- g_debug("value=DURATION:%s\n", icaldurationtype_as_ical_string(trigger.duration));
- }
- g_debug("%s %p", G_STRLOC, subtask->gtz);
- auto trigger_time = get_trigger_time (instance, valarm, subtask->gtz);
- g_debug("%s", G_STRLOC);
- if (trigger_time.is_set())
- {
- g_debug("%s whoo got trigger time! %s", G_STRLOC, trigger_time.format("%F %T %z").c_str());
-
- auto duration_property = icalcomponent_get_first_property(valarm, ICAL_DURATION_PROPERTY);
- auto repeat_property = icalcomponent_get_first_property(valarm, ICAL_DURATION_PROPERTY);
- if ((duration_property != nullptr) && (repeat_property != nullptr))
- {
- // FIXME: implement repeat
- }
- }
- valarm = icalcomponent_get_next_component(instance, ICAL_VALARM_COMPONENT);
- }
-
-/*
-(process:28936): Indicator-Datetime-DEBUG: valarm BEGIN:VALARM^M
-X-EVOLUTION-ALARM-UID:20150519T235024Z-22031-1000-21745-12@ghidorah^M
-DESCRIPTION:Summary^M
-ACTION:DISPLAY^M
-TRIGGER;VALUE=DURATION;RELATED=START:-PT15M^M
-END:VALARM^M
-*/
- };
-
- auto rbegin = icaltimetype_from_datetime(subtask->begin, subtask->default_timezone);
- auto rend = icaltimetype_from_datetime(subtask->end, subtask->default_timezone);
- auto icc = e_cal_component_get_icalcomponent(component); // component owns icc
- g_debug("calling foreach-recurrence... [%s...%s]", icaltime_as_ical_string(rbegin), icaltime_as_ical_string(rend));
- icalcomponent_foreach_recurrence(icc, rbegin, rend, instance_callback, subtask);
-#endif
-
-#if 0
- // look for the in-house tags
- bool disabled = false;
- Appointment::Type type = Appointment::EVENT;
- GSList * categ_list = nullptr;
- e_cal_component_get_categories_list (component, &categ_list);
- for (GSList * l=categ_list; l!=nullptr; l=l->next) {
- auto tag = static_cast<const char*>(l->data);
- if (!g_strcmp0(tag, TAG_ALARM))
- type = Appointment::UBUNTU_ALARM;
- if (!g_strcmp0(tag, TAG_DISABLED))
- disabled = true;
- }
- e_cal_component_free_categories_list(categ_list);
-
- if ((uid != nullptr) &&
- (!disabled) &&
- (status != ICAL_STATUS_COMPLETED) &&
- (status != ICAL_STATUS_CANCELLED))
+ // look for our recognized e-props
+ auto icc = e_cal_component_get_icalcomponent(component); // icc owned by component
+ if (icc != nullptr)
{
- constexpr std::array<ECalComponentAlarmAction,1> omit = { (ECalComponentAlarmAction)-1 }; // list of action types to omit, terminated with -1
- Appointment appointment;
-
- ECalComponentText text {};
- e_cal_component_get_summary(component, &text);
- if (text.value)
- appointment.summary = text.value;
+ g_debug("%s", icalcomponent_as_ical_string(icc)); // libical owns this string; no leak
- auto icc = e_cal_component_get_icalcomponent(component); // component owns icc
- if (icc)
+ auto icalprop = icalcomponent_get_first_property(icc, ICAL_X_PROPERTY);
+ while (icalprop)
{
- g_debug("%s", icalcomponent_as_ical_string(icc)); // libical owns this string; no leak
-
- auto icalprop = icalcomponent_get_first_property(icc, ICAL_X_PROPERTY);
- while (icalprop)
+ const char * x_name = icalproperty_get_x_name(icalprop);
+ if ((x_name != nullptr) && !g_ascii_strcasecmp(x_name, X_PROP_ACTIVATION_URL))
{
- const char * x_name = icalproperty_get_x_name(icalprop);
- if ((x_name != nullptr) && !g_ascii_strcasecmp(x_name, X_PROP_ACTIVATION_URL))
- {
- const char * url = icalproperty_get_value_as_string(icalprop);
- if ((url != nullptr) && appointment.activation_url.empty())
- appointment.activation_url = url;
- }
-
- icalprop = icalcomponent_get_next_property(icc, ICAL_X_PROPERTY);
+ const char * url = icalproperty_get_value_as_string(icalprop);
+ if ((url != nullptr) && appointment.activation_url.empty())
+ appointment.activation_url = url;
}
- }
- appointment.begin = begin;
- appointment.end = end;
- appointment.color = subtask->color;
- appointment.uid = uid;
- appointment.type = type;
-
- auto e_alarms = e_cal_util_generate_alarms_for_comp(component,
- begin.to_unix(),
- end.to_unix(),
- const_cast<ECalComponentAlarmAction*>(omit.data()),
- e_cal_client_resolve_tzid_cb,
- subtask->client,
- nullptr);
-
- std::map<DateTime,Alarm> alarms;
-
- if (e_alarms != nullptr)
- {
- for (auto l=e_alarms->alarms; l!=nullptr; l=l->next)
- {
- auto ai = static_cast<ECalComponentAlarmInstance*>(l->data);
- auto a = e_cal_component_get_alarm(component, ai->auid);
-
- if (a != nullptr)
- {
- const DateTime alarm_begin{gtz, ai->trigger};
- auto& alarm = alarms[alarm_begin];
-
- if (alarm.text.empty())
- alarm.text = get_alarm_text(a);
- if (alarm.audio_url.empty())
- alarm.audio_url = get_alarm_sound_url(a);
- if (!alarm.time.is_set())
- alarm.time = alarm_begin;
-
- e_cal_component_alarm_free(a);
- }
- }
-
- e_cal_component_alarms_free(e_alarms);
- }
- // Hm, no alarm triggers?
- // That's a bug in alarms created by some versions of ubuntu-ui-toolkit.
- // If that's what's happening here, let's handle those alarms anyway
- // by effectively injecting a TRIGGER;VALUE=DURATION;RELATED=START:PT0S
- else if (appointment.is_ubuntu_alarm())
- {
- Alarm tmp;
- tmp.time = appointment.begin;
-
- auto auids = e_cal_component_get_alarm_uids(component);
- for(auto l=auids; l!=nullptr; l=l->next)
- {
- const auto auid = static_cast<const char*>(l->data);
- auto a = e_cal_component_get_alarm(component, auid);
- if (a != nullptr)
- {
- if (tmp.text.empty())
- tmp.text = get_alarm_text(a);
- if (tmp.audio_url.empty())
- tmp.audio_url = get_alarm_sound_url(a);
- e_cal_component_alarm_free(a);
- }
- }
- cal_obj_uid_list_free(auids);
-
- alarms[tmp.time] = tmp;
+ icalprop = icalcomponent_get_next_property(icc, ICAL_X_PROPERTY);
}
-
- appointment.alarms.reserve(alarms.size());
- for (const auto& it : alarms)
- appointment.alarms.push_back(it.second);
-
- subtask->task->appointments.push_back(appointment);
}
- g_time_zone_unref(gtz);
-#endif
+ appointment.alarms.reserve(alarms.size());
+ for (const auto& it : alarms)
+ appointment.alarms.push_back(it.second);
+
+ subtask->task->appointments.push_back(appointment);
}
diff --git a/tests/test-eds-tasks-config-files/.local/share/evolution/tasks/system/tasks.ics b/tests/test-eds-tasks-config-files/.local/share/evolution/tasks/system/tasks.ics
index 1d6dc7a..efde5f7 100644
--- a/tests/test-eds-tasks-config-files/.local/share/evolution/tasks/system/tasks.ics
+++ b/tests/test-eds-tasks-config-files/.local/share/evolution/tasks/system/tasks.ics
@@ -2,24 +2,24 @@ BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
VERSION:2.0
-X-EVOLUTION-DATA-REVISION:2015-05-19T22:52:41.612439Z(53)
+X-EVOLUTION-DATA-REVISION:2015-05-07T21:14:49.315443Z(0)
BEGIN:VTODO
-UID:20150519T225233Z-3878-32011-1770-73@ubuntu-phablet
-DTSTAMP:20150519T225241Z
-DTSTART:20150520T120000
-RRULE:FREQ=DAILY
+UID:20150507T211449Z-4262-32011-1418-1@ubuntu-phablet
+DTSTAMP:20150508T211449Z
+DTSTART:20150508T164000
+RRULE:FREQ=WEEKLY;BYDAY=FR
SUMMARY:Alarm
CATEGORIES:x-canonical-alarm
-SEQUENCE:1
-LAST-MODIFIED:20150519T225241Z
+CREATED:20150507T211449Z
+LAST-MODIFIED:20150507T211449Z
BEGIN:VALARM
-X-EVOLUTION-ALARM-UID:20150519T225241Z-3878-32011-1770-78@ubuntu-phablet
+X-EVOLUTION-ALARM-UID:20150507T211449Z-4262-32011-1418-2@ubuntu-phablet
ACTION:AUDIO
ATTACH:file:///usr/share/sounds/ubuntu/ringtones/Suru arpeggio.ogg
TRIGGER;VALUE=DURATION;RELATED=START:PT0S
END:VALARM
BEGIN:VALARM
-X-EVOLUTION-ALARM-UID:20150519T225241Z-3878-32011-1770-79@ubuntu-phablet
+X-EVOLUTION-ALARM-UID:20150507T211449Z-4262-32011-1418-3@ubuntu-phablet
ACTION:DISPLAY
DESCRIPTION:Alarm
TRIGGER;VALUE=DURATION;RELATED=START:PT0S
diff --git a/tests/test-eds-tasks.cpp b/tests/test-eds-tasks.cpp
index 6dbb49f..2db1708 100644
--- a/tests/test-eds-tasks.cpp
+++ b/tests/test-eds-tasks.cpp
@@ -85,16 +85,15 @@ TEST_F(VAlarmFixture, MultipleAppointments)
// compare it to what we actually loaded...
const auto appts = planner->appointments().get();
- EXPECT_EQ(expected_alarms.size(), appts.size());
- for (size_t i=0, n=expected_alarms.size(); i<n; i++) {
- const auto& appt = appts[i];
- EXPECT_EQ(expected_appt.uid, appt.uid);
- EXPECT_EQ(expected_appt.color, appt.color);
- EXPECT_EQ(expected_appt.summary, appt.summary);
- EXPECT_EQ(1, appt.alarms.size());
- EXPECT_EQ(expected_alarms[i], appt.alarms[0]);
- }
-
+ ASSERT_GT(appts.size(), 0);
+ EXPECT_EQ(1, appts.size());
+ const auto& appt = appts[0];
+ EXPECT_EQ(expected_appt.uid, appt.uid);
+ EXPECT_EQ(expected_appt.color, appt.color);
+ EXPECT_EQ(expected_appt.summary, appt.summary);
+ EXPECT_EQ(expected_alarms.size(), appt.alarms.size());
+ for (size_t i=0, n=expected_alarms.size(); i<n; i++)
+ EXPECT_EQ(expected_alarms[i], appt.alarms[i]);
// cleanup
g_time_zone_unref(gtz);