Esempio n. 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 void
calendar_appointment_generate_occurrences (CalendarAppointment *appointment,
                                           icalcomponent       *ical,
                                           ECalClient          *cal,
                                           time_t               start,
                                           time_t               end,
                                           icaltimezone        *default_zone)
{
  ECalComponent *ecal;

  g_assert (appointment->occurrences == NULL);

  ecal = e_cal_component_new ();
  e_cal_component_set_icalcomponent (ecal,
                                     icalcomponent_new_clone (ical));

  e_cal_recur_generate_instances (ecal,
                                  start,
                                  end,
                                  calendar_appointment_collect_occurrence,
                                  &appointment->occurrences,
                                  (ECalRecurResolveTimezoneFn) resolve_timezone_id,
                                  cal,
                                  default_zone);

  g_object_unref (ecal);

  appointment->occurrences = g_slist_reverse (appointment->occurrences);
}
/*
 * (occurrences-count? START END)
 * (occurrences-count?)
 *
 * Counts occurrences either in the given time range (the first variant)
 * or in the time range defined by the expression itself (the second variant).
 * If the time range cannot be determined, then -1 is returned.
 */
static ESExpResult *
func_occurrences_count (ESExp *esexp,
                        gint argc,
                        ESExpResult **argv,
                        gpointer data)
{
	SearchContext *ctx = data;
	time_t start, end;
	ESExpResult *result;
	icaltimezone *default_zone;

	/* Check argument types */

	if (argc != 2 && argc != 0) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects none or two arguments"),
			"occurrences-count");
		return NULL;
	}

	if (argc == 2) {
		if (argv[0]->type != ESEXP_RES_TIME) {
			e_sexp_fatal_error (
				esexp, _("\"%s\" expects the first argument to be a time_t"),
				"occurrences-count");
			return NULL;
		}
		start = argv[0]->value.time;

		if (argv[1]->type != ESEXP_RES_TIME) {
			e_sexp_fatal_error (
				esexp, _("\"%s\" expects the second argument to be a time_t"),
				"occurrences-count");
			return NULL;
		}
		end = argv[1]->value.time;
	} else if (ctx->expr_range_set) {
		start = ctx->expr_range_start;
		end = ctx->expr_range_end;
	} else {
		result = e_sexp_result_new (esexp, ESEXP_RES_INT);
		result->value.number = -1;

		return result;
	}

	default_zone = icaltimezone_get_utc_timezone ();

	ctx->occurrences_count = 0;
	e_cal_recur_generate_instances (
		ctx->comp, start, end,
		count_instances_time_range_cb, ctx,
		resolve_tzid, ctx, default_zone);

	result = e_sexp_result_new (esexp, ESEXP_RES_INT);
	result->value.number = ctx->occurrences_count;

	return result;
}
Esempio n. 4
0
/**
 * e_cal_util_generate_alarms_for_comp:
 * @comp: The #ECalComponent to generate alarms from
 * @start: Start time
 * @end: End time
 * @omit: Alarm types to omit
 * @resolve_tzid: (closure user_data) (scope call): Callback for resolving
 * timezones
 * @user_data: (closure): Data to be passed to the resolve_tzid callback
 * @default_timezone: The timezone used to resolve DATE and floating DATE-TIME
 * values.
 *
 * Generates alarm instances for a calendar component.  Returns the instances
 * structure, or %NULL if no alarm instances occurred in the specified time
 * range.
 *
 * Returns: (allow-none) (transfer full): a list of all the alarms found for the
 * given component in the given time range. The list of alarms should be freed
 * by using e_cal_component_free_alarm_list().
 */
ECalComponentAlarms *
e_cal_util_generate_alarms_for_comp (ECalComponent *comp,
                                     time_t start,
                                     time_t end,
                                     ECalComponentAlarmAction *omit,
                                     ECalRecurResolveTimezoneFn resolve_tzid,
                                     gpointer user_data,
                                     icaltimezone *default_timezone)
{
	GList *alarm_uids;
	time_t alarm_start, alarm_end;
	struct alarm_occurrence_data aod;
	ECalComponentAlarms *alarms;

	if (!e_cal_component_has_alarms (comp))
		return NULL;

	alarm_uids = e_cal_component_get_alarm_uids (comp);
	compute_alarm_range (
		comp, alarm_uids, start, end, &alarm_start, &alarm_end);

	aod.alarm_uids = alarm_uids;
	aod.start = start;
	aod.end = end;
	aod.omit = omit;
	aod.triggers = NULL;
	aod.n_triggers = 0;

	e_cal_recur_generate_instances (
		comp, alarm_start, alarm_end,
		add_alarm_occurrences_cb, &aod,
		resolve_tzid, user_data,
		default_timezone);

	/* We add the ABSOLUTE triggers separately */
	generate_absolute_triggers (
		comp, &aod, resolve_tzid, user_data, default_timezone);

	cal_obj_uid_list_free (alarm_uids);

	if (aod.n_triggers == 0)
		return NULL;

	/* Create the component alarm instances structure */

	alarms = g_new (ECalComponentAlarms, 1);
	alarms->comp = comp;
	g_object_ref (G_OBJECT (alarms->comp));
	alarms->alarms = g_slist_sort (aod.triggers, compare_alarm_instance);

	return alarms;
}
/* (occur-in-time-range? START END TZLOC)
 *
 * START - time_t, start of the time range, in UTC
 * END - time_t, end of the time range, in UTC
 * TZLOC - optional string with timezone location to use
 *        as default timezone; if not set, UTC is used
 *
 * Returns a boolean indicating whether the component has any occurrences in the
 * specified time range.
 */
