moved google drive sync into app folder (not visible to user)

This commit is contained in:
Mariotaku Lee 2017-01-22 17:15:26 +08:00
parent ce8baef9e5
commit 2dabdbdc39
No known key found for this signature in database
GPG Key ID: 9C0706AE47FCE2AD
6 changed files with 55 additions and 31 deletions

View File

@ -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()

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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
}
@ -243,3 +249,12 @@ 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
}
}
}

View File

@ -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