Skip to content

Commit 53d61ae

Browse files
committed
feat(storage): migrate encoded account directories to readable names
1 parent 7350819 commit 53d61ae

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

opencloudData/src/main/java/eu/opencloud/android/data/providers/ScopedStorageProvider.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
package eu.opencloud.android.data.providers
2121

2222
import android.content.Context
23+
import android.net.Uri
2324
import android.os.Environment
25+
import timber.log.Timber
2426
import java.io.File
2527

2628
@Suppress("UnusedPrivateProperty")
@@ -30,4 +32,38 @@ class ScopedStorageProvider(
3032
) : LocalStorageProvider(rootFolderName) {
3133

3234
override fun getPrimaryStorageDirectory(): File = Environment.getExternalStorageDirectory()
35+
36+
override fun getAccountDirectoryPath(accountName: String): String {
37+
val sanitizedName = accountName.replace("/", "_").replace("\\", "_").replace(":", "_")
38+
val newPath = getRootFolderPath() + File.separator + sanitizedName
39+
40+
val oldEncodedName = Uri.encode(accountName, "@")
41+
val oldPath = getRootFolderPath() + File.separator + oldEncodedName
42+
43+
if (oldPath != newPath) {
44+
val oldDir = File(oldPath)
45+
val newDir = File(newPath)
46+
47+
// If old encoded directory exists, but the new readable one doesn't, migrate it!
48+
if (oldDir.exists() && oldDir.isDirectory && !newDir.exists()) {
49+
try {
50+
if (oldDir.renameTo(newDir)) {
51+
Timber.i("Successfully migrated account directory from $oldEncodedName to readable name $sanitizedName")
52+
return newPath
53+
} else {
54+
return oldPath // Fallback if rename fails
55+
}
56+
} catch (e: Exception) {
57+
Timber.e(e, "Failed to migrate account directory to readable name")
58+
return oldPath
59+
}
60+
} else if (oldDir.exists() && oldDir.isDirectory && newDir.exists()) {
61+
// If both exist, we should probably stick to the new one or the old one. Let's use old one to not lose files
62+
// that haven't been migrated yet.
63+
return oldPath
64+
}
65+
}
66+
67+
return newPath
68+
}
3369
}

opencloudData/src/test/java/eu/opencloud/android/data/providers/ScopedStorageProviderTest.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ class ScopedStorageProviderTest {
8686
mockkStatic(Uri::class)
8787
every { Uri.encode(accountName, "@") } returns uriEncoded
8888

89-
val accountDirectoryPath = filesDir.absolutePath + File.separator + rootFolderName + File.separator + uriEncoded
89+
// Since old directory doesn't exist, it should use the new sanitized account name "opencloud"
90+
val expectedSanitizedName = accountName.replace("/", "_").replace("\\", "_").replace(":", "_")
91+
val accountDirectoryPath = filesDir.absolutePath + File.separator + rootFolderName + File.separator + expectedSanitizedName
9092
val expectedPath = accountDirectoryPath + File.separator + spaceId + File.separator + remotePath
9193
val actualPath = scopedStorageProvider.getDefaultSavePathFor(accountName, remotePath, spaceId)
9294

@@ -104,7 +106,9 @@ class ScopedStorageProviderTest {
104106
mockkStatic(Uri::class)
105107
every { Uri.encode(accountName, "@") } returns uriEncoded
106108

107-
val accountDirectoryPath = filesDir.absolutePath + File.separator + rootFolderName + File.separator + uriEncoded
109+
// Since old directory doesn't exist, it should use the new sanitized account name "opencloud"
110+
val expectedSanitizedName = accountName.replace("/", "_").replace("\\", "_").replace(":", "_")
111+
val accountDirectoryPath = filesDir.absolutePath + File.separator + rootFolderName + File.separator + expectedSanitizedName
108112
val expectedPath = accountDirectoryPath + remotePath
109113
val actualPath = scopedStorageProvider.getDefaultSavePathFor(accountName, remotePath, spaceId)
110114

0 commit comments

Comments
 (0)