Move shared functionality to iCalendar

pull/935/head
Alex Baker 5 years ago
parent bc9b9744fe
commit 57c642ab9c

@ -3,7 +3,6 @@ package com.todoroo.astrid.service;
import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newArrayList;
import static org.tasks.caldav.CaldavUtils.getParent;
import static org.tasks.db.DbUtils.batch; import static org.tasks.db.DbUtils.batch;
import android.content.Context; import android.content.Context;
@ -22,7 +21,7 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.R; import org.tasks.R;
import org.tasks.analytics.Tracker; import org.tasks.analytics.Tracker;
import org.tasks.caldav.CaldavUtils; import org.tasks.caldav.iCalendar;
import org.tasks.data.CaldavCalendar; import org.tasks.data.CaldavCalendar;
import org.tasks.data.CaldavDao; import org.tasks.data.CaldavDao;
import org.tasks.data.CaldavTask; import org.tasks.data.CaldavTask;
@ -69,6 +68,7 @@ public class Upgrader {
private final TaskAttachmentDao taskAttachmentDao; private final TaskAttachmentDao taskAttachmentDao;
private final CaldavDao caldavDao; private final CaldavDao caldavDao;
private final TaskDao taskDao; private final TaskDao taskDao;
private final iCalendar iCal;
@Inject @Inject
public Upgrader( public Upgrader(
@ -83,7 +83,8 @@ public class Upgrader {
UserActivityDao userActivityDao, UserActivityDao userActivityDao,
TaskAttachmentDao taskAttachmentDao, TaskAttachmentDao taskAttachmentDao,
CaldavDao caldavDao, CaldavDao caldavDao,
TaskDao taskDao) { TaskDao taskDao,
iCalendar iCal) {
this.context = context; this.context = context;
this.preferences = preferences; this.preferences = preferences;
this.tracker = tracker; this.tracker = tracker;
@ -96,6 +97,7 @@ public class Upgrader {
this.taskAttachmentDao = taskAttachmentDao; this.taskAttachmentDao = taskAttachmentDao;
this.caldavDao = caldavDao; this.caldavDao = caldavDao;
this.taskDao = taskDao; this.taskDao = taskDao;
this.iCal = iCal;
} }
public void upgrade(int from, int to) { public void upgrade(int from, int to) {
@ -183,11 +185,11 @@ public class Upgrader {
List<CaldavTask> updated = newArrayList(); List<CaldavTask> updated = newArrayList();
for (CaldavTask task : transform(caldavDao.getTasks(), CaldavTaskContainer::getCaldavTask)) { for (CaldavTask task : transform(caldavDao.getTasks(), CaldavTaskContainer::getCaldavTask)) {
at.bitfire.ical4android.Task remoteTask = CaldavUtils.fromVtodo(task.getVtodo()); at.bitfire.ical4android.Task remoteTask = iCalendar.Companion.fromVtodo(task.getVtodo());
if (remoteTask == null) { if (remoteTask == null) {
continue; continue;
} }
task.setRemoteParent(getParent(remoteTask)); task.setRemoteParent(iCalendar.Companion.getParent(remoteTask));
if (!Strings.isNullOrEmpty(task.getRemoteParent())) { if (!Strings.isNullOrEmpty(task.getRemoteParent())) {
updated.add(task); updated.add(task);
} }
@ -201,9 +203,9 @@ public class Upgrader {
List<Long> tasksWithTags = caldavDao.getTasksWithTags(); List<Long> tasksWithTags = caldavDao.getTasksWithTags();
for (CaldavTaskContainer container : caldavDao.getTasks()) { for (CaldavTaskContainer container : caldavDao.getTasks()) {
at.bitfire.ical4android.Task remoteTask = at.bitfire.ical4android.Task remoteTask =
CaldavUtils.fromVtodo(container.caldavTask.getVtodo()); iCalendar.Companion.fromVtodo(container.caldavTask.getVtodo());
if (remoteTask != null) { if (remoteTask != null) {
tagDao.insert(container.task, CaldavUtils.getTags(tagDataDao, remoteTask.getCategories())); tagDao.insert(container.task, iCal.getTags(remoteTask.getCategories()));
} }
} }
batch(tasksWithTags, taskDao::touch); batch(tasksWithTags, taskDao::touch);

@ -3,8 +3,6 @@ package org.tasks.caldav;
import static com.todoroo.andlib.utility.DateUtilities.now; import static com.todoroo.andlib.utility.DateUtilities.now;
import static com.todoroo.astrid.data.Task.URGENCY_SPECIFIC_DAY; import static com.todoroo.astrid.data.Task.URGENCY_SPECIFIC_DAY;
import static com.todoroo.astrid.data.Task.URGENCY_SPECIFIC_DAY_TIME; import static com.todoroo.astrid.data.Task.URGENCY_SPECIFIC_DAY_TIME;
import static org.tasks.caldav.CaldavUtils.fromVtodo;
import static org.tasks.caldav.CaldavUtils.setParent;
import static org.tasks.date.DateTimeUtils.newDateTime; import static org.tasks.date.DateTimeUtils.newDateTime;
import at.bitfire.ical4android.DateUtils; import at.bitfire.ical4android.DateUtils;
@ -109,7 +107,7 @@ public class CaldavConverter {
at.bitfire.ical4android.Task remote = null; at.bitfire.ical4android.Task remote = null;
try { try {
if (!Strings.isNullOrEmpty(caldavTask.getVtodo())) { if (!Strings.isNullOrEmpty(caldavTask.getVtodo())) {
remote = fromVtodo(caldavTask.getVtodo()); remote = iCalendar.Companion.fromVtodo(caldavTask.getVtodo());
} }
} catch (Exception e) { } catch (Exception e) {
Timber.e(e); Timber.e(e);
@ -158,7 +156,7 @@ public class CaldavConverter {
} }
remote.setLastModified(newDateTime(task.getModificationDate()).toUTC().getMillis()); remote.setLastModified(newDateTime(task.getModificationDate()).toUTC().getMillis());
remote.setPriority(toRemote(remote.getPriority(), task.getPriority())); remote.setPriority(toRemote(remote.getPriority(), task.getPriority()));
setParent(remote, task.getParent() == 0 ? null : caldavTask.getRemoteParent()); iCalendar.Companion.setParent(remote, task.getParent() == 0 ? null : caldavTask.getRemoteParent());
return remote; return remote;
} }

@ -7,7 +7,6 @@ import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.transform; import static com.google.common.collect.Lists.transform;
import static com.google.common.collect.Sets.difference; import static com.google.common.collect.Sets.difference;
import static com.google.common.collect.Sets.newHashSet; import static com.google.common.collect.Sets.newHashSet;
import static org.tasks.caldav.CaldavUtils.getParent;
import static org.tasks.time.DateTimeUtils.currentTimeMillis; import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import android.content.Context; import android.content.Context;
@ -30,14 +29,10 @@ import at.bitfire.ical4android.ICalendar;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.SyncFlags;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.UUIDHelper; import com.todoroo.astrid.helper.UUIDHelper;
import com.todoroo.astrid.service.TaskCreator;
import com.todoroo.astrid.service.TaskDeleter; import com.todoroo.astrid.service.TaskDeleter;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
@ -45,7 +40,6 @@ import java.net.UnknownHostException;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
@ -63,9 +57,6 @@ import org.tasks.data.CaldavAccount;
import org.tasks.data.CaldavCalendar; import org.tasks.data.CaldavCalendar;
import org.tasks.data.CaldavDao; import org.tasks.data.CaldavDao;
import org.tasks.data.CaldavTask; import org.tasks.data.CaldavTask;
import org.tasks.data.TagDao;
import org.tasks.data.TagData;
import org.tasks.data.TagDataDao;
import org.tasks.injection.ForApplication; import org.tasks.injection.ForApplication;
import timber.log.Timber; import timber.log.Timber;
@ -78,14 +69,12 @@ public class CaldavSynchronizer {
private final CaldavDao caldavDao; private final CaldavDao caldavDao;
private final TaskDao taskDao; private final TaskDao taskDao;
private final TagDataDao tagDataDao;
private final TagDao tagDao;
private final LocalBroadcastManager localBroadcastManager; private final LocalBroadcastManager localBroadcastManager;
private final TaskCreator taskCreator;
private final TaskDeleter taskDeleter; private final TaskDeleter taskDeleter;
private final Inventory inventory; private final Inventory inventory;
private final Tracker tracker; private final Tracker tracker;
private final CaldavClient client; private final CaldavClient client;
private final iCalendar iCal;
private final Context context; private final Context context;
@Inject @Inject
@ -93,25 +82,21 @@ public class CaldavSynchronizer {
@ForApplication Context context, @ForApplication Context context,
CaldavDao caldavDao, CaldavDao caldavDao,
TaskDao taskDao, TaskDao taskDao,
TagDataDao tagDataDao,
TagDao tagDao,
LocalBroadcastManager localBroadcastManager, LocalBroadcastManager localBroadcastManager,
TaskCreator taskCreator,
TaskDeleter taskDeleter, TaskDeleter taskDeleter,
Inventory inventory, Inventory inventory,
Tracker tracker, Tracker tracker,
CaldavClient client) { CaldavClient client,
iCalendar iCal) {
this.context = context; this.context = context;
this.caldavDao = caldavDao; this.caldavDao = caldavDao;
this.taskDao = taskDao; this.taskDao = taskDao;
this.tagDataDao = tagDataDao;
this.tagDao = tagDao;
this.localBroadcastManager = localBroadcastManager; this.localBroadcastManager = localBroadcastManager;
this.taskCreator = taskCreator;
this.taskDeleter = taskDeleter; this.taskDeleter = taskDeleter;
this.inventory = inventory; this.inventory = inventory;
this.tracker = tracker; this.tracker = tracker;
this.client = client; this.client = client;
this.iCal = iCal;
} }
public void sync(CaldavAccount account) { public void sync(CaldavAccount account) {
@ -188,7 +173,7 @@ public class CaldavSynchronizer {
} }
private void sync(CaldavCalendar caldavCalendar, Response resource, OkHttpClient httpClient) private void sync(CaldavCalendar caldavCalendar, Response resource, OkHttpClient httpClient)
throws IOException, DavException { throws DavException {
Timber.d("sync(%s)", caldavCalendar); Timber.d("sync(%s)", caldavCalendar);
HttpUrl httpUrl = resource.getHref(); HttpUrl httpUrl = resource.getHref();
pushLocalChanges(caldavCalendar, httpClient, httpUrl); pushLocalChanges(caldavCalendar, httpClient, httpUrl);
@ -228,19 +213,6 @@ public class CaldavSynchronizer {
}); });
for (List<Response> items : partition(changed, 30)) { for (List<Response> items : partition(changed, 30)) {
if (items.size() == 1) {
Response vCard = items.get(0);
GetETag eTag = vCard.get(GetETag.class);
HttpUrl url = vCard.getHref();
if (eTag == null || isNullOrEmpty(eTag.getETag())) {
throw new DavException("Received CalDAV GET response without ETag for " + url);
}
Timber.d("SINGLE %s", url);
org.tasks.caldav.Response response = new org.tasks.caldav.Response(true);
new DavResource(httpClient, url).get("text/calendar", response);
processVTodo(vCard.hrefName(), caldavCalendar, eTag.getETag(), response.getBody());
} else {
ArrayList<HttpUrl> urls = newArrayList(Iterables.transform(items, Response::getHref)); ArrayList<HttpUrl> urls = newArrayList(Iterables.transform(items, Response::getHref));
ResponseList responses = new ResponseList(HrefRelation.MEMBER); ResponseList responses = new ResponseList(HrefRelation.MEMBER);
davCalendar.multiget(urls, responses); davCalendar.multiget(urls, responses);
@ -257,10 +229,16 @@ public class CaldavSynchronizer {
if (calendarData == null || isNullOrEmpty(calendarData.getICalendar())) { if (calendarData == null || isNullOrEmpty(calendarData.getICalendar())) {
throw new DavException("Received CalDAV GET response without CalendarData for " + url); throw new DavException("Received CalDAV GET response without CalendarData for " + url);
} }
String fileName = vCard.hrefName();
processVTodo( String vtodo = calendarData.getICalendar();
vCard.hrefName(), caldavCalendar, eTag.getETag(), calendarData.getICalendar()); at.bitfire.ical4android.Task remote = iCalendar.Companion.fromVtodo(vtodo);
if (remote == null) {
Timber.e("Invalid VCALENDAR: %s", fileName);
return;
} }
CaldavTask caldavTask = caldavDao.getTask(caldavCalendar.getUuid(), fileName);
iCal.fromVtodo(caldavCalendar, caldavTask, remote, vtodo, fileName, eTag.getETag());
} }
} }
@ -336,21 +314,7 @@ public class CaldavSynchronizer {
return; return;
} }
at.bitfire.ical4android.Task remoteModel = CaldavConverter.toCaldav(caldavTask, task); byte[] data = iCal.toVtodo(caldavTask, task);
LinkedList<String> categories = remoteModel.getCategories();
categories.clear();
categories.addAll(transform(tagDataDao.getTagDataForTask(task.getId()), TagData::getName));
if (Strings.isNullOrEmpty(caldavTask.getRemoteId())) {
String caldavUid = UUIDHelper.newUUID();
caldavTask.setRemoteId(caldavUid);
remoteModel.setUid(caldavUid);
} else {
remoteModel.setUid(caldavTask.getRemoteId());
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
remoteModel.write(os);
byte[] data = os.toByteArray();
RequestBody requestBody = RequestBody.create(DavCalendar.Companion.getMIME_ICALENDAR(), data); RequestBody requestBody = RequestBody.create(DavCalendar.Companion.getMIME_ICALENDAR(), data);
try { try {
@ -373,42 +337,4 @@ public class CaldavSynchronizer {
caldavDao.update(caldavTask); caldavDao.update(caldavTask);
Timber.d("SENT %s", caldavTask); Timber.d("SENT %s", caldavTask);
} }
private void processVTodo(
String fileName, CaldavCalendar caldavCalendar, String eTag, String vtodo) {
at.bitfire.ical4android.Task remote = CaldavUtils.fromVtodo(vtodo);
if (remote == null) {
Timber.e("Invalid VCALENDAR: %s", fileName);
return;
}
Task task;
CaldavTask caldavTask = caldavDao.getTask(caldavCalendar.getUuid(), fileName);
if (caldavTask == null) {
task = taskCreator.createWithValues("");
taskDao.createNew(task);
caldavTask =
new CaldavTask(task.getId(), caldavCalendar.getUuid(), remote.getUid(), fileName);
} else {
task = taskDao.fetch(caldavTask.getTask());
}
CaldavConverter.apply(task, remote);
tagDao.applyTags(task, tagDataDao, CaldavUtils.getTags(tagDataDao, remote.getCategories()));
task.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true);
task.putTransitory(TaskDao.TRANS_SUPPRESS_REFRESH, true);
taskDao.save(task);
caldavTask.setVtodo(vtodo);
caldavTask.setEtag(eTag);
caldavTask.setLastSync(DateUtilities.now() + 1000L);
caldavTask.setRemoteParent(getParent(remote));
if (caldavTask.getId() == Task.NO_ID) {
caldavTask.setId(caldavDao.insert(caldavTask));
Timber.d("NEW %s", caldavTask);
} else {
caldavDao.update(caldavTask);
Timber.d("UPDATE %s", caldavTask);
}
}
} }

@ -1,68 +0,0 @@
package org.tasks.caldav;
import static com.google.common.collect.Iterables.removeIf;
import static com.google.common.collect.Iterables.tryFind;
import static com.google.common.collect.Lists.transform;
import static com.google.common.collect.Sets.difference;
import static com.google.common.collect.Sets.newHashSet;
import androidx.annotation.Nullable;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import java.io.StringReader;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import net.fortuna.ical4j.model.Parameter;
import net.fortuna.ical4j.model.parameter.RelType;
import net.fortuna.ical4j.model.property.RelatedTo;
import org.tasks.data.TagData;
import org.tasks.data.TagDataDao;
public class CaldavUtils {
private static final Predicate<RelatedTo> IS_PARENT =
r -> r.getParameters().isEmpty() || r.getParameter(Parameter.RELTYPE) == RelType.PARENT;
public static @Nullable at.bitfire.ical4android.Task fromVtodo(String vtodo) {
List<at.bitfire.ical4android.Task> tasks =
at.bitfire.ical4android.Task.Companion.tasksFromReader(new StringReader(vtodo));
return tasks.size() == 1 ? tasks.get(0) : null;
}
public static List<TagData> getTags(TagDataDao tagDataDao, List<String> categories) {
if (categories.isEmpty()) {
return Collections.emptyList();
}
List<TagData> selectedTags = tagDataDao.getTags(categories);
Set<String> toCreate =
difference(newHashSet(categories), newHashSet(transform(selectedTags, TagData::getName)));
for (String name : toCreate) {
TagData tag = new TagData(name);
tagDataDao.createNew(tag);
selectedTags.add(tag);
}
return selectedTags;
}
public static void setParent(at.bitfire.ical4android.Task remote, @Nullable String value) {
LinkedList<RelatedTo> relatedTo = remote.getRelatedTo();
if (Strings.isNullOrEmpty(value)) {
removeIf(relatedTo, IS_PARENT);
} else {
Optional<RelatedTo> parent = tryFind(relatedTo, IS_PARENT);
if (parent.isPresent()) {
parent.get().setValue(value);
} else {
relatedTo.add(new RelatedTo(value));
}
}
}
public static @Nullable String getParent(at.bitfire.ical4android.Task remote) {
LinkedList<RelatedTo> relatedTo = remote.getRelatedTo();
Optional<RelatedTo> parent = tryFind(relatedTo, IS_PARENT);
return parent.isPresent() ? parent.get().getValue() : null;
}
}

@ -0,0 +1,130 @@
package org.tasks.caldav
import at.bitfire.ical4android.Task
import at.bitfire.ical4android.Task.Companion.tasksFromReader
import com.google.common.base.Predicate
import com.google.common.base.Strings
import com.google.common.collect.Iterables
import com.google.common.collect.Lists
import com.google.common.collect.Sets.difference
import com.google.common.collect.Sets.newHashSet
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.SyncFlags
import com.todoroo.astrid.helper.UUIDHelper
import com.todoroo.astrid.service.TaskCreator
import net.fortuna.ical4j.model.Parameter
import net.fortuna.ical4j.model.parameter.RelType
import net.fortuna.ical4j.model.property.RelatedTo
import org.tasks.data.*
import timber.log.Timber
import java.io.ByteArrayOutputStream
import java.io.StringReader
import javax.inject.Inject
class iCalendar @Inject constructor(
private val tagDataDao: TagDataDao,
private val taskCreator: TaskCreator,
private val tagDao: TagDao,
private val taskDao: TaskDao,
private val caldavDao: CaldavDao) {
companion object {
private val IS_PARENT = Predicate { r: RelatedTo? ->
r!!.parameters.isEmpty || r.getParameter(Parameter.RELTYPE) === RelType.PARENT
}
fun fromVtodo(vtodo: String): Task? {
val tasks = tasksFromReader(StringReader(vtodo))
return if (tasks.size == 1) tasks[0] else null
}
fun getParent(remote: Task): String? {
val relatedTo = remote.relatedTo
val parent = Iterables.tryFind(relatedTo, IS_PARENT)
return if (parent.isPresent) parent.get().value else null
}
fun setParent(remote: Task, value: String?) {
val relatedTo = remote.relatedTo
if (Strings.isNullOrEmpty(value)) {
Iterables.removeIf(relatedTo, IS_PARENT)
} else {
val parent = Iterables.tryFind(relatedTo, IS_PARENT)
if (parent.isPresent) {
parent.get().value = value
} else {
relatedTo.add(RelatedTo(value))
}
}
}
}
fun getTags(categories: List<String>): List<TagData> {
if (categories.isEmpty()) {
return emptyList()
}
val tags = tagDataDao.getTags(categories)
val existing = Lists.transform(tags) { obj: TagData? -> obj!!.name }
val toCreate = difference(newHashSet(categories), newHashSet(existing))
for (name in toCreate) {
val tag = TagData(name)
tagDataDao.createNew(tag)
tags.add(tag)
}
return tags
}
fun toVtodo(caldavTask: CaldavTask, task: com.todoroo.astrid.data.Task): ByteArray {
val remoteModel = CaldavConverter.toCaldav(caldavTask, task)
val categories = remoteModel.categories
categories.clear()
categories.addAll(Lists.transform(tagDataDao.getTagDataForTask(task.getId())) { obj: TagData? -> obj!!.name })
if (Strings.isNullOrEmpty(caldavTask.remoteId)) {
val caldavUid = UUIDHelper.newUUID()
caldavTask.remoteId = caldavUid
remoteModel.uid = caldavUid
} else {
remoteModel.uid = caldavTask.remoteId
}
val os = ByteArrayOutputStream()
remoteModel.write(os)
return os.toByteArray()
}
fun fromVtodo(
calendar: CaldavCalendar,
existing: CaldavTask?,
remote: Task,
vtodo: String,
obj: String? = null,
eTag: String? = null) {
val task: com.todoroo.astrid.data.Task
val caldavTask: CaldavTask
if (existing == null) {
task = taskCreator.createWithValues("")
taskDao.createNew(task)
caldavTask = CaldavTask(task.getId(), calendar.uuid, remote.uid, obj)
} else {
task = taskDao.fetch(existing.task)
caldavTask = existing
}
CaldavConverter.apply(task, remote)
tagDao.applyTags(task, tagDataDao, getTags(remote.categories))
task.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true)
task.putTransitory(TaskDao.TRANS_SUPPRESS_REFRESH, true)
taskDao.save(task)
caldavTask.vtodo = vtodo
caldavTask.etag = eTag
caldavTask.lastSync = DateUtilities.now() + 1000L
caldavTask.remoteParent = getParent(remote)
if (caldavTask.id == com.todoroo.astrid.data.Task.NO_ID) {
caldavTask.id = caldavDao.insert(caldavTask)
Timber.d("NEW %s", caldavTask)
} else {
caldavDao.update(caldavTask)
Timber.d("UPDATE %s", caldavTask)
}
}
}

@ -3,11 +3,9 @@ package org.tasks.etesync;
import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.FluentIterable.from; import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.transform;
import static com.google.common.collect.Maps.newHashMap; import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet; import static com.google.common.collect.Sets.newHashSet;
import static java.util.Collections.emptySet; import static java.util.Collections.emptySet;
import static org.tasks.caldav.CaldavUtils.getParent;
import android.content.Context; import android.content.Context;
import androidx.core.util.Pair; import androidx.core.util.Pair;
@ -26,18 +24,11 @@ import com.etesync.journalmanager.model.SyncEntry;
import com.etesync.journalmanager.model.SyncEntry.Actions; import com.etesync.journalmanager.model.SyncEntry.Actions;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.SyncFlags;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.UUIDHelper; import com.todoroo.astrid.helper.UUIDHelper;
import com.todoroo.astrid.service.TaskCreator;
import com.todoroo.astrid.service.TaskDeleter; import com.todoroo.astrid.service.TaskDeleter;
import java.io.ByteArrayOutputStream;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -47,16 +38,12 @@ import org.tasks.BuildConfig;
import org.tasks.LocalBroadcastManager; import org.tasks.LocalBroadcastManager;
import org.tasks.R; import org.tasks.R;
import org.tasks.billing.Inventory; import org.tasks.billing.Inventory;
import org.tasks.caldav.CaldavConverter; import org.tasks.caldav.iCalendar;
import org.tasks.caldav.CaldavUtils;
import org.tasks.data.CaldavAccount; import org.tasks.data.CaldavAccount;
import org.tasks.data.CaldavCalendar; import org.tasks.data.CaldavCalendar;
import org.tasks.data.CaldavDao; import org.tasks.data.CaldavDao;
import org.tasks.data.CaldavTask; import org.tasks.data.CaldavTask;
import org.tasks.data.CaldavTaskContainer; import org.tasks.data.CaldavTaskContainer;
import org.tasks.data.TagDao;
import org.tasks.data.TagData;
import org.tasks.data.TagDataDao;
import org.tasks.injection.ForApplication; import org.tasks.injection.ForApplication;
import timber.log.Timber; import timber.log.Timber;
@ -68,38 +55,29 @@ public class EteSynchronizer {
} }
private final CaldavDao caldavDao; private final CaldavDao caldavDao;
private final TaskDao taskDao;
private final TagDataDao tagDataDao;
private final TagDao tagDao;
private final LocalBroadcastManager localBroadcastManager; private final LocalBroadcastManager localBroadcastManager;
private final TaskCreator taskCreator;
private final TaskDeleter taskDeleter; private final TaskDeleter taskDeleter;
private final Inventory inventory; private final Inventory inventory;
private final EteSyncClient client; private final EteSyncClient client;
private final iCalendar iCal;
private final Context context; private final Context context;
@Inject @Inject
public EteSynchronizer( public EteSynchronizer(
@ForApplication Context context, @ForApplication Context context,
CaldavDao caldavDao, CaldavDao caldavDao,
TaskDao taskDao,
TagDataDao tagDataDao,
TagDao tagDao,
LocalBroadcastManager localBroadcastManager, LocalBroadcastManager localBroadcastManager,
TaskCreator taskCreator,
TaskDeleter taskDeleter, TaskDeleter taskDeleter,
Inventory inventory, Inventory inventory,
EteSyncClient client) { EteSyncClient client,
iCalendar iCal) {
this.context = context; this.context = context;
this.caldavDao = caldavDao; this.caldavDao = caldavDao;
this.taskDao = taskDao;
this.tagDataDao = tagDataDao;
this.tagDao = tagDao;
this.localBroadcastManager = localBroadcastManager; this.localBroadcastManager = localBroadcastManager;
this.taskCreator = taskCreator;
this.taskDeleter = taskDeleter; this.taskDeleter = taskDeleter;
this.inventory = inventory; this.inventory = inventory;
this.client = client; this.client = client;
this.iCal = iCal;
} }
public void sync(CaldavAccount account) { public void sync(CaldavAccount account) {
@ -217,7 +195,10 @@ public class EteSynchronizer {
changes.add(new SyncEntry(vtodo, Actions.DELETE)); changes.add(new SyncEntry(vtodo, Actions.DELETE));
} }
} else { } else {
changes.add(new SyncEntry(getVtodo(task), existingTask ? Actions.CHANGE : Actions.ADD)); changes.add(
new SyncEntry(
new String(iCal.toVtodo(task.getCaldavTask(), task.getTask())),
existingTask ? Actions.CHANGE : Actions.ADD));
} }
} }
@ -255,7 +236,7 @@ public class EteSynchronizer {
Actions action = syncEntry.getAction(); Actions action = syncEntry.getAction();
String vtodo = syncEntry.getContent(); String vtodo = syncEntry.getContent();
Timber.v("%s: %s", action, vtodo); Timber.v("%s: %s", action, vtodo);
at.bitfire.ical4android.Task task = CaldavUtils.fromVtodo(vtodo); at.bitfire.ical4android.Task task = iCalendar.Companion.fromVtodo(vtodo);
String remoteId = task.getUid(); String remoteId = task.getUid();
CaldavTask caldavTask = caldavDao.getTaskByRemoteId(caldavCalendar.getUuid(), remoteId); CaldavTask caldavTask = caldavDao.getTaskByRemoteId(caldavCalendar.getUuid(), remoteId);
switch (action) { switch (action) {
@ -265,7 +246,7 @@ public class EteSynchronizer {
caldavTask.setVtodo(vtodo); caldavTask.setVtodo(vtodo);
caldavDao.update(caldavTask); caldavDao.update(caldavTask);
} else { } else {
processVTodo(caldavCalendar, caldavTask, task, vtodo); iCal.fromVtodo(caldavCalendar, caldavTask, task, vtodo, null, null);
} }
break; break;
case DELETE: case DELETE:
@ -279,57 +260,4 @@ public class EteSynchronizer {
caldavDao.update(caldavCalendar); caldavDao.update(caldavCalendar);
} }
} }
private String getVtodo(CaldavTaskContainer container) {
Task task = container.getTask();
CaldavTask caldavTask = container.getCaldavTask();
at.bitfire.ical4android.Task remoteModel = CaldavConverter.toCaldav(caldavTask, task);
LinkedList<String> categories = remoteModel.getCategories();
categories.clear();
categories.addAll(transform(tagDataDao.getTagDataForTask(task.getId()), TagData::getName));
if (Strings.isNullOrEmpty(caldavTask.getRemoteId())) {
String caldavUid = UUIDHelper.newUUID();
caldavTask.setRemoteId(caldavUid);
remoteModel.setUid(caldavUid);
} else {
remoteModel.setUid(caldavTask.getRemoteId());
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
remoteModel.write(os);
return new String(os.toByteArray());
}
private void processVTodo(
CaldavCalendar calendar,
CaldavTask caldavTask,
at.bitfire.ical4android.Task remote,
String vtodo) {
Task task;
if (caldavTask == null) {
task = taskCreator.createWithValues("");
taskDao.createNew(task);
caldavTask = new CaldavTask(task.getId(), calendar.getUuid(), remote.getUid(), null);
} else {
task = taskDao.fetch(caldavTask.getTask());
}
CaldavConverter.apply(task, remote);
tagDao.applyTags(task, tagDataDao, CaldavUtils.getTags(tagDataDao, remote.getCategories()));
task.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true);
task.putTransitory(TaskDao.TRANS_SUPPRESS_REFRESH, true);
taskDao.save(task);
caldavTask.setVtodo(vtodo);
caldavTask.setLastSync(DateUtilities.now() + 1000L);
caldavTask.setRemoteParent(getParent(remote));
if (caldavTask.getId() == Task.NO_ID) {
caldavTask.setId(caldavDao.insert(caldavTask));
Timber.d("NEW %s", caldavTask);
} else {
caldavDao.update(caldavTask);
Timber.d("UPDATE %s", caldavTask);
}
}
} }

Loading…
Cancel
Save