Example #1
0
/**
 * e_cal_util_is_first_instance:
 * @comp: an #ECalComponent instance
 * @rid: a recurrence ID
 * @tz_cb: (closure tz_cb_data) (scope call): The #ECalRecurResolveTimezoneFn to call
 * @tz_cb_data: (closure): User data to be passed to the @tz_cb callback
 *
 * Returns whether the given @rid is the first instance of
 * the recurrence defined in the @comp.
 *
 * Return: Whether the @rid identifies the first instance of @comp.
 *
 * Since: 3.16
 **/
gboolean
e_cal_util_is_first_instance (ECalComponent *comp,
			      struct icaltimetype rid,
			      ECalRecurResolveTimezoneFn tz_cb,
			      gpointer tz_cb_data)
{
	CheckFirstInstanceData ifs;
	icalcomponent *icalcomp;
	time_t start, end;

	g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
	g_return_val_if_fail (!icaltime_is_null_time (rid), FALSE);

	ifs.rid = rid;
	ifs.matches = FALSE;

	icalcomp = e_cal_component_get_icalcomponent (comp);
	start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp)) - 24 * 60 * 60;
	end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp)) + 24 * 60 * 60;

	e_cal_recur_generate_instances (comp, start, end, check_first_instance_cb, &ifs,
		tz_cb, tz_cb_data, icaltimezone_get_utc_timezone ());

	return ifs.matches;
}
static gboolean
get_ical_is_all_day (icalcomponent *ical,
                     time_t         start_time,
                     icaltimezone  *default_zone)
{
  icalproperty            *prop;
  struct tm               *start_tm;
  time_t                   end_time;
  struct icaldurationtype  duration;
  struct icaltimetype      start_icaltime;

  start_icaltime = icalcomponent_get_dtstart (ical);
  if (start_icaltime.is_date)
    return TRUE;

  start_tm = gmtime (&start_time);
  if (start_tm->tm_sec  != 0 ||
      start_tm->tm_min  != 0 ||
      start_tm->tm_hour != 0)
    return FALSE;

  if ((end_time = get_ical_end_time (ical, default_zone)))
    return (end_time - start_time) % 86400 == 0;

  prop = icalcomponent_get_first_property (ical, ICAL_DURATION_PROPERTY);
  if (!prop)
    return FALSE;

  duration = icalproperty_get_duration (prop);

  return icaldurationtype_as_int (duration) % 86400 == 0;
}
Example #3
0
static gboolean
check_first_instance_cb (ECalComponent *comp,
			 time_t instance_start,
			 time_t instance_end,
			 gpointer user_data)
{
	CheckFirstInstanceData *ifs = user_data;
	icalcomponent *icalcomp;
	struct icaltimetype rid;

	g_return_val_if_fail (ifs != NULL, FALSE);

	icalcomp = e_cal_component_get_icalcomponent (comp);
	if (icalcomponent_get_first_property (icalcomp, ICAL_RECURRENCEID_PROPERTY) != NULL) {
		rid = icalcomponent_get_recurrenceid (icalcomp);
	} else {
		struct icaltimetype dtstart;

		dtstart = icalcomponent_get_dtstart (icalcomp);
		if (dtstart.zone) {
			rid = icaltime_from_timet_with_zone (instance_start, dtstart.is_date, dtstart.zone);
		} else {
			rid = icaltime_from_timet (instance_start, dtstart.is_date);
		}
	}

	ifs->matches = icaltime_compare (ifs->rid, rid) == 0;

	return FALSE;
}
static void
adjust_dtstart_day_to_rrule (icalcomponent *comp, struct icalrecurrencetype rule)
{
	time_t now, year_start;
	struct icaltimetype start, comp_start, iter_start, itime;
	icalrecur_iterator *iter;

	now = time (NULL);
	itime = icaltime_from_timet (now, 0);
	itime.month = itime.day = 1;
	itime.hour = itime.minute = itime.second = 0;
	year_start = icaltime_as_timet(itime);

	comp_start = icalcomponent_get_dtstart (comp);
	start = icaltime_from_timet (year_start, 0);

	iter = icalrecur_iterator_new (rule, start);
	iter_start = icalrecur_iterator_next (iter);
	icalrecur_iterator_free (iter);

	if (iter_start.day != comp_start.day) {
		comp_start.day = iter_start.day;
		icalcomponent_set_dtstart (comp, comp_start);
	}
}
Example #5
0
/**
 * e_cal_util_event_dates_match:
 * @icalcomp1: An #icalcomponent.
 * @icalcomp2: An #icalcomponent.
 *
 * Compare the dates of two #icalcomponent's to check if they match.
 *
 * Returns: TRUE if the dates of both components match, FALSE otherwise.
 */