static ESExpResult *
func_occur_in_time_range (ESExp *esexp,
                          gint argc,
                          ESExpResult **argv,
                          gpointer data)
{
	SearchContext *ctx = data;
	time_t start, end;
	ESExpResult *result;
	icaltimezone *default_zone = NULL;

	/* Check argument types */

	if (argc != 2 && argc != 3) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects two or three arguments"),
			"occur-in-time-range");
		return NULL;
	}

	if (argv[0]->type != ESEXP_RES_TIME) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects the first "
			"argument to be a time_t"),
			"occur-in-time-range");
		return NULL;
	}
	start = argv[0]->value.time;

	if (argv[1]->type != ESEXP_RES_TIME) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects the second "
			"argument to be a time_t"),
			"occur-in-time-range");
		return NULL;
	}
	end = argv[1]->value.time;

	if (argc == 3) {
		if (argv[2]->type != ESEXP_RES_STRING) {
			e_sexp_fatal_error (
				esexp, _("\"%s\" expects the third "
				"argument to be a string"),
				"occur-in-time-range");
			return NULL;
		}

		default_zone = resolve_tzid (argv[2]->value.string, ctx);
	}

	if (!default_zone)
		default_zone = icaltimezone_get_utc_timezone ();

	/* See if the object occurs in the specified time range */
	ctx->occurs = FALSE;
	e_cal_recur_generate_instances (
		ctx->comp, start, end,
		(ECalRecurInstanceFn) check_instance_time_range_cb,
		ctx, resolve_tzid, ctx,
		default_zone);

	result = e_sexp_result_new (esexp, ESEXP_RES_BOOL);
	result->value.boolean = ctx->occurs;

	return result;
}
Esempio n. 6
0
static icalcomponent *
create_user_free_busy (ECalBackendHttp *cbhttp,
                       const gchar *address,
                       const gchar *cn,
                       time_t start,
                       time_t end)
{
	GSList *slist = NULL, *l;
	icalcomponent *vfb;
	icaltimezone *utc_zone;
	ECalBackendSExp *obj_sexp;
	ECalBackendHttpPrivate *priv;
	ECalBackendStore *store;
	gchar *query, *iso_start, *iso_end;

	priv = cbhttp->priv;
	store = priv->store;

        /* create the (unique) VFREEBUSY object that we'll return */
	vfb = icalcomponent_new_vfreebusy ();
	if (address != NULL) {
		icalproperty *prop;
		icalparameter *param;

		prop = icalproperty_new_organizer (address);
		if (prop != NULL && cn != NULL) {
			param = icalparameter_new_cn (cn);
			icalproperty_add_parameter (prop, param);
		}
		if (prop != NULL)
			icalcomponent_add_property (vfb, prop);
	}
	utc_zone = icaltimezone_get_utc_timezone ();
	icalcomponent_set_dtstart (vfb, icaltime_from_timet_with_zone (start, FALSE, utc_zone));
	icalcomponent_set_dtend (vfb, icaltime_from_timet_with_zone (end, FALSE, utc_zone));

        /* add all objects in the given interval */
	iso_start = isodate_from_time_t (start);
	iso_end = isodate_from_time_t (end);
	query = g_strdup_printf (
		"occur-in-time-range? (make-time \"%s\") (make-time \"%s\")",
		iso_start, iso_end);
	obj_sexp = e_cal_backend_sexp_new (query);
	g_free (query);
	g_free (iso_start);
	g_free (iso_end);

	if (!obj_sexp)
		return vfb;

	slist = e_cal_backend_store_get_components (store);

	for (l = slist; l; l = g_slist_next (l)) {
		ECalComponent *comp = l->data;
		icalcomponent *icalcomp, *vcalendar_comp;
		icalproperty *prop;

		icalcomp = e_cal_component_get_icalcomponent (comp);
		if (!icalcomp)
			continue;

                /* If the event is TRANSPARENT, skip it. */
		prop = icalcomponent_get_first_property (
			icalcomp,
			ICAL_TRANSP_PROPERTY);
		if (prop) {
			icalproperty_transp transp_val = icalproperty_get_transp (prop);
			if (transp_val == ICAL_TRANSP_TRANSPARENT ||
			    transp_val == ICAL_TRANSP_TRANSPARENTNOCONFLICT)
				continue;
		}

		if (!e_cal_backend_sexp_match_comp (
			obj_sexp, l->data,
			E_TIMEZONE_CACHE (cbhttp)))
			continue;

		vcalendar_comp = icalcomponent_get_parent (icalcomp);
		if (!vcalendar_comp)
			vcalendar_comp = icalcomp;
		e_cal_recur_generate_instances (
			comp, start, end,
			free_busy_instance,
			vfb,
			resolve_tzid,
			vcalendar_comp,
			icaltimezone_get_utc_timezone ());
	}
	g_object_unref (obj_sexp);

	return vfb;
}