moved google drive sync into app folder (not visible to user)
This commit is contained in:
parent
ce8baef9e5
commit
2dabdbdc39
|
@ -30,7 +30,7 @@ class GoogleDriveAuthActivity : BaseActivity(), GoogleApiClient.ConnectionCallba
|
|||
super.onCreate(savedInstanceState)
|
||||
|
||||
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestScopes(Scope(DriveScopes.DRIVE))
|
||||
.requestScopes(Scope(DriveScopes.DRIVE_APPDATA))
|
||||
.requestServerAuthCode(GoogleDriveSyncProviderInfo.WEB_CLIENT_ID, true)
|
||||
.build()
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ internal class GoogleDriveDraftsSyncAction(
|
|||
val drive: Drive
|
||||
) : FileBasedDraftsSyncAction<DriveFileInfo>(context) {
|
||||
|
||||
val draftsDirName = "Drafts"
|
||||
val draftsFolderName = "Drafts"
|
||||
val draftMimeType = "message/rfc822"
|
||||
|
||||
private lateinit var folderId: String
|
||||
|
@ -37,7 +37,8 @@ internal class GoogleDriveDraftsSyncAction(
|
|||
val file = if (driveId != null) {
|
||||
drive.files().performUpdate(driveId, filename, draftMimeType, stream = `is`, fileConfig = fileConfig)
|
||||
} else {
|
||||
drive.updateOrCreate(filename, draftMimeType, folderId, stream = `is`, fileConfig = fileConfig)
|
||||
drive.updateOrCreate(name = filename, mimeType = draftMimeType, parent = folderId,
|
||||
spaces = appDataFolderSpace, stream = `is`, fileConfig = fileConfig)
|
||||
}
|
||||
return DriveFileInfo(file.id, file.name, Date(file.modifiedTime.value))
|
||||
}
|
||||
|
@ -84,8 +85,7 @@ internal class GoogleDriveDraftsSyncAction(
|
|||
val result = ArrayList<DriveFileInfo>()
|
||||
var nextPageToken: String? = null
|
||||
do {
|
||||
val listResult = files.list().apply {
|
||||
this.fields = requiredFilesRequestFields
|
||||
val listResult = files.basicList(appDataFolderSpace).apply {
|
||||
this.q = "'$folderId' in parents and mimeType = '$draftMimeType' and trashed = false"
|
||||
if (nextPageToken != null) {
|
||||
this.pageToken = nextPageToken
|
||||
|
@ -102,7 +102,9 @@ internal class GoogleDriveDraftsSyncAction(
|
|||
}
|
||||
|
||||
override fun setup(): Boolean {
|
||||
folderId = drive.getFileOrCreate(draftsDirName, folderMimeType, conflictResolver = ::resolveFoldersConflict).id
|
||||
folderId = drive.getFileOrCreate(name = draftsFolderName, mimeType = folderMimeType,
|
||||
parent = appDataFolderName, spaces = appDataFolderSpace,
|
||||
conflictResolver = ::resolveFoldersConflict).id
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ internal class GoogleDriveFiltersDataSyncAction(
|
|||
private val files = drive.files()
|
||||
|
||||
override fun newLoadFromRemoteSession(): CloseableAny<File> {
|
||||
val file = drive.getFileOrNull(fileName, xmlMimeType, commonFolderId,
|
||||
val file = drive.getFileOrNull(name = fileName, mimeType = xmlMimeType,
|
||||
parent = commonFolderId, spaces = appDataFolderSpace,
|
||||
conflictResolver = ::resolveFilesConflict) ?: run {
|
||||
throw FileNotFoundException()
|
||||
}
|
||||
|
@ -64,7 +65,9 @@ internal class GoogleDriveFiltersDataSyncAction(
|
|||
|
||||
|
||||
override fun setup(): Boolean {
|
||||
commonFolderId = drive.getFileOrCreate("Common", folderMimeType, conflictResolver = ::resolveFoldersConflict).id
|
||||
commonFolderId = drive.getFileOrCreate(name = commonFolderName, mimeType = folderMimeType,
|
||||
parent = appDataFolderName, spaces = appDataFolderSpace,
|
||||
conflictResolver = ::resolveFoldersConflict).id
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ internal class GoogleDrivePreferencesValuesSyncAction(
|
|||
private val files = drive.files()
|
||||
|
||||
override fun newLoadFromRemoteSession(): CloseableAny<File> {
|
||||
val file = drive.getFileOrNull(fileName, xmlMimeType, commonFolderId,
|
||||
val file = drive.getFileOrNull(name = fileName, mimeType = xmlMimeType,
|
||||
parent = commonFolderId, spaces = appDataFolderSpace,
|
||||
conflictResolver = ::resolveFilesConflict) ?: run {
|
||||
throw FileNotFoundException()
|
||||
}
|
||||
|
@ -64,7 +65,9 @@ internal class GoogleDrivePreferencesValuesSyncAction(
|
|||
}
|
||||
|
||||
override fun setup(): Boolean {
|
||||
commonFolderId = drive.getFileOrCreate("Common", folderMimeType, conflictResolver = ::resolveFoldersConflict).id
|
||||
commonFolderId = drive.getFileOrCreate(name = commonFolderName, mimeType = folderMimeType,
|
||||
parent = appDataFolderName, spaces = appDataFolderSpace,
|
||||
conflictResolver = ::resolveFoldersConflict).id
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -21,17 +21,22 @@ internal const val folderMimeType = "application/vnd.google-apps.folder"
|
|||
internal const val xmlMimeType = "application/xml"
|
||||
internal const val requiredRequestFields = "id, name, parents, mimeType, modifiedTime"
|
||||
internal const val requiredFilesRequestFields = "files($requiredRequestFields)"
|
||||
internal const val commonFolderName = "Common"
|
||||
internal const val appDataFolderName = "appDataFolder"
|
||||
internal const val rootFolderName = "root"
|
||||
internal const val appDataFolderSpace = appDataFolderName
|
||||
|
||||
internal fun Drive.getFileOrNull(
|
||||
name: String,
|
||||
mimeType: String?,
|
||||
parent: String? = "root",
|
||||
parent: String? = rootFolderName,
|
||||
spaces: String? = null,
|
||||
trashed: Boolean = false,
|
||||
conflictResolver: ((Drive, List<File>) -> File)? = null
|
||||
conflictResolver: ((Drive, List<File>, String?) -> File)? = null
|
||||
): File? {
|
||||
val result = findFilesOrNull(name, mimeType, parent, trashed) ?: return null
|
||||
val result = findFilesOrNull(name, mimeType, parent, spaces, trashed) ?: return null
|
||||
if (result.size > 1 && conflictResolver != null) {
|
||||
return conflictResolver(this, result)
|
||||
return conflictResolver(this, result, spaces)
|
||||
}
|
||||
return result.firstOrNull()
|
||||
}
|
||||
|
@ -39,10 +44,11 @@ internal fun Drive.getFileOrNull(
|
|||
internal fun Drive.findFilesOrNull(
|
||||
name: String,
|
||||
mimeType: String?,
|
||||
parent: String? = "root",
|
||||
parent: String? = rootFolderName,
|
||||
spaces: String? = null,
|
||||
trashed: Boolean = false
|
||||
): List<File>? {
|
||||
val find = files().list()
|
||||
val find = files().basicList(spaces)
|
||||
var query = "name = '$name'"
|
||||
if (parent != null) {
|
||||
query += " and '$parent' in parents"
|
||||
|
@ -52,7 +58,6 @@ internal fun Drive.findFilesOrNull(
|
|||
}
|
||||
query += " and trashed = $trashed"
|
||||
find.q = query
|
||||
find.fields = requiredFilesRequestFields
|
||||
try {
|
||||
val files = find.execute().files
|
||||
if (files.isEmpty()) return null
|
||||
|
@ -69,13 +74,14 @@ internal fun Drive.findFilesOrNull(
|
|||
internal fun Drive.getFileOrCreate(
|
||||
name: String,
|
||||
mimeType: String,
|
||||
parent: String = "root",
|
||||
parent: String = rootFolderName,
|
||||
spaces: String? = null,
|
||||
trashed: Boolean = false,
|
||||
conflictResolver: ((Drive, List<File>) -> File)? = null
|
||||
conflictResolver: ((Drive, List<File>, String?) -> File)? = null
|
||||
): File {
|
||||
val result = findFilesOrCreate(name, mimeType, parent, trashed)
|
||||
val result = findFilesOrCreate(name, mimeType, parent, spaces, trashed)
|
||||
if (result.size > 1 && conflictResolver != null) {
|
||||
return conflictResolver(this, result)
|
||||
return conflictResolver(this, result, spaces)
|
||||
}
|
||||
return result.first()
|
||||
}
|
||||
|
@ -83,10 +89,11 @@ internal fun Drive.getFileOrCreate(
|
|||
internal fun Drive.findFilesOrCreate(
|
||||
name: String,
|
||||
mimeType: String,
|
||||
parent: String = "root",
|
||||
parent: String = rootFolderName,
|
||||
spaces: String? = null,
|
||||
trashed: Boolean = false
|
||||
): List<File> {
|
||||
return findFilesOrNull(name, mimeType, parent, trashed) ?: run {
|
||||
return findFilesOrNull(name, mimeType, parent, spaces, trashed) ?: run {
|
||||
val file = File()
|
||||
file.name = name
|
||||
file.mimeType = mimeType
|
||||
|
@ -99,16 +106,16 @@ internal fun Drive.findFilesOrCreate(
|
|||
internal fun Drive.updateOrCreate(
|
||||
name: String,
|
||||
mimeType: String,
|
||||
parent: String = "root",
|
||||
parent: String = rootFolderName,
|
||||
spaces: String? = null,
|
||||
trashed: Boolean = false,
|
||||
stream: InputStream,
|
||||
fileConfig: ((file: File) -> Unit)? = null
|
||||
): File {
|
||||
val files = files()
|
||||
return run {
|
||||
val find = files.list()
|
||||
val find = files.basicList(spaces)
|
||||
find.q = "name = '$name' and '$parent' in parents and mimeType = '$mimeType' and trashed = $trashed"
|
||||
find.fields = requiredFilesRequestFields
|
||||
val fileId = try {
|
||||
find.execute().files.firstOrNull()?.id ?: return@run null
|
||||
} catch (e: GoogleJsonResponseException) {
|
||||
|
@ -147,7 +154,7 @@ internal fun Drive.Files.performUpdate(
|
|||
return update.execute()
|
||||
}
|
||||
|
||||
internal fun resolveFilesConflict(client: Drive, list: List<File>): File {
|
||||
internal fun resolveFilesConflict(client: Drive, list: List<File>, spaces: String?): File {
|
||||
// Pick newest file
|
||||
val newest = list.maxBy { it.modifiedTime.value }!!
|
||||
|
||||
|
@ -160,7 +167,7 @@ internal fun resolveFilesConflict(client: Drive, list: List<File>): File {
|
|||
return newest
|
||||
}
|
||||
|
||||
internal fun resolveFoldersConflict(client: Drive, list: List<File>): File {
|
||||
internal fun resolveFoldersConflict(client: Drive, list: List<File>, spaces: String?): File {
|
||||
val files = client.files()
|
||||
|
||||
// Pick newest folder
|
||||
|
@ -173,9 +180,8 @@ internal fun resolveFoldersConflict(client: Drive, list: List<File>): File {
|
|||
val conflictFilesMap = HashMultimap.create<String, File>()
|
||||
var nextPageToken: String? = null
|
||||
do {
|
||||
val result = files.list().apply {
|
||||
val result = files.basicList(spaces).apply {
|
||||
this.q = query
|
||||
this.fields = requiredFilesRequestFields
|
||||
if (nextPageToken != null) {
|
||||
this.pageToken = nextPageToken
|
||||
}
|
||||
|
@ -242,4 +248,13 @@ internal fun resolveFoldersConflict(client: Drive, list: List<File>): File {
|
|||
|
||||
return newest
|
||||
|
||||
}
|
||||
|
||||
internal fun Drive.Files.basicList(spaces: String? = null): Drive.Files.List {
|
||||
return list().apply {
|
||||
this.fields = requiredFilesRequestFields
|
||||
if (spaces != null) {
|
||||
this.spaces = spaces
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,7 +25,8 @@ abstract internal class GoogleDriveUploadSession<in Data>(
|
|||
abstract fun Data.toInputStream(): InputStream
|
||||
|
||||
fun uploadData(data: Data): Boolean {
|
||||
drive.updateOrCreate(name, mimeType, parentId, stream = data.toInputStream(), fileConfig = {
|
||||
drive.updateOrCreate(name = name, mimeType = mimeType, parent = parentId,
|
||||
spaces = appDataFolderSpace, stream = data.toInputStream(), fileConfig = {
|
||||
it.modifiedTime = DateTime(localModifiedTime)
|
||||
})
|
||||
return true
|
||||
|
|
Loading…
Reference in New Issue