Update Google Drive backup settings

Display timestamp of last backup
pull/1122/head
Alex Baker 5 years ago
parent 345346b1e9
commit 60e4ca2866

@ -47,9 +47,10 @@ class DriveInvoker @Inject constructor(
}
@Throws(IOException::class)
suspend fun getFilesByPrefix(folderId: String?, prefix: String?): List<File> {
suspend fun getFilesByPrefix(folderId: String?, vararg prefix: String?): List<File> {
val namePredicate = prefix.joinToString(" or ") { "name contains '$it'" }
val query = String.format(
"'%s' in parents and name contains '%s' and trashed = false and mimeType != '%s'",
"'%s' in parents and ($namePredicate) and trashed = false and mimeType != '%s'",
folderId, prefix, MIME_FOLDER)
return execute(
service
@ -59,6 +60,7 @@ class DriveInvoker @Inject constructor(
.setSpaces("drive")
.setFields("files(id, modifiedTime)"))
?.files
?.sortedWith(DRIVE_FILE_COMPARATOR)
?: emptyList()
}
@ -139,5 +141,8 @@ class DriveInvoker @Inject constructor(
companion object {
private const val MIME_FOLDER = "application/vnd.google-apps.folder"
private val DRIVE_FILE_COMPARATOR = Comparator<File> { f1, f2 ->
f2.modifiedTime.value.compareTo(f1.modifiedTime.value)
}
}
}

@ -19,7 +19,6 @@ import java.io.IOException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.util.*
import javax.net.ssl.SSLException
class DriveUploader @WorkerInject constructor(
@ -37,10 +36,12 @@ class DriveUploader @WorkerInject constructor(
preferences.setString(R.string.p_google_drive_backup_folder, folder.id)
drive.createFile(folder.id, uri)
if (inputData.getBoolean(EXTRA_PURGE, false)) {
val files = drive.getFilesByPrefix(folder.id, "auto.")
for (file in getDeleteList(files)) {
drive
.getFilesByPrefix(folder.id, "auto.")
.drop(BackupWork.DAYS_TO_KEEP_BACKUP)
.forEach {
try {
drive.delete(file)
drive.delete(it)
} catch (e: GoogleJsonResponseException) {
if (e.statusCode == 404) {
Timber.e(e)
@ -89,17 +90,11 @@ class DriveUploader @WorkerInject constructor(
private const val FOLDER_NAME = "Tasks Backups"
private const val EXTRA_URI = "extra_uri"
private const val EXTRA_PURGE = "extra_purge"
private val DRIVE_FILE_COMPARATOR = Comparator<File> { f1, f2 ->
f2.modifiedTime.value.compareTo(f1.modifiedTime.value)
}
fun getInputData(uri: Uri, purge: Boolean) =
Data.Builder()
.putString(EXTRA_URI, uri.toString())
.putBoolean(EXTRA_PURGE, purge)
.build()
private fun getDeleteList(files: List<File>) =
files.sortedWith(DRIVE_FILE_COMPARATOR).drop(BackupWork.DAYS_TO_KEEP_BACKUP)
}
}

@ -3,15 +3,18 @@ package org.tasks.preferences.fragments
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import androidx.preference.SwitchPreferenceCompat
import com.google.api.services.drive.DriveScopes
import com.todoroo.andlib.utility.DateUtilities
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.tasks.PermissionUtil
import org.tasks.R
import org.tasks.dialogs.ExportTasksDialog
import org.tasks.dialogs.ImportTasksDialog
import org.tasks.drive.DriveInvoker
import org.tasks.drive.DriveLoginActivity
import org.tasks.files.FileHelper
import org.tasks.gtasks.GoogleAccountManager
@ -37,6 +40,7 @@ class Backups : InjectingPreferenceFragment() {
@Inject lateinit var toaster: Toaster
@Inject lateinit var googleAccountManager: GoogleAccountManager
@Inject lateinit var locale: Locale
@Inject lateinit var driveInvoker: DriveInvoker
override fun getPreferenceXml() = R.xml.preferences_backups
@ -58,12 +62,36 @@ class Backups : InjectingPreferenceFragment() {
.show(parentFragmentManager, FRAG_TAG_EXPORT_TASKS)
false
}
findPreference(R.string.google_drive_backup)
.setOnPreferenceChangeListener(this@Backups::onGoogleDriveCheckChanged)
findPreference(R.string.p_google_drive_backup_account)
.setOnPreferenceClickListener {
requestGoogleDriveLogin()
false
}
}
override fun onResume() {
super.onResume()
updateGoogleDriveCheckbox()
updateDriveAccount()
val driveBackup = findPreference(R.string.google_drive_backup) as SwitchPreferenceCompat
driveBackup.isChecked = driveAccount != null
if (driveAccount != null) {
lifecycleScope.launch {
val folder = preferences.getStringValue(R.string.p_google_drive_backup_folder)
val files = driveInvoker.getFilesByPrefix(folder, "auto.", "user.")
driveBackup.summary = getString(
R.string.last_backup,
if (files.isEmpty()) {
getString(R.string.last_backup_never)
} else {
DateUtilities.getLongDateStringWithTime(files[0].modifiedTime.value, locale)
})
}
}
val lastBackup = preferences.getLong(R.string.p_backups_android_backup_last, 0L)
findPreference(R.string.p_backups_android_backup_enabled).summary =
@ -123,36 +151,47 @@ class Backups : InjectingPreferenceFragment() {
}
}
private fun updateGoogleDriveCheckbox() {
private val driveAccount: String?
get() {
val account = preferences.getStringValue(R.string.p_google_drive_backup_account)
val pref = findPreference(R.string.google_drive_backup) as SwitchPreferenceCompat
pref.isChecked = preferences.getBoolean(R.string.p_google_drive_backup, false)
val enabled = !account.isNullOrBlank()
&& preferences.getBoolean(R.string.p_google_drive_backup, false)
&& googleAccountManager.canAccessAccount(account)
&& !preferences.alreadyNotified(account, DriveScopes.DRIVE_FILE)
pref.summary = if (pref.isChecked) account else null
findPreference(R.string.google_drive_backup)
.setOnPreferenceChangeListener(this@Backups::onGoogleDriveCheckChanged)
return if (enabled) account else null
}
private fun onGoogleDriveCheckChanged(preference: Preference, newValue: Any?) = when {
newValue as Boolean -> {
if (permissionRequestor.requestAccountPermissions()) {
requestGoogleDriveLogin()
}
false
}
else -> {
preference.summary = null
preferences.setString(R.string.p_google_drive_backup_account, null)
updateDriveAccount()
true
}
}
private fun updateDriveAccount() {
val account = driveAccount
val pref = findPreference(R.string.p_google_drive_backup_account)
pref.isEnabled = account != null
pref.summary =
account
?.takeIf { it.isNotBlank() }
?: getString(R.string.none)
}
private fun requestGoogleDriveLogin() {
if (permissionRequestor.requestAccountPermissions()) {
startActivityForResult(
Intent(context, DriveLoginActivity::class.java),
REQUEST_DRIVE_BACKUP
)
}
}
private fun initializeBackupDirectory() {
findPreference(R.string.p_backup_dir)

@ -642,4 +642,5 @@ File %1$s contained %2$s.\n\n
<string name="last_backup">Last backup: %s</string>
<string name="last_backup_never">never</string>
<string name="device_settings">Device settings</string>
<string name="account">Account</string>
</resources>

@ -6,10 +6,6 @@
android:key="@string/p_backup_dir"
android:title="@string/backup_directory" />
<SwitchPreferenceCompat
android:key="@string/google_drive_backup"
android:title="@string/google_drive_backup" />
<Preference
android:key="@string/backup_BAc_import"
android:title="@string/backup_BAc_import" />
@ -18,6 +14,20 @@
android:key="@string/backup_BAc_export"
android:title="@string/backup_BAc_export" />
<PreferenceCategory
android:title="@string/google_drive_backup">
<SwitchPreferenceCompat
android:key="@string/google_drive_backup"
android:title="@string/enabled" />
<Preference
android:key="@string/p_google_drive_backup_account"
android:title="@string/account"
android:summary="@string/none"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/android_auto_backup">

Loading…
Cancel
Save