Update microsoft converter

Add due dates, creation dates, and modification dates
pull/2412/head
Alex Baker 11 months ago
parent 166635e18b
commit ee82f683bd

@ -4,7 +4,9 @@ import com.todoroo.astrid.data.Task
import org.tasks.data.CaldavTask
import org.tasks.data.TagData
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils.startOfDay
import java.text.SimpleDateFormat
import java.time.ZonedDateTime
import java.util.Locale
import java.util.TimeZone
@ -17,29 +19,19 @@ object MicrosoftConverter {
defaultPriority: Int,
) {
title = remote.title
notes = remote.body?.content?.takeIf { it.isNotBlank() }
notes = remote.body?.content?.takeIf { remote.body.contentType == "text" && it.isNotBlank() }
priority = when {
remote.importance == Tasks.Task.Importance.high -> Task.Priority.HIGH
priority != Task.Priority.HIGH -> priority
defaultPriority != Task.Priority.HIGH -> defaultPriority
else -> Task.Priority.NONE
}
completionDate = remote.completedDateTime
?.let {
val tz = TimeZone.getTimeZone(it.timeZone)
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.ssssss", Locale.US)
.apply { timeZone = tz }
.parse(it.dateTime)
?.time
?.let { ts -> DateTime(ts, tz).toLocal().millis }
?: System.currentTimeMillis()
}
?: 0L
completionDate = remote.completedDateTime.toLong(System.currentTimeMillis())
dueDate = remote.dueDateTime.toLong(0L)
creationDate = remote.createdDateTime.parseDateTime()
modificationDate = remote.lastModifiedDateTime.parseDateTime()
// checklist to subtasks
// due date
// repeat
// modification date
// creation date
// sync reminders
// sync files
}
@ -65,15 +57,44 @@ object MicrosoftConverter {
Tasks.Task.Status.notStarted
},
categories = tags.map { it.name!! }.takeIf { it.isNotEmpty() },
dueDateTime = if (hasDueDate()) {
Tasks.Task.DateTime(
dateTime = DateTime(dueDate.startOfDay()).toUTC().toString("yyyy-MM-dd'T'HH:mm:ss.SSS0000"),
timeZone = "UTC"
)
} else {
null
},
lastModifiedDateTime = DateTime(modificationDate).toUTC().toString("yyyy-MM-dd'T'HH:mm:ss.SSS0000'Z'"),
createdDateTime = DateTime(creationDate).toUTC().toString("yyyy-MM-dd'T'HH:mm:ss.SSS0000'Z'"),
completedDateTime = if (isCompleted) {
Tasks.Task.CompletedDateTime(
Tasks.Task.DateTime(
dateTime = DateTime(completionDate).toUTC()
.toString("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS"),
timeZone = "UTC",
)
} else {
null
}
},
// isReminderOn =
)
}
private fun String?.parseDateTime(): Long =
this
?.let { ZonedDateTime.parse(this).toInstant().toEpochMilli() }
?: System.currentTimeMillis()
private fun Tasks.Task.DateTime?.toLong(default: Long): Long =
this
?.let {
val tz = TimeZone.getTimeZone(it.timeZone)
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.ssssss", Locale.US)
.apply { timeZone = tz }
.parse(it.dateTime)
?.time
?.let { ts -> DateTime(ts, tz).toLocal().millis }
?: default
}
?: 0L
}

@ -18,7 +18,8 @@ data class Tasks(
val isReminderOn: Boolean = false,
val createdDateTime: String? = null,
val lastModifiedDateTime: String? = null,
val completedDateTime: CompletedDateTime? = null,
val completedDateTime: DateTime? = null,
val dueDateTime: DateTime? = null,
val linkedResources: List<LinkedResource>? = null,
@field:Json(name = "@removed") val removed: Removed? = null,
) {
@ -38,7 +39,7 @@ data class Tasks(
val reason: String,
)
data class CompletedDateTime(
data class DateTime(
val dateTime: String,
val timeZone: String,
)

@ -66,4 +66,34 @@ class ConvertFromMicrosoftTests {
assertEquals(DateTime(2022, 9, 18, 0, 0).millis, local.completionDate)
}
}
}
@Test
fun parseDueDate() {
val (local, _) = TestUtilities.mstodo("microsoft/basic_task_with_due_date.txt")
withTZ("America/Chicago") {
assertEquals(DateTime(2023, 7, 19, 0, 0).millis, local.dueDate)
}
}
@Test
fun parseCreationDate() {
val (local, _) = TestUtilities.mstodo("microsoft/basic_task_with_due_date.txt")
withTZ("America/Chicago") {
assertEquals(
DateTime(2023, 7, 19, 23, 20, 56, 9).millis,
local.creationDate
)
}
}
@Test
fun parseModificationDate() {
val (local, _) = TestUtilities.mstodo("microsoft/basic_task_with_due_date.txt")
withTZ("America/Chicago") {
assertEquals(
DateTime(2023, 7, 19, 23, 21, 6, 269).millis,
local.modificationDate
)
}
}
}

