Skip to content

Commit 59b6232

Browse files
committed
wip
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent a074a84 commit 59b6232

1 file changed

Lines changed: 134 additions & 0 deletions

File tree

app/src/main/java/com/nextcloud/utils/extensions/FileDataStorageManagerExtensions.kt

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@
77

88
package com.nextcloud.utils.extensions
99

10+
import com.nextcloud.client.database.dao.FileDao
1011
import com.nextcloud.client.database.entity.model.ShareeKey
1112
import com.nextcloud.client.database.entity.toOCCapability
1213
import com.owncloud.android.datamodel.FileDataStorageManager
1314
import com.owncloud.android.datamodel.OCFile
15+
import com.owncloud.android.lib.common.utils.Log_OC
1416
import com.owncloud.android.lib.resources.files.model.RemoteFile
1517
import com.owncloud.android.lib.resources.shares.OCShare
1618
import com.owncloud.android.lib.resources.status.OCCapability
19+
import com.owncloud.android.utils.FileStorageUtils
20+
import com.owncloud.android.utils.MimeTypeUtil
1721
import kotlinx.coroutines.Dispatchers
1822
import kotlinx.coroutines.withContext
23+
import java.io.File
1924

2025
private const val SHARE_PATH_QUERY_CHUNK_SIZE = 400
2126

@@ -116,3 +121,132 @@ fun FileDataStorageManager.getNonEncryptedSubfolders(id: Long, accountName: Stri
116121

117122
suspend fun FileDataStorageManager.getCapabilitiesByAccountName(accountName: String): OCCapability =
118123
capabilityDao.getByAccountName(accountName).toOCCapability()
124+
125+
@Suppress("ReturnCount")
126+
fun FileDataStorageManager.moveFiles(ocFile: OCFile?, targetPath: String, targetParentPath: String) {
127+
Log_OC.d(
128+
FileDataStorageManager.TAG,
129+
(
130+
"moveLocalFile ==> ocFile: " +
131+
(ocFile?.remotePath) +
132+
" targetPath: " +
133+
targetPath +
134+
" targetParentPath: " +
135+
targetParentPath
136+
)
137+
)
138+
139+
if (ocFile == null) {
140+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: file is null, skipping")
141+
return
142+
}
143+
144+
if (!ocFile.fileExists()) {
145+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: file does not exist, skipping")
146+
return
147+
}
148+
149+
if (OCFile.ROOT_PATH == ocFile.fileName) {
150+
Log_OC.w(FileDataStorageManager.TAG, "moveLocalFile: cannot move root path")
151+
return
152+
}
153+
154+
if (ocFile.remotePath == targetPath) {
155+
Log_OC.w(FileDataStorageManager.TAG, "moveLocalFile: source and target paths are identical, skipping")
156+
return
157+
}
158+
159+
val targetParent = getFileByPath(targetParentPath)
160+
if (targetParent == null) {
161+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: target parent folder not found: $targetParentPath")
162+
return
163+
}
164+
165+
if (!targetParent.isFolder) {
166+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: target parent is not a folder: $targetParentPath")
167+
return
168+
}
169+
170+
val oldPath: String = ocFile.remotePath
171+
val accountName = user.accountName
172+
val defaultSavePath = FileStorageUtils.getSavePath(accountName)
173+
174+
val moved = moveLocalFiles(accountName, ocFile, defaultSavePath, targetPath)
175+
if (!moved) return
176+
177+
val originalMediaPaths =
178+
fileDao.moveFilesInDb(oldPath, targetPath, defaultSavePath, targetParent.fileId, accountName)
179+
180+
for (originalMediaPath in originalMediaPaths) {
181+
deleteFileInMediaScan(originalMediaPath)
182+
val newMediaPath = defaultSavePath + targetPath + originalMediaPath.substring(
183+
(defaultSavePath + oldPath).length
184+
)
185+
FileDataStorageManager.triggerMediaScan(newMediaPath)
186+
}
187+
}
188+
189+
@Suppress("ReturnCount")
190+
private fun moveLocalFiles(accountName: String, ocFile: OCFile, defaultSavePath: String, targetPath: String): Boolean {
191+
val localFile = File(FileStorageUtils.getDefaultSavePathFor(accountName, ocFile))
192+
if (!localFile.exists()) {
193+
Log_OC.d(FileDataStorageManager.TAG, "moveLocalFile: no local file to move at " + localFile.absolutePath)
194+
return false
195+
}
196+
197+
val targetFile = File(defaultSavePath + targetPath)
198+
val targetFolder = targetFile.getParentFile()
199+
if (targetFolder != null && !targetFolder.exists() && !targetFolder.mkdirs()) {
200+
Log_OC.e(
201+
FileDataStorageManager.TAG,
202+
"moveLocalFile: failed to create parent folder " + targetFolder.absolutePath
203+
)
204+
}
205+
206+
if (!localFile.renameTo(targetFile)) {
207+
Log_OC.e(
208+
FileDataStorageManager.TAG,
209+
(
210+
"moveLocalFile: failed to rename " + localFile.absolutePath +
211+
" to " + targetFile.absolutePath
212+
)
213+
)
214+
return false
215+
}
216+
217+
return true
218+
}
219+
220+
private fun FileDao.moveFilesInDb(
221+
oldPath: String,
222+
targetPath: String,
223+
defaultSavePath: String,
224+
targetParentId: Long,
225+
accountName: String
226+
): List<String> {
227+
val entities = getFolderWithDescendants("$oldPath%", accountName)
228+
val oldStoragePrefix = defaultSavePath + oldPath
229+
val newStoragePrefix = defaultSavePath + targetPath
230+
231+
val originalMediaPaths = entities
232+
.filter { MimeTypeUtil.isMedia(it.contentType) && it.storagePath?.startsWith(oldStoragePrefix) == true }
233+
.mapNotNull { it.storagePath }
234+
235+
val updated = entities.map { entity ->
236+
val currentPath = entity.path.orEmpty()
237+
val newPath = targetPath + currentPath.substring(oldPath.length)
238+
entity.copy(
239+
path = newPath,
240+
pathDecrypted = if (entity.isEncrypted == 0) newPath else entity.pathDecrypted,
241+
storagePath = if (entity.storagePath?.startsWith(oldStoragePrefix) == true) {
242+
newStoragePrefix + entity.storagePath.substring(oldStoragePrefix.length)
243+
} else {
244+
entity.storagePath
245+
},
246+
parent = if (currentPath == oldPath) targetParentId else entity.parent
247+
)
248+
}
249+
250+
updateAll(updated)
251+
return originalMediaPaths
252+
}

0 commit comments

Comments
 (0)