/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#include <config.h>
#include <unistd.h>
#include <sys/stat.h>
#include "icalendar-save.h"
static void unparse_person (iCalPerson *person, icalproperty *person_prop);
static struct icaltimetype timet_to_icaltime (time_t tt);
static icalproperty *unparse_related (iCalRelation *rel);
static icalcomponent *unparse_alarm (CalendarAlarm *alarm);
icalcomponent*
icalcomponent_create_from_ical_object (iCalObject *ical)
{
icalcomponent_kind kind;
icalcomponent *comp;
icalproperty *prop;
switch (ical->type) {
case ICAL_EVENT: kind = ICAL_VEVENT_COMPONENT; break;
case ICAL_TODO: kind = ICAL_VTODO_COMPONENT; break;
case ICAL_JOURNAL: kind = ICAL_VJOURNAL_COMPONENT; break;
case ICAL_FBREQUEST: kind = ICAL_VFREEBUSY_COMPONENT; break;
case ICAL_TIMEZONE: kind = ICAL_VTIMEZONE_COMPONENT; break;
default:
kind = ICAL_NO_COMPONENT; break;
}
comp = icalcomponent_new (kind);
/*** calscale ***/
prop = icalproperty_new_calscale ("GREGORIAN");
icalcomponent_add_property (comp, prop);
/*** catagories ***/
if (ical->categories) {
/* ical->categories is a GList of (char *) */
GList *cur;
for (cur = ical->categories; cur; cur = cur->next) {
prop = icalproperty_new_categories ((char *) cur);
icalcomponent_add_property (comp, prop);
}
}
/*** class ***/
if (ical->class) {
prop = icalproperty_new_class (ical->class);
icalcomponent_add_property (comp, prop);
}
/*** comment ***/
if (ical->comment) {
prop = icalproperty_new_comment (ical->comment);
icalcomponent_add_property (comp, prop);
}
/*** description ***/
if (ical->desc) {
prop = icalproperty_new_description (ical->desc);
icalcomponent_add_property (comp, prop);
}
/*** geo ***/
if (ical->geo.valid) {
struct icalgeotype v;
v.lat = ical->geo.latitude;
v.lon = ical->geo.longitude;
prop = icalproperty_new_geo (v);
icalcomponent_add_property (comp, prop);
}
/*** location ***/
if (ical->location) {
prop = icalproperty_new_location (ical->location);
icalcomponent_add_property (comp, prop);
}
/*** percentcomplete ***/
prop = icalproperty_new_percentcomplete (ical->percent);
icalcomponent_add_property (comp, prop);
/*** priority ***/
if (ical->priority) {
prop = icalproperty_new_priority (ical->priority);
icalcomponent_add_property (comp, prop);
}
/*** resources ***/
if (ical->resources) {
/* ical->resources is a GList of (char *) */
GList *cur;
for (cur = ical->resources; cur; cur = cur->next) {
prop = icalproperty_new_resources ((char *) cur);
icalcomponent_add_property (comp, prop);
}
}
/*** status ***/
if (ical->status) {
prop = icalproperty_new_status (ical->status);
icalcomponent_add_property (comp, prop);
}
/*** summary ***/
if (ical->summary) {
prop = icalproperty_new_summary (ical->summary);
icalcomponent_add_property (comp, prop);
}
/*** completed ***/
if (ical->completed) {
struct icaltimetype ictime;
ictime = timet_to_icaltime (ical->completed);
prop = icalproperty_new_completed (ictime);
icalcomponent_add_property (comp, prop);
}
/*** dtend ***/ /*** due ***/
if (ical->dtend) {
/* FIXME: We should handle timezone specifiers */
struct icaltimetype ictime;
ictime = timet_to_icaltime (ical->dtend);
if (ical->type == ICAL_TODO)
prop = icalproperty_new_due (ictime);
else
prop = icalproperty_new_dtend (ictime);
if (ical->date_only) {
icalparameter *param;
param = icalparameter_new (ICAL_VALUE_PARAMETER);
icalparameter_set_value (param, ICAL_VALUE_DATE);
icalproperty_add_parameter (prop, param);
}
icalcomponent_add_property (comp, prop);
}
/*** dtstart ***/
if (ical->dtstart) {
/* FIXME: We should handle timezone specifiers */
struct icaltimetype ictime;
ictime = timet_to_icaltime (ical->dtstart);
prop = icalproperty_new_dtstart (ictime);
if (ical->date_only) {
icalparameter *param;
param = icalparameter_new (ICAL_VALUE_PARAMETER);
icalparameter_set_value (param, ICAL_VALUE_DATE);
icalproperty_add_parameter (prop, param);
}
icalcomponent_add_property (comp, prop);
}
/*** duration ***/
{
/* FIX ME */
}
/*** freebusy ***/
{
/* FIX ME */
}
/*** transp ***/
{
if (ical->transp == ICAL_TRANSP_PROPERTY)
prop = icalproperty_new_transp ("TRANSPARENT");
else
prop = icalproperty_new_transp ("OPAQUE");
icalcomponent_add_property (comp, prop);
}
/*
ICAL_TZID_PROPERTY:
ICAL_TZNAME_PROPERTY:
ICAL_TZOFFSETFROM_PROPERTY:
ICAL_TZOFFSETTO_PROPERTY:
ICAL_TZURL_PROPERTY:
*/
/*** attendee ***/
if (ical->attendee) {
/* a list of (iCalPerson *) */
GList *cur;
for (cur = ical->attendee; cur; cur = cur->next) {
iCalPerson *person = (iCalPerson *) cur->data;
prop = icalproperty_new_attendee (person->addr);
unparse_person (person, prop);
icalcomponent_add_property (comp, prop);
}
}
/*** contact ***/
if (ical->contact) {
/* a list of (iCalPerson *) */
GList *cur;
for (cur = ical->contact; cur; cur = cur->next) {
iCalPerson *person = (iCalPerson *) cur->data;
prop = icalproperty_new_contact (person->addr);
unparse_person (person, prop);
icalcomponent_add_property (comp, prop);
}
}
/*** organizer ***/
if (ical->organizer) {
prop = icalproperty_new_organizer (ical->organizer->addr);
unparse_person (ical->organizer, prop);
icalcomponent_add_property (comp, prop);
}
/*** recurrenceid ***/
if (ical->recurid) {
struct icaltimetype ictime;
ictime = timet_to_icaltime (ical->recurid);
prop = icalproperty_new_recurrenceid (ictime);
}
/*** relatedto ***/
if (ical->related) {
/* a list of (iCalPerson *) */
GList *cur;
for (cur = ical->related; cur; cur = cur->next) {
iCalRelation *related = (iCalRelation *) cur->data;
prop = unparse_related (related);
icalcomponent_add_property (comp, prop);
}
}
/*** url ***/
if (ical->url) {
prop = icalproperty_new_url (ical->url);
icalcomponent_add_property (comp, prop);
}
/*** uid ***/
if (ical->uid) {
prop = icalproperty_new_uid (ical->uid);
icalcomponent_add_property (comp, prop);
}
/*** exdate ***/
if (ical->exdate) {
struct icaltimetype v;
GList *cur;
for (cur = ical->exdate; cur; cur = cur->next) {
time_t t = (time_t) cur->data;
v = timet_to_icaltime (t);
prop = icalproperty_new_exdate (v);
icalcomponent_add_property (comp, prop);
}
}
/*** created ***/
if (ical->created) {
struct icaltimetype v;
v = timet_to_icaltime (ical->created);
prop = icalproperty_new_created (v);
icalcomponent_add_property (comp, prop);
}
/*** dtstamp ***/
if (ical->dtstamp) {
struct icaltimetype v;
v = timet_to_icaltime (ical->dtstamp);
prop = icalproperty_new_created (v);
icalcomponent_add_property (comp, prop);
}
/*** lastmodified ***/
if (ical->last_mod) {
struct icaltimetype v;
v = timet_to_icaltime (ical->last_mod);
prop = icalproperty_new_created (v);
icalcomponent_add_property (comp, prop);
}
/*** sequence ***/
if (ical->seq) {
prop = icalproperty_new_sequence (ical->seq);
icalcomponent_add_property (comp, prop);
}
/*** requeststatus ***/
if (ical->rstatus) {
prop = icalproperty_new_requeststatus (ical->rstatus);
icalcomponent_add_property (comp, prop);
}
/* if there is a VALARM subcomponent, add it here */
if (ical->alarms) {
GList *cur;
for (cur = ical->alarms; cur; cur = cur->next) {
CalendarAlarm *alarm = (CalendarAlarm *) cur->data;
icalcomponent *subcomp = unparse_alarm (alarm);
icalcomponent_add_component (comp, subcomp);
}
}
return comp;
}
/* FIX ME -- same as icaltimetype_from_timet in icaltypes.c */
static
struct icaltimetype timet_to_icaltime (time_t tt)
{
struct tm *t;
struct icaltimetype i;
//t = gmtime (&tt);
t = localtime (&tt);
/*return tt - (i->is_utc ? timezone : 0); */
i.is_utc = 0;
i.year = t->tm_year + 1900;
i.month = t->tm_mon + 1;
i.day = t->tm_mday;
if (t->tm_hour == 0 && t->tm_min == 0 && t->tm_sec == 0) {
i.is_date = 1;
i.hour = 0;
i.minute = 0;
i.second = 0;
} else {
i.is_date = 0;
i.hour = t->tm_hour;
i.minute = t->tm_min;
i.second = t->tm_sec;
}
return i;
}
/* fills in "person_prop" with information from "person" */
static
void unparse_person (iCalPerson *person, icalproperty *person_prop)
{
icalparameter *param;
GList *cur;
/* convert iCalPerson to an icalproperty */
if (person->name) {
param = icalparameter_new_cn (person->name);
icalproperty_add_parameter (person_prop, param);
}
if (person->role) {
if (g_strcasecmp (person->role, "CHAIR") == 0)
param = icalparameter_new_role (ICAL_ROLE_CHAIR);
else if (g_strcasecmp (person->role, "REQPARTICIPANT") == 0)
param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT);
else if (g_strcasecmp (person->role, "OPTPARTICIPANT") == 0)
param = icalparameter_new_role (ICAL_ROLE_OPTPARTICIPANT);
else if (g_strcasecmp (person->role, "NONPARTICIPANT") == 0)
param = icalparameter_new_role (ICAL_ROLE_NONPARTICIPANT);
else
param = icalparameter_new_role (ICAL_ROLE_XNAME);
icalproperty_add_parameter (person_prop, param);
}
if (person->partstat) {
if (g_strcasecmp (person->partstat, "NEEDSACTION") == 0)
param = icalparameter_new_partstat (ICAL_PARTSTAT_NEEDSACTION);
else if (g_strcasecmp (person->partstat, "ACCEPTED") == 0)
param = icalparameter_new_partstat (ICAL_PARTSTAT_ACCEPTED);
else if (g_strcasecmp (person->partstat, "DECLINED") == 0)
param = icalparameter_new_partstat (ICAL_PARTSTAT_DECLINED);
else if (g_strcasecmp (person->partstat, "TENTATIVE") == 0)
param = icalparameter_new_partstat (ICAL_PARTSTAT_TENTATIVE);
else if (g_strcasecmp (person->partstat, "DELEGATED") == 0)
param = icalparameter_new_partstat (ICAL_PARTSTAT_DELEGATED);
else if (g_strcasecmp (person->partstat, "COMPLETED") == 0)
param = icalparameter_new_partstat (ICAL_PARTSTAT_COMPLETED);
else if (g_strcasecmp (person->partstat, "INPROCESS") == 0)
param = icalparameter_new_partstat (ICAL_PARTSTAT_INPROCESS);
else /* FIX ME, NEEDSACTION instead? */
param = icalparameter_new_partstat (ICAL_PARTSTAT_XNAME);
icalproperty_add_parameter (person_prop, param);
}
if (person->rsvp != FALSE) {
param = icalparameter_new_rsvp (TRUE);
icalproperty_add_parameter (person_prop, param);
}
if (person->cutype) {
if (g_strcasecmp (person->cutype, "INDIVIDUAL") == 0)
param = icalparameter_new_cutype (ICAL_CUTYPE_INDIVIDUAL);
else if (g_strcasecmp (person->cutype, "GROUP") == 0)
param = icalparameter_new_cutype (ICAL_CUTYPE_GROUP);
else if (g_strcasecmp (person->cutype, "RESOURCE") == 0)
param = icalparameter_new_cutype (ICAL_CUTYPE_RESOURCE);
else if (g_strcasecmp (person->cutype, "ROOM") == 0)
param = icalparameter_new_cutype (ICAL_CUTYPE_ROOM);
else /* FIX ME, INDIVIDUAL instead? */
param = icalparameter_new_cutype (ICAL_CUTYPE_UNKNOWN);
icalproperty_add_parameter (person_prop, param);
}
/* person->member is a list of ICAL_MEMBER_PARAMETER */
for (cur = person->member; cur; cur = cur->next) {
gchar *member = (gchar *) cur->data;
param = icalparameter_new_member (member);
icalproperty_add_parameter (person_prop, param);
}
/* person->deleg_to is a list of ICAL_DELEGATEDTO_PARAMETER */
for (cur = person->deleg_to; cur; cur = cur->next) {
gchar *deleg_to = (gchar *) cur->data;
param = icalparameter_new_delegatedto (deleg_to);
icalproperty_add_parameter (person_prop, param);
}
/* ret->deleg_from is a list of ICAL_DELEGATEDFROM_PARAMETER */
for (cur = person->deleg_from; cur; cur = cur->next) {
gchar *deleg_from = (gchar *) cur->data;
param = icalparameter_new_delegatedfrom (deleg_from);
icalproperty_add_parameter (person_prop, param);
}
if (person->sent_by) {
param = icalparameter_new_sentby (person->sent_by);
icalproperty_add_parameter (person_prop, param);
}
/* ret->deleg_to is a list of ICAL_DIR_PARAMETER */
/* FIX ME ... */
}
static
icalproperty *unparse_related (iCalRelation *rel)
{
icalproperty *prop;
prop = icalproperty_new_relatedto (rel->reltype);
icalproperty_set_relatedto (prop, rel->uid);
/* FIX ME RELTYPE_XNAME ? */
return prop;
}
static
icalcomponent *unparse_alarm (CalendarAlarm *alarm)
{
icalcomponent *comp = icalcomponent_new (ICAL_VALARM_COMPONENT);
icalproperty *prop;
prop = NULL;
switch (alarm->type){
case ALARM_AUDIO:
prop = icalproperty_new_action ("AUDIO");
break;
case ALARM_DISPLAY:
prop = icalproperty_new_action ("DISPLAY");
break;
case ALARM_MAIL:
prop = icalproperty_new_action ("EMAIL");
break;
case ALARM_PROGRAM:
prop = icalproperty_new_action ("PROCEDURE");
break;
default:
g_warning ("Unsupported alarm type!");
break;
}
if (prop)
icalcomponent_add_property (comp, prop);
if (alarm->snooze_repeat)
prop = icalproperty_new_repeat (alarm->snooze_repeat);
if (alarm->snooze_secs) {
struct icaldurationtype dur;
dur = icaldurationtype_from_timet (alarm->snooze_secs);
prop = icalproperty_new_duration (dur);
icalcomponent_add_property (comp, prop);
}
if (alarm->attach) {
struct icalattachtype *attach;
attach = icalattachtype_new ();
icalattachtype_set_url (attach, alarm->attach);
prop = icalproperty_new_attach (*attach);
icalattachtype_free (attach);
icalcomponent_add_property (comp, prop);
}
if (alarm->desc) {
prop = icalproperty_new_description (alarm->desc);
icalcomponent_add_property (comp, prop);
}
if (alarm->summary) {
prop = icalproperty_new_summary (alarm->summary);
icalcomponent_add_property (comp, prop);
}
if (alarm->attendee) {
icalproperty_new_attendee (alarm->attendee);
icalcomponent_add_property (comp, prop);
}
return comp;
}