gboolean
e_cal_util_event_dates_match (icalcomponent *icalcomp1,
                              icalcomponent *icalcomp2)
{
	struct icaltimetype c1_dtstart, c1_dtend, c2_dtstart, c2_dtend;

	g_return_val_if_fail (icalcomp1 != NULL, FALSE);
	g_return_val_if_fail (icalcomp2 != NULL, FALSE);

	c1_dtstart = icalcomponent_get_dtstart (icalcomp1);
	c1_dtend = icalcomponent_get_dtend (icalcomp1);
	c2_dtstart = icalcomponent_get_dtstart (icalcomp2);
	c2_dtend = icalcomponent_get_dtend (icalcomp2);

	/* if either value is NULL, they must both be NULL to match */
	if (icaltime_is_valid_time (c1_dtstart) || icaltime_is_valid_time (c2_dtstart)) {
		if (!(icaltime_is_valid_time (c1_dtstart) && icaltime_is_valid_time (c2_dtstart)))
			return FALSE;
	} else {
		if (icaltime_compare (c1_dtstart, c2_dtstart))
			return FALSE;
	}

	if (icaltime_is_valid_time (c1_dtend) || icaltime_is_valid_time (c2_dtend)) {
		if (!(icaltime_is_valid_time (c1_dtend) && icaltime_is_valid_time (c2_dtend)))
			return FALSE;
	} else {
		if (icaltime_compare (c1_dtend, c2_dtend))
			return FALSE;
	}

	/* now match the timezones */
	if (!(!c1_dtstart.zone && !c2_dtstart.zone) ||
	    (c1_dtstart.zone && c2_dtstart.zone &&
	     !strcmp (icaltimezone_get_tzid ((icaltimezone *) c1_dtstart.zone),
		      icaltimezone_get_tzid ((icaltimezone *) c2_dtstart.zone))))
		return FALSE;

	if (!(!c1_dtend.zone && !c2_dtend.zone) ||
	    (c1_dtend.zone && c2_dtend.zone &&
	     !strcmp (icaltimezone_get_tzid ((icaltimezone *) c1_dtend.zone),
		      icaltimezone_get_tzid ((icaltimezone *) c2_dtend.zone))))
		return FALSE;

	return TRUE;
}
Example #6
0
static void
event_time (icalcomponent * icalcomp, gchar * str, size_t len,
			DNTimeFormat format)
{
	struct icaltimetype istart, iend;
	struct tm tm_start, tm_end;
	
	istart = icalcomponent_get_dtstart (icalcomp);
	iend   = icalcomponent_get_dtend (icalcomp);

	tm_start = icaltimetype_to_tm (&istart);
	tm_end   = icaltimetype_to_tm (&iend);

	gint offset = 0;
	
	if (format == DN_TimeOnly)
	{
		offset = e_utf8_strftime (str, len, "%R", &tm_start);
		str += offset;

		*str++ = ' ';
		*str++ = '-';
		*str++ = ' ';
		
		len -= (offset + 3);
		g_assert (len > 0);
		
		e_utf8_strftime (str, len, "%R", &tm_end);
	}
	else
	{
		offset = e_utf8_strftime (str, len, "%x", &tm_start);
		str += offset;
		*str++ = ' ';
		*str++ = ' ';
		len -= (offset + 2);
		g_assert (len > 0);
		
		offset = e_utf8_strftime (str, len, "%R", &tm_start);
		str += offset;
		*str++ = '-';
		len -= (offset + 1);
		g_assert (len > 0);

		e_utf8_strftime (str, len, "%R", &tm_end);
	}
}
Example #7
0
/**
 * e_cal_util_split_at_instance:
 * @icalcomp: A (recurring) #icalcomponent
 * @rid: The base RECURRENCE-ID to remove
 * @master_dtstart: The DTSTART of the master object
 *
 * Splits a recurring @icalcomp into two at time @rid. The returned icalcomponent
 * is modified @icalcomp which contains recurrences beginning at @rid, inclusive.
 * The instance identified by @rid should exist. The @master_dtstart can be
 * a null time, then it is read from the @icalcomp.
 *
 * Use e_cal_util_remove_instances() with E_CAL_OBJ_MOD_THIS_AND_FUTURE mode
 * on the @icalcomp to remove the overlapping interval from it, if needed.
 *
 * Returns: the split icalcomponent, or %NULL.
 *
 * Since: 3.16
 **/
icalcomponent *
e_cal_util_split_at_instance (icalcomponent *icalcomp,
			      struct icaltimetype rid,
			      struct icaltimetype master_dtstart)
{
	icalproperty *prop;
	struct instance_data instance;
	struct icaltimetype start, end;
	struct icaldurationtype duration;
	GSList *remove_props = NULL, *link;

	g_return_val_if_fail (icalcomp != NULL, NULL);
	g_return_val_if_fail (!icaltime_is_null_time (rid), NULL);

