Debrid: Add InstantAvailability and download to protocol
Unify IA into a passable client side structure and add a common download method to the DebridSource protocol. Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
0fe1cbc888
commit
37450ef979
11 changed files with 160 additions and 142 deletions
|
|
@ -394,6 +394,7 @@
|
|||
0C6C7C9C29315292002DF910 /* AllDebridModels.swift */,
|
||||
0C7ED14028D61BBA009E29AD /* BackupModels.swift */,
|
||||
0C0755C7293425B500ECA142 /* DebridManagerModels.swift */,
|
||||
0CF1ABE12C0C3D2F009F6C26 /* DebridModels.swift */,
|
||||
0C84FCE629E4B61A00B0DFE4 /* FilterModels.swift */,
|
||||
0C68135128BC1A7C00FAD890 /* GithubModels.swift */,
|
||||
0C422E7F293542F300486D65 /* PremiumizeModels.swift */,
|
||||
|
|
@ -403,7 +404,6 @@
|
|||
0C3E00D7296F5B9A00ECECB2 /* PluginModels.swift */,
|
||||
0C6771F929B3D1AE005D38D2 /* KodiModels.swift */,
|
||||
0C1A3E5129C8A7F500DA9730 /* SettingsModels.swift */,
|
||||
0CF1ABE12C0C3D2F009F6C26 /* DebridModels.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import Foundation
|
|||
|
||||
// TODO: Fix errors
|
||||
public class AllDebrid: PollingDebridSource {
|
||||
|
||||
public let id = "AllDebrid"
|
||||
public var authTask: Task<Void, Error>?
|
||||
|
||||
|
|
@ -96,7 +95,7 @@ public class AllDebrid: PollingDebridSource {
|
|||
}
|
||||
|
||||
public func getToken() -> String? {
|
||||
return FerriteKeychain.shared.get("AllDebrid.ApiKey")
|
||||
FerriteKeychain.shared.get("AllDebrid.ApiKey")
|
||||
}
|
||||
|
||||
// Clears tokens. No endpoint to deregister a device
|
||||
|
|
@ -146,6 +145,20 @@ public class AllDebrid: PollingDebridSource {
|
|||
}
|
||||
}
|
||||
|
||||
// Wrapper function to fetch a download link from the API
|
||||
public func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String {
|
||||
let magnetID = try await addMagnet(magnet: magnet)
|
||||
let lockedLink = try await fetchMagnetStatus(
|
||||
magnetId: magnetID,
|
||||
selectedIndex: iaFile?.fileId ?? 0
|
||||
)
|
||||
|
||||
try await saveLink(link: lockedLink)
|
||||
let downloadUrl = try await unlockLink(lockedLink: lockedLink)
|
||||
|
||||
return downloadUrl
|
||||
}
|
||||
|
||||
// Adds a magnet link to the user's AD account
|
||||
public func addMagnet(magnet: Magnet) async throws -> Int {
|
||||
guard let magnetLink = magnet.link else {
|
||||
|
|
@ -255,7 +268,7 @@ public class AllDebrid: PollingDebridSource {
|
|||
try await performRequest(request: &request, requestName: #function)
|
||||
}
|
||||
|
||||
public func instantAvailability(magnets: [Magnet]) async throws -> [IA] {
|
||||
public func instantAvailability(magnets: [Magnet]) async throws -> [DebridIA] {
|
||||
let queryItems = magnets.map { URLQueryItem(name: "magnets[]", value: $0.hash) }
|
||||
var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/magnet/instant", queryItems: queryItems))
|
||||
|
||||
|
|
@ -266,10 +279,10 @@ public class AllDebrid: PollingDebridSource {
|
|||
let availableHashes = filteredMagnets.map { magnetResp in
|
||||
// Force unwrap is OK here since the filter caught any nil values
|
||||
let files = magnetResp.files!.enumerated().map { index, magnetFile in
|
||||
IAFile(id: index, fileName: magnetFile.name)
|
||||
DebridIAFile(fileId: index, name: magnetFile.name)
|
||||
}
|
||||
|
||||
return IA(
|
||||
return DebridIA(
|
||||
magnet: Magnet(hash: magnetResp.hash, link: magnetResp.magnet),
|
||||
expiryTimeStamp: Date().timeIntervalSince1970 + 300,
|
||||
files: files
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
import Foundation
|
||||
|
||||
public class Premiumize: OAuthDebridSource {
|
||||
|
||||
public let id = "Premiumize"
|
||||
|
||||
let baseAuthUrl = "https://www.premiumize.me/authorize"
|
||||
|
|
@ -58,7 +57,7 @@ public class Premiumize: OAuthDebridSource {
|
|||
}
|
||||
|
||||
public func getToken() -> String? {
|
||||
return FerriteKeychain.shared.get("Premiumize.AccessToken")
|
||||
FerriteKeychain.shared.get("Premiumize.AccessToken")
|
||||
}
|
||||
|
||||
// Clears tokens. No endpoint to deregister a device
|
||||
|
|
@ -162,15 +161,15 @@ public class Premiumize: OAuthDebridSource {
|
|||
|
||||
// Function to divide and execute DDL endpoint requests in parallel
|
||||
// Calls this for 10 requests at a time to not overwhelm API servers
|
||||
public func divideDDLRequests(magnetChunk: [Magnet]) async throws -> [IA] {
|
||||
let tempIA = try await withThrowingTaskGroup(of: Premiumize.IA.self) { group in
|
||||
public func divideDDLRequests(magnetChunk: [Magnet]) async throws -> [DebridIA] {
|
||||
let tempIA = try await withThrowingTaskGroup(of: DebridIA.self) { group in
|
||||
for magnet in magnetChunk {
|
||||
group.addTask {
|
||||
try await self.fetchDDL(magnet: magnet)
|
||||
}
|
||||
}
|
||||
|
||||
var chunkedIA: [Premiumize.IA] = []
|
||||
var chunkedIA: [DebridIA] = []
|
||||
for try await ia in group {
|
||||
chunkedIA.append(ia)
|
||||
}
|
||||
|
|
@ -181,7 +180,7 @@ public class Premiumize: OAuthDebridSource {
|
|||
}
|
||||
|
||||
// Grabs DDL links
|
||||
func fetchDDL(magnet: Magnet) async throws -> IA {
|
||||
func fetchDDL(magnet: Magnet) async throws -> DebridIA {
|
||||
if magnet.hash == nil {
|
||||
throw PMError.EmptyData
|
||||
}
|
||||
|
|
@ -200,13 +199,14 @@ public class Premiumize: OAuthDebridSource {
|
|||
|
||||
if !rawResponse.content.isEmpty {
|
||||
let files = rawResponse.content.map { file in
|
||||
IAFile(
|
||||
DebridIAFile(
|
||||
fileId: 0,
|
||||
name: file.path.split(separator: "/").last.flatMap { String($0) } ?? file.path,
|
||||
streamUrlString: file.link
|
||||
)
|
||||
}
|
||||
|
||||
return IA(
|
||||
return DebridIA(
|
||||
magnet: magnet,
|
||||
expiryTimeStamp: Date().timeIntervalSince1970 + 300,
|
||||
files: files
|
||||
|
|
@ -216,6 +216,20 @@ public class Premiumize: OAuthDebridSource {
|
|||
}
|
||||
}
|
||||
|
||||
// Wrapper function to fetch a DDL link from the API
|
||||
public func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String {
|
||||
// Store the item in PM cloud for later use
|
||||
try await createTransfer(magnet: magnet)
|
||||
|
||||
if let iaFile, let streamUrlString = iaFile.streamUrlString {
|
||||
return streamUrlString
|
||||
} else if let premiumizeItem = ia, let firstFile = premiumizeItem.files[safe: 0], let streamUrlString = firstFile.streamUrlString {
|
||||
return streamUrlString
|
||||
} else {
|
||||
throw PMError.FailedRequest(description: "Could not fetch your file from the Premiumize API")
|
||||
}
|
||||
}
|
||||
|
||||
func createTransfer(magnet: Magnet) async throws {
|
||||
guard let magnetLink = magnet.link else {
|
||||
throw PMError.FailedRequest(description: "The magnet link is invalid")
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
import Foundation
|
||||
|
||||
public class RealDebrid: PollingDebridSource {
|
||||
|
||||
public let id = "RealDebrid"
|
||||
public var authTask: Task<Void, Error>?
|
||||
|
||||
|
|
@ -87,7 +86,7 @@ public class RealDebrid: PollingDebridSource {
|
|||
let (data, _) = try await URLSession.shared.data(for: request)
|
||||
|
||||
// We don't care if this fails
|
||||
let rawResponse = try? self.jsonDecoder.decode(DeviceCredentialsResponse.self, from: data)
|
||||
let rawResponse = try? jsonDecoder.decode(DeviceCredentialsResponse.self, from: data)
|
||||
|
||||
// If there's a client ID from the response, end the task successfully
|
||||
if let clientId = rawResponse?.clientID, let clientSecret = rawResponse?.clientSecret {
|
||||
|
|
@ -169,7 +168,7 @@ public class RealDebrid: PollingDebridSource {
|
|||
|
||||
return FerriteKeychain.shared.get("RealDebrid.AccessToken") == key
|
||||
}
|
||||
|
||||
|
||||
// Deletes tokens from device and RD's servers
|
||||
public func logout() async {
|
||||
FerriteKeychain.shared.delete("RealDebrid.RefreshToken")
|
||||
|
|
@ -213,9 +212,8 @@ public class RealDebrid: PollingDebridSource {
|
|||
}
|
||||
|
||||
// Checks if the magnet is streamable on RD
|
||||
// Currently does not work for batch links
|
||||
public func instantAvailability(magnets: [Magnet]) async throws -> [IA] {
|
||||
var availableHashes: [RealDebrid.IA] = []
|
||||
public func instantAvailability(magnets: [Magnet]) async throws -> [DebridIA] {
|
||||
var availableHashes: [DebridIA] = []
|
||||
var request = URLRequest(url: URL(string: "\(baseApiUrl)/torrents/instantAvailability/\(magnets.compactMap(\.hash).joined(separator: "/"))")!)
|
||||
|
||||
let data = try await performRequest(request: &request, requestName: #function)
|
||||
|
|
@ -232,7 +230,7 @@ public class RealDebrid: PollingDebridSource {
|
|||
continue
|
||||
}
|
||||
|
||||
// Is this a batch
|
||||
// Is this a batch?
|
||||
if data.rd.count > 1 || data.rd[0].count > 1 {
|
||||
// Batch array
|
||||
let batches = data.rd.map { fileDict in
|
||||
|
|
@ -244,22 +242,18 @@ public class RealDebrid: PollingDebridSource {
|
|||
return RealDebrid.IABatch(files: batchFiles)
|
||||
}
|
||||
|
||||
// RD files array
|
||||
// Possibly sort this in the future, but not sure how at the moment
|
||||
var files: [RealDebrid.IAFile] = []
|
||||
var files: [DebridIAFile] = []
|
||||
|
||||
for index in batches.indices {
|
||||
let batchFiles = batches[index].files
|
||||
for batch in batches {
|
||||
let batchFileIds = batch.files.map(\.id)
|
||||
|
||||
for batchFileIndex in batchFiles.indices {
|
||||
let batchFile = batchFiles[batchFileIndex]
|
||||
|
||||
if !files.contains(where: { $0.name == batchFile.fileName }) {
|
||||
for batchFile in batch.files {
|
||||
if !files.contains(where: { $0.fileId == batchFile.id }) {
|
||||
files.append(
|
||||
RealDebrid.IAFile(
|
||||
DebridIAFile(
|
||||
fileId: batchFile.id,
|
||||
name: batchFile.fileName,
|
||||
batchIndex: index,
|
||||
batchFileIndex: batchFileIndex
|
||||
batchIds: batchFileIds
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -268,18 +262,18 @@ public class RealDebrid: PollingDebridSource {
|
|||
|
||||
// TTL: 5 minutes
|
||||
availableHashes.append(
|
||||
RealDebrid.IA(
|
||||
DebridIA(
|
||||
magnet: Magnet(hash: hash, link: nil),
|
||||
expiryTimeStamp: Date().timeIntervalSince1970 + 300,
|
||||
files: files,
|
||||
batches: batches
|
||||
files: files
|
||||
)
|
||||
)
|
||||
} else {
|
||||
availableHashes.append(
|
||||
RealDebrid.IA(
|
||||
DebridIA(
|
||||
magnet: Magnet(hash: hash, link: nil),
|
||||
expiryTimeStamp: Date().timeIntervalSince1970 + 300
|
||||
expiryTimeStamp: Date().timeIntervalSince1970 + 300,
|
||||
files: []
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -288,6 +282,21 @@ public class RealDebrid: PollingDebridSource {
|
|||
return availableHashes
|
||||
}
|
||||
|
||||
// Wrapper function to fetch a download link from the API
|
||||
public func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String {
|
||||
let selectedMagnetId = try await addMagnet(magnet: magnet)
|
||||
|
||||
try await selectFiles(debridID: selectedMagnetId, fileIds: iaFile?.batchIds ?? [])
|
||||
|
||||
let torrentLink = try await torrentInfo(
|
||||
debridID: selectedMagnetId,
|
||||
selectedIndex: iaFile?.fileId ?? 0
|
||||
)
|
||||
let downloadLink = try await unrestrictLink(debridDownloadLink: torrentLink)
|
||||
|
||||
return downloadLink
|
||||
}
|
||||
|
||||
// Adds a magnet link to the user's RD account
|
||||
public func addMagnet(magnet: Magnet) async throws -> String {
|
||||
guard let magnetLink = magnet.link else {
|
||||
|
|
@ -335,9 +344,11 @@ public class RealDebrid: PollingDebridSource {
|
|||
|
||||
let data = try await performRequest(request: &request, requestName: #function)
|
||||
let rawResponse = try jsonDecoder.decode(TorrentInfoResponse.self, from: data)
|
||||
let filteredFiles = rawResponse.files.filter { $0.selected == 1 }
|
||||
let linkIndex = filteredFiles.firstIndex(where: { $0.id == selectedIndex })
|
||||
|
||||
// Let the user know if a torrent is downloading
|
||||
if let torrentLink = rawResponse.links[safe: selectedIndex ?? -1], rawResponse.status == "downloaded" {
|
||||
if let torrentLink = rawResponse.links[safe: linkIndex ?? -1], rawResponse.status == "downloaded" {
|
||||
return torrentLink
|
||||
} else if rawResponse.status == "downloading" || rawResponse.status == "queued" {
|
||||
throw RDError.EmptyTorrents
|
||||
|
|
|
|||
|
|
@ -7,10 +7,24 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
public struct DebridIAFile {
|
||||
|
||||
public struct DebridIA: Sendable, Hashable {
|
||||
let magnet: Magnet
|
||||
let expiryTimeStamp: Double
|
||||
var files: [DebridIAFile]
|
||||
}
|
||||
|
||||
public struct DebridCloudFile {
|
||||
|
||||
public struct DebridIAFile: Hashable, Sendable {
|
||||
let fileId: Int
|
||||
let name: String
|
||||
let streamUrlString: String?
|
||||
let batchIds: [Int]
|
||||
|
||||
init(fileId: Int, name: String, streamUrlString: String? = nil, batchIds: [Int] = []) {
|
||||
self.fileId = fileId
|
||||
self.name = name
|
||||
self.streamUrlString = streamUrlString
|
||||
self.batchIds = batchIds
|
||||
}
|
||||
}
|
||||
|
||||
public struct DebridCloudFile {}
|
||||
|
|
|
|||
|
|
@ -92,13 +92,6 @@ public extension RealDebrid {
|
|||
|
||||
// MARK: - Instant Availability client side structures
|
||||
|
||||
struct IA: Codable, Hashable, Sendable {
|
||||
let magnet: Magnet
|
||||
let expiryTimeStamp: Double
|
||||
var files: [IAFile] = []
|
||||
var batches: [IABatch] = []
|
||||
}
|
||||
|
||||
struct IABatch: Codable, Hashable, Sendable {
|
||||
let files: [IABatchFile]
|
||||
}
|
||||
|
|
@ -108,12 +101,6 @@ public extension RealDebrid {
|
|||
let fileName: String
|
||||
}
|
||||
|
||||
struct IAFile: Codable, Hashable, Sendable {
|
||||
let name: String
|
||||
let batchIndex: Int
|
||||
let batchFileIndex: Int
|
||||
}
|
||||
|
||||
// MARK: - addMagnet endpoint
|
||||
|
||||
struct AddMagnetResponse: Codable, Sendable {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ public protocol DebridSource {
|
|||
// Common authentication functions
|
||||
func setApiKey(_ key: String) -> Bool
|
||||
func logout() async
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
public protocol PollingDebridSource: DebridSource {
|
||||
|
|
@ -25,7 +29,6 @@ public protocol PollingDebridSource: DebridSource {
|
|||
}
|
||||
|
||||
public protocol OAuthDebridSource: DebridSource {
|
||||
|
||||
// Fetches the auth URL
|
||||
func getAuthUrl() throws -> URL
|
||||
|
||||
|
|
|
|||
|
|
@ -59,12 +59,12 @@ public class DebridManager: ObservableObject {
|
|||
var realDebridAuthProcessing: Bool = false
|
||||
|
||||
// RealDebrid fetch variables
|
||||
@Published var realDebridIAValues: [RealDebrid.IA] = []
|
||||
@Published var realDebridIAValues: [DebridIA] = []
|
||||
|
||||
@Published var showDeleteAlert: Bool = false
|
||||
|
||||
var selectedRealDebridItem: RealDebrid.IA?
|
||||
var selectedRealDebridFile: RealDebrid.IAFile?
|
||||
var selectedRealDebridItem: DebridIA?
|
||||
var selectedRealDebridFile: DebridIAFile?
|
||||
var selectedRealDebridID: String?
|
||||
|
||||
// TODO: Maybe make these generic?
|
||||
|
|
@ -77,10 +77,10 @@ public class DebridManager: ObservableObject {
|
|||
var allDebridAuthProcessing: Bool = false
|
||||
|
||||
// AllDebrid fetch variables
|
||||
@Published var allDebridIAValues: [AllDebrid.IA] = []
|
||||
@Published var allDebridIAValues: [DebridIA] = []
|
||||
|
||||
var selectedAllDebridItem: AllDebrid.IA?
|
||||
var selectedAllDebridFile: AllDebrid.IAFile?
|
||||
var selectedAllDebridItem: DebridIA?
|
||||
var selectedAllDebridFile: DebridIAFile?
|
||||
|
||||
// AllDebrid cloud variables
|
||||
@Published var allDebridCloudMagnets: [AllDebrid.MagnetStatusData] = []
|
||||
|
|
@ -91,10 +91,10 @@ public class DebridManager: ObservableObject {
|
|||
var premiumizeAuthProcessing: Bool = false
|
||||
|
||||
// Premiumize fetch variables
|
||||
@Published var premiumizeIAValues: [Premiumize.IA] = []
|
||||
@Published var premiumizeIAValues: [DebridIA] = []
|
||||
|
||||
var selectedPremiumizeItem: Premiumize.IA?
|
||||
var selectedPremiumizeFile: Premiumize.IAFile?
|
||||
var selectedPremiumizeItem: DebridIA?
|
||||
var selectedPremiumizeFile: DebridIAFile?
|
||||
|
||||
// Premiumize cloud variables
|
||||
@Published var premiumizeCloudItems: [Premiumize.UserItem] = []
|
||||
|
|
@ -282,10 +282,10 @@ public class DebridManager: ObservableObject {
|
|||
return .none
|
||||
}
|
||||
|
||||
if realDebridMatch.batches.isEmpty {
|
||||
return .full
|
||||
} else {
|
||||
if realDebridMatch.files.count > 1 {
|
||||
return .partial
|
||||
} else {
|
||||
return .full
|
||||
}
|
||||
case .allDebrid:
|
||||
guard let allDebridMatch = allDebridIAValues.first(where: { magnetHash == $0.magnet.hash }) else {
|
||||
|
|
@ -578,7 +578,7 @@ public class DebridManager: ObservableObject {
|
|||
case .allDebrid:
|
||||
await fetchAdDownload(magnet: magnet, existingLockedLink: cloudInfo)
|
||||
case .premiumize:
|
||||
await fetchPmDownload(cloudItemId: cloudInfo)
|
||||
await fetchPmDownload(magnet: magnet, cloudItemId: cloudInfo)
|
||||
case .none:
|
||||
break
|
||||
}
|
||||
|
|
@ -586,6 +586,7 @@ public class DebridManager: ObservableObject {
|
|||
|
||||
func fetchRdDownload(magnet: Magnet?, existingLink: String?) async {
|
||||
// If an existing link is passed in args, set it to that. Otherwise, find one from RD cloud.
|
||||
/*
|
||||
let torrentLink: String?
|
||||
if let existingLink {
|
||||
torrentLink = existingLink
|
||||
|
|
@ -596,42 +597,23 @@ public class DebridManager: ObservableObject {
|
|||
let existingTorrent = realDebridCloudTorrents.first { $0.hash == selectedRealDebridItem?.magnet.hash && $0.status == "downloaded" }
|
||||
torrentLink = existingTorrent?.links[safe: selectedRealDebridFile?.batchFileIndex ?? 0]
|
||||
}
|
||||
*/
|
||||
|
||||
do {
|
||||
// If the links match from a user's downloads, no need to re-run a download
|
||||
/*
|
||||
if let torrentLink,
|
||||
let downloadLink = await checkRdUserDownloads(userTorrentLink: torrentLink)
|
||||
{
|
||||
downloadUrl = downloadLink
|
||||
} else if let magnet {
|
||||
// Add a magnet after all the cache checks fail
|
||||
selectedRealDebridID = try await realDebrid.addMagnet(magnet: magnet)
|
||||
} else */
|
||||
if let magnet {
|
||||
let downloadLink = try await realDebrid.getDownloadLink(
|
||||
magnet: magnet, ia: selectedRealDebridItem, iaFile: selectedRealDebridFile
|
||||
)
|
||||
|
||||
var fileIds: [Int] = []
|
||||
if let iaFile = selectedRealDebridFile {
|
||||
guard let iaBatchFromFile = selectedRealDebridItem?.batches[safe: iaFile.batchIndex] else {
|
||||
return
|
||||
}
|
||||
|
||||
fileIds = iaBatchFromFile.files.map(\.id)
|
||||
}
|
||||
|
||||
if let realDebridId = selectedRealDebridID {
|
||||
try await realDebrid.selectFiles(debridID: realDebridId, fileIds: fileIds)
|
||||
|
||||
let torrentLink = try await realDebrid.torrentInfo(
|
||||
debridID: realDebridId,
|
||||
selectedIndex: selectedRealDebridFile?.batchFileIndex ?? 0
|
||||
)
|
||||
let downloadLink = try await realDebrid.unrestrictLink(debridDownloadLink: torrentLink)
|
||||
|
||||
downloadUrl = downloadLink
|
||||
} else {
|
||||
logManager?.error(
|
||||
"RealDebrid: Could not cache torrent with hash \(String(describing: magnet.hash))",
|
||||
description: "Could not cache this torrent. Aborting."
|
||||
)
|
||||
}
|
||||
// Update the UI
|
||||
downloadUrl = downloadLink
|
||||
} else {
|
||||
throw RealDebrid.RDError.FailedRequest(description: "Could not fetch your file from RealDebrid's cache or API")
|
||||
}
|
||||
|
|
@ -645,7 +627,7 @@ public class DebridManager: ObservableObject {
|
|||
default:
|
||||
await sendDebridError(error, prefix: "RealDebrid download error", cancelString: "Download cancelled")
|
||||
|
||||
await deleteRdTorrent(torrentID: selectedRealDebridID, presentError: false)
|
||||
// await deleteRdTorrent(torrentID: selectedRealDebridID, presentError: false)
|
||||
}
|
||||
|
||||
logManager?.hideIndeterminateToast()
|
||||
|
|
@ -695,8 +677,6 @@ public class DebridManager: ObservableObject {
|
|||
do {
|
||||
if let torrentID {
|
||||
try await realDebrid.deleteTorrent(debridID: torrentID)
|
||||
} else if let selectedTorrentID = selectedRealDebridID {
|
||||
try await realDebrid.deleteTorrent(debridID: selectedTorrentID)
|
||||
} else {
|
||||
throw RealDebrid.RDError.FailedRequest(description: "No torrent ID was provided")
|
||||
}
|
||||
|
|
@ -720,34 +700,36 @@ public class DebridManager: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Integrate with AD saved links
|
||||
func fetchAdDownload(magnet: Magnet?, existingLockedLink: String?) async {
|
||||
// If an existing link is passed in args, set it to that. Otherwise, find one from AD cloud.
|
||||
let lockedLink: String?
|
||||
if let existingLockedLink {
|
||||
lockedLink = existingLockedLink
|
||||
} else {
|
||||
// Bypass the TTL for up to date information
|
||||
await fetchAdCloud(bypassTTL: true)
|
||||
/*
|
||||
let lockedLink: String?
|
||||
if let existingLockedLink {
|
||||
lockedLink = existingLockedLink
|
||||
} else {
|
||||
// Bypass the TTL for up to date information
|
||||
await fetchAdCloud(bypassTTL: true)
|
||||
|
||||
let existingMagnet = allDebridCloudMagnets.first { $0.hash == selectedAllDebridItem?.magnet.hash && $0.status == "Ready" }
|
||||
lockedLink = existingMagnet?.links[safe: selectedAllDebridFile?.id ?? 0]?.link
|
||||
}
|
||||
let existingMagnet = allDebridCloudMagnets.first { $0.hash == selectedAllDebridItem?.magnet.hash && $0.status == "Ready" }
|
||||
lockedLink = existingMagnet?.links[safe: selectedAllDebridFile?.fileId ?? 0]?.link
|
||||
}
|
||||
*/
|
||||
|
||||
do {
|
||||
if let lockedLink,
|
||||
let unlockedLink = await checkAdUserLinks(lockedLink: lockedLink)
|
||||
{
|
||||
downloadUrl = unlockedLink
|
||||
} else if let magnet {
|
||||
let magnetID = try await allDebrid.addMagnet(magnet: magnet)
|
||||
let lockedLink = try await allDebrid.fetchMagnetStatus(
|
||||
magnetId: magnetID,
|
||||
selectedIndex: selectedAllDebridFile?.id ?? 0
|
||||
/*
|
||||
if let lockedLink,
|
||||
let unlockedLink = await checkAdUserLinks(lockedLink: lockedLink)
|
||||
{
|
||||
downloadUrl = unlockedLink
|
||||
} else if let magnet {
|
||||
*/
|
||||
if let magnet {
|
||||
let downloadLink = try await allDebrid.getDownloadLink(
|
||||
magnet: magnet, ia: selectedAllDebridItem, iaFile: selectedAllDebridFile
|
||||
)
|
||||
|
||||
try await allDebrid.saveLink(link: lockedLink)
|
||||
downloadUrl = try await allDebrid.unlockLink(lockedLink: lockedLink)
|
||||
// Update UI
|
||||
downloadUrl = downloadLink
|
||||
} else {
|
||||
throw AllDebrid.ADError.FailedRequest(description: "Could not fetch your file from AllDebrid's cache or API")
|
||||
}
|
||||
|
|
@ -810,28 +792,22 @@ public class DebridManager: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
func fetchPmDownload(cloudItemId: String? = nil) async {
|
||||
func fetchPmDownload(magnet: Magnet?, cloudItemId: String? = nil) async {
|
||||
do {
|
||||
if let cloudItemId {
|
||||
downloadUrl = try await premiumize.itemDetails(itemID: cloudItemId).link
|
||||
} else if let premiumizeFile = selectedPremiumizeFile {
|
||||
downloadUrl = premiumizeFile.streamUrlString
|
||||
} else if
|
||||
let premiumizeItem = selectedPremiumizeItem,
|
||||
let firstFile = premiumizeItem.files[safe: 0]
|
||||
{
|
||||
downloadUrl = firstFile.streamUrlString
|
||||
} else if let magnet {
|
||||
let downloadLink = try await premiumize.getDownloadLink(
|
||||
magnet: magnet, ia: selectedPremiumizeItem, iaFile: selectedPremiumizeFile
|
||||
)
|
||||
|
||||
downloadUrl = downloadLink
|
||||
} else {
|
||||
throw Premiumize.PMError.FailedRequest(description: "There were no items or files found!")
|
||||
throw Premiumize.PMError.FailedRequest(description: "Could not fetch your file from Premiumize's cache or API")
|
||||
}
|
||||
|
||||
// Fetch one more time to add updated data into the PM cloud cache
|
||||
await fetchPmCloud(bypassTTL: true)
|
||||
|
||||
// Add a PM transfer if the item exists
|
||||
if let premiumizeItem = selectedPremiumizeItem {
|
||||
try await premiumize.createTransfer(magnet: premiumizeItem.magnet)
|
||||
}
|
||||
} catch {
|
||||
await sendDebridError(error, prefix: "Premiumize download error", cancelString: "Download or transfer cancelled")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ struct HybridSecureField: View {
|
|||
private var isFieldDisabled: Bool = false
|
||||
|
||||
init(text: Binding<String>, onCommit: (() -> Void)? = nil, showPassword: Bool = false) {
|
||||
self._text = text
|
||||
_text = text
|
||||
if let onCommit {
|
||||
self.onCommit = onCommit
|
||||
}
|
||||
|
|
@ -57,6 +57,6 @@ struct HybridSecureField: View {
|
|||
|
||||
extension HybridSecureField {
|
||||
public func fieldDisabled(_ isFieldDisabled: Bool) -> Self {
|
||||
modifyViewProp({ $0.isFieldDisabled = isFieldDisabled })
|
||||
modifyViewProp { $0.isFieldDisabled = isFieldDisabled }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ struct SettingsView: View {
|
|||
if changed {
|
||||
Task {
|
||||
let dataRecords = await WKWebsiteDataStore.default().dataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes())
|
||||
|
||||
|
||||
await WKWebsiteDataStore.default().removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), for: dataRecords)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ struct BatchChoiceView: View {
|
|||
}
|
||||
case .allDebrid:
|
||||
ForEach(debridManager.selectedAllDebridItem?.files ?? [], id: \.self) { file in
|
||||
if file.fileName.lowercased().contains(searchText.lowercased()) || searchText.isEmpty {
|
||||
Button(file.fileName) {
|
||||
if file.name.lowercased().contains(searchText.lowercased()) || searchText.isEmpty {
|
||||
Button(file.name) {
|
||||
debridManager.selectedAllDebridFile = file
|
||||
|
||||
queueCommonDownload(fileName: file.fileName)
|
||||
queueCommonDownload(fileName: file.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue