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;
}
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;
}
Aggregations