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