	/* Make sure this is really recurring */
	if (!icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY) &&
	    !icalcomponent_get_first_property (icalcomp, ICAL_RDATE_PROPERTY))
		return NULL;

	/* Make sure the specified instance really exists */
	start = icaltime_convert_to_zone (rid, icaltimezone_get_utc_timezone ());
	end = start;
	icaltime_adjust (&end, 0, 0, 0, 1);

	instance.start = icaltime_as_timet (start);
	instance.found = FALSE;
	icalcomponent_foreach_recurrence (icalcomp, start, end,
					  check_instance, &instance);
	/* Make the copy */
	icalcomp = icalcomponent_new_clone (icalcomp);

	e_cal_util_remove_instances_ex (icalcomp, rid, E_CAL_OBJ_MOD_THIS_AND_PRIOR, TRUE, FALSE);

	start = rid;
	if (icaltime_is_null_time (master_dtstart))
		master_dtstart = icalcomponent_get_dtstart (icalcomp);
	duration = icalcomponent_get_duration (icalcomp);

	/* Expect that DTSTART and DTEND are already set when the instance could not be found */
	if (instance.found) {
		icalcomponent_set_dtstart (icalcomp, start);
		/* Update either DURATION or DTEND */
		if (icaltime_is_null_time (icalcomponent_get_dtend (icalcomp))) {
			icalcomponent_set_duration (icalcomp, duration);
		} else {
			end = start;
			if (duration.is_neg)
				icaltime_adjust (&end, -duration.days - 7 * duration.weeks, -duration.hours, -duration.minutes, -duration.seconds);
			else
				icaltime_adjust (&end, duration.days + 7 * duration.weeks, duration.hours, duration.minutes, duration.seconds);
			icalcomponent_set_dtend (icalcomp, end);
		}
	}

	/* any RRULE with 'count' should be shortened */
	for (prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
	     prop;
	     prop = icalcomponent_get_next_property (icalcomp, ICAL_RRULE_PROPERTY)) {
		struct icaltimetype recur;
		struct icalrecurrencetype rule;

		rule = icalproperty_get_rrule (prop);

		if (rule.count != 0) {
			gint occurrences_count = 0;
			icalrecur_iterator *iter;

			iter = icalrecur_iterator_new (rule, master_dtstart);
			while (recur = icalrecur_iterator_next (iter), !icaltime_is_null_time (recur) && occurrences_count < rule.count) {
				if (icaltime_compare (recur, rid) >= 0)
					break;

				occurrences_count++;
			}

			icalrecur_iterator_free (iter);

			if (icaltime_is_null_time (recur)) {
				remove_props = g_slist_prepend (remove_props, prop);
			} else {
				rule.count -= occurrences_count;
				icalproperty_set_rrule (prop, rule);
				icalproperty_remove_parameter_by_name (prop, "X-EVOLUTION-ENDDATE");
			}
		}
	}

	for (link = remove_props; link; link = g_slist_next (link)) {
		prop = link->data;

		icalcomponent_remove_property (icalcomp, prop);
	}

	g_slist_free (remove_props);

	return icalcomp;
}
Example #8
0
static void
e_cal_util_remove_instances_ex (icalcomponent *icalcomp,
				struct icaltimetype rid,
				ECalObjModType mod,
				gboolean keep_rid,
				gboolean can_add_exrule)
{
	icalproperty *prop;
	struct icaltimetype itt, recur;
	struct icalrecurrencetype rule;
	icalrecur_iterator *iter;
	GSList *remove_props = NULL, *rrules = NULL, *link;

	g_return_if_fail (icalcomp != NULL);
	g_return_if_fail (mod != E_CAL_OBJ_MOD_ALL);

	/* First remove RDATEs and EXDATEs in the indicated range. */
	for (prop = icalcomponent_get_first_property (icalcomp, ICAL_RDATE_PROPERTY);
	     prop;
	     prop = icalcomponent_get_next_property (icalcomp, ICAL_RDATE_PROPERTY)) {
		struct icaldatetimeperiodtype period;

		period = icalproperty_get_rdate (prop);
		if (time_matches_rid (period.time, rid, mod) && (!keep_rid ||
		    icaltime_compare (period.time, rid) != 0))
			remove_props = g_slist_prepend (remove_props, prop);
	}
	for (prop = icalcomponent_get_first_property (icalcomp, ICAL_EXDATE_PROPERTY);
	     prop;
	     prop = icalcomponent_get_next_property (icalcomp, ICAL_EXDATE_PROPERTY)) {
		itt = icalproperty_get_exdate (prop);
		if (time_matches_rid (itt, rid, mod) && (!keep_rid ||
		    icaltime_compare (itt, rid) != 0))
			remove_props = g_slist_prepend (remove_props, prop);
	}

	for (link = remove_props; link; link = g_slist_next (link)) {
		prop = link->data;

		icalcomponent_remove_property (icalcomp, prop);
	}

	g_slist_free (remove_props);
	remove_props = NULL;

	/* If we're only removing one instance, just add an EXDATE. */
	if (mod == E_CAL_OBJ_MOD_THIS) {
		prop = icalproperty_new_exdate (rid);
		icalcomponent_add_property (icalcomp, prop);
		return;
	}

	/* Otherwise, iterate through RRULEs */
	/* FIXME: this may generate duplicate EXRULEs */
	for (prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
	     prop;
	     prop = icalcomponent_get_next_property (icalcomp, ICAL_RRULE_PROPERTY)) {
		rrules = g_slist_prepend (rrules, prop);
	}

	for (link = rrules; link; link = g_slist_next (link)) {
		prop = link->data;
		rule = icalproperty_get_rrule (prop);

		iter = icalrecur_iterator_new (rule, rid);
		recur = icalrecur_iterator_next (iter);

		if (mod & E_CAL_OBJ_MOD_THIS_AND_FUTURE) {
			/* Truncate the rule at rid. */
			if (!icaltime_is_null_time (recur)) {
				/* Use count if it was used */
				if (rule.count > 0) {
					gint occurrences_count = 0;
					icalrecur_iterator *count_iter;
					struct icaltimetype count_recur;

					count_iter = icalrecur_iterator_new (rule, icalcomponent_get_dtstart (icalcomp));
					while (count_recur = icalrecur_iterator_next (count_iter), !icaltime_is_null_time (count_recur) && occurrences_count < rule.count) {
						if (icaltime_compare (count_recur, rid) >= 0)
							break;

						occurrences_count++;
					}

					icalrecur_iterator_free (count_iter);

					if (keep_rid && icaltime_compare (count_recur, rid) == 0)
						occurrences_count++;

					/* The caller should make sure that the remove will keep at least one instance */
					g_warn_if_fail (occurrences_count > 0);

					rule.count = occurrences_count;
				} else {
					if (keep_rid && icaltime_compare (recur, rid) == 0)
						rule.until = icaltime_add (rid, icalcomponent_get_duration (icalcomp));
					else
						rule.until = rid;
					icaltime_adjust (&rule.until, 0, 0, 0, -1);
				}

				icalproperty_set_rrule (prop, rule);
				icalproperty_remove_parameter_by_name (prop, "X-EVOLUTION-ENDDATE");
			}
		} else {
			/* (If recur == rid, skip to the next occurrence) */
			if (!keep_rid && icaltime_compare (recur, rid) == 0)
				recur = icalrecur_iterator_next (iter);

			/* If there is a recurrence after rid, add
			 * an EXRULE to block instances up to rid.
			 * Otherwise, just remove the RRULE.
			 */
			if (!icaltime_is_null_time (recur)) {
				if (can_add_exrule) {
					rule.count = 0;
					/* iCalendar says we should just use rid
					 * here, but Outlook/Exchange handle
					 * UNTIL incorrectly.
					 */
					if (keep_rid && icaltime_compare (recur, rid) == 0) {
						struct icaldurationtype duration = icalcomponent_get_duration (icalcomp);
						duration.is_neg = !duration.is_neg;
						rule.until = icaltime_add (rid, duration);
					} else
						rule.until = icaltime_add (rid, icalcomponent_get_duration (icalcomp));
					prop = icalproperty_new_exrule (rule);
					icalcomponent_add_property (icalcomp, prop);
				}
			} else {
				remove_props = g_slist_prepend (remove_props, prop);
			}
		}

		icalrecur_iterator_free (iter);
	}

	for (link = remove_props; link; link = g_slist_next (link)) {
		prop = link->data;

		icalcomponent_remove_property (icalcomp, prop);
	}

	g_slist_free (remove_props);
	g_slist_free (rrules);
}
Example #9
0
int main(int argc, char *argv[])
{
    icalcomponent *c, *next_c = NULL;
    int i = 0;
    int dont_remove;
    icalfileset_options options = { O_RDONLY, 0644, 0, NULL };

    icalset *f = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/process-incoming.ics", &options);
    icalset *trash = icalset_new_file("trash.ics");
    icalset *cal = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/process-calendar.ics", &options);
    icalset *out = icalset_new_file("outgoing.ics");

    const char *this_user = "******";

    _unused(argc);
    _unused(argv);

    assert(f != 0);
    assert(cal != 0);
    assert(trash != 0);
    assert(out != 0);

    /* Foreach incoming message */
    for (c = icalset_get_first_component(f); c != 0; c = next_c) {

        icalproperty_xlicclass class;
        icalcomponent *match;
        icalcomponent *inner;
        icalcomponent *reply = 0;

        assert(c != 0);

        inner = icalcomponent_get_first_real_component(c);

        i++;
        reply = 0;
        dont_remove = 0;

        if (inner == 0) {
            printf("Bad component, no inner\n %s\n", icalcomponent_as_ical_string(c));
            continue;
        }

        /* Find a booked component that is matched to the incoming
           message, based on the incoming component's UID, SEQUENCE
           and RECURRENCE-ID */

        match = icalset_fetch_match(cal, c);

        class = icalclassify(c, match, this_user);

        /* Print out the notes associated with the incoming component
           and the matched component in the */
        {
            const char *inc_note = 0;
            const char *match_note = 0;
            icalproperty *p;

            for (p = icalcomponent_get_first_property(c, ICAL_X_PROPERTY);
                 p != 0; p = icalcomponent_get_next_property(c, ICAL_X_PROPERTY)) {

                if (strcmp(icalproperty_get_x_name(p), "X-LIC-NOTE") == 0) {
                    inc_note = icalproperty_get_x(p);
                }
            }

            if (match != 0) {
                for (p = icalcomponent_get_first_property(match, ICAL_X_PROPERTY);
                     p != 0;
                     p = icalcomponent_get_next_property(match, ICAL_X_PROPERTY)) {
                    if (strcmp(icalproperty_get_x_name(p), "X-LIC-NOTE") == 0) {
                        match_note = icalproperty_get_x(p);
                    }
                }
            }

            if (inc_note != 0) {
                printf("Incoming: %s\n", inc_note);
            }
            if (match_note != 0) {
                printf("Match   : %s\n", match_note);
            }
        }

        /* Main processing structure */

        switch (class) {
        case ICAL_XLICCLASS_NONE:{
                char temp[1024];

                /* Huh? Return an error to sender */
                icalrestriction_check(c);
                icalcomponent_convert_errors(c);

                snprintf(temp, 1024,
                         "I can't understand the component you sent.\n"
                         "Here is the component you sent, possibly with error messages:\n"
                         "%s",
                         icalcomponent_as_ical_string(c));

                reply = icalmessage_new_error_reply(c, this_user, temp, "", ICAL_UNKNOWN_STATUS);

                break;
            }
        case ICAL_XLICCLASS_PUBLISHNEW:{

                /* Don't accept published events from anyone but
                   self. If self, fall through to ICAL_XLICCLASS_REQUESTNEW */
            }
        case ICAL_XLICCLASS_REQUESTNEW:{

                /* Book the new component if it does not overlap
                   anything. If the time is busy and the start time is
                   an even modulo 4, delegate to
                   [email protected]. If the time is busy and
                   is 1 modulo 4, counterpropose for the first
                   available free time. Otherwise, deline the meeting */

                icalcomponent *overlaps = icalclassify_find_overlaps(cal, c);

                if (overlaps == 0) {
                    /* No overlaps, book the meeting */
/*                  icalset_add_component(cal,icalcomponent_new_clone(c));*/

                    /* Return a reply */
                    reply =
                        icalmessage_new_accept_reply(
                            c, this_user, "I can make it to this meeting");

                    (void)icalset_add_component(out, reply);

                } else {
                    /* There was a conflict, so delegate, counterpropose
                       or decline it */
                    struct icaltimetype dtstart = icalcomponent_get_dtstart(c);

                    if (dtstart.hour % 4 == 0) {
                        /* Delegate the meeting */
                        reply =
                            icalmessage_new_delegate_reply(
                                c,
                                this_user,
                                "*****@*****.**",
                                "Unfortunately, I have another commitment that conflicts "
                                "with this meeting. I am delegating my attendance to Bob.");
                        (void)icalset_add_component(out, reply);

                    } else if (dtstart.hour % 4 == 1) {
                        /* Counter propose to next available time */
                        icalcomponent *newc;
                        struct icalperiodtype next_time;

                        icalspanlist *spanl = icalspanlist_new(cal, dtstart,
                                                               icaltime_null_time());

                        next_time =
                            icalspanlist_next_free_time(spanl, icalcomponent_get_dtstart(c));

                        newc = icalcomponent_new_clone(c);

                        icalcomponent_set_dtstart(newc, next_time.start);

                        /* Hack, the duration of the counterproposed
                           meeting may be longer than the free time
                           available */
                        icalcomponent_set_duration(newc, icalcomponent_get_duration(c));

                        reply =
                            icalmessage_new_counterpropose_reply(
                                c,
                                newc,
                                this_user,
                                "Unfortunately, I have another commitment that conflicts with "
                                "this meeting. I am proposing a time that works better for me.");

                        (void)icalset_add_component(out, reply);
                        icalspanlist_free(spanl);
                        icalcomponent_free(newc);

                    } else {
                        /* Decline the meeting */

                        reply =
                            icalmessage_new_decline_reply(
                                c,
                                this_user,
                                "I can't make it to this meeting");

                        (void)icalset_add_component(out, reply);
                    }
                }
                icalcomponent_free(overlaps);
                break;
            }
        case ICAL_XLICCLASS_PUBLISHFREEBUSY:{
                /* Store the busy time information in a file named after
                   the sender */
                break;
            }

        case ICAL_XLICCLASS_PUBLISHUPDATE:{
                /* Only accept publish updates from self. If self, fall
                   through to ICAL_XLICCLASS_REQUESTUPDATE */
            }

        case ICAL_XLICCLASS_REQUESTUPDATE:{
                /* always accept the changes */
                break;
            }

        case ICAL_XLICCLASS_REQUESTRESCHEDULE:{
                /* Use same rules as REQUEST_NEW */
                (void)icalclassify_find_overlaps(cal, c);
                break;
            }
        case ICAL_XLICCLASS_REQUESTDELEGATE:{

                break;
            }
        case ICAL_XLICCLASS_REQUESTNEWORGANIZER:{
                break;
            }
        case ICAL_XLICCLASS_REQUESTFORWARD:{
                break;
            }
        case ICAL_XLICCLASS_REQUESTSTATUS:{
                break;
            }

        case ICAL_XLICCLASS_REQUESTFREEBUSY:{
                break;
            }
        case ICAL_XLICCLASS_REPLYACCEPT:{
                /* Change the PARTSTAT of the sender */
                break;
            }
        case ICAL_XLICCLASS_REPLYDECLINE:{
                /* Change the PARTSTAT of the sender */
                break;
            }
        case ICAL_XLICCLASS_REPLYCRASHERACCEPT:{
                /* Add the crasher to the ATTENDEE list with the
                   appropriate PARTSTAT */
                break;
            }
        case ICAL_XLICCLASS_REPLYCRASHERDECLINE:{
                /* Add the crasher to the ATTENDEE list with the
                   appropriate PARTSTAT */
                break;
            }
        case ICAL_XLICCLASS_ADDINSTANCE:{
                break;
            }
        case ICAL_XLICCLASS_CANCELEVENT:{
                /* Remove the component */
                break;
            }
        case ICAL_XLICCLASS_CANCELINSTANCE:{
                break;
            }
        case ICAL_XLICCLASS_CANCELALL:{
                /* Remove the component */
                break;
            }
        case ICAL_XLICCLASS_REFRESH:{
                /* Resend the latest copy of the request */
                break;
            }
        case ICAL_XLICCLASS_COUNTER:{
                break;
            }
        case ICAL_XLICCLASS_DECLINECOUNTER:{
                break;
            }
        case ICAL_XLICCLASS_MALFORMED:{
                /* Send back an error */
                break;
            }
        case ICAL_XLICCLASS_OBSOLETE:{
                printf(" ** Got an obsolete component:\n%s", icalcomponent_as_ical_string(c));
                /* Send back an error */
                break;
            }
        case ICAL_XLICCLASS_MISSEQUENCED:{
                printf(" ** Got a missequenced component:\n%s", icalcomponent_as_ical_string(c));
                /* Send back an error */
                break;
            }
        case ICAL_XLICCLASS_UNKNOWN:{
                printf(" ** Don't know what to do with this component:\n%s",
                       icalcomponent_as_ical_string(c));
                /* Send back an error */
                break;
            }
        case ICAL_XLICCLASS_X:
        case ICAL_XLICCLASS_REPLYDELEGATE:
        default:{
            }
        }

#if 0
        if (reply != 0) {

            /* Don't send the reply if the RSVP parameter indicates not to */
            icalcomponent *reply_inner;
            icalproperty *attendee;
            icalparameter *rsvp;

            reply_inner = icalcomponent_get_first_real_component(reply);
            attendee = icalcomponent_get_first_property(reply_inner, ICAL_ATTENDEE_PROPERTY);
            rsvp = icalproperty_get_first_parameter(attendee, ICAL_RSVP_PARAMETER);

            if (rsvp == 0 || icalparameter_get_rsvp(rsvp) == 1) {
                icalrestriction_check(reply);
                send_message(reply, this_user);
            }

            icalcomponent_free(reply);
        }
#endif

        if (reply != 0) {
            printf("%s\n", icalcomponent_as_ical_string(reply));
        }

        next_c = icalset_get_next_component(f);

        if (dont_remove == 0) {
            /*icalset_remove_component(f,c);
               icalset_add_component(trash,c); */
        }
    }

#if 0

    for (c = icalset_get_first_component(out); c != 0; c = icalset_get_next_component(out)) {

        printf("%s", icalcomponent_as_ical_string(c));
    }
#endif

    icalset_free(f);
    icalset_free(trash);
    icalset_free(cal);
    icalset_free(out);

    return 0;
}
Example #10
0
static int gn_ical2calnote_real(icalcomponent *comp, gn_calnote *calnote, int id)
{
	int retval = GN_ERR_FAILED;
	struct icaltimetype dtstart = {0}, dtend = {0};
	icalcomponent *compresult = NULL;

	if (id < 1)
		id = 1;

	/* iterate through the component */
	iterate_cal(comp, 0, &id, &compresult, ICAL_VEVENT_COMPONENT);

	if (!compresult) {
		dprintf("No component found.\n");
		retval = GN_ERR_EMPTYLOCATION;
	} else {
		const char *str;
		icalcomponent *alarm = {0};
		icalproperty *rrule;
		struct icalrecurrencetype recur;
		retval = GN_ERR_NONE;

		calnote->phone_number[0] = 0;

		/* type */
		str = comp_get_category(compresult);
		calnote->type = str2calnote_type(str);
		switch (calnote->type) {
		case GN_CALNOTE_CALL:
			/* description goes into text */
			/* TODO: UTF8 --> ascii */
			snprintf(calnote->phone_number, GN_CALNOTE_NUMBER_MAX_LENGTH-1, "%s", icalcomponent_get_summary(compresult));
			str = icalcomponent_get_description(compresult);
			break;
		default:
			/* summary goes into text */
			/* TODO: UTF8 --> ascii */
			str = icalcomponent_get_summary(compresult);
			break;
		}
		if (str) {
			snprintf(calnote->text, GN_CALNOTE_MAX_LENGTH - 1, "%s", str);
		}

		/* start time */
		dtstart = icalcomponent_get_dtstart(compresult);
		if (!icaltime_is_null_time(dtstart)) {
			calnote->time.year = dtstart.year;
			calnote->time.month = dtstart.month;
			calnote->time.day = dtstart.day;
			if (!icaltime_is_date(dtstart)) {
				calnote->time.hour = dtstart.hour;
				calnote->time.minute = dtstart.minute;
				calnote->time.second = dtstart.second;
				/* TODO: what about time zones? */
			}
		}

		/* end time */
		memset(&calnote->end_time, 0, sizeof(calnote->end_time));
		dtend = icalcomponent_get_dtend(compresult);
		if (!icaltime_is_null_time(dtend)) {
			calnote->end_time.year = dtend.year;
			calnote->end_time.month = dtend.month;
			calnote->end_time.day = dtend.day;
			if (!icaltime_is_date(dtend)) {
				calnote->end_time.hour = dtend.hour;
				calnote->end_time.minute = dtend.minute;
				calnote->end_time.second = dtend.second;
				/* TODO: what about time zones? */
			}
		}

		/* alarm */
		alarm = icalcomponent_get_first_component(compresult, ICAL_VALARM_COMPONENT);
		if (alarm) {
			icalproperty *trigger = NULL;

			trigger = icalcomponent_get_first_property(alarm, ICAL_TRIGGER_PROPERTY);
			if (trigger) {
				struct icaltriggertype trigger_value;
				struct icaltimetype alarm_start;
				icalproperty *property;

				trigger_value = icalvalue_get_trigger(icalproperty_get_value(trigger));
				if (icaltriggertype_is_null_trigger(trigger_value) ||
						icaltriggertype_is_bad_trigger(trigger_value)) {
					calnote->alarm.enabled = 0;
				} else {
					if (icaltime_is_null_time(trigger_value.time)) {
						memcpy(&alarm_start, &dtstart, sizeof(struct icaltimetype));
					} else {
						memcpy(&alarm_start, &trigger_value.time, sizeof(struct icaltimetype));
					}
					if (!(icaldurationtype_is_bad_duration(trigger_value.duration) ||
							icaldurationtype_is_null_duration(trigger_value.duration))) {
						alarm_start = icaltime_add(alarm_start, trigger_value.duration);
					}
					calnote->alarm.enabled = 1;
					calnote->alarm.timestamp.year = alarm_start.year;
					calnote->alarm.timestamp.month = alarm_start.month;
					calnote->alarm.timestamp.day = alarm_start.day;
					calnote->alarm.timestamp.hour = alarm_start.hour;
					calnote->alarm.timestamp.minute = alarm_start.minute;
					calnote->alarm.timestamp.second = alarm_start.second;
					/* TODO: time zone? */

					property = icalcomponent_get_first_property(alarm, ICAL_ACTION_PROPERTY);
					calnote->alarm.tone = icalproperty_get_action(property) == ICAL_ACTION_AUDIO ? 1 : 0;
				}
			}
		}

		/* recurrence */
		rrule = icalcomponent_get_first_property(compresult, ICAL_RRULE_PROPERTY);
		if (rrule) {
			recur = icalproperty_get_rrule(rrule);
			calnote->occurrences = recur.count;
			switch (recur.freq) {
			case ICAL_SECONDLY_RECURRENCE:
				dprintf("Not supported recurrence type. Approximating recurrence\n");
				calnote->recurrence = recur.interval / 3600;
				if (!calnote->recurrence)
					calnote->recurrence = 1;
				break;
			case ICAL_MINUTELY_RECURRENCE:
				dprintf("Not supported recurrence type. Approximating recurrence\n");
				calnote->recurrence = recur.interval / 60;
				if (!calnote->recurrence)
					calnote->recurrence = 1;
				break;
			case ICAL_HOURLY_RECURRENCE:
				calnote->recurrence = recur.interval;
				break;
			case ICAL_DAILY_RECURRENCE:
				calnote->recurrence = recur.interval * 24;
				break;
			case ICAL_WEEKLY_RECURRENCE:
				calnote->recurrence = recur.interval * 24 * 7;
				break;
			case ICAL_MONTHLY_RECURRENCE:
				calnote->recurrence = GN_CALNOTE_MONTHLY;
				break;
			case ICAL_YEARLY_RECURRENCE:
				calnote->recurrence = GN_CALNOTE_YEARLY;
				break;
			case ICAL_NO_RECURRENCE:
				calnote->recurrence = GN_CALNOTE_NEVER;
				break;
			default:
				dprintf("Not supported recurrence type. Assuming never\n");
				calnote->recurrence = GN_CALNOTE_NEVER;
				break;
			}
		}

		str = icalcomponent_get_location(compresult);
		if (!str)
			str = "";
		snprintf(calnote->mlocation, sizeof(calnote->mlocation), "%s", str);
	}
	if (compresult) {
#ifdef DEBUG
		char *temp;

		temp = icalcomponent_as_ical_string(compresult);
		dprintf("Component found\n%s\n", temp);
		free(temp);
#endif
		icalcomponent_free(compresult);
	}

	return retval;
}
Example #11
0
void parse_iCal(icalcomponent* comp)
{
  icalcomponent * c;
  icalproperty * rrule;
  icalproperty * exdate;

  icalrecur_iterator * data;
  struct icaldurationtype offset;
  struct icaltimetype time_start;
  struct icaltimetype time_end;
  struct icaltimetype time_next;
  struct icaltimetype exdatetime;
  struct icaltimetype now;
  struct icalrecurrencetype recur;
  int i = 0;
  double duration;

  // Get offset:
  time_t t = time(NULL);
  struct tm lt = {0};
  localtime_r(&t, &lt);
  if (debug_flag)
  {
    printf("Offset to GMT is %lds.\n", lt.tm_gmtoff);
  }
  offset.days = 0;
  offset.weeks = 0;
  offset.hours = 0;
  offset.minutes = 0;
  offset.seconds = 0;
  offset.hours = lt.tm_gmtoff / 3600;
  if (lt.tm_gmtoff < 0) {
   offset.is_neg = 1;
  } else {
   offset.is_neg = 0;
  }

  // Get time now:
  now = icaltime_today();

  // Read each event:
  for (c = icalcomponent_get_first_component(comp,ICAL_VEVENT_COMPONENT) ;
       c != 0 ;
       c = icalcomponent_get_next_component(comp,ICAL_VEVENT_COMPONENT)
  )
  {
    // Get details about the event:
    const char * summary = icalcomponent_get_summary(c);
    const char * description = icalcomponent_get_description(c);

    // Help:
    if (debug_flag)
    {
      if (summary != NULL)
      {
        printf("summary: %s\n", summary);
      }
      if (description != NULL)
      {
        printf("description: %s\n", description);
      }
    }

    // Ranging time:
    time_start = icalcomponent_get_dtstart (c);
    time_end = icalcomponent_get_dtend (c);
    duration = difftime(icaltime_as_timet(time_end), icaltime_as_timet(time_start));

    // Rules:
    rrule = icalcomponent_get_first_property(c,ICAL_RRULE_PROPERTY);
    recur = icalproperty_get_rrule(rrule);
    data = icalrecur_iterator_new (recur, time_start);

    // Find next event:
    while (1)
    {
      time_next = icalrecur_iterator_next (data);

      if (icaltime_is_null_time(time_next) == 1) break;
      if (icaltime_compare(time_next, now) >= 0) break;
    }

    // Help:
    if (debug_flag)
    {
      dump_icaltimetype("time start", time_start);
      dump_icaltimetype("time end", time_end);
      dump_icaltimetype("until", recur.until);
      dump_icaltimetype("time next", time_next);
    }

    // One shot event:
    if (
      icaltime_is_null_time(time_next) == 1
      &&
      icaltime_compare(time_start, now) < 0
    )
    {
      if (debug_flag) printf ("event (one shot) is in the past\n");
      continue;
    }

    // Old event: discard recurent events finished before today...
    if (
      icaltime_is_null_time(recur.until) == 0
      &&
      icaltime_compare(recur.until, now) < 0
    )
    {
      if (debug_flag) printf ("event is recurent in the past ...\n");
      continue;
    }

    // Some help:
    if (debug_flag > 2)
    {
      dump_icalrecurrencetype(recur);
    }


    // Set time and hours:
    struct icaltimetype local_time_start = icaltime_add(time_start, offset);
    printf ("%d	%d	", local_time_start.minute, local_time_start.hour);

    // Set option depending of recurence:
    switch (recur.freq)
    {
      // Weekly: OK but need to remove days not needed... ?
      case ICAL_WEEKLY_RECURRENCE:
        printf ("%s", "*	*	");
        for (i = 0; recur.by_day[i] != 32639; i++)
        {
          printf ("%02d", icalrecurrencetype_day_day_of_week(recur.by_day[i]) -1);
          if (recur.by_day[i+1] != 32639)
          {
            printf ("%s", ",");
          }
        }
        printf ("%s", "	");
        break;

      // Happening each month:
      case ICAL_MONTHLY_RECURRENCE:
        // The Xth of the month:
        if (recur.by_month_day[0] != 32639)
        {
          printf ("%02d	*	*	", recur.by_month_day[0]);
        }

        // Day of the week:
        else
        {
            printf ("%d	%d	*	", time_next.day, time_next.month);
        }
        break;


      // Event happening each year ...  OK???
      // OK: one shoot.
      case ICAL_YEARLY_RECURRENCE:
      case ICAL_NO_RECURRENCE:
      default:
        printf ("%02d	%02d	*	", 
          local_time_start.day,
          local_time_start.month
        );
    }



    // How many valid exclude dates:
    exdate = icalcomponent_get_first_property(c, ICAL_EXDATE_PROPERTY);
    unsigned int num_ex = 0;
    if (exdate != NULL)
    {
      for (; exdate != NULL; exdate = icalcomponent_get_next_property(c, ICAL_EXDATE_PROPERTY) )
      {
        exdatetime = icalvalue_get_datetime(icalproperty_get_value(exdate));
        if (icaltime_compare(exdatetime, now) >= 0)
        {
          num_ex++;
        }
      }
    }
    if (num_ex > 0)
    {
      exdate = icalcomponent_get_first_property(c, ICAL_EXDATE_PROPERTY);
      for (; exdate != NULL; exdate = icalcomponent_get_next_property(c, ICAL_EXDATE_PROPERTY) )
      {
        exdatetime = icalvalue_get_datetime(icalproperty_get_value(exdate));
        if (icaltime_compare(exdatetime, now) >= 0)
        {
          struct icaltimetype local_exdatetime = icaltime_add(exdatetime, offset);
          printf ("%s", "[ \"$(date \"+\\\%Y\\\%m\\\%d\")\" = \"");
          printf ("%04d%02d%02d", local_exdatetime.year, local_exdatetime.month, local_exdatetime.day);
          printf ("%s", "\" ] || ");
        }
      }
    }

    // And the action:
    printf ("%s %.0f\n", 
      summary,
      duration
    );

    icalrecur_iterator_free (data);
  }
}