mirror of https://github.com/tasks/tasks
Convert Upgrader to Kotlin
parent
9ff92418e2
commit
9ba34ab14f
@ -1,411 +0,0 @@
|
||||
package com.todoroo.astrid.service;
|
||||
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.tasks.Strings.isNullOrEmpty;
|
||||
import static org.tasks.db.DbUtils.batch;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.ColorRes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.todoroo.astrid.api.GtasksFilter;
|
||||
import com.todoroo.astrid.dao.TaskDao;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import net.fortuna.ical4j.model.property.Geo;
|
||||
import org.tasks.R;
|
||||
import org.tasks.caldav.iCalendar;
|
||||
import org.tasks.data.CaldavCalendar;
|
||||
import org.tasks.data.CaldavDao;
|
||||
import org.tasks.data.CaldavTask;
|
||||
import org.tasks.data.CaldavTaskContainer;
|
||||
import org.tasks.data.Filter;
|
||||
import org.tasks.data.FilterDao;
|
||||
import org.tasks.data.GoogleTaskAccount;
|
||||
import org.tasks.data.GoogleTaskList;
|
||||
import org.tasks.data.GoogleTaskListDao;
|
||||
import org.tasks.data.Location;
|
||||
import org.tasks.data.LocationDao;
|
||||
import org.tasks.data.Tag;
|
||||
import org.tasks.data.TagDao;
|
||||
import org.tasks.data.TagData;
|
||||
import org.tasks.data.TagDataDao;
|
||||
import org.tasks.data.TaskAttachment;
|
||||
import org.tasks.data.TaskAttachmentDao;
|
||||
import org.tasks.data.UserActivity;
|
||||
import org.tasks.data.UserActivityDao;
|
||||
import org.tasks.injection.ForApplication;
|
||||
import org.tasks.preferences.DefaultFilterProvider;
|
||||
import org.tasks.preferences.Preferences;
|
||||
import org.tasks.widget.AppWidgetManager;
|
||||
import org.tasks.widget.WidgetPreferences;
|
||||
|
||||
public class Upgrader {
|
||||
|
||||
private static final int V4_9_5 = 434;
|
||||
private static final int V5_3_0 = 491;
|
||||
private static final int V6_0_beta_1 = 522;
|
||||
private static final int V6_0_beta_2 = 523;
|
||||
private static final int V6_4 = 546;
|
||||
private static final int V6_7 = 585;
|
||||
private static final int V6_8_1 = 607;
|
||||
private static final int V6_9 = 608;
|
||||
private static final int V7_0 = 617;
|
||||
public static final int V8_2 = 675;
|
||||
private static final int V8_5 = 700;
|
||||
private static final int V8_8 = 717;
|
||||
private static final int V8_10 = 735;
|
||||
private static final int V9_3 = 90300;
|
||||
private final Context context;
|
||||
private final Preferences preferences;
|
||||
private final TagDataDao tagDataDao;
|
||||
private final TagDao tagDao;
|
||||
private final FilterDao filterDao;
|
||||
private final DefaultFilterProvider defaultFilterProvider;
|
||||
private final GoogleTaskListDao googleTaskListDao;
|
||||
private final UserActivityDao userActivityDao;
|
||||
private final TaskAttachmentDao taskAttachmentDao;
|
||||
private final CaldavDao caldavDao;
|
||||
private final TaskDao taskDao;
|
||||
private final LocationDao locationDao;
|
||||
private final iCalendar iCal;
|
||||
private final AppWidgetManager widgetManager;
|
||||
|
||||
@Inject
|
||||
public Upgrader(
|
||||
@ForApplication Context context,
|
||||
Preferences preferences,
|
||||
TagDataDao tagDataDao,
|
||||
TagDao tagDao,
|
||||
FilterDao filterDao,
|
||||
DefaultFilterProvider defaultFilterProvider,
|
||||
GoogleTaskListDao googleTaskListDao,
|
||||
UserActivityDao userActivityDao,
|
||||
TaskAttachmentDao taskAttachmentDao,
|
||||
CaldavDao caldavDao,
|
||||
TaskDao taskDao,
|
||||
LocationDao locationDao,
|
||||
iCalendar iCal,
|
||||
AppWidgetManager widgetManager) {
|
||||
this.context = context;
|
||||
this.preferences = preferences;
|
||||
this.tagDataDao = tagDataDao;
|
||||
this.tagDao = tagDao;
|
||||
this.filterDao = filterDao;
|
||||
this.defaultFilterProvider = defaultFilterProvider;
|
||||
this.googleTaskListDao = googleTaskListDao;
|
||||
this.userActivityDao = userActivityDao;
|
||||
this.taskAttachmentDao = taskAttachmentDao;
|
||||
this.caldavDao = caldavDao;
|
||||
this.taskDao = taskDao;
|
||||
this.locationDao = locationDao;
|
||||
this.iCal = iCal;
|
||||
this.widgetManager = widgetManager;
|
||||
}
|
||||
|
||||
public void upgrade(int from, int to) {
|
||||
if (from > 0) {
|
||||
run(from, V4_9_5, this::removeDuplicateTags);
|
||||
run(from, V5_3_0, this::migrateFilters);
|
||||
run(from, V6_0_beta_1, this::migrateDefaultSyncList);
|
||||
run(from, V6_0_beta_2, this::migrateGoogleTaskAccount);
|
||||
run(from, V6_4, this::migrateUris);
|
||||
run(from, V6_7, this::migrateGoogleTaskFilters);
|
||||
run(from, V6_8_1, this::migrateCaldavFilters);
|
||||
run(from, V6_9, this::applyCaldavCategories);
|
||||
run(from, V7_0, this::applyCaldavSubtasks);
|
||||
run(from, V8_2, this::migrateColors);
|
||||
run(from, V8_5, this::applyCaldavGeo);
|
||||
run(from, V8_8, () -> {
|
||||
preferences.setBoolean(R.string.p_linkify_task_edit, true);
|
||||
preferences.setBoolean(R.string.p_auto_dismiss_datetime_edit_screen, true);
|
||||
});
|
||||
run(from, V8_10, this::migrateWidgets);
|
||||
run(from, V9_3, this::applyCaldavOrder);
|
||||
preferences.setBoolean(R.string.p_just_updated, true);
|
||||
}
|
||||
preferences.setCurrentVersion(to);
|
||||
}
|
||||
|
||||
private void run(int from, int version, Runnable runnable) {
|
||||
if (from < version) {
|
||||
runnable.run();
|
||||
preferences.setCurrentVersion(version);
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateWidgets() {
|
||||
for (int widgetId : widgetManager.getWidgetIds()) {
|
||||
WidgetPreferences widgetPreferences = new WidgetPreferences(context, preferences, widgetId);
|
||||
widgetPreferences.maintainExistingConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateColors() {
|
||||
preferences.setInt(
|
||||
R.string.p_theme_color, getAndroidColor(preferences.getInt(R.string.p_theme_color, 7)));
|
||||
for (CaldavCalendar calendar : caldavDao.getCalendars()) {
|
||||
calendar.setColor(getAndroidColor(calendar.getColor()));
|
||||
caldavDao.update(calendar);
|
||||
}
|
||||
for (GoogleTaskList list : googleTaskListDao.getAllLists()) {
|
||||
list.setColor(getAndroidColor(list.getColor()));
|
||||
googleTaskListDao.update(list);
|
||||
}
|
||||
for (TagData tagData : tagDataDao.getAll()) {
|
||||
tagData.setColor(getAndroidColor(tagData.getColor()));
|
||||
tagDataDao.update(tagData);
|
||||
}
|
||||
for (Filter filter : filterDao.getFilters()) {
|
||||
filter.setColor(getAndroidColor(filter.getColor()));
|
||||
filterDao.update(filter);
|
||||
}
|
||||
}
|
||||
|
||||
private int getAndroidColor(int index) {
|
||||
return getAndroidColor(context, index);
|
||||
}
|
||||
|
||||
public static int getAndroidColor(Context context, int index) {
|
||||
int legacyColor = getLegacyColor(index, 0);
|
||||
return legacyColor == 0 ? 0 : context.getColor(legacyColor);
|
||||
}
|
||||
|
||||
public static @ColorRes int getLegacyColor(int index, int def) {
|
||||
switch (index) {
|
||||
case 0: return R.color.blue_grey_500;
|
||||
case 1: return R.color.grey_900;
|
||||
case 2: return R.color.red_500;
|
||||
case 3: return R.color.pink_500;
|
||||
case 4: return R.color.purple_500;
|
||||
case 5: return R.color.deep_purple_500;
|
||||
case 6: return R.color.indigo_500;
|
||||
case 7: return R.color.blue_500;
|
||||
case 8: return R.color.light_blue_500;
|
||||
case 9: return R.color.cyan_500;
|
||||
case 10: return R.color.teal_500;
|
||||
case 11: return R.color.green_500;
|
||||
case 12: return R.color.light_green_500;
|
||||
case 13: return R.color.lime_500;
|
||||
case 14: return R.color.yellow_500;
|
||||
case 15: return R.color.amber_500;
|
||||
case 16: return R.color.orange_500;
|
||||
case 17: return R.color.deep_orange_500;
|
||||
case 18: return R.color.brown_500;
|
||||
case 19: return R.color.grey_500;
|
||||
case 20: return R.color.white_100;
|
||||
default: return def;
|
||||
}
|
||||
}
|
||||
|
||||
private void applyCaldavOrder() {
|
||||
for (CaldavTask task : transform(caldavDao.getTasks(), CaldavTaskContainer::getCaldavTask)) {
|
||||
at.bitfire.ical4android.Task remoteTask = iCalendar.Companion.fromVtodo(task.getVtodo());
|
||||
if (remoteTask == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Long order = iCalendar.Companion.getOrder(remoteTask);
|
||||
if (order != null) {
|
||||
task.setOrder(order);
|
||||
caldavDao.update(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void applyCaldavGeo() {
|
||||
List<Long> tasksWithLocations =
|
||||
Lists.transform(locationDao.getActiveGeofences(), Location::getTask);
|
||||
|
||||
for (CaldavTask task : transform(caldavDao.getTasks(), CaldavTaskContainer::getCaldavTask)) {
|
||||
long taskId = task.getTask();
|
||||
if (tasksWithLocations.contains(taskId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
at.bitfire.ical4android.Task remoteTask = iCalendar.Companion.fromVtodo(task.getVtodo());
|
||||
if (remoteTask == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Geo geo = remoteTask.getGeoPosition();
|
||||
if (geo == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iCal.setPlace(taskId, geo);
|
||||
}
|
||||
|
||||
batch(tasksWithLocations, taskDao::touch);
|
||||
}
|
||||
|
||||
private void applyCaldavSubtasks() {
|
||||
List<CaldavTask> updated = new ArrayList<>();
|
||||
|
||||
for (CaldavTask task : transform(caldavDao.getTasks(), CaldavTaskContainer::getCaldavTask)) {
|
||||
at.bitfire.ical4android.Task remoteTask = iCalendar.Companion.fromVtodo(task.getVtodo());
|
||||
if (remoteTask == null) {
|
||||
continue;
|
||||
}
|
||||
task.setRemoteParent(iCalendar.Companion.getParent(remoteTask));
|
||||
if (!isNullOrEmpty(task.getRemoteParent())) {
|
||||
updated.add(task);
|
||||
}
|
||||
}
|
||||
|
||||
caldavDao.update(updated);
|
||||
caldavDao.updateParents();
|
||||
}
|
||||
|
||||
private void applyCaldavCategories() {
|
||||
List<Long> tasksWithTags = caldavDao.getTasksWithTags();
|
||||
for (CaldavTaskContainer container : caldavDao.getTasks()) {
|
||||
at.bitfire.ical4android.Task remoteTask =
|
||||
iCalendar.Companion.fromVtodo(container.getVtodo());
|
||||
if (remoteTask != null) {
|
||||
tagDao.insert(container.getTask(), iCal.getTags(remoteTask.getCategories()));
|
||||
}
|
||||
}
|
||||
batch(tasksWithTags, taskDao::touch);
|
||||
}
|
||||
|
||||
private void removeDuplicateTags() {
|
||||
ListMultimap<String, TagData> tagsByUuid =
|
||||
Multimaps.index(tagDataDao.tagDataOrderedByName(), TagData::getRemoteId);
|
||||
for (String uuid : tagsByUuid.keySet()) {
|
||||
removeDuplicateTagData(tagsByUuid.get(uuid));
|
||||
removeDuplicateTagMetadata(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateGoogleTaskFilters() {
|
||||
for (Filter filter : filterDao.getAll()) {
|
||||
filter.setSql(migrateGoogleTaskFilters(filter.getSql()));
|
||||
filter.setCriterion(migrateGoogleTaskFilters(filter.getCriterion()));
|
||||
filterDao.update(filter);
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateCaldavFilters() {
|
||||
for (Filter filter : filterDao.getAll()) {
|
||||
filter.setSql(migrateCaldavFilters(filter.getSql()));
|
||||
filter.setCriterion(migrateCaldavFilters(filter.getCriterion()));
|
||||
filterDao.update(filter);
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateFilters() {
|
||||
for (Filter filter : filterDao.getFilters()) {
|
||||
filter.setSql(migrateMetadata(filter.getSql()));
|
||||
filter.setCriterion(migrateMetadata(filter.getCriterion()));
|
||||
filterDao.update(filter);
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateDefaultSyncList() {
|
||||
String account = preferences.getStringValue("gtasks_user");
|
||||
if (isNullOrEmpty(account)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String defaultGoogleTaskList = preferences.getStringValue("gtasks_defaultlist");
|
||||
if (isNullOrEmpty(defaultGoogleTaskList)) {
|
||||
// TODO: look up default list
|
||||
} else {
|
||||
GoogleTaskList googleTaskList = googleTaskListDao.getByRemoteId(defaultGoogleTaskList);
|
||||
if (googleTaskList != null) {
|
||||
defaultFilterProvider.setDefaultRemoteList(new GtasksFilter(googleTaskList));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateGoogleTaskAccount() {
|
||||
String account = preferences.getStringValue("gtasks_user");
|
||||
if (!isNullOrEmpty(account)) {
|
||||
GoogleTaskAccount googleTaskAccount = new GoogleTaskAccount();
|
||||
googleTaskAccount.setAccount(account);
|
||||
googleTaskListDao.insert(googleTaskAccount);
|
||||
for (GoogleTaskList list : googleTaskListDao.getAllLists()) {
|
||||
list.setAccount(account);
|
||||
googleTaskListDao.insertOrReplace(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateUris() {
|
||||
migrateUriPreference(R.string.p_backup_dir);
|
||||
migrateUriPreference(R.string.p_attachment_dir);
|
||||
for (UserActivity userActivity : userActivityDao.getComments()) {
|
||||
userActivity.convertPictureUri();
|
||||
userActivityDao.update(userActivity);
|
||||
}
|
||||
for (TaskAttachment attachment : taskAttachmentDao.getAttachments()) {
|
||||
attachment.convertPathUri();
|
||||
taskAttachmentDao.update(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateUriPreference(int pref) {
|
||||
String path = preferences.getStringValue(pref);
|
||||
if (isNullOrEmpty(path)) {
|
||||
return;
|
||||
}
|
||||
File file = new File(path);
|
||||
try {
|
||||
if (file.canWrite()) {
|
||||
preferences.setUri(pref, file.toURI());
|
||||
} else {
|
||||
preferences.remove(pref);
|
||||
}
|
||||
} catch (SecurityException ignored) {
|
||||
preferences.remove(pref);
|
||||
}
|
||||
}
|
||||
|
||||
private String migrateGoogleTaskFilters(String input) {
|
||||
return input
|
||||
.replace("SELECT task FROM google_tasks", "SELECT gt_task as task FROM google_tasks")
|
||||
.replace("(list_id", "(gt_list_id")
|
||||
.replace("google_tasks.list_id", "google_tasks.gt_list_id")
|
||||
.replace("google_tasks.task", "google_tasks.gt_task");
|
||||
}
|
||||
|
||||
private String migrateCaldavFilters(String input) {
|
||||
return input
|
||||
.replace("SELECT task FROM caldav_tasks", "SELECT cd_task as task FROM caldav_tasks")
|
||||
.replace("(calendar", "(cd_calendar");
|
||||
}
|
||||
|
||||
private String migrateMetadata(String input) {
|
||||
return input
|
||||
.replaceAll(
|
||||
"SELECT metadata\\.task AS task FROM metadata INNER JOIN tasks ON \\(\\(metadata\\.task=tasks\\._id\\)\\) WHERE \\(\\(\\(tasks\\.completed=0\\) AND \\(tasks\\.deleted=0\\) AND \\(tasks\\.hideUntil<\\(strftime\\(\\'%s\\',\\'now\\'\\)\\*1000\\)\\)\\) AND \\(metadata\\.key=\\'tags-tag\\'\\) AND \\(metadata\\.value",
|
||||
"SELECT tags.task AS task FROM tags INNER JOIN tasks ON ((tags.task=tasks._id)) WHERE (((tasks.completed=0) AND (tasks.deleted=0) AND (tasks.hideUntil<(strftime('%s','now')*1000))) AND (tags.name")
|
||||
.replaceAll(
|
||||
"SELECT metadata\\.task AS task FROM metadata INNER JOIN tasks ON \\(\\(metadata\\.task=tasks\\._id\\)\\) WHERE \\(\\(\\(tasks\\.completed=0\\) AND \\(tasks\\.deleted=0\\) AND \\(tasks\\.hideUntil<\\(strftime\\(\\'%s\\',\\'now\\'\\)\\*1000\\)\\)\\) AND \\(metadata\\.key=\\'gtasks\\'\\) AND \\(metadata\\.value2",
|
||||
"SELECT google_tasks.task AS task FROM google_tasks INNER JOIN tasks ON ((google_tasks.task=tasks._id)) WHERE (((tasks.completed=0) AND (tasks.deleted=0) AND (tasks.hideUntil<(strftime('%s','now')*1000))) AND (google_tasks.list_id")
|
||||
.replaceAll("AND \\(metadata\\.deleted=0\\)", "");
|
||||
}
|
||||
|
||||
private void removeDuplicateTagData(List<TagData> tagData) {
|
||||
if (tagData.size() > 1) {
|
||||
tagDataDao.delete(tagData.subList(1, tagData.size()));
|
||||
}
|
||||
}
|
||||
|
||||
private void removeDuplicateTagMetadata(String uuid) {
|
||||
List<Tag> metadatas = tagDao.getByTagUid(uuid);
|
||||
ImmutableListMultimap<Long, Tag> metadataByTask = Multimaps.index(metadatas, Tag::getTask);
|
||||
for (Long key : metadataByTask.keySet()) {
|
||||
ImmutableList<Tag> tags = metadataByTask.get(key);
|
||||
if (tags.size() > 1) {
|
||||
tagDao.delete(tags.subList(1, tags.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,339 @@
|
||||
package com.todoroo.astrid.service
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.ColorRes
|
||||
import com.google.common.collect.ImmutableListMultimap
|
||||
import com.google.common.collect.ListMultimap
|
||||
import com.google.common.collect.Multimaps
|
||||
import com.todoroo.astrid.api.GtasksFilter
|
||||
import com.todoroo.astrid.dao.TaskDao
|
||||
import org.tasks.R
|
||||
import org.tasks.Strings.isNullOrEmpty
|
||||
import org.tasks.caldav.iCalendar
|
||||
import org.tasks.caldav.iCalendar.Companion.fromVtodo
|
||||
import org.tasks.caldav.iCalendar.Companion.getParent
|
||||
import org.tasks.caldav.iCalendar.Companion.order
|
||||
import org.tasks.data.*
|
||||
import org.tasks.db.DbUtils
|
||||
import org.tasks.injection.ForApplication
|
||||
import org.tasks.preferences.DefaultFilterProvider
|
||||
import org.tasks.preferences.Preferences
|
||||
import org.tasks.widget.AppWidgetManager
|
||||
import org.tasks.widget.WidgetPreferences
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class Upgrader @Inject constructor(
|
||||
@param:ForApplication private val context: Context,
|
||||
private val preferences: Preferences,
|
||||
private val tagDataDao: TagDataDao,
|
||||
private val tagDao: TagDao,
|
||||
private val filterDao: FilterDao,
|
||||
private val defaultFilterProvider: DefaultFilterProvider,
|
||||
private val googleTaskListDao: GoogleTaskListDao,
|
||||
private val userActivityDao: UserActivityDao,
|
||||
private val taskAttachmentDao: TaskAttachmentDao,
|
||||
private val caldavDao: CaldavDao,
|
||||
private val taskDao: TaskDao,
|
||||
private val locationDao: LocationDao,
|
||||
private val iCal: iCalendar,
|
||||
private val widgetManager: AppWidgetManager) {
|
||||
|
||||
fun upgrade(from: Int, to: Int) {
|
||||
if (from > 0) {
|
||||
run(from, V4_9_5) { removeDuplicateTags() }
|
||||
run(from, V5_3_0) { migrateFilters() }
|
||||
run(from, V6_0_beta_1) { migrateDefaultSyncList() }
|
||||
run(from, V6_0_beta_2) { migrateGoogleTaskAccount() }
|
||||
run(from, V6_4) { migrateUris() }
|
||||
run(from, V6_7) { this.migrateGoogleTaskFilters() }
|
||||
run(from, V6_8_1) { this.migrateCaldavFilters() }
|
||||
run(from, V6_9) { applyCaldavCategories() }
|
||||
run(from, V7_0) { applyCaldavSubtasks() }
|
||||
run(from, V8_2) { migrateColors() }
|
||||
run(from, V8_5) { applyCaldavGeo() }
|
||||
run(from, V8_8) {
|
||||
preferences.setBoolean(R.string.p_linkify_task_edit, true)
|
||||
preferences.setBoolean(R.string.p_auto_dismiss_datetime_edit_screen, true)
|
||||
}
|
||||
run(from, V8_10) { migrateWidgets() }
|
||||
run(from, V9_3) { applyCaldavOrder() }
|
||||
preferences.setBoolean(R.string.p_just_updated, true)
|
||||
}
|
||||
preferences.setCurrentVersion(to)
|
||||
}
|
||||
|
||||
private fun run(from: Int, version: Int, runnable: () -> Unit) {
|
||||
if (from < version) {
|
||||
runnable.invoke()
|
||||
preferences.setCurrentVersion(version)
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateWidgets() {
|
||||
for (widgetId in widgetManager.widgetIds) {
|
||||
val widgetPreferences = WidgetPreferences(context, preferences, widgetId)
|
||||
widgetPreferences.maintainExistingConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateColors() {
|
||||
preferences.setInt(
|
||||
R.string.p_theme_color, getAndroidColor(preferences.getInt(R.string.p_theme_color, 7)))
|
||||
for (calendar in caldavDao.getCalendars()) {
|
||||
calendar.color = getAndroidColor(calendar.color)
|
||||
caldavDao.update(calendar)
|
||||
}
|
||||
for (list in googleTaskListDao.getAllLists()) {
|
||||
list.setColor(getAndroidColor(list.getColor()!!))
|
||||
googleTaskListDao.update(list)
|
||||
}
|
||||
for (tagData in tagDataDao.getAll()) {
|
||||
tagData.setColor(getAndroidColor(tagData.getColor()!!))
|
||||
tagDataDao.update(tagData)
|
||||
}
|
||||
for (filter in filterDao.getFilters()) {
|
||||
filter.setColor(getAndroidColor(filter.getColor()!!))
|
||||
filterDao.update(filter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAndroidColor(index: Int): Int {
|
||||
return getAndroidColor(context, index)
|
||||
}
|
||||
|
||||
private fun applyCaldavOrder() {
|
||||
for (task in caldavDao.getTasks().map(CaldavTaskContainer::caldavTask)) {
|
||||
val remoteTask = fromVtodo(task.vtodo!!) ?: continue
|
||||
val order: Long? = remoteTask.order
|
||||
if (order != null) {
|
||||
task.order = order
|
||||
caldavDao.update(task)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyCaldavGeo() {
|
||||
val tasksWithLocations = locationDao.getActiveGeofences().map(Location::task)
|
||||
for (task in caldavDao.getTasks().map(CaldavTaskContainer::caldavTask)) {
|
||||
val taskId = task.task
|
||||
if (tasksWithLocations.contains(taskId)) {
|
||||
continue
|
||||
}
|
||||
val remoteTask = fromVtodo(task.vtodo!!) ?: continue
|
||||
val geo = remoteTask.geoPosition ?: continue
|
||||
iCal.setPlace(taskId, geo)
|
||||
}
|
||||
DbUtils.batch(tasksWithLocations) { ids: List<Long>? -> taskDao.touch(ids!!) }
|
||||
}
|
||||
|
||||
private fun applyCaldavSubtasks() {
|
||||
val updated: MutableList<CaldavTask> = ArrayList()
|
||||
for (task in caldavDao.getTasks().map(CaldavTaskContainer::caldavTask)) {
|
||||
val remoteTask = fromVtodo(task.vtodo!!) ?: continue
|
||||
task.remoteParent = getParent(remoteTask)
|
||||
if (!isNullOrEmpty(task.remoteParent)) {
|
||||
updated.add(task)
|
||||
}
|
||||
}
|
||||
caldavDao.update(updated)
|
||||
caldavDao.updateParents()
|
||||
}
|
||||
|
||||
private fun applyCaldavCategories() {
|
||||
val tasksWithTags: List<Long> = caldavDao.getTasksWithTags()
|
||||
for (container in caldavDao.getTasks()) {
|
||||
val remoteTask = fromVtodo(container.vtodo!!)
|
||||
if (remoteTask != null) {
|
||||
tagDao.insert(container.task, iCal.getTags(remoteTask.categories))
|
||||
}
|
||||
}
|
||||
DbUtils.batch(tasksWithTags) { ids: List<Long> -> taskDao.touch(ids) }
|
||||
}
|
||||
|
||||
private fun removeDuplicateTags() {
|
||||
val tagsByUuid: ListMultimap<String, TagData> = Multimaps.index(tagDataDao.tagDataOrderedByName()) { it!!.remoteId }
|
||||
for (uuid in tagsByUuid.keySet()) {
|
||||
removeDuplicateTagData(tagsByUuid[uuid])
|
||||
removeDuplicateTagMetadata(uuid)
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateGoogleTaskFilters() {
|
||||
for (filter in filterDao.getAll()) {
|
||||
filter.setSql(migrateGoogleTaskFilters(filter.getSql()))
|
||||
filter.criterion = migrateGoogleTaskFilters(filter.criterion)
|
||||
filterDao.update(filter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateCaldavFilters() {
|
||||
for (filter in filterDao.getAll()) {
|
||||
filter.setSql(migrateCaldavFilters(filter.getSql()))
|
||||
filter.criterion = migrateCaldavFilters(filter.criterion)
|
||||
filterDao.update(filter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateFilters() {
|
||||
for (filter in filterDao.getFilters()) {
|
||||
filter.setSql(migrateMetadata(filter.getSql()))
|
||||
filter.criterion = migrateMetadata(filter.criterion)
|
||||
filterDao.update(filter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateDefaultSyncList() {
|
||||
val account = preferences.getStringValue("gtasks_user")
|
||||
if (isNullOrEmpty(account)) {
|
||||
return
|
||||
}
|
||||
val defaultGoogleTaskList = preferences.getStringValue("gtasks_defaultlist")
|
||||
if (isNullOrEmpty(defaultGoogleTaskList)) {
|
||||
// TODO: look up default list
|
||||
} else {
|
||||
val googleTaskList = googleTaskListDao.getByRemoteId(defaultGoogleTaskList)
|
||||
if (googleTaskList != null) {
|
||||
defaultFilterProvider.defaultRemoteList = GtasksFilter(googleTaskList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateGoogleTaskAccount() {
|
||||
val account = preferences.getStringValue("gtasks_user")
|
||||
if (!isNullOrEmpty(account)) {
|
||||
val googleTaskAccount = GoogleTaskAccount()
|
||||
googleTaskAccount.account = account
|
||||
googleTaskListDao.insert(googleTaskAccount)
|
||||
for (list in googleTaskListDao.getAllLists()) {
|
||||
list.account = account
|
||||
googleTaskListDao.insertOrReplace(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateUris() {
|
||||
migrateUriPreference(R.string.p_backup_dir)
|
||||
migrateUriPreference(R.string.p_attachment_dir)
|
||||
for (userActivity in userActivityDao.getComments()) {
|
||||
userActivity.convertPictureUri()
|
||||
userActivityDao.update(userActivity)
|
||||
}
|
||||
for (attachment in taskAttachmentDao.getAttachments()) {
|
||||
attachment.convertPathUri()
|
||||
taskAttachmentDao.update(attachment)
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateUriPreference(pref: Int) {
|
||||
val path = preferences.getStringValue(pref)
|
||||
if (isNullOrEmpty(path)) {
|
||||
return
|
||||
}
|
||||
val file = File(path)
|
||||
try {
|
||||
if (file.canWrite()) {
|
||||
preferences.setUri(pref, file.toURI())
|
||||
} else {
|
||||
preferences.remove(pref)
|
||||
}
|
||||
} catch (ignored: SecurityException) {
|
||||
preferences.remove(pref)
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrateGoogleTaskFilters(input: String?): String {
|
||||
return input.orEmpty()
|
||||
.replace("SELECT task FROM google_tasks", "SELECT gt_task as task FROM google_tasks")
|
||||
.replace("(list_id", "(gt_list_id")
|
||||
.replace("google_tasks.list_id", "google_tasks.gt_list_id")
|
||||
.replace("google_tasks.task", "google_tasks.gt_task")
|
||||
}
|
||||
|
||||
private fun migrateCaldavFilters(input: String?): String {
|
||||
return input.orEmpty()
|
||||
.replace("SELECT task FROM caldav_tasks", "SELECT cd_task as task FROM caldav_tasks")
|
||||
.replace("(calendar", "(cd_calendar")
|
||||
}
|
||||
|
||||
private fun migrateMetadata(input: String?): String {
|
||||
return input.orEmpty()
|
||||
.replace(
|
||||
"SELECT metadata\\.task AS task FROM metadata INNER JOIN tasks ON \\(\\(metadata\\.task=tasks\\._id\\)\\) WHERE \\(\\(\\(tasks\\.completed=0\\) AND \\(tasks\\.deleted=0\\) AND \\(tasks\\.hideUntil<\\(strftime\\(\\'%s\\',\\'now\\'\\)\\*1000\\)\\)\\) AND \\(metadata\\.key=\\'tags-tag\\'\\) AND \\(metadata\\.value".toRegex(),
|
||||
"SELECT tags.task AS task FROM tags INNER JOIN tasks ON ((tags.task=tasks._id)) WHERE (((tasks.completed=0) AND (tasks.deleted=0) AND (tasks.hideUntil<(strftime('%s','now')*1000))) AND (tags.name")
|
||||
.replace(
|
||||
"SELECT metadata\\.task AS task FROM metadata INNER JOIN tasks ON \\(\\(metadata\\.task=tasks\\._id\\)\\) WHERE \\(\\(\\(tasks\\.completed=0\\) AND \\(tasks\\.deleted=0\\) AND \\(tasks\\.hideUntil<\\(strftime\\(\\'%s\\',\\'now\\'\\)\\*1000\\)\\)\\) AND \\(metadata\\.key=\\'gtasks\\'\\) AND \\(metadata\\.value2".toRegex(),
|
||||
"SELECT google_tasks.task AS task FROM google_tasks INNER JOIN tasks ON ((google_tasks.task=tasks._id)) WHERE (((tasks.completed=0) AND (tasks.deleted=0) AND (tasks.hideUntil<(strftime('%s','now')*1000))) AND (google_tasks.list_id")
|
||||
.replace("AND \\(metadata\\.deleted=0\\)".toRegex(), "")
|
||||
}
|
||||
|
||||
private fun removeDuplicateTagData(tagData: List<TagData>) {
|
||||
if (tagData.size > 1) {
|
||||
tagDataDao.delete(tagData.subList(1, tagData.size))
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeDuplicateTagMetadata(uuid: String) {
|
||||
val metadatas = tagDao.getByTagUid(uuid)
|
||||
val metadataByTask: ImmutableListMultimap<Long, Tag> = Multimaps.index(metadatas) { it!!.task }
|
||||
for (key in metadataByTask.keySet()) {
|
||||
val tags = metadataByTask[key]
|
||||
if (tags.size > 1) {
|
||||
tagDao.delete(tags.subList(1, tags.size))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val V4_9_5 = 434
|
||||
private const val V5_3_0 = 491
|
||||
private const val V6_0_beta_1 = 522
|
||||
private const val V6_0_beta_2 = 523
|
||||
private const val V6_4 = 546
|
||||
private const val V6_7 = 585
|
||||
private const val V6_8_1 = 607
|
||||
private const val V6_9 = 608
|
||||
private const val V7_0 = 617
|
||||
const val V8_2 = 675
|
||||
private const val V8_5 = 700
|
||||
private const val V8_8 = 717
|
||||
private const val V8_10 = 735
|
||||
private const val V9_3 = 90300
|
||||
|
||||
@JvmStatic
|
||||
fun getAndroidColor(context: Context, index: Int): Int {
|
||||
val legacyColor = getLegacyColor(index, 0)
|
||||
return if (legacyColor == 0) 0 else context.getColor(legacyColor)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@ColorRes
|
||||
fun getLegacyColor(index: Int, def: Int): Int {
|
||||
return when (index) {
|
||||
0 -> R.color.blue_grey_500
|
||||
1 -> R.color.grey_900
|
||||
2 -> R.color.red_500
|
||||
3 -> R.color.pink_500
|
||||
4 -> R.color.purple_500
|
||||
5 -> R.color.deep_purple_500
|
||||
6 -> R.color.indigo_500
|
||||
7 -> R.color.blue_500
|
||||
8 -> R.color.light_blue_500
|
||||
9 -> R.color.cyan_500
|
||||
10 -> R.color.teal_500
|
||||
11 -> R.color.green_500
|
||||
12 -> R.color.light_green_500
|
||||
13 -> R.color.lime_500
|
||||
14 -> R.color.yellow_500
|
||||
15 -> R.color.amber_500
|
||||
16 -> R.color.orange_500
|
||||
17 -> R.color.deep_orange_500
|
||||
18 -> R.color.brown_500
|
||||
19 -> R.color.grey_500
|
||||
20 -> R.color.white_100
|
||||
else -> def
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue