mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-27 20:09:27 +03:00
DefaultFileService: store just sent file
This commit is contained in:
parent
ca7796114c
commit
1c43f92e49
2 changed files with 44 additions and 32 deletions
|
@ -111,7 +111,7 @@ internal class DefaultFileService @Inject constructor(
|
|||
// ensure we use unique file name by using URL (mapped to suitable file name)
|
||||
// Also we need to add extension for the FileProvider, if not it lot's of app that it's
|
||||
// shared with will not function well (even if mime type is passed in the intent)
|
||||
getFiles(url, fileName, mimeType, elementToDecrypt)
|
||||
getFiles(url, fileName, mimeType, elementToDecrypt != null)
|
||||
}.flatMap { cachedFiles ->
|
||||
if (!cachedFiles.file.exists()) {
|
||||
val resolvedUrl = contentUrlResolver.resolveFullSize(url) ?: return@flatMap Try.Failure(IllegalArgumentException("url is null"))
|
||||
|
@ -202,24 +202,29 @@ internal class DefaultFileService @Inject constructor(
|
|||
}.toCancelable()
|
||||
}
|
||||
|
||||
/*
|
||||
fun storeDataFor(url: String, mimeType: String?, inputStream: InputStream) {
|
||||
val file = File(downloadFolder, fileForUrl(url, mimeType))
|
||||
val source = inputStream.source().buffer()
|
||||
file.sink().buffer().let { sink ->
|
||||
source.use { input ->
|
||||
sink.use { output ->
|
||||
output.writeAll(input)
|
||||
}
|
||||
}
|
||||
fun storeDataFor(mxcUrl: String,
|
||||
filename: String?,
|
||||
mimeType: String?,
|
||||
originalFile: File,
|
||||
encryptedFile: File?) {
|
||||
val files = getFiles(mxcUrl, filename, mimeType, encryptedFile != null)
|
||||
if (encryptedFile != null) {
|
||||
// We switch the two files here, original file it the decrypted file
|
||||
files.decryptedFile?.let { originalFile.copyTo(it) }
|
||||
encryptedFile.copyTo(files.file)
|
||||
} else {
|
||||
// Just copy the original file
|
||||
originalFile.copyTo(files.file)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private fun safeFileName(fileName: String, mimeType: String?): String {
|
||||
private fun safeFileName(fileName: String?, mimeType: String?): String {
|
||||
return buildString {
|
||||
// filename has to be safe for the Android System
|
||||
val result = fileName.replace("[^a-z A-Z0-9\\\\.\\-]".toRegex(), "_")
|
||||
val result = fileName
|
||||
?.replace("[^a-z A-Z0-9\\\\.\\-]".toRegex(), "_")
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?: DEFAULT_FILENAME
|
||||
append(result)
|
||||
// Check that the extension is correct regarding the mimeType
|
||||
val extensionFromMime = mimeType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType) }
|
||||
|
@ -252,23 +257,23 @@ internal class DefaultFileService @Inject constructor(
|
|||
}
|
||||
|
||||
private fun getFiles(mxcUrl: String,
|
||||
fileName: String,
|
||||
fileName: String?,
|
||||
mimeType: String?,
|
||||
elementToDecrypt: ElementToDecrypt?): CachedFiles {
|
||||
isEncrypted: Boolean): CachedFiles {
|
||||
val hashFolder = mxcUrl.md5()
|
||||
val safeFileName = safeFileName(fileName, mimeType)
|
||||
return if (elementToDecrypt == null) {
|
||||
// Clear file
|
||||
CachedFiles(
|
||||
File(downloadFolder, "$hashFolder/$safeFileName"),
|
||||
null
|
||||
)
|
||||
} else {
|
||||
return if (isEncrypted) {
|
||||
// Encrypted file
|
||||
CachedFiles(
|
||||
File(downloadFolder, "$hashFolder/$ENCRYPTED_FILENAME"),
|
||||
File(decryptedFolder, "$hashFolder/$safeFileName"),
|
||||
)
|
||||
} else {
|
||||
// Clear file
|
||||
CachedFiles(
|
||||
File(downloadFolder, "$hashFolder/$safeFileName"),
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,7 +282,7 @@ internal class DefaultFileService @Inject constructor(
|
|||
mimeType: String?,
|
||||
elementToDecrypt: ElementToDecrypt?): FileService.FileState {
|
||||
mxcUrl ?: return FileService.FileState.UNKNOWN
|
||||
if (getFiles(mxcUrl, fileName, mimeType, elementToDecrypt).file.exists()) return FileService.FileState.IN_CACHE
|
||||
if (getFiles(mxcUrl, fileName, mimeType, elementToDecrypt != null).file.exists()) return FileService.FileState.IN_CACHE
|
||||
val isDownloading = synchronized(ongoing) {
|
||||
ongoing[mxcUrl] != null
|
||||
}
|
||||
|
@ -295,7 +300,7 @@ internal class DefaultFileService @Inject constructor(
|
|||
mxcUrl ?: return null
|
||||
// this string could be extracted no?
|
||||
val authority = "${context.packageName}.mx-sdk.fileprovider"
|
||||
val targetFile = getFiles(mxcUrl, fileName, mimeType, elementToDecrypt).getClearFile()
|
||||
val targetFile = getFiles(mxcUrl, fileName, mimeType, elementToDecrypt != null).getClearFile()
|
||||
if (!targetFile.exists()) return null
|
||||
return FileProvider.getUriForFile(context, authority, targetFile)
|
||||
}
|
||||
|
@ -319,5 +324,7 @@ internal class DefaultFileService @Inject constructor(
|
|||
|
||||
companion object {
|
||||
private const val ENCRYPTED_FILENAME = "encrypted.bin"
|
||||
// The extension would be added from the mimetype
|
||||
private const val DEFAULT_FILENAME = "file"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,14 +174,15 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
|||
}
|
||||
}
|
||||
|
||||
val encryptedFile: File?
|
||||
val contentUploadResponse = if (params.isEncrypted) {
|
||||
Timber.v("## FileService: Encrypt file")
|
||||
|
||||
val tmpEncrypted = File.createTempFile(UUID.randomUUID().toString(), null, context.cacheDir)
|
||||
encryptedFile = File.createTempFile(UUID.randomUUID().toString(), null, context.cacheDir)
|
||||
.also { filesToDelete.add(it) }
|
||||
|
||||
uploadedFileEncryptedFileInfo =
|
||||
MXEncryptedAttachments.encrypt(fileToUpload.inputStream(), attachment.getSafeMimeType(), tmpEncrypted) { read, total ->
|
||||
MXEncryptedAttachments.encrypt(fileToUpload.inputStream(), attachment.getSafeMimeType(), encryptedFile) { read, total ->
|
||||
notifyTracker(params) {
|
||||
contentUploadStateTracker.setEncrypting(it, read.toLong(), total.toLong())
|
||||
}
|
||||
|
@ -190,19 +191,23 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
|||
Timber.v("## FileService: Uploading file")
|
||||
|
||||
fileUploader
|
||||
.uploadFile(tmpEncrypted, attachment.name, "application/octet-stream", progressListener)
|
||||
.uploadFile(encryptedFile, attachment.name, "application/octet-stream", progressListener)
|
||||
} else {
|
||||
Timber.v("## FileService: Clear file")
|
||||
encryptedFile = null
|
||||
fileUploader
|
||||
.uploadFile(fileToUpload, attachment.name, attachment.getSafeMimeType(), progressListener)
|
||||
}
|
||||
|
||||
Timber.v("## FileService: Update cache storage for ${contentUploadResponse.contentUri}")
|
||||
try {
|
||||
/* TODO
|
||||
context.contentResolver.openInputStream(attachment.queryUri)?.let {
|
||||
fileService.storeDataFor(contentUploadResponse.contentUri, params.attachment.getSafeMimeType(), it)
|
||||
} */
|
||||
fileService.storeDataFor(
|
||||
mxcUrl = contentUploadResponse.contentUri,
|
||||
filename = params.attachment.name,
|
||||
mimeType = params.attachment.getSafeMimeType(),
|
||||
originalFile = workingFile,
|
||||
encryptedFile = encryptedFile
|
||||
)
|
||||
Timber.v("## FileService: cache storage updated")
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure, "## FileService: Failed to update file cache")
|
||||
|
|
Loading…
Reference in a new issue