Search in sources :

Example 1 with FbType

use of net.fortuna.ical4j.model.parameter.FbType 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)

Example 2 with FbType

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

the class SaveCalendar method convertFromDb.

private VEvent convertFromDb(Cursor cur, Calendar cal, DtStamp timestamp) {
    Log_OC.d(TAG, "cursor: " + DatabaseUtils.dumpCurrentRowToString(cur));
    if (hasStringValue(cur, Events.ORIGINAL_ID)) {
        // FIXME: Support these edited instances
        Log_OC.w(TAG, "Ignoring edited instance of a recurring event");
        return null;
    }
    PropertyList l = new PropertyList();
    l.add(timestamp);
    copyProperty(l, Property.UID, cur, Events.UID_2445);
    String summary = copyProperty(l, Property.SUMMARY, cur, Events.TITLE);
    String description = copyProperty(l, Property.DESCRIPTION, cur, Events.DESCRIPTION);
    String organizer = getString(cur, Events.ORGANIZER);
    if (!TextUtils.isEmpty(organizer)) {
        // incorrectly left it in the organizer column.
        if (!organizer.startsWith("mailto:")) {
            organizer = "mailto:" + organizer;
        }
        try {
            l.add(new Organizer(organizer));
        } catch (URISyntaxException ignored) {
            if (!mFailedOrganisers.contains(organizer)) {
                Log_OC.e(TAG, "Failed to create mailTo for organizer " + organizer);
                mFailedOrganisers.add(organizer);
            }
        }
    }
    copyProperty(l, Property.LOCATION, cur, Events.EVENT_LOCATION);
    copyEnumProperty(l, Property.STATUS, cur, Events.STATUS, STATUS_ENUM);
    boolean allDay = TextUtils.equals(getString(cur, Events.ALL_DAY), "1");
    boolean isTransparent;
    DtEnd dtEnd = null;
    if (allDay) {
        // All day event
        isTransparent = true;
        Date start = getDateTime(cur, Events.DTSTART, null, null);
        Date end = getDateTime(cur, Events.DTEND, null, null);
        l.add(new DtStart(new Date(start)));
        if (end != null) {
            dtEnd = new DtEnd(new Date(end));
        } else {
            dtEnd = new DtEnd(utcDateFromMs(start.getTime() + DateUtils.DAY_IN_MILLIS));
        }
        l.add(dtEnd);
    } else {
        // Regular or zero-time event. Start date must be a date-time
        Date startDate = getDateTime(cur, Events.DTSTART, Events.EVENT_TIMEZONE, cal);
        l.add(new DtStart(startDate));
        // Use duration if we have one, otherwise end date
        if (hasStringValue(cur, Events.DURATION)) {
            isTransparent = getString(cur, Events.DURATION).equals("PT0S");
            if (!isTransparent) {
                copyProperty(l, Property.DURATION, cur, Events.DURATION);
            }
        } else {
            String endTz = Events.EVENT_END_TIMEZONE;
            if (endTz == null) {
                endTz = Events.EVENT_TIMEZONE;
            }
            Date end = getDateTime(cur, Events.DTEND, endTz, cal);
            dtEnd = new DtEnd(end);
            isTransparent = startDate.getTime() == end.getTime();
            if (!isTransparent) {
                l.add(dtEnd);
            }
        }
    }
    copyEnumProperty(l, Property.CLASS, cur, Events.ACCESS_LEVEL, CLASS_ENUM);
    int availability = getInt(cur, Events.AVAILABILITY);
    if (availability > Events.AVAILABILITY_TENTATIVE) {
        // Unknown/Invalid
        availability = -1;
    }
    if (isTransparent) {
        // not free, then mark it opaque.
        if (availability >= 0 && availability != Events.AVAILABILITY_FREE) {
            l.add(Transp.OPAQUE);
        }
    } else if (availability > Events.AVAILABILITY_BUSY) {
        // This event is ordinarily busy but differs, so output a FREEBUSY
        // period covering the time of the event
        FreeBusy fb = new FreeBusy();
        fb.getParameters().add(new FbType(AVAIL_ENUM.get(availability)));
        DateTime start = new DateTime(((DtStart) l.getProperty(Property.DTSTART)).getDate());
        if (dtEnd != null) {
            fb.getPeriods().add(new Period(start, new DateTime(dtEnd.getDate())));
        } else {
            Duration d = (Duration) l.getProperty(Property.DURATION);
            fb.getPeriods().add(new Period(start, d.getDuration()));
        }
        l.add(fb);
    }
    copyProperty(l, Property.RRULE, cur, Events.RRULE);
    copyProperty(l, Property.RDATE, cur, Events.RDATE);
    copyProperty(l, Property.EXRULE, cur, Events.EXRULE);
    copyProperty(l, Property.EXDATE, cur, Events.EXDATE);
    if (TextUtils.isEmpty(getString(cur, Events.CUSTOM_APP_PACKAGE))) {
        // Only copy URL if there is no app i.e. we probably imported it.
        copyProperty(l, Property.URL, cur, Events.CUSTOM_APP_URI);
    }
    VEvent e = new VEvent(l);
    if (getInt(cur, Events.HAS_ALARM) == 1) {
        // Add alarms
        String s = summary == null ? (description == null ? "" : description) : summary;
        Description desc = new Description(s);
        ContentResolver resolver = activity.getContentResolver();
        long eventId = getLong(cur, Events._ID);
        Cursor alarmCur;
        alarmCur = Reminders.query(resolver, eventId, mAllCols ? null : REMINDER_COLS);
        while (alarmCur.moveToNext()) {
            int mins = getInt(alarmCur, Reminders.MINUTES);
            if (mins == -1) {
                // FIXME: Get the real default
                mins = 60;
            }
            // FIXME: We should support other types if possible
            int method = getInt(alarmCur, Reminders.METHOD);
            if (method == Reminders.METHOD_DEFAULT || method == Reminders.METHOD_ALERT) {
                VAlarm alarm = new VAlarm(new Dur(0, 0, -mins, 0));
                alarm.getProperties().add(Action.DISPLAY);
                alarm.getProperties().add(desc);
                e.getAlarms().add(alarm);
            }
        }
        alarmCur.close();
    }
    return e;
}
Also used : VEvent(net.fortuna.ical4j.model.component.VEvent) Dur(net.fortuna.ical4j.model.Dur) Description(net.fortuna.ical4j.model.property.Description) Organizer(net.fortuna.ical4j.model.property.Organizer) FreeBusy(net.fortuna.ical4j.model.property.FreeBusy) Period(net.fortuna.ical4j.model.Period) Duration(net.fortuna.ical4j.model.property.Duration) URISyntaxException(java.net.URISyntaxException) Cursor(android.database.Cursor) Date(net.fortuna.ical4j.model.Date) SuppressLint(android.annotation.SuppressLint) DateTime(net.fortuna.ical4j.model.DateTime) ContentResolver(android.content.ContentResolver) PropertyList(net.fortuna.ical4j.model.PropertyList) DtStart(net.fortuna.ical4j.model.property.DtStart) FbType(net.fortuna.ical4j.model.parameter.FbType) VAlarm(net.fortuna.ical4j.model.component.VAlarm) DtEnd(net.fortuna.ical4j.model.property.DtEnd)

Aggregations

SuppressLint (android.annotation.SuppressLint)2 DateTime (net.fortuna.ical4j.model.DateTime)2 VAlarm (net.fortuna.ical4j.model.component.VAlarm)2 FbType (net.fortuna.ical4j.model.parameter.FbType)2 Duration (net.fortuna.ical4j.model.property.Duration)2 FreeBusy (net.fortuna.ical4j.model.property.FreeBusy)2 ContentResolver (android.content.ContentResolver)1 ContentValues (android.content.ContentValues)1 Cursor (android.database.Cursor)1 MailTo (android.net.MailTo)1 ParseException (android.net.ParseException)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 Date (net.fortuna.ical4j.model.Date)1 Dur (net.fortuna.ical4j.model.Dur)1 Period (net.fortuna.ical4j.model.Period)1 PropertyList (net.fortuna.ical4j.model.PropertyList)1 VEvent (net.fortuna.ical4j.model.component.VEvent)1 Related (net.fortuna.ical4j.model.parameter.Related)1 Description (net.fortuna.ical4j.model.property.Description)1