Remove CaldavConverter

pull/1348/head
Alex Baker 5 years ago
parent e45f767c1f
commit 9ae31d5949

@ -4,7 +4,7 @@ import android.content.Context
import at.bitfire.ical4android.Task.Companion.tasksFromReader
import com.todoroo.astrid.data.Task
import kotlinx.coroutines.runBlocking
import org.tasks.caldav.CaldavConverter
import org.tasks.caldav.iCalendar.Companion.applyRemote
import org.tasks.data.CaldavTask
import org.tasks.preferences.Preferences
import org.tasks.time.DateTime
@ -40,7 +40,7 @@ object TestUtilities {
fun vtodo(path: String): Task {
val task = Task()
CaldavConverter.apply(task, fromResource(path))
task.applyRemote(fromResource(path))
return task
}
@ -48,7 +48,7 @@ object TestUtilities {
val task = Task()
val vtodo = readFile(path)
val remote = fromString(vtodo)
CaldavConverter.apply(task, remote)
task.applyRemote(remote)
return Triple(task, CaldavTask().apply { this.vtodo = vtodo }, remote)
}

@ -1,138 +0,0 @@
package org.tasks.caldav;
import static com.todoroo.andlib.utility.DateUtilities.now;
import static com.todoroo.astrid.data.Task.withoutRRULE;
import static org.tasks.caldav.iCalendar.getLocal;
import static org.tasks.date.DateTimeUtils.newDateTime;
import static org.tasks.time.DateTime.UTC;
import static org.tasks.time.DateTimeUtils.startOfDay;
import at.bitfire.ical4android.DateUtils;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.Task.Priority;
import java.text.ParseException;
import java.util.TimeZone;
import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.property.Completed;
import net.fortuna.ical4j.model.property.DtStart;
import net.fortuna.ical4j.model.property.Due;
import net.fortuna.ical4j.model.property.RRule;
import net.fortuna.ical4j.model.property.Status;
import org.tasks.data.CaldavTask;
import timber.log.Timber;
public class CaldavConverter {
public static void apply(Task local, at.bitfire.ical4android.Task remote) {
Completed completedAt = remote.getCompletedAt();
if (completedAt != null) {
local.setCompletionDate(getLocal(completedAt));
} else if (remote.getStatus() == Status.VTODO_COMPLETED) {
if (!local.isCompleted()) {
local.setCompletionDate(now());
}
} else {
local.setCompletionDate(0L);
}
Long createdAt = remote.getCreatedAt();
if (createdAt != null) {
local.setCreationDate(newDateTime(createdAt, UTC).toLocal().getMillis());
}
local.setTitle(remote.getSummary());
local.setNotes(remote.getDescription());
local.setPriority(fromRemote(remote.getPriority()));
local.setRecurrence(remote.getRRule());
iCalendar.Companion.apply(remote.getDue(), local);
iCalendar.Companion.apply(remote.getDtStart(), local);
}
public static @Priority int fromRemote(int remotePriority) {
// https://tools.ietf.org/html/rfc5545#section-3.8.1.9
if (remotePriority == 0) {
return Priority.NONE;
}
if (remotePriority == 5) {
return Priority.MEDIUM;
}
return remotePriority < 5 ? Priority.HIGH : Priority.LOW;
}
public static int toRemote(int remotePriority, int localPriority) {
switch (localPriority) {
case Priority.NONE:
return 0;
case Priority.MEDIUM:
return 5;
case Priority.HIGH:
return remotePriority < 5 ? Math.max(1, remotePriority) : 1;
default:
return remotePriority > 5 ? Math.min(9, remotePriority) : 9;
}
}
public static void toCaldav(CaldavTask caldavTask, Task task, at.bitfire.ical4android.Task remote) {
remote.setCreatedAt(newDateTime(task.getCreationDate()).toUTC().getMillis());
remote.setSummary(task.getTitle());
remote.setDescription(task.getNotes());
boolean allDay = !task.hasDueTime() && !task.hasStartTime();
long dueDate = task.hasDueTime() ? task.getDueDate() : startOfDay(task.getDueDate());
long startDate = task.hasStartTime() ? task.getHideUntil() : startOfDay(task.getHideUntil());
if (dueDate > 0) {
startDate = Math.min(dueDate, startDate);
remote.setDue(new Due(allDay ? getDate(dueDate) : getDateTime(dueDate)));
} else {
remote.setDue(null);
}
if (startDate > 0) {
remote.setDtStart(new DtStart(allDay ? getDate(startDate) : getDateTime(startDate)));
} else {
remote.setDtStart(null);
}
if (task.isCompleted()) {
remote.setCompletedAt(new Completed(new DateTime(task.getCompletionDate())));
remote.setStatus(Status.VTODO_COMPLETED);
remote.setPercentComplete(100);
} else if (remote.getCompletedAt() != null) {
remote.setCompletedAt(null);
remote.setStatus(null);
remote.setPercentComplete(null);
}
if (task.isRecurring()) {
try {
RRule rrule = new RRule(withoutRRULE(task.getRecurrenceWithoutFrom()));
long repeatUntil = task.getRepeatUntil();
rrule
.getRecur()
.setUntil(
repeatUntil > 0 ? new DateTime(newDateTime(repeatUntil).toUTC().getMillis()) : null);
String sanitized = Task.sanitizeRRule(rrule.getValue()); // ical4j adds COUNT=-1 if there is an UNTIL value
remote.setRRule(new RRule(sanitized));
} catch (ParseException e) {
Timber.e(e);
}
} else {
remote.setRRule(null);
}
remote.setLastModified(newDateTime(task.getModificationDate()).toUTC().getMillis());
remote.setPriority(toRemote(remote.getPriority(), task.getPriority()));
iCalendar.Companion.setParent(remote, task.getParent() == 0 ? null : caldavTask.getRemoteParent());
}
private static Date getDate(long timestamp) {
return new Date(timestamp + newDateTime(timestamp).getOffset());
}
private static DateTime getDateTime(long timestamp) {
net.fortuna.ical4j.model.TimeZone tz =
DateUtils.INSTANCE.ical4jTimeZone(TimeZone.getDefault().getID());
DateTime dateTime = new DateTime(tz != null
? timestamp
: new org.tasks.time.DateTime(timestamp).toUTC().getMillis());
dateTime.setTimeZone(tz);
return dateTime;
}
}

@ -1,14 +1,19 @@
package org.tasks.caldav
import at.bitfire.ical4android.DateUtils.ical4jTimeZone
import at.bitfire.ical4android.Task
import at.bitfire.ical4android.Task.Companion.tasksFromReader
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task.Companion.HIDE_UNTIL_SPECIFIC_DAY
import com.todoroo.astrid.data.Task.Companion.HIDE_UNTIL_SPECIFIC_DAY_TIME
import com.todoroo.astrid.data.Task.Companion.URGENCY_SPECIFIC_DAY
import com.todoroo.astrid.data.Task.Companion.URGENCY_SPECIFIC_DAY_TIME
import com.todoroo.astrid.data.Task.Companion.sanitizeRRule
import com.todoroo.astrid.data.Task.Companion.withoutRRULE
import com.todoroo.astrid.helper.UUIDHelper
import com.todoroo.astrid.service.TaskCreator
import net.fortuna.ical4j.model.Date
import net.fortuna.ical4j.model.DateTime
import net.fortuna.ical4j.model.Parameter
import net.fortuna.ical4j.model.Property
@ -19,15 +24,20 @@ import org.tasks.caldav.GeoUtils.equalish
import org.tasks.caldav.GeoUtils.toGeo
import org.tasks.caldav.GeoUtils.toLikeString
import org.tasks.data.*
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.jobs.WorkManager
import org.tasks.location.GeofenceApi
import org.tasks.preferences.Preferences
import org.tasks.time.DateTime.UTC
import org.tasks.time.DateTimeUtils.startOfDay
import timber.log.Timber
import java.io.ByteArrayOutputStream
import java.io.StringReader
import java.text.ParseException
import java.util.*
import javax.inject.Inject
import kotlin.math.max
import kotlin.math.min
@Suppress("ClassName")
class iCalendar @Inject constructor(
@ -107,7 +117,7 @@ class iCalendar @Inject constructor(
}
suspend fun toVtodo(caldavTask: CaldavTask, task: com.todoroo.astrid.data.Task, remoteModel: Task) {
CaldavConverter.toCaldav(caldavTask, task, remoteModel)
remoteModel.applyLocal(caldavTask, task)
remoteModel.order = caldavTask.order
val categories = remoteModel.categories
categories.clear()
@ -139,7 +149,7 @@ class iCalendar @Inject constructor(
existing?.task = id
}
val caldavTask = existing ?: CaldavTask(task.id, calendar.uuid, remote.uid, obj)
CaldavConverter.apply(task, remote)
task.applyRemote(remote)
setPlace(task.id, remote.geoPosition)
tagDao.applyTags(task, tagDataDao, getTags(remote.categories))
task.suppressSync()
@ -260,5 +270,97 @@ class iCalendar @Inject constructor(
}
}
}
fun com.todoroo.astrid.data.Task.applyRemote(remote: Task) {
val completedAt = remote.completedAt
if (completedAt != null) {
completionDate = getLocal(completedAt)
} else if (remote.status === Status.VTODO_COMPLETED) {
if (!isCompleted) {
completionDate = DateUtilities.now()
}
} else {
completionDate = 0L
}
remote.createdAt?.let {
creationDate = newDateTime(it, UTC).toLocal().millis
}
title = remote.summary
notes = remote.description
priority = when (remote.priority) {
// https://tools.ietf.org/html/rfc5545#section-3.8.1.9
in 1..4 -> com.todoroo.astrid.data.Task.Priority.HIGH
5 -> com.todoroo.astrid.data.Task.Priority.MEDIUM
in 6..9 -> com.todoroo.astrid.data.Task.Priority.LOW
else -> com.todoroo.astrid.data.Task.Priority.NONE
}
setRecurrence(remote.rRule)
remote.due.apply(this)
remote.dtStart.apply(this)
}
fun Task.applyLocal(caldavTask: CaldavTask, task: com.todoroo.astrid.data.Task) {
createdAt = newDateTime(task.creationDate).toUTC().millis
summary = task.title
description = task.notes
val allDay = !task.hasDueTime() && !task.hasStartTime()
val dueDate = if (task.hasDueTime()) task.dueDate else task.dueDate.startOfDay()
var startDate = if (task.hasStartTime()) task.hideUntil else task.hideUntil.startOfDay()
due = if (dueDate > 0) {
startDate = min(dueDate, startDate)
Due(if (allDay) getDate(dueDate) else getDateTime(dueDate))
} else {
null
}
dtStart = if (startDate > 0) {
DtStart(if (allDay) getDate(startDate) else getDateTime(startDate))
} else {
null
}
if (task.isCompleted) {
completedAt = Completed(DateTime(task.completionDate))
status = Status.VTODO_COMPLETED
percentComplete = 100
} else if (completedAt != null) {
completedAt = null
status = null
percentComplete = null
}
rRule = if (task.isRecurring) {
try {
val rrule = RRule(task.getRecurrenceWithoutFrom().withoutRRULE())
val repeatUntil = task.repeatUntil
rrule
.recur.until = if (repeatUntil > 0) DateTime(newDateTime(repeatUntil).toUTC().millis) else null
val sanitized: String = rrule.value.sanitizeRRule()!! // ical4j adds COUNT=-1 if there is an UNTIL value
RRule(sanitized)
} catch (e: ParseException) {
Timber.e(e)
null
}
} else {
null
}
lastModified = newDateTime(task.modificationDate).toUTC().millis
priority = when (task.priority) {
com.todoroo.astrid.data.Task.Priority.NONE -> 0
com.todoroo.astrid.data.Task.Priority.MEDIUM -> 5
com.todoroo.astrid.data.Task.Priority.HIGH ->
if (priority < 5) max(1, priority) else 1
else -> if (priority > 5) min(9, priority) else 9
}
setParent(if (task.parent == 0L) null else caldavTask.remoteParent)
}
private fun getDate(timestamp: Long): Date {
return Date(timestamp + newDateTime(timestamp).offset)
}
private fun getDateTime(timestamp: Long): DateTime {
val tz = ical4jTimeZone(TimeZone.getDefault().id)
val dateTime = DateTime(if (tz != null) timestamp else org.tasks.time.DateTime(timestamp).toUTC().millis)
dateTime.timeZone = tz
return dateTime
}
}
}

@ -8,6 +8,7 @@ import org.junit.Ignore
import org.junit.Test
import org.tasks.TestUtilities.setup
import org.tasks.TestUtilities.vtodo
import org.tasks.caldav.iCalendar.Companion.applyLocal
import org.tasks.time.DateTime
import java.util.*
@ -96,7 +97,7 @@ class ThunderbirdTests {
@Test
fun dontTruncateTimeFromUntil() {
val (task, caldavTask, remote) = setup("thunderbird/repeat_until_date_time.txt")
CaldavConverter.toCaldav(caldavTask, task, remote)
remote.applyLocal(caldavTask, task)
assertEquals(
"FREQ=WEEKLY;UNTIL=20200731T160000Z;BYDAY=MO,TU,WE,TH,FR",
remote.rRule!!.value)

Loading…
Cancel
Save