mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-04 07:06:58 +02:00
fix(download): resolve missing album folders before publishing
This commit is contained in:
1 parent
fed88fc3a9
commit
c48406f5d0
15 files changed
+383
-13
No files matched your search
@@ -186,6 +186,9 @@ object NativeDownloadFinalizer {
|
||||
val itemObject = parseObject(itemJson)
|
||||
val requestObject = parseObject(requestJson)
|
||||
validateRequestContract(requestObject)
|
||||
if (result.optBoolean("saf_deferred_publish", false) && result.has("saf_relative_dir")) {
|
||||
requestObject.put("saf_relative_dir", result.getString("saf_relative_dir"))
|
||||
}
|
||||
val input = FinalizeInput(
|
||||
itemId = itemId,
|
||||
request = requestObject,
|
||||
|
||||
@@ -11,6 +11,24 @@ import kotlin.math.roundToInt
|
||||
* finalizer's I/O-heavy orchestration.
|
||||
*/
|
||||
internal object NativeFinalizationPolicy {
|
||||
fun resolvedAlbumRelativeDirectory(
|
||||
relativeDirectory: String,
|
||||
albumFolderTemplate: String,
|
||||
resolvedAlbumFolder: String,
|
||||
): String {
|
||||
val albumFolder = resolvedAlbumFolder.trim()
|
||||
if (!albumFolderTemplate.contains("{album}") || albumFolder.isEmpty()) {
|
||||
return relativeDirectory
|
||||
}
|
||||
// The backend supplies one sanitized leaf, never a relative path.
|
||||
if (albumFolder == "." || albumFolder == ".." ||
|
||||
albumFolder.contains('/') || albumFolder.contains('\\')) {
|
||||
return relativeDirectory
|
||||
}
|
||||
val parent = relativeDirectory.substringBeforeLast('/', "")
|
||||
return if (parent.isEmpty()) albumFolder else "$parent/$albumFolder"
|
||||
}
|
||||
|
||||
private val lyricsMetadataLinePattern = Regex(
|
||||
"^\\[[a-z][a-z0-9_]*:.*]$",
|
||||
RegexOption.IGNORE_CASE,
|
||||
|
||||
@@ -95,7 +95,7 @@ object SafDownloadHandler {
|
||||
val stagedMimeType = if (useStagedOutput) STAGED_SAF_MIME_TYPE else mimeType
|
||||
|
||||
val existingDir = findDocumentDir(context, treeUri, relativeDir)
|
||||
if (existingDir != null) {
|
||||
if (existingDir != null && req.optString("album_folder_template", "").isBlank()) {
|
||||
val existing = existingDir.findFile(fileName)
|
||||
if (existing != null && existing.isFile && existing.length() > 0) {
|
||||
deleteStaleStagedFiles(existingDir, fileName, outputExt)
|
||||
@@ -109,11 +109,8 @@ object SafDownloadHandler {
|
||||
}
|
||||
}
|
||||
|
||||
val targetDir = ensureDocumentDir(context, treeUri, relativeDir)
|
||||
?: return errorJson("Failed to access SAF directory")
|
||||
|
||||
if (deferSafPublish) {
|
||||
deleteStaleStagedFiles(targetDir, fileName, outputExt)
|
||||
existingDir?.let { deleteStaleStagedFiles(it, fileName, outputExt) }
|
||||
val workingExt = outputExt.ifBlank { ".tmp" }
|
||||
val workingFile = File.createTempFile("native_saf_work_", workingExt, context.cacheDir)
|
||||
return try {
|
||||
@@ -135,7 +132,12 @@ object SafDownloadHandler {
|
||||
respObj.put("file_name", resolvedFileName)
|
||||
respObj.put("saf_deferred_publish", true)
|
||||
respObj.put("saf_final_file_name", resolvedFileName)
|
||||
respObj.put("saf_relative_dir", relativeDir)
|
||||
val resolvedDir = NativeFinalizationPolicy.resolvedAlbumRelativeDirectory(
|
||||
relativeDirectory = relativeDir,
|
||||
albumFolderTemplate = req.optString("album_folder_template", ""),
|
||||
resolvedAlbumFolder = respObj.optString("resolved_album_folder", ""),
|
||||
)
|
||||
respObj.put("saf_relative_dir", resolvedDir)
|
||||
respObj.put("saf_tree_uri", treeUriStr)
|
||||
respObj.put("saf_output_ext", outputExt)
|
||||
respObj.put("saf_final_mime_type", mimeType)
|
||||
@@ -149,6 +151,9 @@ object SafDownloadHandler {
|
||||
}
|
||||
}
|
||||
|
||||
val targetDir = ensureDocumentDir(context, treeUri, relativeDir)
|
||||
?: return errorJson("Failed to access SAF directory")
|
||||
|
||||
// Remove any stale partial from a previous killed attempt before
|
||||
// creating the staged document: reusing it would let a shorter new
|
||||
// write leave the old tail bytes in place (fd truncation is
|
||||
|
||||
Reference in new issue
Block a user