void ical_property_TRIGGER(struct exchange2ical *exchange2ical)
{
	struct icaltriggertype duration;
	icalproperty *prop;
	if (!exchange2ical->ReminderDelta) return;
	if (*exchange2ical->ReminderDelta == 0x5AE980E1) {
		duration = icaltriggertype_from_int(-15 * 60);
		prop = icalproperty_new_trigger(duration);
		icalcomponent_add_property(exchange2ical->valarm, prop);
	} else {
		duration = icaltriggertype_from_int(*(exchange2ical->ReminderDelta) * -1 * 60);
		prop = icalproperty_new_trigger(duration);
		icalcomponent_add_property(exchange2ical->valarm, prop);
	}
}
Example #2
0
/*
	ICALENDAR Reading functions
 */
GNOKII_API char *gn_calnote2icalstr(gn_calnote *calnote)
{
	ical_string str;

#ifdef HAVE_LIBICAL
	icalcomponent *pIcal = NULL, *vevent;
	struct icaltimetype stime = {0}, etime = {0};
	char compuid[64];

	memset(&str, 0, sizeof (str));

	/* In at least some Nokia phones it is possible to skip the year of
	   birth, in this case year == 0xffff, so we set it to the arbitrary
	   value of 1800 */

	stime.year = (calnote->time.year == 0xffff ? 1800 : calnote->time.year);
	stime.month = calnote->time.month;
	stime.day = calnote->time.day;
	stime.hour = calnote->time.hour;
	stime.minute = calnote->time.minute;
	stime.second = calnote->time.second;

	stime.is_daylight = 1;

	snprintf(compuid, sizeof(compuid), "guid.gnokii.org_%d_%d", calnote->location, rand());

	vevent = icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
				     icalproperty_new_dtstart(stime),
				     icalproperty_new_uid(compuid),
				     icalproperty_new_categories("GNOKII"),
				     0);
	if (!vevent) {
		dprintf("ERROR in icalcomponent_vanew() creating VEVENT\n");
		return NULL;
	}

	if (calnote->end_time.year) {
		etime.year = (calnote->end_time.year == 0xffff ? 1800 : calnote->end_time.year);
		etime.month = calnote->end_time.month;
		etime.day = calnote->end_time.day;
		etime.hour = calnote->end_time.hour;
		etime.minute = calnote->end_time.minute;
		etime.second = calnote->end_time.second;
		etime.is_daylight = 1;

		icalcomponent_add_property(vevent, icalproperty_new_dtend(etime));
	}

	/* TODO: should the strings be configurable? */
	switch(calnote->type) {
	case GN_CALNOTE_MEMO:
		icalcomponent_add_property(vevent, icalproperty_new_categories("MISCELLANEOUS"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		break;
	case GN_CALNOTE_REMINDER:
		icalcomponent_add_property(vevent, icalproperty_new_categories("REMINDER"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		break;
	case GN_CALNOTE_CALL:
		icalcomponent_add_property(vevent, icalproperty_new_categories("PHONE CALL"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->phone_number));
		icalcomponent_add_property(vevent, icalproperty_new_description(calnote->text));
		break;
	case GN_CALNOTE_MEETING:
		icalcomponent_add_property(vevent, icalproperty_new_categories("MEETING"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		if (calnote->mlocation[0])
			icalcomponent_add_property(vevent, icalproperty_new_location(calnote->mlocation));
		break;
	case GN_CALNOTE_BIRTHDAY:
		icalcomponent_add_property(vevent, icalproperty_new_categories("ANNIVERSARY"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		stime.is_date = 1;
		calnote->recurrence = GN_CALNOTE_YEARLY;
		break;
	default:
		icalcomponent_add_property(vevent, icalproperty_new_categories("UNKNOWN"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		break;
	}

	if (calnote->recurrence) {
		char rrule[64];
		char *freq;
		int interval = 1;

		switch (calnote->recurrence) {
		case GN_CALNOTE_NEVER:
			goto norecurrence;
		case GN_CALNOTE_DAILY:
			freq = "DAILY";
			break;
		case GN_CALNOTE_WEEKLY:
			freq = "WEEKLY";
			break;
		case GN_CALNOTE_2WEEKLY:
			freq = "WEEKLY";
			interval = 2;
			break;
		case GN_CALNOTE_MONTHLY:
			freq = "MONTHLY";
			break;
		case GN_CALNOTE_YEARLY:
			freq = "YEARLY";
			break;
		default:
			freq = "HOURLY";
			interval = calnote->recurrence;
			break;
		}
		if (calnote->type == GN_CALNOTE_BIRTHDAY)
			snprintf(rrule, sizeof(rrule), "FREQ=YEARLY;INTERVAL=1;BYMONTH=%d", stime.month);
		else if (calnote->occurrences == 0)
			snprintf(rrule, sizeof(rrule), "FREQ=%s;INTERVAL=%d", freq, interval);
		else
			snprintf(rrule, sizeof(rrule), "FREQ=%s;COUNT=%d;INTERVAL=%d", freq, calnote->occurrences, interval);
		icalcomponent_add_property(vevent, icalproperty_new_rrule(icalrecurrencetype_from_string(rrule)));
	}
norecurrence:

	if (calnote->alarm.enabled) {
		icalcomponent *valarm;
		struct icaltriggertype trig;

		trig.time.year = (calnote->alarm.timestamp.year == 0xffff ? 1800 : calnote->alarm.timestamp.year);
		trig.time.month = calnote->alarm.timestamp.month;
		trig.time.day = calnote->alarm.timestamp.day;
		trig.time.hour = calnote->alarm.timestamp.hour;
		trig.time.minute = calnote->alarm.timestamp.minute;
		trig.time.second = calnote->alarm.timestamp.second;
		trig.time.is_daylight = 1;

		valarm = icalcomponent_new_valarm();

		icalcomponent_add_property(valarm, icalproperty_new_trigger(trig));
		/* FIXME: with ICAL_ACTION_DISPLAY a DESCRIPTION property is mandatory */
		icalcomponent_add_property(valarm, icalproperty_new_action(calnote->alarm.tone ? ICAL_ACTION_AUDIO : ICAL_ACTION_DISPLAY));

		icalcomponent_add_component(vevent, valarm);
	}

	pIcal = icalcomponent_vanew(ICAL_VCALENDAR_COMPONENT,
				    icalproperty_new_version("2.0"),
				    icalproperty_new_prodid(get_prodid()),
				    vevent,
				    0);

	if (pIcal) {
		char *icalstrbuf = NULL;
		const char *icalstr = icalcomponent_as_ical_string(pIcal);

		/* conversion to UTF-8 */
		if (string_base64(icalstr)) {
			int icalstrlen = strlen(icalstr);
			icalstrbuf = malloc(icalstrlen * 2 + 1);
			utf8_encode(icalstrbuf, icalstrlen * 2, icalstr, icalstrlen);

			icalstr = icalstrbuf;
		}
		ical_append_printf(&str, "%s\n", icalstr);
		dprintf("%s\n", icalstr);
		if (icalstrbuf)
			free(icalstrbuf);

		icalcomponent_free(pIcal);
		pIcal = NULL;
	} else {
		dprintf("ERROR in icalcomponent_vanew() creating VCALENDAR\n");
	}
	return str.str;
#else
	memset(&str, 0, sizeof (str));

	ical_append_printf(&str, "BEGIN:VCALENDAR\r\n");
	ical_append_printf(&str, "VERSION:1.0\r\n");
	ical_append_printf(&str, "BEGIN:VEVENT\r\n");
	ical_append_printf(&str, "CATEGORIES:");
	switch (calnote->type) {
	case GN_CALNOTE_MEMO:
		ical_append_printf(&str, "MISCELLANEOUS\r\n");
		break;
	case GN_CALNOTE_REMINDER:
		ical_append_printf(&str, "REMINDER\r\n");
		break;
	case GN_CALNOTE_CALL: 
		ical_append_printf(&str, "PHONE CALL\r\n");
		ical_append_printf(&str, "SUMMARY:%s\r\n", calnote->phone_number);
		ical_append_printf(&str, "DESCRIPTION:%s\r\n", calnote->text);
		break; 
	case GN_CALNOTE_MEETING: 
		ical_append_printf(&str, "MEETING\r\n"); 
		if (calnote->mlocation[0])
			ical_append_printf(&str, "LOCATION:%s\r\n", calnote->mlocation);
		break; 
	case GN_CALNOTE_BIRTHDAY: 
		ical_append_printf(&str, "SPECIAL OCCASION\r\n"); 
		break; 
	default: 
		ical_append_printf(&str, "UNKNOWN\r\n"); 
		break; 
	} 
	if (calnote->type != GN_CALNOTE_CALL)
		ical_append_printf(&str, "SUMMARY:%s\r\n", calnote->text);
	ical_append_printf(&str, "DTSTART:%04d%02d%02dT%02d%02d%02d\r\n", calnote->time.year,
		calnote->time.month, calnote->time.day, calnote->time.hour, 
		calnote->time.minute, calnote->time.second); 
	if (calnote->end_time.year) {
		ical_append_printf(&str, "DTEND:%04d%02d%02dT%02d%02d%02d\r\n", calnote->end_time.year, 
			calnote->end_time.month, calnote->end_time.day, calnote->end_time.hour, 
			calnote->end_time.minute, calnote->end_time.second); 
	}
	if (calnote->alarm.enabled) {
		ical_append_printf(&str, "%sALARM:%04d%02d%02dT%02d%02d%02d\r\n",
		(calnote->alarm.tone ? "A" : "D"),
		calnote->alarm.timestamp.year, 
		calnote->alarm.timestamp.month, calnote->alarm.timestamp.day, calnote->alarm.timestamp.hour, 
		calnote->alarm.timestamp.minute, calnote->alarm.timestamp.second); 
	} 
	switch (calnote->recurrence) { 
	case GN_CALNOTE_NEVER: 
		break; 
	case GN_CALNOTE_DAILY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=DAILY\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=DAILY;COUNT=%d\r\n", calnote->occurrences);
		break; 
	case GN_CALNOTE_WEEKLY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=WEEKLY\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=WEEKLY;COUNT=%d\r\n", calnote->occurrences);
		break; 
	case GN_CALNOTE_2WEEKLY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=WEEKLY;INTERVAL=2\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=%d\r\n", calnote->occurrences);
		break; 
	case GN_CALNOTE_MONTHLY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=MONTHLY\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=MONTHLY;COUNT=%d\r\n", calnote->occurrences);
		break; 
	case GN_CALNOTE_YEARLY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=YEARLY\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=YEARLY;COUNT=%d\r\n", calnote->occurrences);
		break; 
	default: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=HOURLY;INTERVAL=%d\r\n", calnote->recurrence) :
			ical_append_printf(&str, "RRULE:FREQ=HOURLY;INTERVAL=%d;COUNT=%d\r\n", calnote->recurrence, calnote->occurrences);
		break; 
	} 
	ical_append_printf(&str, "END:VEVENT\r\n"); 
	ical_append_printf(&str, "END:VCALENDAR\r\n");
	return str.str;
#endif /* HAVE_LIBICAL */
}