Refactor AbsDownloader

This commit is contained in:
Nicholas Wallace
2025-02-28 22:07:24 -07:00
parent ee0ab43fc5
commit 4a09238a8e
@@ -160,66 +160,53 @@ class AbsDownloader : Plugin() {
val tempFolderPath = val tempFolderPath =
if (isInternal) "${mainActivity.filesDir}/downloads/${libraryItem.id}" if (isInternal) "${mainActivity.filesDir}/downloads/${libraryItem.id}"
else mainActivity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) else "${mainActivity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)}"
Log.d(tag, "downloadCacheDirectory=$tempFolderPath") Log.d(tag, "downloadCacheDirectory=$tempFolderPath")
val itemFolderPath =
if (isInternal) "$tempFolderPath"
else
"${localFolder.absolutePath}/${cleanStringForFileSystem(libraryItem.media.metadata.title)}"
val downloadItemId = if (episode != null) "${libraryItem.id}-${episode.id}" else libraryItem.id
val titleCleaned = cleanStringForFileSystem(libraryItem.media.metadata.title)
val author =
if (episode == null)
cleanStringForFileSystem(libraryItem.media.metadata.getAuthorDisplayName())
else titleCleaned
val itemSubfolder = if (episode == null) "$author/$titleCleaned" else "$titleCleaned"
val downloadItem =
DownloadItem(
downloadItemId,
libraryItem.id,
episode?.id,
libraryItem.userMediaProgress,
DeviceManager.serverConnectionConfig?.id ?: "",
DeviceManager.serverAddress,
DeviceManager.serverUserId,
libraryItem.mediaType,
itemFolderPath,
localFolder,
titleCleaned,
itemSubfolder,
libraryItem.media,
mutableListOf()
)
if (libraryItem.mediaType == "book") { if (libraryItem.mediaType == "book") {
val bookTitle = cleanStringForFileSystem(libraryItem.media.metadata.title)
val bookAuthor = cleanStringForFileSystem(libraryItem.media.metadata.getAuthorDisplayName())
val tracks = libraryItem.media.getAudioTracks()
Log.d(tag, "Starting library item download with ${tracks.size} tracks")
val itemSubfolder = "$bookAuthor/$bookTitle"
val itemFolderPath =
if (isInternal) "$tempFolderPath" else "${localFolder.absolutePath}/$itemSubfolder"
val downloadItem =
DownloadItem(
libraryItem.id,
libraryItem.id,
null,
libraryItem.userMediaProgress,
DeviceManager.serverConnectionConfig?.id ?: "",
DeviceManager.serverAddress,
DeviceManager.serverUserId,
libraryItem.mediaType,
itemFolderPath,
localFolder,
bookTitle,
itemSubfolder,
libraryItem.media,
mutableListOf()
)
val book = libraryItem.media as Book val book = libraryItem.media as Book
book.ebookFile?.let { ebookFile -> book.ebookFile?.let { ebookFile ->
val fileSize = ebookFile.metadata?.size ?: 0
val serverPath = "/api/items/${libraryItem.id}/file/${ebookFile.ino}/download" val serverPath = "/api/items/${libraryItem.id}/file/${ebookFile.ino}/download"
val destinationFilename = getFilenameFromRelPath(ebookFile.metadata?.relPath ?: "") val destinationFilename = getFilenameFromRelPath(ebookFile.metadata?.relPath ?: "")
val finalDestinationFile = File("$itemFolderPath/$destinationFilename")
val destinationFile = File("$tempFolderPath/$destinationFilename") val destinationFile = File("$tempFolderPath/$destinationFilename")
val finalDestinationFile = File("$itemFolderPath/$destinationFilename")
if (destinationFile.exists()) { checkAndDeleteFile(destinationFile, finalDestinationFile)
Log.d(
tag,
"TEMP ebook file already exists, removing it from ${destinationFile.absolutePath}"
)
destinationFile.delete()
}
if (finalDestinationFile.exists()) {
Log.d(
tag,
"ebook file already exists, removing it from ${finalDestinationFile.absolutePath}"
)
finalDestinationFile.delete()
}
val downloadItemPart = val downloadItemPart =
DownloadItemPart.make( DownloadItemPart.make(
downloadItem.id, downloadItem.id,
destinationFilename, destinationFilename,
fileSize, ebookFile.metadata?.size ?: 0,
destinationFile, destinationFile,
finalDestinationFile, finalDestinationFile,
itemSubfolder, itemSubfolder,
@@ -232,46 +219,20 @@ class AbsDownloader : Plugin() {
downloadItem.downloadItemParts.add(downloadItemPart) downloadItem.downloadItemParts.add(downloadItemPart)
} }
// Create download item part for each audio track val audioFiles = book.audioFiles ?: mutableListOf()
val audioFiles = (libraryItem.media as Book).audioFiles ?: mutableListOf() libraryItem.media.getAudioTracks().forEach { audioTrack ->
tracks.forEach { audioTrack ->
val fileSize = audioTrack.metadata?.size ?: 0
// TODO: Currently file ino is only stored on AudioFile. This should be updated server side
// to be in FileMetadata or on the AudioTrack
val audioFileIno = audioFiles.find { it.metadata.path == audioTrack.metadata?.path }?.ino val audioFileIno = audioFiles.find { it.metadata.path == audioTrack.metadata?.path }?.ino
val serverPath = "/api/items/${libraryItem.id}/file/${audioFileIno}/download" val serverPath = "/api/items/${libraryItem.id}/file/${audioFileIno}/download"
val destinationFilename = getFilenameFromRelPath(audioTrack.relPath) val destinationFilename = getFilenameFromRelPath(audioTrack.relPath)
Log.d(
tag,
"Audio File Server Path $serverPath | AF RelPath ${audioTrack.relPath} | LocalFolder Path ${localFolder.absolutePath} | DestName $destinationFilename"
)
val finalDestinationFile = File("$itemFolderPath/$destinationFilename")
val destinationFile = File("$tempFolderPath/$destinationFilename") val destinationFile = File("$tempFolderPath/$destinationFilename")
val finalDestinationFile = File("$itemFolderPath/$destinationFilename")
if (destinationFile.exists()) { checkAndDeleteFile(destinationFile, finalDestinationFile)
Log.d(
tag,
"TEMP Audio file already exists, removing it from ${destinationFile.absolutePath}"
)
destinationFile.delete()
}
if (finalDestinationFile.exists()) {
Log.d(
tag,
"Audio file already exists, removing it from ${finalDestinationFile.absolutePath}"
)
finalDestinationFile.delete()
}
val downloadItemPart = val downloadItemPart =
DownloadItemPart.make( DownloadItemPart.make(
downloadItem.id, downloadItem.id,
destinationFilename, destinationFilename,
fileSize, audioTrack.metadata?.size ?: 0,
destinationFile, destinationFile,
finalDestinationFile, finalDestinationFile,
itemSubfolder, itemSubfolder,
@@ -283,110 +244,22 @@ class AbsDownloader : Plugin() {
) )
downloadItem.downloadItemParts.add(downloadItemPart) downloadItem.downloadItemParts.add(downloadItemPart)
} }
if (downloadItem.downloadItemParts.isNotEmpty()) {
// Add cover download item
if (libraryItem.media.coverPath != null && libraryItem.media.coverPath?.isNotEmpty() == true
) {
val coverLibraryFile =
libraryItem.libraryFiles?.find { it.metadata.path == libraryItem.media.coverPath }
val coverFileSize = coverLibraryFile?.metadata?.size ?: 0
val serverPath = "/api/items/${libraryItem.id}/cover"
val destinationFilename = "cover-${libraryItem.id}.jpg"
val destinationFile = File("$tempFolderPath/$destinationFilename")
val finalDestinationFile = File("$itemFolderPath/$destinationFilename")
if (destinationFile.exists()) {
Log.d(
tag,
"TEMP Audio file already exists, removing it from ${destinationFile.absolutePath}"
)
destinationFile.delete()
}
if (finalDestinationFile.exists()) {
Log.d(
tag,
"Cover already exists, removing it from ${finalDestinationFile.absolutePath}"
)
finalDestinationFile.delete()
}
val downloadItemPart =
DownloadItemPart.make(
downloadItem.id,
destinationFilename,
coverFileSize,
destinationFile,
finalDestinationFile,
itemSubfolder,
serverPath,
localFolder,
null,
null,
null
)
downloadItem.downloadItemParts.add(downloadItemPart)
}
downloadItemManager.addDownloadItem(downloadItem)
}
} else { } else {
// Podcast episode download
val podcastTitle = cleanStringForFileSystem(libraryItem.media.metadata.title)
val audioTrack = episode?.audioTrack val audioTrack = episode?.audioTrack
val audioFileIno = episode?.audioFile?.ino val audioFileIno = episode?.audioFile?.ino
val fileSize = audioTrack?.metadata?.size ?: 0 val serverPath = "/api/items/${libraryItem.id}/file/${audioFileIno}/download"
val destinationFilename = getFilenameFromRelPath(audioTrack?.relPath ?: "")
Log.d(tag, "Starting podcast episode download") val destinationFile = File("$tempFolderPath/$destinationFilename")
val itemFolderPath = val finalDestinationFile = File("$itemFolderPath/$destinationFilename")
if (isInternal) "$tempFolderPath" else "${localFolder.absolutePath}/$podcastTitle" checkAndDeleteFile(destinationFile, finalDestinationFile)
val downloadItemId = "${libraryItem.id}-${episode?.id}" val downloadItemPart =
val downloadItem =
DownloadItem(
downloadItemId,
libraryItem.id,
episode?.id,
libraryItem.userMediaProgress,
DeviceManager.serverConnectionConfig?.id ?: "",
DeviceManager.serverAddress,
DeviceManager.serverUserId,
libraryItem.mediaType,
itemFolderPath,
localFolder,
podcastTitle,
podcastTitle,
libraryItem.media,
mutableListOf()
)
var serverPath = "/api/items/${libraryItem.id}/file/${audioFileIno}/download"
var destinationFilename = getFilenameFromRelPath(audioTrack?.relPath ?: "")
Log.d(
tag,
"Audio File Server Path $serverPath | AF RelPath ${audioTrack?.relPath} | LocalFolder Path ${localFolder.absolutePath} | DestName $destinationFilename"
)
var destinationFile = File("$tempFolderPath/$destinationFilename")
var finalDestinationFile = File("$itemFolderPath/$destinationFilename")
if (finalDestinationFile.exists()) {
Log.d(
tag,
"Audio file already exists, removing it from ${finalDestinationFile.absolutePath}"
)
finalDestinationFile.delete()
}
var downloadItemPart =
DownloadItemPart.make( DownloadItemPart.make(
downloadItem.id, downloadItem.id,
destinationFilename, destinationFilename,
fileSize, audioTrack?.metadata?.size ?: 0,
destinationFile, destinationFile,
finalDestinationFile, finalDestinationFile,
podcastTitle, titleCleaned,
serverPath, serverPath,
localFolder, localFolder,
null, null,
@@ -394,41 +267,49 @@ class AbsDownloader : Plugin() {
episode episode
) )
downloadItem.downloadItemParts.add(downloadItemPart) downloadItem.downloadItemParts.add(downloadItemPart)
}
if (libraryItem.media.coverPath != null && libraryItem.media.coverPath?.isNotEmpty() == true if (libraryItem.media.coverPath != null && libraryItem.media.coverPath?.isNotEmpty() == true) {
) { val coverLibraryFile =
val coverLibraryFile = libraryItem.libraryFiles?.find { it.metadata.path == libraryItem.media.coverPath }
libraryItem.libraryFiles?.find { it.metadata.path == libraryItem.media.coverPath } val serverPath = "/api/items/${libraryItem.id}/cover"
val coverFileSize = coverLibraryFile?.metadata?.size ?: 0 val destinationFilename = if (episode == null) "cover-${libraryItem.id}.jpg" else "cover.jpg"
val destinationFile = File("$tempFolderPath/$destinationFilename")
serverPath = "/api/items/${libraryItem.id}/cover" val finalDestinationFile = File("$itemFolderPath/$destinationFilename")
destinationFilename = "cover.jpg" checkAndDeleteFile(destinationFile, finalDestinationFile)
val downloadItemPart =
destinationFile = File("$tempFolderPath/$destinationFilename") DownloadItemPart.make(
finalDestinationFile = File("$itemFolderPath/$destinationFilename") downloadItem.id,
destinationFilename,
if (finalDestinationFile.exists()) { coverLibraryFile?.metadata?.size ?: 0,
Log.d(tag, "Podcast cover already exists - not downloading cover again") destinationFile,
} else { finalDestinationFile,
downloadItemPart = titleCleaned,
DownloadItemPart.make( serverPath,
downloadItem.id, localFolder,
destinationFilename, null,
coverFileSize, null,
destinationFile, null
finalDestinationFile, )
podcastTitle, downloadItem.downloadItemParts.add(downloadItemPart)
serverPath, }
localFolder,
null,
null,
null
)
downloadItem.downloadItemParts.add(downloadItemPart)
}
}
if (downloadItem.downloadItemParts.isNotEmpty()) {
downloadItemManager.addDownloadItem(downloadItem) downloadItemManager.addDownloadItem(downloadItem)
} }
} }
/* Delete files if they already exist */
private fun checkAndDeleteFile(destinationFile: File, finalDestinationFile: File) {
if (destinationFile.exists()) {
Log.d(tag, "TEMP file already exists, removing it from ${destinationFile.absolutePath}")
destinationFile.delete()
}
if (finalDestinationFile.exists()) {
Log.d(tag, "File already exists, removing it from ${finalDestinationFile.absolutePath}")
finalDestinationFile.delete()
}
}
} }