fix: clean up temp files after upload completes
MetadataStripper, MediaCompressor, and EncryptFiles create intermediate temp files in cacheDir during the upload pipeline, but these were never deleted after the upload finished. Over time this causes unbounded disk growth. Wrap upload calls in try/finally to ensure all intermediate temp files (compressed, stripped, encrypted) are deleted regardless of success or failure. https://claude.ai/code/session_01YS3dbZ1k84N2EHS3AruYRV
This commit is contained in:
+44
-8
@@ -31,10 +31,12 @@ import com.vitorpamplona.amethyst.service.uploads.nip96.Nip96Uploader
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import com.vitorpamplona.quartz.utils.ciphers.NostrCipher
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import okhttp3.OkHttpClient
|
||||
import java.io.File
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
sealed class UploadingState {
|
||||
@@ -324,6 +326,26 @@ class UploadOrchestrator {
|
||||
return strippingResult.uri
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a temporary file created during the upload pipeline if its URI
|
||||
* differs from the original (meaning it's an intermediate temp file, not the user's content).
|
||||
*/
|
||||
private fun deleteTempUri(
|
||||
tempUri: Uri,
|
||||
originalUri: Uri,
|
||||
) {
|
||||
if (tempUri == originalUri) return
|
||||
try {
|
||||
val path = tempUri.path ?: return
|
||||
val file = File(path)
|
||||
if (file.exists() && file.delete()) {
|
||||
Log.d("UploadOrchestrator", "Deleted temp file: $path")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w("UploadOrchestrator", "Failed to delete temp file: ${tempUri.path}", e)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun upload(
|
||||
uri: Uri,
|
||||
mimeType: String?,
|
||||
@@ -343,10 +365,17 @@ class UploadOrchestrator {
|
||||
stripAfterCompression(uri, compressed, mimeType, compressionQuality, stripMetadata, onStrippingFailed, context)
|
||||
?: return error(R.string.upload_cancelled)
|
||||
|
||||
return when (server.type) {
|
||||
ServerType.NIP95 -> uploadNIP95(finalUri, compressed.contentType, null, null, context)
|
||||
ServerType.NIP96 -> uploadNIP96(finalUri, compressed.contentType, compressed.size, alt, contentWarningReason, server.baseUrl, null, null, account, context)
|
||||
ServerType.Blossom -> uploadBlossom(finalUri, compressed.contentType, compressed.size, alt, contentWarningReason, server.baseUrl, null, null, account, context)
|
||||
try {
|
||||
return when (server.type) {
|
||||
ServerType.NIP95 -> uploadNIP95(finalUri, compressed.contentType, null, null, context)
|
||||
ServerType.NIP96 -> uploadNIP96(finalUri, compressed.contentType, compressed.size, alt, contentWarningReason, server.baseUrl, null, null, account, context)
|
||||
ServerType.Blossom -> uploadBlossom(finalUri, compressed.contentType, compressed.size, alt, contentWarningReason, server.baseUrl, null, null, account, context)
|
||||
}
|
||||
} finally {
|
||||
// Clean up intermediate temp files created by stripping and compression.
|
||||
// Delete stripped file first (if different from compressed), then compressed (if different from original).
|
||||
deleteTempUri(finalUri, compressed.uri)
|
||||
deleteTempUri(compressed.uri, uri)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,10 +401,17 @@ class UploadOrchestrator {
|
||||
|
||||
val encrypted = EncryptFiles().encryptFile(context, finalUri, encrypt)
|
||||
|
||||
return when (server.type) {
|
||||
ServerType.NIP95 -> uploadNIP95(encrypted.uri, encrypted.contentType, compressed.contentType, encrypted.originalHash, context)
|
||||
ServerType.NIP96 -> uploadNIP96(encrypted.uri, encrypted.contentType, encrypted.size, alt, contentWarningReason, server.baseUrl, compressed.contentType, encrypted.originalHash, account, context)
|
||||
ServerType.Blossom -> uploadBlossom(encrypted.uri, encrypted.contentType, encrypted.size, alt, contentWarningReason, server.baseUrl, compressed.contentType, encrypted.originalHash, account, context)
|
||||
try {
|
||||
return when (server.type) {
|
||||
ServerType.NIP95 -> uploadNIP95(encrypted.uri, encrypted.contentType, compressed.contentType, encrypted.originalHash, context)
|
||||
ServerType.NIP96 -> uploadNIP96(encrypted.uri, encrypted.contentType, encrypted.size, alt, contentWarningReason, server.baseUrl, compressed.contentType, encrypted.originalHash, account, context)
|
||||
ServerType.Blossom -> uploadBlossom(encrypted.uri, encrypted.contentType, encrypted.size, alt, contentWarningReason, server.baseUrl, compressed.contentType, encrypted.originalHash, account, context)
|
||||
}
|
||||
} finally {
|
||||
// Clean up all intermediate temp files: encrypted, stripped, and compressed.
|
||||
deleteTempUri(encrypted.uri, finalUri)
|
||||
deleteTempUri(finalUri, compressed.uri)
|
||||
deleteTempUri(compressed.uri, uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user