Import backup file in two passes

Import non-task data before loading tasks
pull/3565/head
Alex Baker 7 months ago
parent 93674075cb
commit 4c01ab2e66

@ -15,6 +15,8 @@ import com.todoroo.astrid.service.Upgrader.Companion.V12_4
import com.todoroo.astrid.service.Upgrader.Companion.V12_8 import com.todoroo.astrid.service.Upgrader.Companion.V12_8
import com.todoroo.astrid.service.Upgrader.Companion.V6_4 import com.todoroo.astrid.service.Upgrader.Companion.V6_4
import com.todoroo.astrid.service.Upgrader.Companion.getAndroidColor import com.todoroo.astrid.service.Upgrader.Companion.getAndroidColor
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.tasks.LocalBroadcastManager import org.tasks.LocalBroadcastManager
@ -85,9 +87,37 @@ class TasksJsonImporter @Inject constructor(
handler.post { progressDialog.setMessage(message) } handler.post { progressDialog.setMessage(message) }
} }
suspend fun importTasks(context: Context, backupFile: Uri?, progressDialog: ProgressDialog?): ImportResult { suspend fun importTasks(
context: Context,
backupFile: Uri?,
progressDialog: ProgressDialog?
): ImportResult = withContext(Dispatchers.IO) {
Timber.d("Importing backup file $backupFile") Timber.d("Importing backup file $backupFile")
val handler = Handler(context.mainLooper) try {
val version = importMetadata(context, backupFile)
importTasks(context, backupFile, progressDialog, version)
if (version < Upgrader.V8_2) {
val themeIndex = preferences.getInt(R.string.p_theme_color, 7)
preferences.setInt(
R.string.p_theme_color,
getAndroidColor(context, themeIndex))
}
if (version < Upgrader.V9_6) {
taskMover.migrateLocalTasks()
}
Timber.d("Updating parents")
caldavDao.updateParents()
} catch (e: IOException) {
Timber.e(e)
}
localBroadcastManager.broadcastRefresh()
result
}
private suspend fun importMetadata(
context: Context,
backupFile: Uri?,
): Int {
val `is`: InputStream? = try { val `is`: InputStream? = try {
context.contentResolver.openInputStream(backupFile!!) context.contentResolver.openInputStream(backupFile!!)
} catch (e: FileNotFoundException) { } catch (e: FileNotFoundException) {
@ -97,7 +127,6 @@ class TasksJsonImporter @Inject constructor(
val reader = JsonReader(bufferedReader) val reader = JsonReader(bufferedReader)
reader.isLenient = true reader.isLenient = true
val ignoreKeys = ignorePrefs.map { context.getString(it) } val ignoreKeys = ignorePrefs.map { context.getString(it) }
try {
reader.beginObject() reader.beginObject()
var version = 0 var version = 0
while (reader.hasNext()) { while (reader.hasNext()) {
@ -108,16 +137,6 @@ class TasksJsonImporter @Inject constructor(
reader.beginObject() reader.beginObject()
while (reader.hasNext()) { while (reader.hasNext()) {
when (val element = reader.nextName()) { when (val element = reader.nextName()) {
"tasks" -> {
reader.forEach<TaskBackup> { backup ->
result.taskCount++
setProgressMessage(
handler,
progressDialog,
context.getString(R.string.import_progress_read, result.taskCount))
importTask(backup, version)
}
}
"places" -> reader.forEach<Place> { place -> "places" -> reader.forEach<Place> { place ->
if (locationDao.getByUid(place.uid!!) == null) { if (locationDao.getByUid(place.uid!!) == null) {
locationDao.insert( locationDao.insert(
@ -239,25 +258,61 @@ class TasksJsonImporter @Inject constructor(
} }
} }
} }
if (version < Upgrader.V8_2) { reader.close()
val themeIndex = preferences.getInt(R.string.p_theme_color, 7) bufferedReader.close()
preferences.setInt( `is`.close()
R.string.p_theme_color, return version
getAndroidColor(context, themeIndex)) }
private suspend fun importTasks(
context: Context,
backupFile: Uri?,
progressDialog: ProgressDialog?,
version: Int,
) {
val handler = Handler(context.mainLooper)
val `is`: InputStream? = try {
context.contentResolver.openInputStream(backupFile!!)
} catch (e: FileNotFoundException) {
throw IllegalStateException(e)
}
val bufferedReader = `is`!!.bufferedReader()
val reader = JsonReader(bufferedReader)
reader.isLenient = true
reader.beginObject()
while (reader.hasNext()) {
when (val name = reader.nextName()) {
"data" -> {
reader.beginObject()
while (reader.hasNext()) {
when (val element = reader.nextName()) {
"tasks" -> {
reader.forEach<TaskBackup> { backup ->
result.taskCount++
setProgressMessage(
handler,
progressDialog,
context.getString(R.string.import_progress_read, result.taskCount))
importTask(backup, version)
}
}
else -> {
Timber.w("Skipping $element")
reader.skipValue()
}
}
}
reader.endObject()
}
else -> {
Timber.w("Skipping $name")
reader.skipValue()
}
} }
if (version < Upgrader.V9_6) {
taskMover.migrateLocalTasks()
} }
Timber.d("Updating parents")
caldavDao.updateParents()
reader.close() reader.close()
bufferedReader.close() bufferedReader.close()
`is`!!.close() `is`.close()
} catch (e: IOException) {
Timber.e(e)
}
localBroadcastManager.broadcastRefresh()
return result
} }
private suspend fun importTask(backup: TaskBackup, version: Int) { private suspend fun importTask(backup: TaskBackup, version: Int) {

Loading…
Cancel
Save