mirror of https://github.com/tasks/tasks
Use non-blocking daos in json importer
parent
523893a2d9
commit
e65a855b02
@ -1,59 +0,0 @@
|
|||||||
package org.tasks.backup;
|
|
||||||
|
|
||||||
import android.app.backup.BackupAgentHelper;
|
|
||||||
import android.app.backup.BackupDataInput;
|
|
||||||
import android.app.backup.FileBackupHelper;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import com.todoroo.astrid.backup.BackupConstants;
|
|
||||||
import dagger.hilt.EntryPoint;
|
|
||||||
import dagger.hilt.InstallIn;
|
|
||||||
import dagger.hilt.android.EntryPointAccessors;
|
|
||||||
import dagger.hilt.android.components.ApplicationComponent;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
public class TasksBackupAgent extends BackupAgentHelper {
|
|
||||||
|
|
||||||
@EntryPoint
|
|
||||||
@InstallIn(ApplicationComponent.class)
|
|
||||||
interface TasksBackupAgentEntryPoint {
|
|
||||||
TasksJsonImporter getTasksJsonImporter();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String BACKUP_KEY = "backup";
|
|
||||||
|
|
||||||
private TasksJsonImporter importer;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
TasksBackupAgentEntryPoint hilt =
|
|
||||||
EntryPointAccessors.fromApplication(getApplicationContext(), TasksBackupAgentEntryPoint.class);
|
|
||||||
importer = hilt.getTasksJsonImporter();
|
|
||||||
|
|
||||||
addHelper(BACKUP_KEY, new FileBackupHelper(this, BackupConstants.INTERNAL_BACKUP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
|
|
||||||
throws IOException {
|
|
||||||
super.onRestore(data, appVersionCode, newState);
|
|
||||||
|
|
||||||
File backup =
|
|
||||||
new File(
|
|
||||||
String.format(
|
|
||||||
"%s/%s", getFilesDir().getAbsolutePath(), BackupConstants.INTERNAL_BACKUP));
|
|
||||||
|
|
||||||
if (backup.exists()) {
|
|
||||||
importer.importTasks(this, Uri.fromFile(backup), null);
|
|
||||||
} else {
|
|
||||||
Timber.w("%s not found", backup.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onQuotaExceeded(long backupDataBytes, long quotaBytes) {
|
|
||||||
Timber.e("onQuotaExceeded(%s, %s)", backupDataBytes, quotaBytes);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,54 @@
|
|||||||
|
package org.tasks.backup
|
||||||
|
|
||||||
|
import android.app.backup.BackupAgentHelper
|
||||||
|
import android.app.backup.BackupDataInput
|
||||||
|
import android.app.backup.FileBackupHelper
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.ParcelFileDescriptor
|
||||||
|
import com.todoroo.astrid.backup.BackupConstants
|
||||||
|
import dagger.hilt.EntryPoint
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.EntryPointAccessors
|
||||||
|
import dagger.hilt.android.components.ApplicationComponent
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
class TasksBackupAgent : BackupAgentHelper() {
|
||||||
|
@EntryPoint
|
||||||
|
@InstallIn(ApplicationComponent::class)
|
||||||
|
internal interface TasksBackupAgentEntryPoint {
|
||||||
|
val tasksJsonImporter: TasksJsonImporter
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var importer: TasksJsonImporter
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
val hilt = EntryPointAccessors.fromApplication(applicationContext, TasksBackupAgentEntryPoint::class.java)
|
||||||
|
importer = hilt.tasksJsonImporter
|
||||||
|
addHelper(BACKUP_KEY, FileBackupHelper(this, BackupConstants.INTERNAL_BACKUP))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun onRestore(data: BackupDataInput, appVersionCode: Int, newState: ParcelFileDescriptor) {
|
||||||
|
super.onRestore(data, appVersionCode, newState)
|
||||||
|
val backup = File(String.format(
|
||||||
|
"%s/%s", filesDir.absolutePath, BackupConstants.INTERNAL_BACKUP))
|
||||||
|
if (backup.exists()) {
|
||||||
|
runBlocking {
|
||||||
|
importer.importTasks(this@TasksBackupAgent, Uri.fromFile(backup), null)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Timber.w("%s not found", backup.absolutePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQuotaExceeded(backupDataBytes: Long, quotaBytes: Long) {
|
||||||
|
Timber.e("onQuotaExceeded(%s, %s)", backupDataBytes, quotaBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val BACKUP_KEY = "backup"
|
||||||
|
}
|
||||||
|
}
|
@ -1,95 +0,0 @@
|
|||||||
package org.tasks.dialogs;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.app.ProgressDialog;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import androidx.fragment.app.DialogFragment;
|
|
||||||
import com.todoroo.andlib.utility.DialogUtilities;
|
|
||||||
import com.todoroo.astrid.backup.TasksXmlImporter;
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import org.tasks.R;
|
|
||||||
import org.tasks.backup.TasksJsonImporter;
|
|
||||||
import org.tasks.backup.TasksJsonImporter.ImportResult;
|
|
||||||
import org.tasks.ui.Toaster;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
public class ImportTasksDialog extends DialogFragment {
|
|
||||||
|
|
||||||
private static final String EXTRA_URI = "extra_uri";
|
|
||||||
private static final String EXTRA_EXTENSION = "extra_extension";
|
|
||||||
|
|
||||||
@Inject TasksXmlImporter xmlImporter;
|
|
||||||
@Inject TasksJsonImporter jsonImporter;
|
|
||||||
@Inject DialogBuilder dialogBuilder;
|
|
||||||
@Inject Activity context;
|
|
||||||
@Inject Toaster toaster;
|
|
||||||
|
|
||||||
public static ImportTasksDialog newImportTasksDialog(Uri data, String extension) {
|
|
||||||
ImportTasksDialog importTasksDialog = new ImportTasksDialog();
|
|
||||||
Bundle args = new Bundle();
|
|
||||||
args.putParcelable(EXTRA_URI, data);
|
|
||||||
args.putString(EXTRA_EXTENSION, extension);
|
|
||||||
importTasksDialog.setArguments(args);
|
|
||||||
return importTasksDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
|
||||||
Bundle arguments = getArguments();
|
|
||||||
Uri data = arguments.getParcelable(EXTRA_URI);
|
|
||||||
String extension = arguments.getString(EXTRA_EXTENSION);
|
|
||||||
ProgressDialog progressDialog = dialogBuilder.newProgressDialog();
|
|
||||||
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
|
||||||
progressDialog.setCancelable(false);
|
|
||||||
progressDialog.setIndeterminate(true);
|
|
||||||
progressDialog.show();
|
|
||||||
setCancelable(false);
|
|
||||||
switch (extension) {
|
|
||||||
case "json":
|
|
||||||
Handler handler = new Handler();
|
|
||||||
new Thread(
|
|
||||||
() -> {
|
|
||||||
ImportResult result =
|
|
||||||
jsonImporter.importTasks(getActivity(), data, progressDialog);
|
|
||||||
handler.post(() -> {
|
|
||||||
if (progressDialog.isShowing()) {
|
|
||||||
DialogUtilities.dismissDialog((Activity) context, progressDialog);
|
|
||||||
}
|
|
||||||
showSummary(result);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.start();
|
|
||||||
break;
|
|
||||||
case "xml":
|
|
||||||
xmlImporter.importTasks(getActivity(), data, progressDialog);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new RuntimeException("Invalid extension: " + extension);
|
|
||||||
}
|
|
||||||
return progressDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showSummary(ImportResult result) {
|
|
||||||
Resources r = context.getResources();
|
|
||||||
dialogBuilder
|
|
||||||
.newDialog(R.string.import_summary_title)
|
|
||||||
.setMessage(
|
|
||||||
context.getString(
|
|
||||||
R.string.import_summary_message,
|
|
||||||
"",
|
|
||||||
r.getQuantityString(R.plurals.Ntasks, result.getTaskCount(), result.getTaskCount()),
|
|
||||||
r.getQuantityString(
|
|
||||||
R.plurals.Ntasks,
|
|
||||||
result.getImportCount(),
|
|
||||||
result.getImportCount()),
|
|
||||||
r.getQuantityString(R.plurals.Ntasks, result.getSkipCount(), result.getSkipCount()),
|
|
||||||
r.getQuantityString(R.plurals.Ntasks, 0, 0)))
|
|
||||||
.setPositiveButton(android.R.string.ok, (dialog, id) -> dialog.dismiss())
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,90 @@
|
|||||||
|
package org.tasks.dialogs
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.app.ProgressDialog
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.todoroo.astrid.backup.TasksXmlImporter
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.NonCancellable
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.tasks.R
|
||||||
|
import org.tasks.backup.TasksJsonImporter
|
||||||
|
import org.tasks.backup.TasksJsonImporter.ImportResult
|
||||||
|
import org.tasks.ui.Toaster
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class ImportTasksDialog : DialogFragment() {
|
||||||
|
@Inject lateinit var xmlImporter: TasksXmlImporter
|
||||||
|
@Inject lateinit var jsonImporter: TasksJsonImporter
|
||||||
|
@Inject lateinit var dialogBuilder: DialogBuilder
|
||||||
|
@Inject lateinit var context: Activity
|
||||||
|
@Inject lateinit var toaster: Toaster
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
val arguments = requireArguments()
|
||||||
|
val data = arguments.getParcelable<Uri>(EXTRA_URI)
|
||||||
|
val extension = arguments.getString(EXTRA_EXTENSION)
|
||||||
|
val progressDialog = dialogBuilder.newProgressDialog()
|
||||||
|
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER)
|
||||||
|
progressDialog.setCancelable(false)
|
||||||
|
progressDialog.isIndeterminate = true
|
||||||
|
progressDialog.show()
|
||||||
|
isCancelable = false
|
||||||
|
when (extension) {
|
||||||
|
"json" -> {
|
||||||
|
val activity = requireActivity()
|
||||||
|
lifecycleScope.launch {
|
||||||
|
val result = withContext(NonCancellable) {
|
||||||
|
jsonImporter.importTasks(activity, data, progressDialog)
|
||||||
|
}
|
||||||
|
if (progressDialog.isShowing) {
|
||||||
|
progressDialog.dismiss()
|
||||||
|
}
|
||||||
|
showSummary(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"xml" -> xmlImporter.importTasks(activity, data, progressDialog)
|
||||||
|
else -> throw RuntimeException("Invalid extension: $extension")
|
||||||
|
}
|
||||||
|
return progressDialog
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showSummary(result: ImportResult) {
|
||||||
|
val r = requireContext().resources
|
||||||
|
dialogBuilder
|
||||||
|
.newDialog(R.string.import_summary_title)
|
||||||
|
.setMessage(
|
||||||
|
r.getString(
|
||||||
|
R.string.import_summary_message,
|
||||||
|
"",
|
||||||
|
r.getQuantityString(R.plurals.Ntasks, result.taskCount, result.taskCount),
|
||||||
|
r.getQuantityString(
|
||||||
|
R.plurals.Ntasks,
|
||||||
|
result.importCount,
|
||||||
|
result.importCount),
|
||||||
|
r.getQuantityString(R.plurals.Ntasks, result.skipCount, result.skipCount),
|
||||||
|
r.getQuantityString(R.plurals.Ntasks, 0, 0)))
|
||||||
|
.setPositiveButton(android.R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val EXTRA_URI = "extra_uri"
|
||||||
|
private const val EXTRA_EXTENSION = "extra_extension"
|
||||||
|
|
||||||
|
fun newImportTasksDialog(data: Uri?, extension: String?): ImportTasksDialog {
|
||||||
|
val importTasksDialog = ImportTasksDialog()
|
||||||
|
val args = Bundle()
|
||||||
|
args.putParcelable(EXTRA_URI, data)
|
||||||
|
args.putString(EXTRA_EXTENSION, extension)
|
||||||
|
importTasksDialog.arguments = args
|
||||||
|
return importTasksDialog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue