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)
|
// 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
|
// 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)
|
// 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 ->
|
}.flatMap { cachedFiles ->
|
||||||
if (!cachedFiles.file.exists()) {
|
if (!cachedFiles.file.exists()) {
|
||||||
val resolvedUrl = contentUrlResolver.resolveFullSize(url) ?: return@flatMap Try.Failure(IllegalArgumentException("url is null"))
|
val resolvedUrl = contentUrlResolver.resolveFullSize(url) ?: return@flatMap Try.Failure(IllegalArgumentException("url is null"))
|
||||||
|
@ -202,24 +202,29 @@ internal class DefaultFileService @Inject constructor(
|
||||||
}.toCancelable()
|
}.toCancelable()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
fun storeDataFor(mxcUrl: String,
|
||||||
fun storeDataFor(url: String, mimeType: String?, inputStream: InputStream) {
|
filename: String?,
|
||||||
val file = File(downloadFolder, fileForUrl(url, mimeType))
|
mimeType: String?,
|
||||||
val source = inputStream.source().buffer()
|
originalFile: File,
|
||||||
file.sink().buffer().let { sink ->
|
encryptedFile: File?) {
|
||||||
source.use { input ->
|
val files = getFiles(mxcUrl, filename, mimeType, encryptedFile != null)
|
||||||
sink.use { output ->
|
if (encryptedFile != null) {
|
||||||
output.writeAll(input)
|
// 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 {
|
return buildString {
|
||||||
// filename has to be safe for the Android System
|
// 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)
|
append(result)
|
||||||
// Check that the extension is correct regarding the mimeType
|
// Check that the extension is correct regarding the mimeType
|
||||||
val extensionFromMime = mimeType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType) }
|
val extensionFromMime = mimeType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType) }
|
||||||
|
@ -252,23 +257,23 @@ internal class DefaultFileService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFiles(mxcUrl: String,
|
private fun getFiles(mxcUrl: String,
|
||||||
fileName: String,
|
fileName: String?,
|
||||||
mimeType: String?,
|
mimeType: String?,
|
||||||
elementToDecrypt: ElementToDecrypt?): CachedFiles {
|
isEncrypted: Boolean): CachedFiles {
|
||||||
val hashFolder = mxcUrl.md5()
|
val hashFolder = mxcUrl.md5()
|
||||||
val safeFileName = safeFileName(fileName, mimeType)
|
val safeFileName = safeFileName(fileName, mimeType)
|
||||||
return if (elementToDecrypt == null) {
|
return if (isEncrypted) {
|
||||||
// Clear file
|
|
||||||
CachedFiles(
|
|
||||||
File(downloadFolder, "$hashFolder/$safeFileName"),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// Encrypted file
|
// Encrypted file
|
||||||
CachedFiles(
|
CachedFiles(
|
||||||
File(downloadFolder, "$hashFolder/$ENCRYPTED_FILENAME"),
|
File(downloadFolder, "$hashFolder/$ENCRYPTED_FILENAME"),
|
||||||
File(decryptedFolder, "$hashFolder/$safeFileName"),
|
File(decryptedFolder, "$hashFolder/$safeFileName"),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
// Clear file
|
||||||
|
CachedFiles(
|
||||||
|
File(downloadFolder, "$hashFolder/$safeFileName"),
|
||||||
|
null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +282,7 @@ internal class DefaultFileService @Inject constructor(
|
||||||
mimeType: String?,
|
mimeType: String?,
|
||||||
elementToDecrypt: ElementToDecrypt?): FileService.FileState {
|
elementToDecrypt: ElementToDecrypt?): FileService.FileState {
|
||||||
mxcUrl ?: return FileService.FileState.UNKNOWN
|
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) {
|
val isDownloading = synchronized(ongoing) {
|
||||||
ongoing[mxcUrl] != null
|
ongoing[mxcUrl] != null
|
||||||
}
|
}
|
||||||
|
@ -295,7 +300,7 @@ internal class DefaultFileService @Inject constructor(
|
||||||
mxcUrl ?: return null
|
mxcUrl ?: return null
|
||||||
// this string could be extracted no?
|
// this string could be extracted no?
|
||||||
val authority = "${context.packageName}.mx-sdk.fileprovider"
|
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
|
if (!targetFile.exists()) return null
|
||||||
return FileProvider.getUriForFile(context, authority, targetFile)
|
return FileProvider.getUriForFile(context, authority, targetFile)
|
||||||
}
|
}
|
||||||
|
@ -319,5 +324,7 @@ internal class DefaultFileService @Inject constructor(
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ENCRYPTED_FILENAME = "encrypted.bin"
|
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) {
|
val contentUploadResponse = if (params.isEncrypted) {
|
||||||
Timber.v("## FileService: Encrypt file")
|
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) }
|
.also { filesToDelete.add(it) }
|
||||||
|
|
||||||
uploadedFileEncryptedFileInfo =
|
uploadedFileEncryptedFileInfo =
|
||||||
MXEncryptedAttachments.encrypt(fileToUpload.inputStream(), attachment.getSafeMimeType(), tmpEncrypted) { read, total ->
|
MXEncryptedAttachments.encrypt(fileToUpload.inputStream(), attachment.getSafeMimeType(), encryptedFile) { read, total ->
|
||||||
notifyTracker(params) {
|
notifyTracker(params) {
|
||||||
contentUploadStateTracker.setEncrypting(it, read.toLong(), total.toLong())
|
contentUploadStateTracker.setEncrypting(it, read.toLong(), total.toLong())
|
||||||
}
|
}
|
||||||
|
@ -190,19 +191,23 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
||||||
Timber.v("## FileService: Uploading file")
|
Timber.v("## FileService: Uploading file")
|
||||||
|
|
||||||
fileUploader
|
fileUploader
|
||||||
.uploadFile(tmpEncrypted, attachment.name, "application/octet-stream", progressListener)
|
.uploadFile(encryptedFile, attachment.name, "application/octet-stream", progressListener)
|
||||||
} else {
|
} else {
|
||||||
Timber.v("## FileService: Clear file")
|
Timber.v("## FileService: Clear file")
|
||||||
|
encryptedFile = null
|
||||||
fileUploader
|
fileUploader
|
||||||
.uploadFile(fileToUpload, attachment.name, attachment.getSafeMimeType(), progressListener)
|
.uploadFile(fileToUpload, attachment.name, attachment.getSafeMimeType(), progressListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
Timber.v("## FileService: Update cache storage for ${contentUploadResponse.contentUri}")
|
Timber.v("## FileService: Update cache storage for ${contentUploadResponse.contentUri}")
|
||||||
try {
|
try {
|
||||||
/* TODO
|
fileService.storeDataFor(
|
||||||
context.contentResolver.openInputStream(attachment.queryUri)?.let {
|
mxcUrl = contentUploadResponse.contentUri,
|
||||||
fileService.storeDataFor(contentUploadResponse.contentUri, params.attachment.getSafeMimeType(), it)
|
filename = params.attachment.name,
|
||||||
} */
|
mimeType = params.attachment.getSafeMimeType(),
|
||||||
|
originalFile = workingFile,
|
||||||
|
encryptedFile = encryptedFile
|
||||||
|
)
|
||||||
Timber.v("## FileService: cache storage updated")
|
Timber.v("## FileService: cache storage updated")
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
Timber.e(failure, "## FileService: Failed to update file cache")
|
Timber.e(failure, "## FileService: Failed to update file cache")
|
||||||
|
|
Loading…
Reference in a new issue