Fix merge conflict errors

This commit is contained in:
ronaldheft 2022-08-14 18:22:50 -04:00
parent 934a07a5ad
commit 4c8217edf6
7 changed files with 48 additions and 105 deletions

View file

@ -171,7 +171,7 @@ public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate {
statusNotification["localLibraryItem"] = try? localLibraryItem.asDictionary() statusNotification["localLibraryItem"] = try? localLibraryItem.asDictionary()
if let progress = libraryItem.userMediaProgress { if let progress = libraryItem.userMediaProgress {
let episode = downloadItem.media?.episodes?.first(where: { $0.id == downloadItem.episodeId }) let episode = downloadItem.media?.episodes.first(where: { $0.id == downloadItem.episodeId })
let localMediaProgress = LocalMediaProgress(localLibraryItem: localLibraryItem!, episode: episode, progress: progress) let localMediaProgress = LocalMediaProgress(localLibraryItem: localLibraryItem!, episode: episode, progress: progress)
Database.shared.saveLocalMediaProgress(localMediaProgress) Database.shared.saveLocalMediaProgress(localMediaProgress)
statusNotification["localMediaProgress"] = try? localMediaProgress.asDictionary() statusNotification["localMediaProgress"] = try? localMediaProgress.asDictionary()

View file

@ -89,12 +89,14 @@ public class AbsFileSystem: CAPPlugin {
var success = false var success = false
do { do {
if let localLibraryItemId = localLibraryItemId, let trackLocalFileId = trackLocalFileId, var item = Database.shared.getLocalLibraryItem(localLibraryItemId: localLibraryItemId) { if let localLibraryItemId = localLibraryItemId, let trackLocalFileId = trackLocalFileId, let item = Database.shared.getLocalLibraryItem(localLibraryItemId: localLibraryItemId) {
if let fileIndex = item.localFiles.firstIndex(where: { $0.id == trackLocalFileId }) { if let fileIndex = item.localFiles.firstIndex(where: { $0.id == trackLocalFileId }) {
try FileManager.default.removeItem(at: item.localFiles[fileIndex].contentPath) try FileManager.default.removeItem(at: item.localFiles[fileIndex].contentPath)
item.localFiles.remove(at: fileIndex) item.localFiles.remove(at: fileIndex)
if item.isPodcast, var media = item.media { if item.isPodcast, let media = item.media {
media.episodes = media.episodes?.filter { $0.audioTrack?.localFileId != trackLocalFileId } if let episodeIndex = media.episodes.firstIndex(where: { $0.audioTrack?.localFileId == trackLocalFileId }) {
media.episodes.remove(at: episodeIndex)
}
item.media = media item.media = media
} }
Database.shared.saveLocalLibraryItem(localLibraryItem: item) Database.shared.saveLocalLibraryItem(localLibraryItem: item)

View file

@ -175,6 +175,8 @@ class Metadata: Object, Codable {
@Persisted var seriesName: String? @Persisted var seriesName: String?
@Persisted var feedUrl: String? @Persisted var feedUrl: String?
var authorDisplayName: String { self.authorName ?? "Unknown" }
private enum CodingKeys : String, CodingKey { private enum CodingKeys : String, CodingKey {
case title, case title,
subtitle, subtitle,
@ -254,7 +256,7 @@ class Metadata: Object, Codable {
class PodcastEpisode: Object, Codable { class PodcastEpisode: Object, Codable {
@Persisted var id: String = "" @Persisted var id: String = ""
@Persisted var index: Int = 0 @Persisted var index: Int?
@Persisted var episode: String? @Persisted var episode: String?
@Persisted var episodeType: String? @Persisted var episodeType: String?
@Persisted var title: String = "Unknown" @Persisted var title: String = "Unknown"
@ -262,8 +264,8 @@ class PodcastEpisode: Object, Codable {
@Persisted var desc: String? @Persisted var desc: String?
@Persisted var audioFile: AudioFile? @Persisted var audioFile: AudioFile?
@Persisted var audioTrack: AudioTrack? @Persisted var audioTrack: AudioTrack?
@Persisted var duration: Double = 0 @Persisted var duration: Double?
@Persisted var size: Int = 0 @Persisted var size: Int?
var serverEpisodeId: String { self.id } var serverEpisodeId: String { self.id }
private enum CodingKeys : String, CodingKey { private enum CodingKeys : String, CodingKey {
@ -281,7 +283,9 @@ class PodcastEpisode: Object, Codable {
serverEpisodeId serverEpisodeId
} }
init(from decoder: Decoder) throws { override init() {}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self) let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decode(String.self, forKey: .id) id = try values.decode(String.self, forKey: .id)
index = try? values.decode(Int.self, forKey: .index) index = try? values.decode(Int.self, forKey: .index)
@ -369,9 +373,6 @@ class Author: Object, Codable {
try container.encode(name, forKey: .name) try container.encode(name, forKey: .name)
try container.encode(coverPath, forKey: .coverPath) try container.encode(coverPath, forKey: .coverPath)
} }
override init() {
super.init()
} }
class Chapter: Object, Codable { class Chapter: Object, Codable {
@ -451,7 +452,7 @@ class AudioTrack: Object, Codable {
try container.encode(serverIndex, forKey: .serverIndex) try container.encode(serverIndex, forKey: .serverIndex)
} }
mutating func setLocalInfo(filenameIdMap: [String: String], serverIndex: Int) -> Bool { func setLocalInfo(filenameIdMap: [String: String], serverIndex: Int) -> Bool {
if let localFileId = filenameIdMap[self.metadata?.filename ?? ""] { if let localFileId = filenameIdMap[self.metadata?.filename ?? ""] {
self.localFileId = localFileId self.localFileId = localFileId
self.serverIndex = serverIndex self.serverIndex = serverIndex

View file

@ -75,35 +75,6 @@ class DownloadItemPart: Object, Codable {
@Persisted var progress: Double = 0 @Persisted var progress: Double = 0
var task: URLSessionDownloadTask? var task: URLSessionDownloadTask?
struct DownloadItemPart: Realmable, Codable {
var id: String = UUID().uuidString
var filename: String?
var itemTitle: String?
var serverPath: String?
var audioTrack: AudioTrack?
var episode: PodcastEpisode?
var completed: Bool = false
var moved: Bool = false
var failed: Bool = false
var uri: String?
var downloadURL: URL? {
if let uri = self.uri {
return URL(string: uri)
} else {
return nil
}
}
var destinationUri: String?
var destinationURL: URL? {
if let destinationUri = self.destinationUri {
return AbsDownloader.itemDownloadFolder(path: destinationUri)!
} else {
return nil
}
}
var progress: Double = 0
var task: URLSessionDownloadTask!
private enum CodingKeys : String, CodingKey { private enum CodingKeys : String, CodingKey {
case id, filename, itemTitle, completed, moved, failed, progress case id, filename, itemTitle, completed, moved, failed, progress
} }
@ -134,36 +105,3 @@ struct DownloadItemPart: Realmable, Codable {
try container.encode(progress, forKey: .progress) try container.encode(progress, forKey: .progress)
} }
} }
extension DownloadItemPart {
init(filename: String, destination: String, itemTitle: String, serverPath: String, audioTrack: AudioTrack?, episode: PodcastEpisode?) {
self.filename = filename
self.itemTitle = itemTitle
self.serverPath = serverPath
self.audioTrack = audioTrack
self.episode = episode
let config = Store.serverConfig!
var downloadUrl = ""
if (serverPath.hasSuffix("/cover")) {
downloadUrl += "\(config.address)\(serverPath)?token=\(config.token)"
downloadUrl += "&format=jpeg" // For cover images force to jpeg
} else {
downloadUrl = destination
}
self.uri = downloadUrl
self.destinationUri = destination
}
func mimeType() -> String? {
if let track = audioTrack {
return track.mimeType
} else if let podcastTrack = episode?.audioTrack {
return podcastTrack.mimeType
} else if serverPath?.hasSuffix("/cover") ?? false {
return "image/jpg"
} else {
return nil
}
}
}

View file

@ -65,7 +65,7 @@ extension DownloadItemPart {
var destinationURL: URL? { var destinationURL: URL? {
if let destinationUri = self.destinationUri { if let destinationUri = self.destinationUri {
return AbsDownloader.downloadsDirectory.appendingPathComponent(destinationUri) return AbsDownloader.itemDownloadFolder(path: destinationUri)
} else { } else {
return nil return nil
} }

View file

@ -133,7 +133,7 @@ class LocalPodcastEpisode: Object, Codable {
class LocalFile: Object, Codable { class LocalFile: Object, Codable {
@Persisted(primaryKey: true) var id: String = UUID().uuidString @Persisted(primaryKey: true) var id: String = UUID().uuidString
@Persisted var filename: String? @Persisted var filename: String?
@Persisted var contentUrl: String = "" @Persisted var _contentUrl: String = ""
@Persisted var mimeType: String? @Persisted var mimeType: String?
@Persisted var size: Int = 0 @Persisted var size: Int = 0

View file

@ -6,12 +6,13 @@
// //
import Foundation import Foundation
import RealmSwift
extension LocalLibraryItem { extension LocalLibraryItem {
convenience init(_ item: LibraryItem, localUrl: String, server: ServerConnectionConfig, files: [LocalFile], coverPath: String?) { convenience init(_ item: LibraryItem, localUrl: String, server: ServerConnectionConfig, files: [LocalFile], coverPath: String?) {
self.init() self.init()
self.contentUrl = localUrl self._contentUrl = localUrl
self.mediaType = item.mediaType self.mediaType = item.mediaType
self.localFiles.append(objectsIn: files) self.localFiles.append(objectsIn: files)
self._coverContentUrl = coverPath self._coverContentUrl = coverPath
@ -21,34 +22,33 @@ extension LocalLibraryItem {
self.serverUserId = server.userId self.serverUserId = server.userId
// Link the audio tracks and files // Link the audio tracks and files
linkLocalFiles(files, fromMedia: item.media)
}
mutating func addFiles(_ files: [LocalFile], item: LibraryItem) throws {
guard self.isPodcast else { throw LibraryItemDownloadError.podcastOnlySupported }
self.localFiles.append(contentsOf: files.filter({ $0.isAudioFile() }))
linkLocalFiles(self.localFiles, fromMedia: item.media) linkLocalFiles(self.localFiles, fromMedia: item.media)
} }
mutating private func linkLocalFiles(_ files: [LocalFile], fromMedia: MediaType) { func addFiles(_ files: [LocalFile], item: LibraryItem) throws {
var fromMedia = fromMedia guard self.isPodcast else { throw LibraryItemDownloadError.podcastOnlySupported }
self.localFiles.append(objectsIn: files.filter({ $0.isAudioFile() }))
linkLocalFiles(self.localFiles, fromMedia: item.media)
}
private func linkLocalFiles(_ files: List<LocalFile>, fromMedia: MediaType?) {
guard let fromMedia = fromMedia else { return }
let fileMap = files.map { ($0.filename ?? "", $0.id) } let fileMap = files.map { ($0.filename ?? "", $0.id) }
let fileIdByFilename = Dictionary(fileMap, uniquingKeysWith: { (_, last) in last }) let fileIdByFilename = Dictionary(fileMap, uniquingKeysWith: { (_, last) in last })
if ( self.isBook ) { if ( self.isBook ) {
if let tracks = fromMedia.tracks { for i in fromMedia.tracks.indices {
for i in tracks.indices { _ = fromMedia.tracks[i].setLocalInfo(filenameIdMap: fileIdByFilename, serverIndex: i)
_ = fromMedia.tracks?[i].setLocalInfo(filenameIdMap: fileIdByFilename, serverIndex: i)
}
} }
} else if ( self.isPodcast ) { } else if ( self.isPodcast ) {
if let episodes = fromMedia.episodes { let episodes = List<PodcastEpisode>()
fromMedia.episodes = episodes.compactMap { episode in for episode in fromMedia.episodes {
// Filter out episodes not downloaded // Filter out episodes not downloaded
var episode = episode let episodeIsDownloaded = episode.audioTrack?.setLocalInfo(filenameIdMap: fileIdByFilename, serverIndex: 0) ?? false
let episodeIsDownloaded = episode.audioTrack?.setLocalInfo(filenameIdMap: fileIdByFilename, serverIndex: 0) ?? false if episodeIsDownloaded {
return episodeIsDownloaded ? episode : nil episodes.append(episode)
} }
} }
fromMedia.episodes = episodes
} }
self.media = fromMedia self.media = fromMedia
} }
@ -74,12 +74,14 @@ extension LocalLibraryItem {
let mediaProgress = Database.shared.getLocalMediaProgress(localMediaProgressId: mediaProgressId) let mediaProgress = Database.shared.getLocalMediaProgress(localMediaProgressId: mediaProgressId)
let mediaMetadata = self.media?.metadata let mediaMetadata = self.media?.metadata
let chapters = self.media?.chapters let chapters = Array(self.media?.chapters ?? List<Chapter>())
var audioTracks = self.media?.tracks
let authorName = mediaMetadata?.authorDisplayName let authorName = mediaMetadata?.authorDisplayName
var audioTracks = [AudioTrack]()
if let episode = episode, let track = episode.audioTrack { if let episode = episode, let track = episode.audioTrack {
audioTracks = [track] audioTracks.append(track)
} else if let tracks = self.media?.tracks {
audioTracks.append(contentsOf: tracks)
} }
let dateNow = Date().timeIntervalSince1970 let dateNow = Date().timeIntervalSince1970
@ -89,7 +91,7 @@ extension LocalLibraryItem {
libraryItemId: self.libraryItemId, libraryItemId: self.libraryItemId,
episodeId: episode?.serverEpisodeId, episodeId: episode?.serverEpisodeId,
mediaType: self.mediaType, mediaType: self.mediaType,
chapters: chapters ?? [], chapters: chapters,
displayTitle: mediaMetadata?.title, displayTitle: mediaMetadata?.title,
displayAuthor: authorName, displayAuthor: authorName,
coverPath: self.coverContentUrl, coverPath: self.coverContentUrl,
@ -98,7 +100,7 @@ extension LocalLibraryItem {
startedAt: dateNow, startedAt: dateNow,
updatedAt: 0, updatedAt: 0,
timeListening: 0.0, timeListening: 0.0,
audioTracks: audioTracks ?? [], audioTracks: audioTracks,
currentTime: mediaProgress?.currentTime ?? 0.0, currentTime: mediaProgress?.currentTime ?? 0.0,
libraryItem: nil, libraryItem: nil,
localLibraryItem: self, localLibraryItem: self,
@ -120,7 +122,7 @@ extension LocalFile {
} }
var absolutePath: String { var absolutePath: String {
return AbsDownloader.downloadsDirectory.appendingPathComponent(self.contentUrl).absoluteString return AbsDownloader.itemDownloadFolder(path: self._contentUrl)?.absoluteString ?? ""
} }
func isAudioFile() -> Bool { func isAudioFile() -> Bool {
@ -161,7 +163,7 @@ extension LocalMediaProgress {
} }
} }
init(localLibraryItem: LocalLibraryItem, episode: PodcastEpisode?, progress: MediaProgress) { convenience init(localLibraryItem: LocalLibraryItem, episode: PodcastEpisode?, progress: MediaProgress) {
self.init(localLibraryItem: localLibraryItem, episode: episode) self.init(localLibraryItem: localLibraryItem, episode: episode)
self.duration = progress.duration self.duration = progress.duration
self.progress = progress.progress self.progress = progress.progress
@ -172,7 +174,7 @@ extension LocalMediaProgress {
self.finishedAt = progress.finishedAt self.finishedAt = progress.finishedAt
} }
mutating func updateIsFinished(_ finished: Bool) { func updateIsFinished(_ finished: Bool) {
if self.isFinished != finished { if self.isFinished != finished {
self.progress = finished ? 1.0 : 0.0 self.progress = finished ? 1.0 : 0.0
} }
@ -186,7 +188,7 @@ extension LocalMediaProgress {
self.finishedAt = finished ? lastUpdate : nil self.finishedAt = finished ? lastUpdate : nil
} }
mutating func updateFromPlaybackSession(_ playbackSession: PlaybackSession) { func updateFromPlaybackSession(_ playbackSession: PlaybackSession) {
self.currentTime = playbackSession.currentTime self.currentTime = playbackSession.currentTime
self.progress = playbackSession.progress self.progress = playbackSession.progress
self.lastUpdate = Int(Date().timeIntervalSince1970) self.lastUpdate = Int(Date().timeIntervalSince1970)
@ -194,7 +196,7 @@ extension LocalMediaProgress {
self.finishedAt = self.isFinished ? self.lastUpdate : nil self.finishedAt = self.isFinished ? self.lastUpdate : nil
} }
mutating func updateFromServerMediaProgress(_ serverMediaProgress: MediaProgress) { func updateFromServerMediaProgress(_ serverMediaProgress: MediaProgress) {
self.isFinished = serverMediaProgress.isFinished self.isFinished = serverMediaProgress.isFinished
self.progress = serverMediaProgress.progress self.progress = serverMediaProgress.progress
self.currentTime = serverMediaProgress.currentTime self.currentTime = serverMediaProgress.currentTime