From 9e306eff1eb2e3fba8105ffc7cdc33a57abe9926 Mon Sep 17 00:00:00 2001 From: kingbri Date: Mon, 3 Jun 2024 15:46:18 -0400 Subject: [PATCH] Debrid: Add protocol for cloud handling Cloud downloads and torrents are now unified under their own protocol and models. Downloads and torrents are separated. Signed-off-by: kingbri --- Ferrite/API/AllDebridWrapper.swift | 75 ++++++++++++------- Ferrite/API/PremiumizeWrapper.swift | 24 +++++- Ferrite/API/RealDebridWrapper.swift | 58 ++++++++------ Ferrite/Models/DebridModels.swift | 16 +++- Ferrite/Protocols/Debrid.swift | 10 +++ Ferrite/ViewModels/DebridManager.swift | 34 ++++----- .../Library/Cloud/AllDebridCloudView.swift | 54 ++++++------- .../Library/Cloud/PremiumizeCloudView.swift | 18 ++--- .../Library/Cloud/RealDebridCloudView.swift | 44 +++++------ 9 files changed, 204 insertions(+), 129 deletions(-) diff --git a/Ferrite/API/AllDebridWrapper.swift b/Ferrite/API/AllDebridWrapper.swift index c5616ee..d0251e5 100644 --- a/Ferrite/API/AllDebridWrapper.swift +++ b/Ferrite/API/AllDebridWrapper.swift @@ -10,6 +10,8 @@ import Foundation // TODO: Fix errors public class AllDebrid: PollingDebridSource { public let id = "AllDebrid" + public let abbreviation = "AD" + public let website = "https://alldebrid.com" public var authTask: Task? let baseApiUrl = "https://api.alldebrid.com/v4" @@ -203,28 +205,6 @@ public class AllDebrid: PollingDebridSource { } } - public func userMagnets() async throws -> [MagnetStatusData] { - var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/magnet/status")) - - let data = try await performRequest(request: &request, requestName: #function) - let rawResponse = try jsonDecoder.decode(ADResponse.self, from: data).data - - if rawResponse.magnets.isEmpty { - throw ADError.EmptyData - } else { - return rawResponse.magnets - } - } - - public func deleteMagnet(magnetId: Int) async throws { - let queryItems = [ - URLQueryItem(name: "id", value: String(magnetId)) - ] - var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/magnet/delete", queryItems: queryItems)) - - try await performRequest(request: &request, requestName: #function) - } - public func unlockLink(lockedLink: String) async throws -> String { let queryItems = [ URLQueryItem(name: "link", value: lockedLink) @@ -246,7 +226,40 @@ public class AllDebrid: PollingDebridSource { try await performRequest(request: &request, requestName: #function) } - public func savedLinks() async throws -> [SavedLink] { + // Referred to as "User magnets" in AllDebrid's API + public func getUserTorrents() async throws -> [DebridCloudTorrent] { + var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/magnet/status")) + + let data = try await performRequest(request: &request, requestName: #function) + let rawResponse = try jsonDecoder.decode(ADResponse.self, from: data).data + + if rawResponse.magnets.isEmpty { + throw ADError.EmptyData + } + + let torrents = rawResponse.magnets.map { magnetResponse in + DebridCloudTorrent( + torrentId: String(magnetResponse.id), + fileName: magnetResponse.filename, + status: magnetResponse.status, + hash: magnetResponse.hash, + links: magnetResponse.links.map { $0.link } + ) + } + + return torrents + } + + public func deleteTorrent(torrentId: String) async throws { + let queryItems = [ + URLQueryItem(name: "id", value: torrentId) + ] + var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/magnet/delete", queryItems: queryItems)) + + try await performRequest(request: &request, requestName: #function) + } + + public func getUserDownloads() async throws -> [DebridCloudDownload] { var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/user/links")) let data = try await performRequest(request: &request, requestName: #function) @@ -254,14 +267,22 @@ public class AllDebrid: PollingDebridSource { if rawResponse.links.isEmpty { throw ADError.EmptyData - } else { - return rawResponse.links } + + // The link is also the ID + let downloads = rawResponse.links.map { link in + DebridCloudDownload( + downloadId: link.link, fileName: link.filename, link: link.link + ) + } + + return downloads } - public func deleteLink(link: String) async throws { + // The downloadId is actually the download link + public func deleteDownload(downloadId: String) async throws { let queryItems = [ - URLQueryItem(name: "link", value: link) + URLQueryItem(name: "link", value: downloadId) ] var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/user/links/delete", queryItems: queryItems)) diff --git a/Ferrite/API/PremiumizeWrapper.swift b/Ferrite/API/PremiumizeWrapper.swift index d0ab2eb..54d489f 100644 --- a/Ferrite/API/PremiumizeWrapper.swift +++ b/Ferrite/API/PremiumizeWrapper.swift @@ -9,6 +9,8 @@ import Foundation public class Premiumize: OAuthDebridSource { public let id = "Premiumize" + public let abbreviation = "PM" + public let website = "https://premiumize.me" let baseAuthUrl = "https://www.premiumize.me/authorize" let baseApiUrl = "https://www.premiumize.me/api" @@ -247,7 +249,7 @@ public class Premiumize: OAuthDebridSource { try await performRequest(request: &request, requestName: #function) } - func userItems() async throws -> [UserItem] { + public func getUserDownloads() async throws -> [DebridCloudDownload] { var request = URLRequest(url: URL(string: "\(baseApiUrl)/item/listall")!) let data = try await performRequest(request: &request, requestName: #function) @@ -257,7 +259,12 @@ public class Premiumize: OAuthDebridSource { throw PMError.EmptyData } - return rawResponse.files + // The "link" is the ID for Premiumize + let downloads = rawResponse.files.map { file in + DebridCloudDownload(downloadId: file.id, fileName: file.name, link: file.id) + } + + return downloads } func itemDetails(itemID: String) async throws -> ItemDetailsResponse { @@ -275,16 +282,25 @@ public class Premiumize: OAuthDebridSource { return rawResponse } - func deleteItem(itemID: String) async throws { + public func deleteDownload(downloadId: String) async throws { var request = URLRequest(url: URL(string: "\(baseApiUrl)/item/delete")!) request.httpMethod = "POST" request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") var bodyComponents = URLComponents() - bodyComponents.queryItems = [URLQueryItem(name: "id", value: itemID)] + bodyComponents.queryItems = [URLQueryItem(name: "id", value: downloadId)] request.httpBody = bodyComponents.query?.data(using: .utf8) try await performRequest(request: &request, requestName: #function) } + + // No user torrents for Premiumize + public func getUserTorrents() async throws -> [DebridCloudTorrent] { + return [] + } + + public func deleteTorrent(torrentId: String) async throws { + return + } } diff --git a/Ferrite/API/RealDebridWrapper.swift b/Ferrite/API/RealDebridWrapper.swift index f11812d..59a362b 100644 --- a/Ferrite/API/RealDebridWrapper.swift +++ b/Ferrite/API/RealDebridWrapper.swift @@ -9,6 +9,8 @@ import Foundation public class RealDebrid: PollingDebridSource { public let id = "RealDebrid" + public let abbreviation = "RD" + public let website = "https://real-debrid.com" public var authTask: Task? let baseAuthUrl = "https://api.real-debrid.com/oauth/v2" @@ -357,24 +359,6 @@ public class RealDebrid: PollingDebridSource { } } - // Gets the user's torrent library - public func userTorrents() async throws -> [UserTorrentsResponse] { - var request = URLRequest(url: URL(string: "\(baseApiUrl)/torrents")!) - - let data = try await performRequest(request: &request, requestName: #function) - let rawResponse = try jsonDecoder.decode([UserTorrentsResponse].self, from: data) - - return rawResponse - } - - // Deletes a torrent download from RD - public func deleteTorrent(debridID: String) async throws { - var request = URLRequest(url: URL(string: "\(baseApiUrl)/torrents/delete/\(debridID)")!) - request.httpMethod = "DELETE" - - try await performRequest(request: &request, requestName: #function) - } - // Downloads link from selectFiles for playback public func unrestrictLink(debridDownloadLink: String) async throws -> String { var request = URLRequest(url: URL(string: "\(baseApiUrl)/unrestrict/link")!) @@ -392,18 +376,48 @@ public class RealDebrid: PollingDebridSource { return rawResponse.download } + // Gets the user's torrent library + public func getUserTorrents() async throws -> [DebridCloudTorrent] { + var request = URLRequest(url: URL(string: "\(baseApiUrl)/torrents")!) + + let data = try await performRequest(request: &request, requestName: #function) + let rawResponse = try jsonDecoder.decode([UserTorrentsResponse].self, from: data) + let torrents = rawResponse.map { response in + DebridCloudTorrent( + torrentId: response.id, + fileName: response.filename, + status: response.status, + hash: response.hash, + links: response.links + ) + } + + return torrents + } + + // Deletes a torrent download from RD + public func deleteTorrent(torrentId: String) async throws { + var request = URLRequest(url: URL(string: "\(baseApiUrl)/torrents/delete/\(torrentId)")!) + request.httpMethod = "DELETE" + + try await performRequest(request: &request, requestName: #function) + } + // Gets the user's downloads - public func userDownloads() async throws -> [UserDownloadsResponse] { + public func getUserDownloads() async throws -> [DebridCloudDownload] { var request = URLRequest(url: URL(string: "\(baseApiUrl)/downloads")!) let data = try await performRequest(request: &request, requestName: #function) let rawResponse = try jsonDecoder.decode([UserDownloadsResponse].self, from: data) + let downloads = rawResponse.map { response in + DebridCloudDownload(downloadId: response.id, fileName: response.filename, link: response.download) + } - return rawResponse + return downloads } - public func deleteDownload(debridID: String) async throws { - var request = URLRequest(url: URL(string: "\(baseApiUrl)/downloads/delete/\(debridID)")!) + public func deleteDownload(downloadId: String) async throws { + var request = URLRequest(url: URL(string: "\(baseApiUrl)/downloads/delete/\(downloadId)")!) request.httpMethod = "DELETE" try await performRequest(request: &request, requestName: #function) diff --git a/Ferrite/Models/DebridModels.swift b/Ferrite/Models/DebridModels.swift index 14a46a1..1431807 100644 --- a/Ferrite/Models/DebridModels.swift +++ b/Ferrite/Models/DebridModels.swift @@ -7,7 +7,7 @@ import Foundation -public struct DebridIA: Sendable, Hashable { +public struct DebridIA: Hashable, Sendable { let magnet: Magnet let expiryTimeStamp: Double var files: [DebridIAFile] @@ -27,4 +27,16 @@ public struct DebridIAFile: Hashable, Sendable { } } -public struct DebridCloudFile {} +public struct DebridCloudDownload: Hashable, Sendable { + let downloadId: String + let fileName: String + let link: String +} + +public struct DebridCloudTorrent: Hashable, Sendable { + let torrentId: String + let fileName: String + let status: String + let hash: String + let links: [String] +} diff --git a/Ferrite/Protocols/Debrid.swift b/Ferrite/Protocols/Debrid.swift index 396ebe6..b4cd275 100644 --- a/Ferrite/Protocols/Debrid.swift +++ b/Ferrite/Protocols/Debrid.swift @@ -10,6 +10,8 @@ import Foundation public protocol DebridSource { // ID of the service var id: String { get } + var abbreviation: String { get } + var website: String { get } // Common authentication functions func setApiKey(_ key: String) -> Bool @@ -18,6 +20,14 @@ public protocol DebridSource { // Fetches a download link from a source // Include the instant availability information with the args func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String + + // Fetches cloud information from the service + func getUserDownloads() async throws -> [DebridCloudDownload] + func getUserTorrents() async throws -> [DebridCloudTorrent] + + // Deletes information from the service + func deleteDownload(downloadId: String) async throws + func deleteTorrent(torrentId: String) async throws } public protocol PollingDebridSource: DebridSource { diff --git a/Ferrite/ViewModels/DebridManager.swift b/Ferrite/ViewModels/DebridManager.swift index c39c904..87139b3 100644 --- a/Ferrite/ViewModels/DebridManager.swift +++ b/Ferrite/ViewModels/DebridManager.swift @@ -69,8 +69,8 @@ public class DebridManager: ObservableObject { // TODO: Maybe make these generic? // RealDebrid cloud variables - @Published var realDebridCloudTorrents: [RealDebrid.UserTorrentsResponse] = [] - @Published var realDebridCloudDownloads: [RealDebrid.UserDownloadsResponse] = [] + @Published var realDebridCloudTorrents: [DebridCloudTorrent] = [] + @Published var realDebridCloudDownloads: [DebridCloudDownload] = [] var realDebridCloudTTL: Double = 0.0 // AllDebrid auth variables @@ -83,8 +83,8 @@ public class DebridManager: ObservableObject { var selectedAllDebridFile: DebridIAFile? // AllDebrid cloud variables - @Published var allDebridCloudMagnets: [AllDebrid.MagnetStatusData] = [] - @Published var allDebridCloudLinks: [AllDebrid.SavedLink] = [] + @Published var allDebridCloudMagnets: [DebridCloudTorrent] = [] + @Published var allDebridCloudLinks: [DebridCloudDownload] = [] var allDebridCloudTTL: Double = 0.0 // Premiumize auth variables @@ -97,7 +97,7 @@ public class DebridManager: ObservableObject { var selectedPremiumizeFile: DebridIAFile? // Premiumize cloud variables - @Published var premiumizeCloudItems: [Premiumize.UserItem] = [] + @Published var premiumizeCloudItems: [DebridCloudDownload] = [] var premiumizeCloudTTL: Double = 0.0 init() { @@ -651,8 +651,8 @@ public class DebridManager: ObservableObject { public func fetchRdCloud(bypassTTL: Bool = false) async { if bypassTTL || Date().timeIntervalSince1970 > realDebridCloudTTL { do { - realDebridCloudTorrents = try await realDebrid.userTorrents() - realDebridCloudDownloads = try await realDebrid.userDownloads() + realDebridCloudTorrents = try await realDebrid.getUserTorrents() + realDebridCloudDownloads = try await realDebrid.getUserDownloads() // 5 minutes realDebridCloudTTL = Date().timeIntervalSince1970 + 300 @@ -664,7 +664,7 @@ public class DebridManager: ObservableObject { func deleteRdDownload(downloadID: String) async { do { - try await realDebrid.deleteDownload(debridID: downloadID) + try await realDebrid.deleteDownload(downloadId: downloadID) // Bypass TTL to get current RD values await fetchRdCloud(bypassTTL: true) @@ -676,7 +676,7 @@ public class DebridManager: ObservableObject { func deleteRdTorrent(torrentID: String? = nil, presentError: Bool = true) async { do { if let torrentID { - try await realDebrid.deleteTorrent(debridID: torrentID) + try await realDebrid.deleteTorrent(torrentId: torrentID) } else { throw RealDebrid.RDError.FailedRequest(description: "No torrent ID was provided") } @@ -688,7 +688,7 @@ public class DebridManager: ObservableObject { func checkRdUserDownloads(userTorrentLink: String) async -> String? { do { let existingLinks = realDebridCloudDownloads.first { $0.link == userTorrentLink } - if let existingLink = existingLinks?.download { + if let existingLink = existingLinks?.fileName { return existingLink } else { return try await realDebrid.unrestrictLink(debridDownloadLink: userTorrentLink) @@ -761,8 +761,8 @@ public class DebridManager: ObservableObject { public func fetchAdCloud(bypassTTL: Bool = false) async { if bypassTTL || Date().timeIntervalSince1970 > allDebridCloudTTL { do { - allDebridCloudMagnets = try await allDebrid.userMagnets() - allDebridCloudLinks = try await allDebrid.savedLinks() + allDebridCloudMagnets = try await allDebrid.getUserTorrents() + allDebridCloudLinks = try await allDebrid.getUserDownloads() // 5 minutes allDebridCloudTTL = Date().timeIntervalSince1970 + 300 @@ -774,7 +774,7 @@ public class DebridManager: ObservableObject { func deleteAdLink(link: String) async { do { - try await allDebrid.deleteLink(link: link) + try await allDebrid.deleteDownload(downloadId: link) await fetchAdCloud(bypassTTL: true) } catch { @@ -782,9 +782,9 @@ public class DebridManager: ObservableObject { } } - func deleteAdMagnet(magnetId: Int) async { + func deleteAdMagnet(magnetId: String) async { do { - try await allDebrid.deleteMagnet(magnetId: magnetId) + try await allDebrid.deleteTorrent(torrentId: magnetId) await fetchAdCloud(bypassTTL: true) } catch { @@ -817,7 +817,7 @@ public class DebridManager: ObservableObject { public func fetchPmCloud(bypassTTL: Bool = false) async { if bypassTTL || Date().timeIntervalSince1970 > premiumizeCloudTTL { do { - let userItems = try await premiumize.userItems() + let userItems = try await premiumize.getUserDownloads() withAnimation { premiumizeCloudItems = userItems } @@ -835,7 +835,7 @@ public class DebridManager: ObservableObject { public func deletePmItem(id: String) async { do { - try await premiumize.deleteItem(itemID: id) + try await premiumize.deleteDownload(downloadId: id) // Bypass TTL to get current RD values await fetchPmCloud(bypassTTL: true) diff --git a/Ferrite/Views/ComponentViews/Library/Cloud/AllDebridCloudView.swift b/Ferrite/Views/ComponentViews/Library/Cloud/AllDebridCloudView.swift index f0cf0ce..ed09447 100644 --- a/Ferrite/Views/ComponentViews/Library/Cloud/AllDebridCloudView.swift +++ b/Ferrite/Views/ComponentViews/Library/Cloud/AllDebridCloudView.swift @@ -17,17 +17,17 @@ struct AllDebridCloudView: View { var body: some View { DisclosureGroup("Links") { ForEach(debridManager.allDebridCloudLinks.filter { - searchText.isEmpty ? true : $0.filename.lowercased().contains(searchText.lowercased()) - }, id: \.self) { downloadResponse in - Button(downloadResponse.filename) { + searchText.isEmpty ? true : $0.fileName.lowercased().contains(searchText.lowercased()) + }, id: \.self) { cloudDownload in + Button(cloudDownload.fileName) { navModel.resultFromCloud = true - navModel.selectedTitle = downloadResponse.filename - debridManager.downloadUrl = downloadResponse.link + navModel.selectedTitle = cloudDownload.fileName + debridManager.downloadUrl = cloudDownload.link PersistenceController.shared.createHistory( HistoryEntryJson( - name: downloadResponse.filename, - url: downloadResponse.link, + name: cloudDownload.fileName, + url: cloudDownload.link, source: DebridType.allDebrid.toString() ), performSave: true @@ -43,9 +43,9 @@ struct AllDebridCloudView: View { } .onDelete { offsets in for index in offsets { - if let savedLink = debridManager.allDebridCloudLinks[safe: index] { + if let cloudDownload = debridManager.allDebridCloudLinks[safe: index] { Task { - await debridManager.deleteAdLink(link: savedLink.link) + await debridManager.deleteAdLink(link: cloudDownload.downloadId) } } } @@ -54,26 +54,26 @@ struct AllDebridCloudView: View { DisclosureGroup("Magnets") { ForEach(debridManager.allDebridCloudMagnets.filter { - searchText.isEmpty ? true : $0.filename.lowercased().contains(searchText.lowercased()) - }, id: \.id) { magnet in + searchText.isEmpty ? true : $0.fileName.lowercased().contains(searchText.lowercased()) + }, id: \.self) { cloudTorrent in Button { - if magnet.status == "Ready", !magnet.links.isEmpty { + if cloudTorrent.status == "Ready", !cloudTorrent.links.isEmpty { navModel.resultFromCloud = true - navModel.selectedTitle = magnet.filename + navModel.selectedTitle = cloudTorrent.fileName var historyInfo = HistoryEntryJson( - name: magnet.filename, + name: cloudTorrent.fileName, source: DebridType.allDebrid.toString() ) Task { - if magnet.links.count == 1 { - if let lockedLink = magnet.links[safe: 0]?.link { - await debridManager.fetchDebridDownload(magnet: nil, cloudInfo: lockedLink) - + if cloudTorrent.links.count == 1 { + if let torrentLink = cloudTorrent.links[safe: 0] { + await debridManager.fetchDebridDownload(magnet: nil, cloudInfo: torrentLink) if !debridManager.downloadUrl.isEmpty { historyInfo.url = debridManager.downloadUrl PersistenceController.shared.createHistory(historyInfo, performSave: true) + pluginManager.runDefaultAction( urlString: debridManager.downloadUrl, navModel: navModel @@ -81,7 +81,7 @@ struct AllDebridCloudView: View { } } } else { - let magnet = Magnet(hash: magnet.hash, link: nil) + let magnet = Magnet(hash: cloudTorrent.hash, link: nil) // Do not clear old IA values await debridManager.populateDebridIA([magnet]) @@ -93,27 +93,29 @@ struct AllDebridCloudView: View { } } } - } label: { VStack(alignment: .leading, spacing: 10) { - Text(magnet.filename) + Text(cloudTorrent.fileName) + .font(.callout) + .fixedSize(horizontal: false, vertical: true) + .lineLimit(4) HStack { - Text(magnet.status) + Text(cloudTorrent.status.capitalizingFirstLetter()) Spacer() - DebridLabelView(cloudLinks: magnet.links.map(\.link)) + DebridLabelView(cloudLinks: cloudTorrent.links) } .font(.caption) } } - .disabledAppearance(navModel.currentChoiceSheet != nil, dimmedOpacity: 0.9, animation: .easeOut(duration: 0.2)) + .disabledAppearance(navModel.currentChoiceSheet != nil, dimmedOpacity: 0.7, animation: .easeOut(duration: 0.2)) .tint(.primary) } .onDelete { offsets in for index in offsets { - if let magnet = debridManager.allDebridCloudMagnets[safe: index] { + if let cloudTorrent = debridManager.allDebridCloudMagnets[safe: index] { Task { - await debridManager.deleteAdMagnet(magnetId: magnet.id) + await debridManager.deleteAdMagnet(magnetId: cloudTorrent.torrentId) } } } diff --git a/Ferrite/Views/ComponentViews/Library/Cloud/PremiumizeCloudView.swift b/Ferrite/Views/ComponentViews/Library/Cloud/PremiumizeCloudView.swift index d309684..e9acb9a 100644 --- a/Ferrite/Views/ComponentViews/Library/Cloud/PremiumizeCloudView.swift +++ b/Ferrite/Views/ComponentViews/Library/Cloud/PremiumizeCloudView.swift @@ -17,20 +17,20 @@ struct PremiumizeCloudView: View { var body: some View { DisclosureGroup("Items") { ForEach(debridManager.premiumizeCloudItems.filter { - searchText.isEmpty ? true : $0.name.lowercased().contains(searchText.lowercased()) - }, id: \.id) { item in - Button(item.name) { + searchText.isEmpty ? true : $0.fileName.lowercased().contains(searchText.lowercased()) + }, id: \.self) { cloudDownload in + Button(cloudDownload.fileName) { Task { navModel.resultFromCloud = true - navModel.selectedTitle = item.name + navModel.selectedTitle = cloudDownload.fileName - await debridManager.fetchDebridDownload(magnet: nil, cloudInfo: item.id) + await debridManager.fetchDebridDownload(magnet: nil, cloudInfo: cloudDownload.downloadId) if !debridManager.downloadUrl.isEmpty { PersistenceController.shared.createHistory( HistoryEntryJson( - name: item.name, - url: debridManager.downloadUrl, + name: cloudDownload.fileName, + url: cloudDownload.link, source: DebridType.premiumize.toString() ), performSave: true @@ -48,9 +48,9 @@ struct PremiumizeCloudView: View { } .onDelete { offsets in for index in offsets { - if let item = debridManager.premiumizeCloudItems[safe: index] { + if let cloudDownload = debridManager.premiumizeCloudItems[safe: index] { Task { - await debridManager.deletePmItem(id: item.id) + await debridManager.deletePmItem(id: cloudDownload.downloadId) } } } diff --git a/Ferrite/Views/ComponentViews/Library/Cloud/RealDebridCloudView.swift b/Ferrite/Views/ComponentViews/Library/Cloud/RealDebridCloudView.swift index b133ef8..0cc39cf 100644 --- a/Ferrite/Views/ComponentViews/Library/Cloud/RealDebridCloudView.swift +++ b/Ferrite/Views/ComponentViews/Library/Cloud/RealDebridCloudView.swift @@ -18,17 +18,17 @@ struct RealDebridCloudView: View { Group { DisclosureGroup("Downloads") { ForEach(debridManager.realDebridCloudDownloads.filter { - searchText.isEmpty ? true : $0.filename.lowercased().contains(searchText.lowercased()) - }, id: \.self) { downloadResponse in - Button(downloadResponse.filename) { + searchText.isEmpty ? true : $0.fileName .lowercased().contains(searchText.lowercased()) + }, id: \.self) { cloudDownload in + Button(cloudDownload.fileName) { navModel.resultFromCloud = true - navModel.selectedTitle = downloadResponse.filename - debridManager.downloadUrl = downloadResponse.download + navModel.selectedTitle = cloudDownload.fileName + debridManager.downloadUrl = cloudDownload.link PersistenceController.shared.createHistory( HistoryEntryJson( - name: downloadResponse.filename, - url: downloadResponse.download, + name: cloudDownload.fileName, + url: cloudDownload.link, source: DebridType.realDebrid.toString() ), performSave: true @@ -44,9 +44,9 @@ struct RealDebridCloudView: View { } .onDelete { offsets in for index in offsets { - if let downloadResponse = debridManager.realDebridCloudDownloads[safe: index] { + if let cloudDownload = debridManager.realDebridCloudDownloads[safe: index] { Task { - await debridManager.deleteRdDownload(downloadID: downloadResponse.id) + await debridManager.deleteRdDownload(downloadID: cloudDownload.downloadId) } } } @@ -55,21 +55,21 @@ struct RealDebridCloudView: View { DisclosureGroup("Torrents") { ForEach(debridManager.realDebridCloudTorrents.filter { - searchText.isEmpty ? true : $0.filename.lowercased().contains(searchText.lowercased()) - }, id: \.self) { torrentResponse in + searchText.isEmpty ? true : $0.fileName.lowercased().contains(searchText.lowercased()) + }, id: \.self) { cloudTorrent in Button { - if torrentResponse.status == "downloaded", !torrentResponse.links.isEmpty { + if cloudTorrent.status == "downloaded", !cloudTorrent.links.isEmpty { navModel.resultFromCloud = true - navModel.selectedTitle = torrentResponse.filename + navModel.selectedTitle = cloudTorrent.fileName var historyInfo = HistoryEntryJson( - name: torrentResponse.filename, + name: cloudTorrent.fileName, source: DebridType.realDebrid.toString() ) Task { - if torrentResponse.links.count == 1 { - if let torrentLink = torrentResponse.links[safe: 0] { + if cloudTorrent.links.count == 1 { + if let torrentLink = cloudTorrent.links[safe: 0] { await debridManager.fetchDebridDownload(magnet: nil, cloudInfo: torrentLink) if !debridManager.downloadUrl.isEmpty { historyInfo.url = debridManager.downloadUrl @@ -82,7 +82,7 @@ struct RealDebridCloudView: View { } } } else { - let magnet = Magnet(hash: torrentResponse.hash, link: nil) + let magnet = Magnet(hash: cloudTorrent.hash, link: nil) // Do not clear old IA values await debridManager.populateDebridIA([magnet]) @@ -96,15 +96,15 @@ struct RealDebridCloudView: View { } } label: { VStack(alignment: .leading, spacing: 10) { - Text(torrentResponse.filename) + Text(cloudTorrent.fileName) .font(.callout) .fixedSize(horizontal: false, vertical: true) .lineLimit(4) HStack { - Text(torrentResponse.status.capitalizingFirstLetter()) + Text(cloudTorrent.status.capitalizingFirstLetter()) Spacer() - DebridLabelView(cloudLinks: torrentResponse.links) + DebridLabelView(cloudLinks: cloudTorrent.links) } .font(.caption) } @@ -114,9 +114,9 @@ struct RealDebridCloudView: View { } .onDelete { offsets in for index in offsets { - if let torrentResponse = debridManager.realDebridCloudTorrents[safe: index] { + if let cloudTorrent = debridManager.realDebridCloudTorrents[safe: index] { Task { - await debridManager.deleteRdTorrent(torrentID: torrentResponse.id) + await debridManager.deleteRdTorrent(torrentID: cloudTorrent.torrentId) } } }