mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-31 07:09:53 +02:00
Handle download complete lifecycle
This commit is contained in:
parent
5495bcb945
commit
b549528e23
5 changed files with 62 additions and 9 deletions
|
@ -83,6 +83,8 @@ public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate {
|
||||||
|
|
||||||
// Handle a completed download
|
// Handle a completed download
|
||||||
if ( downloadItem.isDoneDownloading() ) {
|
if ( downloadItem.isDoneDownloading() ) {
|
||||||
|
// Delete the download item on exit even if handling complete errors
|
||||||
|
defer { Database.shared.removeDownloadItem(downloadItem) }
|
||||||
handleDownloadTaskCompleteFromDownloadItem(downloadItem)
|
handleDownloadTaskCompleteFromDownloadItem(downloadItem)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -92,17 +94,31 @@ public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleDownloadTaskCompleteFromDownloadItem(_ downloadItem: DownloadItem) {
|
private func handleDownloadTaskCompleteFromDownloadItem(_ downloadItem: DownloadItem) {
|
||||||
var statusNotification = [String: String]()
|
|
||||||
|
|
||||||
if ( downloadItem.didDownloadSuccessfully() ) {
|
if ( downloadItem.didDownloadSuccessfully() ) {
|
||||||
|
|
||||||
ApiClient.getLibraryItemWithProgress(libraryItemId: downloadItem.libraryItemId!, episodeId: downloadItem.episodeId) { libraryItem in
|
ApiClient.getLibraryItemWithProgress(libraryItemId: downloadItem.libraryItemId!, episodeId: downloadItem.episodeId) { libraryItem in
|
||||||
//let localDirectory = documentsDirectory.appendingPathComponent("\(libraryItem.id)")
|
var statusNotification = [String: Any]()
|
||||||
//let localLibraryItem = LocalLibraryItem(libraryItem, localUrl: localDirectory, server: Store.serverConfig!, files: <#T##[LocalFile]#>)
|
statusNotification["libraryItemId"] = libraryItem?.id
|
||||||
|
|
||||||
|
guard let libraryItem = libraryItem else { NSLog("LibraryItem not found"); return }
|
||||||
|
let localDirectory = self.documentsDirectory.appendingPathComponent("\(libraryItem.id)")
|
||||||
|
let files = downloadItem.downloadItemParts.map { part in LocalFile(libraryItem.id, part.filename!, part.mimeType()!, part.destinationURL()!) }
|
||||||
|
let localLibraryItem = LocalLibraryItem(libraryItem, localUrl: localDirectory, server: Store.serverConfig!, files: files)
|
||||||
|
|
||||||
|
Database.shared.saveLocalLibraryItem(localLibraryItem: localLibraryItem)
|
||||||
|
statusNotification["localLibraryItem"] = try? localLibraryItem.asDictionary()
|
||||||
|
|
||||||
|
if let progress = libraryItem.userMediaProgress {
|
||||||
|
// TODO: Handle podcast
|
||||||
|
let localMediaProgress = LocalMediaProgress(localLibraryItem: localLibraryItem, episode: nil, progress: progress)
|
||||||
|
Database.shared.saveLocalMediaProgress(localMediaProgress)
|
||||||
|
statusNotification["localMediaProgress"] = try? localMediaProgress.asDictionary()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.notifyListeners("onItemDownloadComplete", data: statusNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyListeners("onItemDownloadComplete", data: statusNotification)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func downloadLibraryItem(_ call: CAPPluginCall) {
|
@objc func downloadLibraryItem(_ call: CAPPluginCall) {
|
||||||
|
@ -203,4 +219,5 @@ enum LibraryItemDownloadError: String, Error {
|
||||||
case downloadItemNotFound = "DownloadItem not found"
|
case downloadItemNotFound = "DownloadItem not found"
|
||||||
case downloadItemPartNotFound = "DownloadItemPart not found"
|
case downloadItemPartNotFound = "DownloadItemPart not found"
|
||||||
case downloadItemPartDestinationUrlNotDefined = "DownloadItemPart destination URL not defined"
|
case downloadItemPartDestinationUrlNotDefined = "DownloadItemPart destination URL not defined"
|
||||||
|
case libraryItemNotFound = "LibraryItem not found for id"
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import Foundation
|
||||||
import Unrealm
|
import Unrealm
|
||||||
|
|
||||||
struct DownloadItem: Realmable, Codable {
|
struct DownloadItem: Realmable, Codable {
|
||||||
var id: String = UUID().uuidString
|
var id: String?
|
||||||
var libraryItemId: String?
|
var libraryItemId: String?
|
||||||
var episodeId: String?
|
var episodeId: String?
|
||||||
var userMediaProgress: MediaProgress?
|
var userMediaProgress: MediaProgress?
|
||||||
|
@ -36,6 +36,7 @@ struct DownloadItem: Realmable, Codable {
|
||||||
|
|
||||||
extension DownloadItem {
|
extension DownloadItem {
|
||||||
init(libraryItem: LibraryItem, server: ServerConnectionConfig) {
|
init(libraryItem: LibraryItem, server: ServerConnectionConfig) {
|
||||||
|
self.id = libraryItem.id
|
||||||
self.libraryItemId = libraryItem.id
|
self.libraryItemId = libraryItem.id
|
||||||
//self.episodeId // TODO
|
//self.episodeId // TODO
|
||||||
self.userMediaProgress = libraryItem.userMediaProgress
|
self.userMediaProgress = libraryItem.userMediaProgress
|
||||||
|
@ -52,7 +53,7 @@ extension DownloadItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
func didDownloadSuccessfully() -> Bool {
|
func didDownloadSuccessfully() -> Bool {
|
||||||
self.downloadItemParts.allSatisfy({ $0.failed = false })
|
self.downloadItemParts.allSatisfy({ $0.failed == false })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +102,10 @@ extension DownloadItemPart {
|
||||||
self.destinationUri = destination.path
|
self.destinationUri = destination.path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mimeType() -> String? {
|
||||||
|
audioTrack?.mimeType ?? episode?.audioTrack?.mimeType
|
||||||
|
}
|
||||||
|
|
||||||
func downloadURL() -> URL? {
|
func downloadURL() -> URL? {
|
||||||
if let uri = self.uri {
|
if let uri = self.uri {
|
||||||
return URL(string: uri)
|
return URL(string: uri)
|
||||||
|
|
|
@ -63,7 +63,7 @@ struct LocalFile: Realmable, Codable {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LocalMediaProgress: Realmable, Codable {
|
struct LocalMediaProgress: Realmable, Codable {
|
||||||
var id: String = UUID().uuidString
|
var id: String = ""
|
||||||
var localLibraryItemId: String = ""
|
var localLibraryItemId: String = ""
|
||||||
var localEpisodeId: String?
|
var localEpisodeId: String?
|
||||||
var duration: Double = 0
|
var duration: Double = 0
|
||||||
|
|
|
@ -75,6 +75,7 @@ extension LocalFile {
|
||||||
self.init()
|
self.init()
|
||||||
self.id = "\(libraryItemId)_\(filename.toBase64())"
|
self.id = "\(libraryItemId)_\(filename.toBase64())"
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
self.mimeType = mimeType
|
||||||
self.contentUrl = localUrl.absoluteString
|
self.contentUrl = localUrl.absoluteString
|
||||||
self.absolutePath = localUrl.path
|
self.absolutePath = localUrl.path
|
||||||
self.size = Int(localUrl.fileSize)
|
self.size = Int(localUrl.fileSize)
|
||||||
|
@ -90,3 +91,27 @@ extension LocalFile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension LocalMediaProgress {
|
||||||
|
init(localLibraryItem: LocalLibraryItem, episode: LocalPodcastEpisode?, progress: MediaProgress) {
|
||||||
|
self.id = localLibraryItem.id
|
||||||
|
self.localLibraryItemId = localLibraryItem.id
|
||||||
|
self.libraryItemId = localLibraryItem.libraryItemId
|
||||||
|
|
||||||
|
if let episode = episode {
|
||||||
|
self.id += "-\(episode.id)"
|
||||||
|
self.episodeId = episode.id
|
||||||
|
}
|
||||||
|
|
||||||
|
self.serverAddress = localLibraryItem.serverAddress
|
||||||
|
self.serverUserId = localLibraryItem.serverUserId
|
||||||
|
self.serverConnectionConfigId = localLibraryItem.serverConnectionConfigId
|
||||||
|
|
||||||
|
self.duration = progress.duration
|
||||||
|
self.currentTime = progress.currentTime
|
||||||
|
self.isFinished = false
|
||||||
|
self.lastUpdate = progress.lastUpdate
|
||||||
|
self.startedAt = progress.startedAt
|
||||||
|
self.finishedAt = progress.finishedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -177,6 +177,12 @@ class Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func removeDownloadItem(_ downloadItem: DownloadItem) {
|
||||||
|
Database.realmQueue.sync {
|
||||||
|
try! instance.write { instance.delete(downloadItem) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func getDeviceSettings() -> DeviceSettings {
|
public func getDeviceSettings() -> DeviceSettings {
|
||||||
return Database.realmQueue.sync {
|
return Database.realmQueue.sync {
|
||||||
return instance.objects(DeviceSettings.self).first ?? getDefaultDeviceSettings()
|
return instance.objects(DeviceSettings.self).first ?? getDefaultDeviceSettings()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue