From 84cbec548407b7a63dca2e26e9c3c81a4a9bba8e Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Tue, 8 Jan 2019 15:20:08 -0600 Subject: [PATCH] Google Drive uploader changes * Fix auto backup purging * Add random delay for midnight backups so they don't all upload at once --- .../java/com/todoroo/astrid/dao/TaskDao.java | 18 ++++++---- .../org/tasks/backup/TasksJsonExporter.java | 2 +- .../java/org/tasks/drive/DriveInvoker.java | 9 ++++- .../main/java/org/tasks/jobs/BackupWork.java | 35 ++----------------- .../java/org/tasks/jobs/DriveUploader.java | 29 +++++++++++++-- .../main/java/org/tasks/jobs/WorkManager.java | 15 ++++---- 6 files changed, 58 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java b/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java index 41b7b4bbc..a507c66d1 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java +++ b/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java @@ -5,12 +5,8 @@ */ package com.todoroo.astrid.dao; -import static com.todoroo.andlib.utility.DateUtilities.now; - import android.database.Cursor; -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.Update; + import com.todoroo.andlib.data.Property; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Functions; @@ -19,12 +15,20 @@ import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.PermaSql; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.helper.UUIDHelper; -import java.util.ArrayList; -import java.util.List; + import org.tasks.BuildConfig; import org.tasks.jobs.WorkManager; + +import java.util.ArrayList; +import java.util.List; + +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.Update; import timber.log.Timber; +import static com.todoroo.andlib.utility.DateUtilities.now; + @Dao public abstract class TaskDao { diff --git a/app/src/main/java/org/tasks/backup/TasksJsonExporter.java b/app/src/main/java/org/tasks/backup/TasksJsonExporter.java index 7308b1be2..259ca2be5 100755 --- a/app/src/main/java/org/tasks/backup/TasksJsonExporter.java +++ b/app/src/main/java/org/tasks/backup/TasksJsonExporter.java @@ -153,7 +153,7 @@ public class TasksJsonExporter { OutputStream os = context.getContentResolver().openOutputStream(uri); doTasksExport(os, tasks); os.close(); - workManager.scheduleDriveUpload(uri); + workManager.scheduleDriveUpload(uri, exportType == ExportType.EXPORT_TYPE_SERVICE); } if (exportType == ExportType.EXPORT_TYPE_MANUAL) { diff --git a/app/src/main/java/org/tasks/drive/DriveInvoker.java b/app/src/main/java/org/tasks/drive/DriveInvoker.java index 16f06b1e2..7c12a32fc 100644 --- a/app/src/main/java/org/tasks/drive/DriveInvoker.java +++ b/app/src/main/java/org/tasks/drive/DriveInvoker.java @@ -67,7 +67,14 @@ public class DriveInvoker { String.format( "'%s' in parents and name contains '%s' and trashed = false and mimeType != '%s'", folderId, prefix, MIME_FOLDER); - return execute(service.files().list().setQ(query).setSpaces("drive")).getFiles(); + return execute( + service + .files() + .list() + .setQ(query) + .setSpaces("drive") + .setFields("files(id, modifiedTime)")) + .getFiles(); } public File createFolder(String name) throws IOException { diff --git a/app/src/main/java/org/tasks/jobs/BackupWork.java b/app/src/main/java/org/tasks/jobs/BackupWork.java index 833d9be5a..e49550fc9 100644 --- a/app/src/main/java/org/tasks/jobs/BackupWork.java +++ b/app/src/main/java/org/tasks/jobs/BackupWork.java @@ -4,7 +4,6 @@ import android.content.Context; import android.net.Uri; import com.google.common.base.Predicate; -import com.google.common.base.Strings; import org.tasks.R; import org.tasks.backup.TasksJsonExporter; @@ -15,7 +14,6 @@ import org.tasks.preferences.Preferences; import java.io.File; import java.io.FileFilter; -import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; @@ -43,10 +41,9 @@ public class BackupWork extends RepeatingWorker { (f1, f2) -> Long.compare(f2.lastModified(), f1.lastModified()); private static final Comparator DOCUMENT_FILE_COMPARATOR = (d1, d2) -> Long.compare(d2.lastModified(), d1.lastModified()); - private static final Comparator DRIVE_FILE_COMPARATOR = - (f1, f2) -> Long.compare(f2.getModifiedTime().getValue(), f1.getModifiedTime().getValue()); - private static final int DAYS_TO_KEEP_BACKUP = 7; + public static final int DAYS_TO_KEEP_BACKUP = 7; + @Inject @ForApplication Context context; @Inject TasksJsonExporter tasksJsonExporter; @Inject Preferences preferences; @@ -90,11 +87,6 @@ public class BackupWork extends RepeatingWorker { return newArrayList(skip(files, DAYS_TO_KEEP_BACKUP)); } - private static List getDeleteList(List files) { - Collections.sort(files, DRIVE_FILE_COMPARATOR); - return newArrayList(skip(files, DAYS_TO_KEEP_BACKUP)); - } - @Override protected void inject(JobComponent component) { component.inject(this); @@ -107,12 +99,6 @@ public class BackupWork extends RepeatingWorker { Timber.e(e); } - try { - deleteOldDriveBackups(); - } catch (Exception e) { - Timber.e(e); - } - try { tasksJsonExporter.exportTasks( context, TasksJsonExporter.ExportType.EXPORT_TYPE_SERVICE, null); @@ -143,21 +129,4 @@ public class BackupWork extends RepeatingWorker { break; } } - - private void deleteOldDriveBackups() throws IOException { - if (!preferences.getBoolean(R.string.p_google_drive_backup, false)) { - return; - } - - String folderId = preferences.getStringValue(R.string.p_google_drive_backup_folder); - - if (Strings.isNullOrEmpty(folderId)) { - return; - } - - List files = drive.getFilesByPrefix(folderId, "auto."); - for (com.google.api.services.drive.model.File file : getDeleteList(files)) { - drive.delete(file); - } - } } diff --git a/app/src/main/java/org/tasks/jobs/DriveUploader.java b/app/src/main/java/org/tasks/jobs/DriveUploader.java index 3336caaea..1b0dc01f7 100644 --- a/app/src/main/java/org/tasks/jobs/DriveUploader.java +++ b/app/src/main/java/org/tasks/jobs/DriveUploader.java @@ -15,6 +15,9 @@ import org.tasks.injection.JobComponent; import org.tasks.preferences.Preferences; import java.io.IOException; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; import javax.inject.Inject; @@ -22,18 +25,27 @@ import androidx.annotation.NonNull; import androidx.work.Data; import androidx.work.WorkerParameters; +import static com.google.common.collect.Iterables.skip; +import static com.google.common.collect.Lists.newArrayList; + public class DriveUploader extends InjectingWorker { private static final String FOLDER_NAME = "Tasks Backups"; private static final String EXTRA_URI = "extra_uri"; + private static final String EXTRA_PURGE = "extra_purge"; + private static final Comparator DRIVE_FILE_COMPARATOR = + (f1, f2) -> Long.compare(f2.getModifiedTime().getValue(), f1.getModifiedTime().getValue()); @Inject @ForApplication Context context; @Inject DriveInvoker drive; @Inject Preferences preferences; @Inject Tracker tracker; - static Data getInputData(Uri uri) { - return new Data.Builder().putString(EXTRA_URI, uri.toString()).build(); + static Data getInputData(Uri uri, boolean purge) { + return new Data.Builder() + .putString(EXTRA_URI, uri.toString()) + .putBoolean(EXTRA_PURGE, purge) + .build(); } public DriveUploader(@NonNull Context context, @NonNull WorkerParameters workerParams) { @@ -48,6 +60,14 @@ public class DriveUploader extends InjectingWorker { File folder = getFolder(); preferences.setString(R.string.p_google_drive_backup_folder, folder.getId()); drive.createFile(folder.getId(), uri); + + if (inputData.getBoolean(EXTRA_PURGE, false)) { + List files = drive.getFilesByPrefix(folder.getId(), "auto."); + for (File file : getDeleteList(files)) { + drive.delete(file); + } + } + return Result.SUCCESS; } catch (IOException e) { tracker.reportException(e); @@ -61,6 +81,11 @@ public class DriveUploader extends InjectingWorker { return file == null || file.getTrashed() ? drive.createFolder(FOLDER_NAME) : file; } + private static List getDeleteList(List files) { + Collections.sort(files, DRIVE_FILE_COMPARATOR); + return newArrayList(skip(files, BackupWork.DAYS_TO_KEEP_BACKUP)); + } + @Override protected void inject(JobComponent component) { component.inject(this); diff --git a/app/src/main/java/org/tasks/jobs/WorkManager.java b/app/src/main/java/org/tasks/jobs/WorkManager.java index 5a6e495a8..ccfc95ecf 100644 --- a/app/src/main/java/org/tasks/jobs/WorkManager.java +++ b/app/src/main/java/org/tasks/jobs/WorkManager.java @@ -20,6 +20,7 @@ import androidx.work.Worker; import com.google.common.primitives.Longs; import com.todoroo.astrid.data.Task; import java.util.List; +import java.util.Random; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; import javax.inject.Inject; @@ -149,16 +150,18 @@ public class WorkManager { Math.min(newDateTime(lastBackup).plusDays(1).getMillis(), midnight())); } - public void scheduleDriveUpload(Uri uri) { + public void scheduleDriveUpload(Uri uri, boolean purge) { if (!preferences.getBoolean(R.string.p_google_drive_backup, false)) { return; } - workManager.enqueue( - new Builder(DriveUploader.class) - .setInputData(DriveUploader.getInputData(uri)) - .setConstraints(getNetworkConstraints()) - .build()); + Builder builder = new Builder(DriveUploader.class) + .setInputData(DriveUploader.getInputData(uri, purge)) + .setConstraints(getNetworkConstraints()); + if (purge) { + builder.setInitialDelay(new Random().nextInt(3600), TimeUnit.SECONDS); + } + workManager.enqueue(builder.build()); } private Constraints getNetworkConstraints() {