@ -5,12 +5,14 @@ import com.todoroo.astrid.data.Task
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test
import org.tasks.TestUtilities.withTZ
import org.tasks.makers.CaldavTaskMaker.REMOTE_ID
import org.tasks.makers.CaldavTaskMaker.newCaldavTask
import org.tasks.makers.TagDataMaker.NAME
import org.tasks.makers.TagDataMaker.newTagData
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.makers.TaskMaker.DESCRIPTION
import org.tasks.makers.TaskMaker.DUE_TIME
import org.tasks.makers.TaskMaker.PRIORITY
import org.tasks.makers.TaskMaker.TITLE
import org.tasks.makers.TaskMaker.newTask
@ -112,4 +114,45 @@ class ConvertToMicrosoftTests {
)
assertEquals(listOf("tag1", "tag2"), remote.categories)
}
@Test
fun setCreationTime() {
withTZ("America/Chicago") {
val remote = Task(
creationDate = DateTime(2023, 7, 21, 0, 42, 13, 475).millis,
).toRemote(newCaldavTask(), emptyList())
assertEquals(
"2023-07-21T05:42:13.4750000Z",
remote.createdDateTime
)
}
}
@Test
fun setModificationTime() {
withTZ("America/Chicago") {
val remote = Task(
modificationDate = DateTime(2023, 7, 21, 0, 49, 4, 3).millis,
).toRemote(newCaldavTask(), emptyList())
assertEquals(
"2023-07-21T05:49:04.0030000Z",
remote.lastModifiedDateTime
)
}
}
@Test
fun setDueDateTime() {
withTZ("America/Chicago") {
val remote = newTask(
with(
DUE_TIME,
DateTime(2023, 7, 21, 13, 30)
)
)
.toRemote(newCaldavTask(), emptyList())
assertEquals("2023-07-21T05:00:00.0000000", remote.dueDateTime?.dateTime)
assertEquals("UTC", remote.dueDateTime?.timeZone)
}
}
}

@ -0,0 +1,27 @@
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(todoTask)",
"@odata.deltaLink": "https://graph.microsoft.com/v1.0/me/todo/lists/AQMkADAwATNiZmYAZC04OABiMC0xZDlkLTAwAi0wMAoALgAAA8dKmrSa60tBjeiKoPukmoQBAEkTxp6Wx2BEtV1vFJWK7bIAAAIBEgAAAA==/tasks/delta?$deltatoken=l7WI41swwioT5csv4k99ngHvnDU_spnidrOYzb78--8L_CvTDIAkbXl6MuXT-elf4jUsC_1pCyBUISy7PuGdnyLUQmoalQs1lf0G56o9TRE.2lrmzz4U-RHVGMXDGcA8SE7GeYKapG_mWFDPJgqZsjo",
"value": [
{
"@odata.type": "#microsoft.graph.todoTask",
"@odata.etag": "W/\"SRPGnpbHYES1XW8UlYrtsgAGXHw+qw==\"",
"importance": "high",
"isReminderOn": false,
"status": "notStarted",
"title": "Test",
"createdDateTime": "2023-07-20T04:20:56.0091837Z",
"lastModifiedDateTime": "2023-07-20T04:21:06.2690268Z",
"hasAttachments": false,
"categories": [],
"id": "AQMkADAwATNiZmYAZC04OABiMC0xZDlkLTAwAi0wMAoARgAAA8dKmrSa60tBjeiKoPukmoQHAEkTxp6Wx2BEtV1vFJWK7bIAAAIBEgAAAEkTxp6Wx2BEtV1vFJWK7bIABlxbFkEAAAA=",
"body": {
"content": "",
"contentType": "text"
},
"dueDateTime": {
"dateTime": "2023-07-19T05:00:00.0000000",
"timeZone": "UTC"
}
}
]
}
Loading…
Cancel
Save