Debrid: Make TorBox a rich service and fix cloud downloads

TorBox can now show if there's a batch before loading a file.

Cloud downloads should check the server in case there's a different
method to fetch a download link.

Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
kingbri 2024-06-14 10:31:13 -04:00
parent 89367b72da
commit d0728e1a9b
8 changed files with 58 additions and 54 deletions

View file

@ -347,8 +347,8 @@ class AllDebrid: PollingDebridSource, ObservableObject {
}
// Not used
func checkUserDownloads(link: String) async throws -> String? {
nil
func checkUserDownloads(link: String) -> String? {
link
}
// The downloadId is actually the download link

View file

@ -17,7 +17,7 @@ class OffCloud: DebridSource, ObservableObject {
let id = "OffCloud"
let abbreviation = "OC"
let website = "https://offcloud.com"
let description = "OffCloud is a debrid service that is used for downloads and media playback. " +
let description: String? = "OffCloud is a debrid service that is used for downloads and media playback. " +
"You must pay to access this service. \n\n" +
"This service does not inform if a torrent is a batch before downloading."
@ -229,13 +229,13 @@ class OffCloud: DebridSource, ObservableObject {
return streamUrlString
}
func getUserDownloads() async throws {}
func getUserDownloads() {}
func checkUserDownloads(link: String) async throws -> String? {
nil
func checkUserDownloads(link: String) -> String? {
link
}
func deleteDownload(downloadId: String) async throws {}
func deleteDownload(downloadId: String) {}
func getUserTorrents() async throws {
var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/cloud/history"))

View file

@ -11,7 +11,7 @@ class Premiumize: OAuthDebridSource, ObservableObject {
let id = "Premiumize"
let abbreviation = "PM"
let website = "https://premiumize.me"
let description = "Premiumize is a debrid service that is used for downloads and media playback with seeding. " +
let description: String? = "Premiumize is a debrid service that is used for downloads and media playback with seeding. " +
"You must pay to access the service."
@Published var authProcessing: Bool = false
@ -369,7 +369,7 @@ class Premiumize: OAuthDebridSource, ObservableObject {
}
// No user torrents for Premiumize
func getUserTorrents() async throws {}
func getUserTorrents() {}
func deleteTorrent(torrentId: String?) async throws {}
func deleteTorrent(torrentId: String?) {}
}

View file

@ -483,7 +483,7 @@ class RealDebrid: PollingDebridSource, ObservableObject {
// Not used
func checkUserDownloads(link: String) -> String? {
nil
link
}
func deleteDownload(downloadId: String) async throws {

View file

@ -17,9 +17,8 @@ class TorBox: DebridSource, ObservableObject {
let id = "TorBox"
let abbreviation = "TB"
let website = "https://torbox.app"
let description = "TorBox is a debrid service that is used for downloads and media playback with seeding. " +
"Both free and paid plans are available. \n\n" +
"This service does not inform if a torrent is a batch before downloading."
let description: String? = "TorBox is a debrid service that is used for downloads and media playback with seeding. " +
"Both free and paid plans are available."
@Published var authProcessing: Bool = false
var isLoggedIn: Bool {
@ -109,6 +108,7 @@ class TorBox: DebridSource, ObservableObject {
var components = URLComponents(string: "\(baseApiUrl)/torrents/checkcached")!
components.queryItems = sendMagnets.map { URLQueryItem(name: "hash", value: $0.hash) }
components.queryItems?.append(URLQueryItem(name: "format", value: "list"))
components.queryItems?.append(URLQueryItem(name: "list_files", value: "true"))
guard let url = components.url else {
throw DebridError.InvalidUrl
@ -124,12 +124,21 @@ class TorBox: DebridSource, ObservableObject {
return
}
let availableHashes = iaObjects.map {
let availableHashes = iaObjects.map { iaObject in
DebridIA(
magnet: Magnet(hash: $0.hash, link: nil),
magnet: Magnet(hash: iaObject.hash, link: nil),
source: self.id,
expiryTimeStamp: Date().timeIntervalSince1970 + 300,
files: []
files: iaObject.files.enumerated().compactMap { index, iaFile in
guard let fileName = iaFile.name.split(separator: "/").last else {
return nil
}
return DebridIAFile(
fileId: index,
name: String(fileName)
)
}
)
}
@ -150,25 +159,12 @@ class TorBox: DebridSource, ObservableObject {
throw DebridError.IsCaching
}
if filteredTorrent.files.count > 1 {
var copiedIA = ia
copiedIA?.files = filteredTorrent.files.map { torrentFile in
DebridIAFile(
fileId: torrentFile.id,
name: torrentFile.shortName,
streamUrlString: String(torrentId)
)
}
return (nil, copiedIA)
} else if let torrentFile = filteredTorrent.files.first {
let restrictedFile = DebridIAFile(fileId: torrentFile.id, name: torrentFile.name, streamUrlString: String(torrentId))
return (restrictedFile, nil)
} else {
return (nil, nil)
guard let torrentFile = filteredTorrent.files[safe: iaFile?.fileId ?? 0] else {
throw DebridError.EmptyTorrents
}
let restrictedFile = DebridIAFile(fileId: torrentFile.id, name: torrentFile.name, streamUrlString: String(torrentId))
return (restrictedFile, nil)
}
private func createTorrent(magnet: Magnet) async throws -> Int {
@ -233,13 +229,13 @@ class TorBox: DebridSource, ObservableObject {
// MARK: - Cloud methods
// Unused
func getUserDownloads() async throws {}
func getUserDownloads() {}
func checkUserDownloads(link: String) async throws -> String? {
nil
func checkUserDownloads(link: String) -> String? {
link
}
func deleteDownload(downloadId: String) async throws {}
func deleteDownload(downloadId: String) {}
func getUserTorrents() async throws {
let torrentList = try await myTorrentList()
@ -252,7 +248,7 @@ class TorBox: DebridSource, ObservableObject {
fileName: torrent.name,
status: torrent.downloadState == "cached" || torrent.downloadState == "completed" ? "downloaded" : torrent.downloadState,
hash: torrent.hash,
links: [String(torrent.id)]
links: torrent.files.map { String($0.id) }
)
}
}

View file

@ -20,7 +20,6 @@ extension Premiumize {
struct DDLResponse: Codable {
let status: String
let content: [DDLData]?
let location: String
let filename: String
let filesize: Int
}

View file

@ -47,6 +47,12 @@ extension TorBox {
let name: String
let size: Int
let hash: String
let files: [InstantAvailabilityFile]
}
struct InstantAvailabilityFile: Codable, Sendable {
let name: String
let size: Int
}
struct InstantAvailabilityDataFailure: Codable, Sendable {

View file

@ -24,21 +24,24 @@ struct CloudDownloadView: View {
Button(cloudDownload.fileName) {
navModel.resultFromCloud = true
navModel.selectedTitle = cloudDownload.fileName
debridManager.downloadUrl = cloudDownload.link
PersistenceController.shared.createHistory(
HistoryEntryJson(
name: cloudDownload.fileName,
url: cloudDownload.link,
source: debridSource.id
),
performSave: true
var historyEntry = HistoryEntryJson(
name: cloudDownload.fileName,
source: debridSource.id
)
pluginManager.runDefaultAction(
urlString: debridManager.downloadUrl,
navModel: navModel
)
debridManager.currentDebridTask = Task {
await debridManager.fetchDebridDownload(magnet: nil, cloudInfo: cloudDownload.link)
if !debridManager.downloadUrl.isEmpty {
historyEntry.url = debridManager.downloadUrl
PersistenceController.shared.createHistory(historyEntry, performSave: true)
pluginManager.runDefaultAction(
urlString: debridManager.downloadUrl,
navModel: navModel
)
}
}
}
.disabledAppearance(navModel.currentChoiceSheet != nil, dimmedOpacity: 0.7, animation: .easeOut(duration: 0.2))
.tint(.primary)