mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-29 06:37:16 +02:00
Refactor AbsDownloader
This commit is contained in:
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user