From ee0ab43fc57d5d23bed80f6be1f353402df896ab Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Fri, 28 Feb 2025 20:37:08 -0700 Subject: [PATCH] Auto formatting `AbsDownloader.kt` --- .../app/plugins/AbsDownloader.kt | 257 ++++++++++++++---- 1 file changed, 208 insertions(+), 49 deletions(-) diff --git a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDownloader.kt b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDownloader.kt index d3e42029..758b5b50 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDownloader.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDownloader.kt @@ -8,10 +8,10 @@ import com.audiobookshelf.app.MainActivity import com.audiobookshelf.app.data.* import com.audiobookshelf.app.device.DeviceManager import com.audiobookshelf.app.device.FolderScanner +import com.audiobookshelf.app.managers.DownloadItemManager import com.audiobookshelf.app.models.DownloadItem import com.audiobookshelf.app.models.DownloadItemPart import com.audiobookshelf.app.server.ApiHandler -import com.audiobookshelf.app.managers.DownloadItemManager import com.fasterxml.jackson.core.json.JsonReadFeature import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.getcapacitor.JSObject @@ -24,7 +24,9 @@ import java.io.File @CapacitorPlugin(name = "AbsDownloader") class AbsDownloader : Plugin() { private val tag = "AbsDownloader" - private var jacksonMapper = jacksonObjectMapper().enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature()) + private var jacksonMapper = + jacksonObjectMapper() + .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature()) lateinit var mainActivity: MainActivity lateinit var downloadManager: DownloadManager @@ -32,24 +34,32 @@ class AbsDownloader : Plugin() { lateinit var folderScanner: FolderScanner lateinit var downloadItemManager: DownloadItemManager - private val clientEventEmitter = (object : DownloadItemManager.DownloadEventEmitter { - override fun onDownloadItem(downloadItem:DownloadItem) { - notifyListeners("onDownloadItem", JSObject(jacksonMapper.writeValueAsString(downloadItem))) - } - override fun onDownloadItemPartUpdate(downloadItemPart:DownloadItemPart) { - notifyListeners("onDownloadItemPartUpdate", JSObject(jacksonMapper.writeValueAsString(downloadItemPart))) - } - override fun onDownloadItemComplete(jsobj:JSObject) { - notifyListeners("onItemDownloadComplete", jsobj) - } - }) + private val clientEventEmitter = + (object : DownloadItemManager.DownloadEventEmitter { + override fun onDownloadItem(downloadItem: DownloadItem) { + notifyListeners( + "onDownloadItem", + JSObject(jacksonMapper.writeValueAsString(downloadItem)) + ) + } + override fun onDownloadItemPartUpdate(downloadItemPart: DownloadItemPart) { + notifyListeners( + "onDownloadItemPartUpdate", + JSObject(jacksonMapper.writeValueAsString(downloadItemPart)) + ) + } + override fun onDownloadItemComplete(jsobj: JSObject) { + notifyListeners("onItemDownloadComplete", jsobj) + } + }) override fun load() { mainActivity = (activity as MainActivity) downloadManager = activity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager folderScanner = FolderScanner(mainActivity) apiHandler = ApiHandler(mainActivity) - downloadItemManager = DownloadItemManager(downloadManager, folderScanner, mainActivity, clientEventEmitter) + downloadItemManager = + DownloadItemManager(downloadManager, folderScanner, mainActivity, clientEventEmitter) } @PluginMethod @@ -58,12 +68,17 @@ class AbsDownloader : Plugin() { var episodeId = call.data.getString("episodeId").toString() if (episodeId == "null") episodeId = "" var localFolderId = call.data.getString("localFolderId", "").toString() - Log.d(tag, "Download library item $libraryItemId to folder $localFolderId / episode: $episodeId") + Log.d( + tag, + "Download library item $libraryItemId to folder $localFolderId / episode: $episodeId" + ) val downloadId = if (episodeId.isEmpty()) libraryItemId else "$libraryItemId-$episodeId" if (downloadItemManager.downloadItemQueue.find { it.id == downloadId } != null) { Log.d(tag, "Download already started for this media entity $downloadId") - return call.resolve(JSObject("{\"error\":\"Download already started for this media entity\"}")) + return call.resolve( + JSObject("{\"error\":\"Download already started for this media entity\"}") + ) } apiHandler.getLibraryItemWithProgress(libraryItemId, episodeId) { libraryItem -> @@ -79,7 +94,17 @@ class AbsDownloader : Plugin() { if (localFolder == null && localFolderId.startsWith("internal-")) { Log.d(tag, "Creating new App Storage internal LocalFolder $localFolderId") - localFolder = LocalFolder(localFolderId, "Internal App Storage", "", "", "", "", "internal", libraryItem.mediaType) + localFolder = + LocalFolder( + localFolderId, + "Internal App Storage", + "", + "", + "", + "", + "internal", + libraryItem.mediaType + ) DeviceManager.dbManager.saveLocalFolder(localFolder) } @@ -89,9 +114,8 @@ class AbsDownloader : Plugin() { call.resolve(JSObject("{\"error\":\"Invalid library item not a podcast\"}")) } else if (episodeId.isNotEmpty()) { val podcast = libraryItem.media as Podcast - val episode = podcast.episodes?.find { podcastEpisode -> - podcastEpisode.id == episodeId - } + val episode = + podcast.episodes?.find { podcastEpisode -> podcastEpisode.id == episodeId } if (episode == null) { call.resolve(JSObject("{\"error\":\"Invalid podcast episode not found\"}")) } else { @@ -118,21 +142,25 @@ class AbsDownloader : Plugin() { // Replace characters that cant be used in the file system // Reserved characters: ?:\"*|/\\<> - private fun cleanStringForFileSystem(str:String):String { + private fun cleanStringForFileSystem(str: String): String { val reservedCharacters = listOf("?", "\"", "*", "|", "/", "\\", "<", ">") var newTitle = str newTitle = newTitle.replace(":", " -") // Special case replace : with - - reservedCharacters.forEach { - newTitle = newTitle.replace(it, "") - } + reservedCharacters.forEach { newTitle = newTitle.replace(it, "") } return newTitle } - private fun startLibraryItemDownload(libraryItem: LibraryItem, localFolder: LocalFolder, episode:PodcastEpisode?) { + private fun startLibraryItemDownload( + libraryItem: LibraryItem, + localFolder: LocalFolder, + episode: PodcastEpisode? + ) { val isInternal = localFolder.id.startsWith("internal-") - val tempFolderPath = if (isInternal) "${mainActivity.filesDir}/downloads/${libraryItem.id}" else mainActivity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + val tempFolderPath = + if (isInternal) "${mainActivity.filesDir}/downloads/${libraryItem.id}" + else mainActivity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) Log.d(tag, "downloadCacheDirectory=$tempFolderPath") @@ -143,8 +171,25 @@ class AbsDownloader : Plugin() { 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 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 book.ebookFile?.let { ebookFile -> @@ -155,16 +200,35 @@ class AbsDownloader : Plugin() { val destinationFile = File("$tempFolderPath/$destinationFilename") if (destinationFile.exists()) { - Log.d(tag, "TEMP ebook file already exists, removing it from ${destinationFile.absolutePath}") + 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}") + Log.d( + tag, + "ebook file already exists, removing it from ${finalDestinationFile.absolutePath}" + ) finalDestinationFile.delete() } - val downloadItemPart = DownloadItemPart.make(downloadItem.id, destinationFilename, fileSize, destinationFile,finalDestinationFile,itemSubfolder,serverPath,localFolder,ebookFile,null,null) + val downloadItemPart = + DownloadItemPart.make( + downloadItem.id, + destinationFilename, + fileSize, + destinationFile, + finalDestinationFile, + itemSubfolder, + serverPath, + localFolder, + ebookFile, + null, + null + ) downloadItem.downloadItemParts.add(downloadItemPart) } @@ -173,34 +237,59 @@ class AbsDownloader : Plugin() { 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 + // 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 serverPath = "/api/items/${libraryItem.id}/file/${audioFileIno}/download" val destinationFilename = getFilenameFromRelPath(audioTrack.relPath) - Log.d(tag, "Audio File Server Path $serverPath | AF RelPath ${audioTrack.relPath} | LocalFolder Path ${localFolder.absolutePath} | DestName $destinationFilename") + 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") if (destinationFile.exists()) { - Log.d(tag, "TEMP Audio file already exists, removing it from ${destinationFile.absolutePath}") + 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}") + Log.d( + tag, + "Audio file already exists, removing it from ${finalDestinationFile.absolutePath}" + ) finalDestinationFile.delete() } - val downloadItemPart = DownloadItemPart.make(downloadItem.id, destinationFilename, fileSize, destinationFile,finalDestinationFile,itemSubfolder,serverPath,localFolder,null,audioTrack,null) + val downloadItemPart = + DownloadItemPart.make( + downloadItem.id, + destinationFilename, + fileSize, + destinationFile, + finalDestinationFile, + itemSubfolder, + serverPath, + localFolder, + null, + audioTrack, + null + ) 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 } + 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" @@ -209,16 +298,35 @@ class AbsDownloader : Plugin() { val finalDestinationFile = File("$itemFolderPath/$destinationFilename") if (destinationFile.exists()) { - Log.d(tag, "TEMP Audio file already exists, removing it from ${destinationFile.absolutePath}") + 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}") + 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) + val downloadItemPart = + DownloadItemPart.make( + downloadItem.id, + destinationFilename, + coverFileSize, + destinationFile, + finalDestinationFile, + itemSubfolder, + serverPath, + localFolder, + null, + null, + null + ) downloadItem.downloadItemParts.add(downloadItemPart) } @@ -233,26 +341,64 @@ class AbsDownloader : Plugin() { val fileSize = audioTrack?.metadata?.size ?: 0 Log.d(tag, "Starting podcast episode download") - val itemFolderPath = if (isInternal) "$tempFolderPath" else "${localFolder.absolutePath}/$podcastTitle" + val itemFolderPath = + if (isInternal) "$tempFolderPath" else "${localFolder.absolutePath}/$podcastTitle" val downloadItemId = "${libraryItem.id}-${episode?.id}" - 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()) + 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") + 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}") + Log.d( + tag, + "Audio file already exists, removing it from ${finalDestinationFile.absolutePath}" + ) finalDestinationFile.delete() } - var downloadItemPart = DownloadItemPart.make(downloadItem.id, destinationFilename,fileSize, destinationFile,finalDestinationFile,podcastTitle,serverPath,localFolder,null,audioTrack,episode) + var downloadItemPart = + DownloadItemPart.make( + downloadItem.id, + destinationFilename, + fileSize, + destinationFile, + finalDestinationFile, + podcastTitle, + serverPath, + localFolder, + null, + audioTrack, + episode + ) downloadItem.downloadItemParts.add(downloadItemPart) - if (libraryItem.media.coverPath != null && libraryItem.media.coverPath?.isNotEmpty() == true) { - val coverLibraryFile = libraryItem.libraryFiles?.find { it.metadata.path == libraryItem.media.coverPath } + 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 serverPath = "/api/items/${libraryItem.id}/cover" @@ -264,7 +410,20 @@ class AbsDownloader : Plugin() { if (finalDestinationFile.exists()) { Log.d(tag, "Podcast cover already exists - not downloading cover again") } else { - downloadItemPart = DownloadItemPart.make(downloadItem.id, destinationFilename,coverFileSize,destinationFile,finalDestinationFile,podcastTitle,serverPath,localFolder,null,null,null) + downloadItemPart = + DownloadItemPart.make( + downloadItem.id, + destinationFilename, + coverFileSize, + destinationFile, + finalDestinationFile, + podcastTitle, + serverPath, + localFolder, + null, + null, + null + ) downloadItem.downloadItemParts.add(downloadItemPart) } }