Search in sources :

Example 1 with Related

use of net.fortuna.ical4j.model.parameter.Related in project android by nextcloud.

the class ProcessVEvent method convertToDB.

// Munge a VEvent so Android won't reject it, then convert to ContentValues for inserting
private ContentValues convertToDB(VEvent e, Options options, List<Integer> reminders, long calendarId) {
    reminders.clear();
    boolean allDay = false;
    boolean startIsDate = !(e.getStartDate().getDate() instanceof DateTime);
    boolean isRecurring = hasProperty(e, Property.RRULE) || hasProperty(e, Property.RDATE);
    if (startIsDate) {
        // If the start date is a DATE we expect the end date to be a date too and the
        // event is all-day, midnight to midnight (RFC 2445).
        allDay = true;
    }
    if (!hasProperty(e, Property.DTEND) && !hasProperty(e, Property.DURATION)) {
        // No end date or duration given.
        // Since we added a duration above when the start date is a DATE:
        // - The start date is a DATETIME, the event lasts no time at all (RFC 2445).
        e.getProperties().add(ZERO_SECONDS);
        // Zero time events are always free (RFC 2445), so override/set TRANSP accordingly.
        removeProperty(e, Property.TRANSP);
        e.getProperties().add(Transp.TRANSPARENT);
    }
    if (isRecurring) {
        // Recurring event. Android insists on a duration.
        if (!hasProperty(e, Property.DURATION)) {
            // Calculate duration from start to end date
            Duration d = new Duration(e.getStartDate().getDate(), e.getEndDate().getDate());
            e.getProperties().add(d);
        }
        removeProperty(e, Property.DTEND);
    } else {
        // Non-recurring event. Android insists on an end date.
        if (!hasProperty(e, Property.DTEND)) {
            // Calculate end date from duration, set it and remove the duration.
            e.getProperties().add(e.getEndDate());
        }
        removeProperty(e, Property.DURATION);
    }
    // Now calculate the db values for the event
    ContentValues c = new ContentValues();
    c.put(Events.CALENDAR_ID, calendarId);
    copyProperty(c, Events.TITLE, e, Property.SUMMARY);
    copyProperty(c, Events.DESCRIPTION, e, Property.DESCRIPTION);
    if (e.getOrganizer() != null) {
        URI uri = e.getOrganizer().getCalAddress();
        try {
            MailTo mailTo = MailTo.parse(uri.toString());
            c.put(Events.ORGANIZER, mailTo.getTo());
            // Ensure we can edit if not the organiser
            c.put(Events.GUESTS_CAN_MODIFY, 1);
        } catch (ParseException ignored) {
            Log_OC.e(TAG, "Failed to parse Organiser URI " + uri.toString());
        }
    }
    copyProperty(c, Events.EVENT_LOCATION, e, Property.LOCATION);
    if (hasProperty(e, Property.STATUS)) {
        String status = e.getProperty(Property.STATUS).getValue();
        switch(status) {
            case "TENTATIVE":
                c.put(Events.STATUS, Events.STATUS_TENTATIVE);
                break;
            case "CONFIRMED":
                c.put(Events.STATUS, Events.STATUS_CONFIRMED);
                break;
            case // NOTE: In ical4j it is CANCELLED with two L
            "CANCELLED":
                c.put(Events.STATUS, Events.STATUS_CANCELED);
                break;
        }
    }
    copyProperty(c, Events.DURATION, e, Property.DURATION);
    if (allDay) {
        c.put(Events.ALL_DAY, 1);
    }
    copyDateProperty(c, Events.DTSTART, Events.EVENT_TIMEZONE, e.getStartDate());
    if (hasProperty(e, Property.DTEND)) {
        copyDateProperty(c, Events.DTEND, Events.EVENT_END_TIMEZONE, e.getEndDate());
    }
    if (hasProperty(e, Property.CLASS)) {
        String access = e.getProperty(Property.CLASS).getValue();
        int accessLevel = Events.ACCESS_DEFAULT;
        switch(access) {
            case "CONFIDENTIAL":
                accessLevel = Events.ACCESS_CONFIDENTIAL;
                break;
            case "PRIVATE":
                accessLevel = Events.ACCESS_PRIVATE;
                break;
            case "PUBLIC":
                accessLevel = Events.ACCESS_PUBLIC;
                break;
        }
        c.put(Events.ACCESS_LEVEL, accessLevel);
    }
    // Work out availability. This is confusing as FREEBUSY and TRANSP overlap.
    if (Events.AVAILABILITY != null) {
        int availability = Events.AVAILABILITY_BUSY;
        if (hasProperty(e, Property.TRANSP)) {
            if (e.getTransparency() == Transp.TRANSPARENT) {
                availability = Events.AVAILABILITY_FREE;
            }
        } else if (hasProperty(e, Property.FREEBUSY)) {
            FreeBusy fb = (FreeBusy) e.getProperty(Property.FREEBUSY);
            FbType fbType = (FbType) fb.getParameter(Parameter.FBTYPE);
            if (fbType != null && fbType == FbType.FREE) {
                availability = Events.AVAILABILITY_FREE;
            } else if (fbType != null && fbType == FbType.BUSY_TENTATIVE) {
                availability = Events.AVAILABILITY_TENTATIVE;
            }
        }
        c.put(Events.AVAILABILITY, availability);
    }
    copyProperty(c, Events.RRULE, e, Property.RRULE);
    copyProperty(c, Events.RDATE, e, Property.RDATE);
    copyProperty(c, Events.EXRULE, e, Property.EXRULE);
    copyProperty(c, Events.EXDATE, e, Property.EXDATE);
    copyProperty(c, Events.CUSTOM_APP_URI, e, Property.URL);
    copyProperty(c, Events.UID_2445, e, Property.UID);
    if (c.containsKey(Events.UID_2445) && TextUtils.isEmpty(c.getAsString(Events.UID_2445))) {
        // Remove null/empty UIDs
        c.remove(Events.UID_2445);
    }
    for (Object alarm : e.getAlarms()) {
        VAlarm a = (VAlarm) alarm;
        if (a.getAction() != Action.AUDIO && a.getAction() != Action.DISPLAY) {
            // Ignore email and procedure alarms
            continue;
        }
        Trigger t = a.getTrigger();
        final long startMs = e.getStartDate().getDate().getTime();
        long alarmStartMs = startMs;
        long alarmMs;
        // - Check the calendars max number of alarms
        if (t.getDateTime() != null) {
            // Absolute
            alarmMs = t.getDateTime().getTime();
        } else if (t.getDuration() != null && t.getDuration().isNegative()) {
            Related rel = (Related) t.getParameter(Parameter.RELATED);
            if (rel != null && rel == Related.END) {
                alarmStartMs = e.getEndDate().getDate().getTime();
            }
            // Relative
            alarmMs = alarmStartMs - durationToMs(t.getDuration());
        } else {
            continue;
        }
        int reminder = (int) ((startMs - alarmMs) / DateUtils.MINUTE_IN_MILLIS);
        if (reminder >= 0 && !reminders.contains(reminder)) {
            reminders.add(reminder);
        }
    }
    if (options.getReminders(reminders).size() > 0) {
        c.put(Events.HAS_ALARM, 1);
    }
    // FIXME: Attendees, SELF_ATTENDEE_STATUS
    return c;
}
Also used : ContentValues(android.content.ContentValues) FreeBusy(net.fortuna.ical4j.model.property.FreeBusy) Duration(net.fortuna.ical4j.model.property.Duration) URI(java.net.URI) DateTime(net.fortuna.ical4j.model.DateTime) SuppressLint(android.annotation.SuppressLint) Trigger(net.fortuna.ical4j.model.property.Trigger) Related(net.fortuna.ical4j.model.parameter.Related) FbType(net.fortuna.ical4j.model.parameter.FbType) ParseException(android.net.ParseException) VAlarm(net.fortuna.ical4j.model.component.VAlarm) MailTo(android.net.MailTo)

Aggregations

SuppressLint (android.annotation.SuppressLint)1 ContentValues (android.content.ContentValues)1 MailTo (android.net.MailTo)1 ParseException (android.net.ParseException)1 URI (java.net.URI)1 DateTime (net.fortuna.ical4j.model.DateTime)1 VAlarm (net.fortuna.ical4j.model.component.VAlarm)1 FbType (net.fortuna.ical4j.model.parameter.FbType)1 Related (net.fortuna.ical4j.model.parameter.Related)1 Duration (net.fortuna.ical4j.model.property.Duration)1 FreeBusy (net.fortuna.ical4j.model.property.FreeBusy)1 Trigger (net.fortuna.ical4j.model.property.Trigger)1