Debrid: Order API implementations
Reorder everything and mark off where different functions are located. Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
9e306eff1e
commit
37ef64224e
3 changed files with 102 additions and 72 deletions
|
|
@ -19,6 +19,8 @@ public class AllDebrid: PollingDebridSource {
|
||||||
|
|
||||||
let jsonDecoder = JSONDecoder()
|
let jsonDecoder = JSONDecoder()
|
||||||
|
|
||||||
|
// MARK: - Auth
|
||||||
|
|
||||||
// Fetches information for PIN auth
|
// Fetches information for PIN auth
|
||||||
public func getAuthUrl() async throws -> URL {
|
public func getAuthUrl() async throws -> URL {
|
||||||
let url = try buildRequestURL(urlString: "\(baseApiUrl)/pin/get")
|
let url = try buildRequestURL(urlString: "\(baseApiUrl)/pin/get")
|
||||||
|
|
@ -106,6 +108,8 @@ public class AllDebrid: PollingDebridSource {
|
||||||
UserDefaults.standard.removeObject(forKey: "AllDebrid.UseManualKey")
|
UserDefaults.standard.removeObject(forKey: "AllDebrid.UseManualKey")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Common request
|
||||||
|
|
||||||
// Wrapper request function which matches the responses and returns data
|
// Wrapper request function which matches the responses and returns data
|
||||||
@discardableResult private func performRequest(request: inout URLRequest, requestName: String) async throws -> Data {
|
@discardableResult private func performRequest(request: inout URLRequest, requestName: String) async throws -> Data {
|
||||||
guard let token = getToken() else {
|
guard let token = getToken() else {
|
||||||
|
|
@ -147,6 +151,34 @@ public class AllDebrid: PollingDebridSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Instant availability
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
let data = try await performRequest(request: &request, requestName: #function)
|
||||||
|
let rawResponse = try jsonDecoder.decode(ADResponse<InstantAvailabilityResponse>.self, from: data).data
|
||||||
|
|
||||||
|
let filteredMagnets = rawResponse.magnets.filter { $0.instant == true && $0.files != nil }
|
||||||
|
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
|
||||||
|
DebridIAFile(fileId: index, name: magnetFile.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return DebridIA(
|
||||||
|
magnet: Magnet(hash: magnetResp.hash, link: magnetResp.magnet),
|
||||||
|
expiryTimeStamp: Date().timeIntervalSince1970 + 300,
|
||||||
|
files: files
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableHashes
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Downloading
|
||||||
|
|
||||||
// Wrapper function to fetch a download link from the API
|
// Wrapper function to fetch a download link from the API
|
||||||
public func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String {
|
public func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String {
|
||||||
let magnetID = try await addMagnet(magnet: magnet)
|
let magnetID = try await addMagnet(magnet: magnet)
|
||||||
|
|
@ -226,6 +258,8 @@ public class AllDebrid: PollingDebridSource {
|
||||||
try await performRequest(request: &request, requestName: #function)
|
try await performRequest(request: &request, requestName: #function)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Cloud methods
|
||||||
|
|
||||||
// Referred to as "User magnets" in AllDebrid's API
|
// Referred to as "User magnets" in AllDebrid's API
|
||||||
public func getUserTorrents() async throws -> [DebridCloudTorrent] {
|
public func getUserTorrents() async throws -> [DebridCloudTorrent] {
|
||||||
var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/magnet/status"))
|
var request = URLRequest(url: try buildRequestURL(urlString: "\(baseApiUrl)/magnet/status"))
|
||||||
|
|
@ -288,28 +322,4 @@ public class AllDebrid: PollingDebridSource {
|
||||||
|
|
||||||
try await performRequest(request: &request, requestName: #function)
|
try await performRequest(request: &request, requestName: #function)
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
let data = try await performRequest(request: &request, requestName: #function)
|
|
||||||
let rawResponse = try jsonDecoder.decode(ADResponse<InstantAvailabilityResponse>.self, from: data).data
|
|
||||||
|
|
||||||
let filteredMagnets = rawResponse.magnets.filter { $0.instant == true && $0.files != nil }
|
|
||||||
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
|
|
||||||
DebridIAFile(fileId: index, name: magnetFile.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return DebridIA(
|
|
||||||
magnet: Magnet(hash: magnetResp.hash, link: magnetResp.magnet),
|
|
||||||
expiryTimeStamp: Date().timeIntervalSince1970 + 300,
|
|
||||||
files: files
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return availableHashes
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ public class Premiumize: OAuthDebridSource {
|
||||||
|
|
||||||
let jsonDecoder = JSONDecoder()
|
let jsonDecoder = JSONDecoder()
|
||||||
|
|
||||||
|
// MARK: - Auth
|
||||||
|
|
||||||
public func getAuthUrl() throws -> URL {
|
public func getAuthUrl() throws -> URL {
|
||||||
var urlComponents = URLComponents(string: baseAuthUrl)!
|
var urlComponents = URLComponents(string: baseAuthUrl)!
|
||||||
urlComponents.queryItems = [
|
urlComponents.queryItems = [
|
||||||
|
|
@ -68,6 +70,8 @@ public class Premiumize: OAuthDebridSource {
|
||||||
UserDefaults.standard.removeObject(forKey: "Premiumize.UseManualKey")
|
UserDefaults.standard.removeObject(forKey: "Premiumize.UseManualKey")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Common request
|
||||||
|
|
||||||
// Wrapper request function which matches the responses and returns data
|
// Wrapper request function which matches the responses and returns data
|
||||||
@discardableResult private func performRequest(request: inout URLRequest, requestName: String) async throws -> Data {
|
@discardableResult private func performRequest(request: inout URLRequest, requestName: String) async throws -> Data {
|
||||||
guard let token = getToken() else {
|
guard let token = getToken() else {
|
||||||
|
|
@ -112,54 +116,7 @@ public class Premiumize: OAuthDebridSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to divide and execute cache endpoint requests in parallel
|
// MARK: - Instant availability
|
||||||
// Calls this for 100 hashes at a time due to API limits
|
|
||||||
public func divideCacheRequests(magnets: [Magnet]) async throws -> [Magnet] {
|
|
||||||
let availableMagnets = try await withThrowingTaskGroup(of: [Magnet].self) { group in
|
|
||||||
for chunk in magnets.chunked(into: 100) {
|
|
||||||
group.addTask {
|
|
||||||
try await self.checkCache(magnets: chunk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var chunkedMagnets: [Magnet] = []
|
|
||||||
for try await magnetArray in group {
|
|
||||||
chunkedMagnets += magnetArray
|
|
||||||
}
|
|
||||||
|
|
||||||
return chunkedMagnets
|
|
||||||
}
|
|
||||||
|
|
||||||
return availableMagnets
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parent function for initial checking of the cache
|
|
||||||
func checkCache(magnets: [Magnet]) async throws -> [Magnet] {
|
|
||||||
var urlComponents = URLComponents(string: "\(baseApiUrl)/cache/check")!
|
|
||||||
urlComponents.queryItems = magnets.map { URLQueryItem(name: "items[]", value: $0.hash) }
|
|
||||||
guard let url = urlComponents.url else {
|
|
||||||
throw PMError.InvalidUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
var request = URLRequest(url: url)
|
|
||||||
|
|
||||||
let data = try await performRequest(request: &request, requestName: #function)
|
|
||||||
let rawResponse = try jsonDecoder.decode(CacheCheckResponse.self, from: data)
|
|
||||||
|
|
||||||
if rawResponse.response.isEmpty {
|
|
||||||
throw PMError.EmptyData
|
|
||||||
} else {
|
|
||||||
let availableMagnets = magnets.enumerated().compactMap { index, magnet in
|
|
||||||
if rawResponse.response[safe: index] == true {
|
|
||||||
return magnet
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return availableMagnets
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to divide and execute DDL endpoint requests in parallel
|
// Function to divide and execute DDL endpoint requests in parallel
|
||||||
// Calls this for 10 requests at a time to not overwhelm API servers
|
// Calls this for 10 requests at a time to not overwhelm API servers
|
||||||
|
|
@ -218,6 +175,57 @@ public class Premiumize: OAuthDebridSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to divide and execute cache endpoint requests in parallel
|
||||||
|
// Calls this for 100 hashes at a time due to API limits
|
||||||
|
public func divideCacheRequests(magnets: [Magnet]) async throws -> [Magnet] {
|
||||||
|
let availableMagnets = try await withThrowingTaskGroup(of: [Magnet].self) { group in
|
||||||
|
for chunk in magnets.chunked(into: 100) {
|
||||||
|
group.addTask {
|
||||||
|
try await self.checkCache(magnets: chunk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var chunkedMagnets: [Magnet] = []
|
||||||
|
for try await magnetArray in group {
|
||||||
|
chunkedMagnets += magnetArray
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunkedMagnets
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableMagnets
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parent function for initial checking of the cache
|
||||||
|
func checkCache(magnets: [Magnet]) async throws -> [Magnet] {
|
||||||
|
var urlComponents = URLComponents(string: "\(baseApiUrl)/cache/check")!
|
||||||
|
urlComponents.queryItems = magnets.map { URLQueryItem(name: "items[]", value: $0.hash) }
|
||||||
|
guard let url = urlComponents.url else {
|
||||||
|
throw PMError.InvalidUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = URLRequest(url: url)
|
||||||
|
|
||||||
|
let data = try await performRequest(request: &request, requestName: #function)
|
||||||
|
let rawResponse = try jsonDecoder.decode(CacheCheckResponse.self, from: data)
|
||||||
|
|
||||||
|
if rawResponse.response.isEmpty {
|
||||||
|
throw PMError.EmptyData
|
||||||
|
} else {
|
||||||
|
let availableMagnets = magnets.enumerated().compactMap { index, magnet in
|
||||||
|
if rawResponse.response[safe: index] == true {
|
||||||
|
return magnet
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableMagnets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Downloading
|
||||||
|
|
||||||
// Wrapper function to fetch a DDL link from the API
|
// Wrapper function to fetch a DDL link from the API
|
||||||
public func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String {
|
public func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String {
|
||||||
// Store the item in PM cloud for later use
|
// Store the item in PM cloud for later use
|
||||||
|
|
@ -249,6 +257,8 @@ public class Premiumize: OAuthDebridSource {
|
||||||
try await performRequest(request: &request, requestName: #function)
|
try await performRequest(request: &request, requestName: #function)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Cloud methods
|
||||||
|
|
||||||
public func getUserDownloads() async throws -> [DebridCloudDownload] {
|
public func getUserDownloads() async throws -> [DebridCloudDownload] {
|
||||||
var request = URLRequest(url: URL(string: "\(baseApiUrl)/item/listall")!)
|
var request = URLRequest(url: URL(string: "\(baseApiUrl)/item/listall")!)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ public class RealDebrid: PollingDebridSource {
|
||||||
UserDefaults.standard.removeObject(forKey: forKey)
|
UserDefaults.standard.removeObject(forKey: forKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Auth
|
||||||
|
|
||||||
// Fetches the device code from RD
|
// Fetches the device code from RD
|
||||||
public func getAuthUrl() async throws -> URL {
|
public func getAuthUrl() async throws -> URL {
|
||||||
var urlComponents = URLComponents(string: "\(baseAuthUrl)/device/code")!
|
var urlComponents = URLComponents(string: "\(baseAuthUrl)/device/code")!
|
||||||
|
|
@ -189,6 +191,8 @@ public class RealDebrid: PollingDebridSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Common request
|
||||||
|
|
||||||
// Wrapper request function which matches the responses and returns data
|
// Wrapper request function which matches the responses and returns data
|
||||||
@discardableResult private func performRequest(request: inout URLRequest, requestName: String) async throws -> Data {
|
@discardableResult private func performRequest(request: inout URLRequest, requestName: String) async throws -> Data {
|
||||||
guard let token = await fetchToken() else {
|
guard let token = await fetchToken() else {
|
||||||
|
|
@ -213,6 +217,8 @@ public class RealDebrid: PollingDebridSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Instant availability
|
||||||
|
|
||||||
// Checks if the magnet is streamable on RD
|
// Checks if the magnet is streamable on RD
|
||||||
public func instantAvailability(magnets: [Magnet]) async throws -> [DebridIA] {
|
public func instantAvailability(magnets: [Magnet]) async throws -> [DebridIA] {
|
||||||
var availableHashes: [DebridIA] = []
|
var availableHashes: [DebridIA] = []
|
||||||
|
|
@ -284,6 +290,8 @@ public class RealDebrid: PollingDebridSource {
|
||||||
return availableHashes
|
return availableHashes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Downloading
|
||||||
|
|
||||||
// Wrapper function to fetch a download link from the API
|
// Wrapper function to fetch a download link from the API
|
||||||
public func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String {
|
public func getDownloadLink(magnet: Magnet, ia: DebridIA?, iaFile: DebridIAFile?) async throws -> String {
|
||||||
let selectedMagnetId = try await addMagnet(magnet: magnet)
|
let selectedMagnetId = try await addMagnet(magnet: magnet)
|
||||||
|
|
@ -376,6 +384,8 @@ public class RealDebrid: PollingDebridSource {
|
||||||
return rawResponse.download
|
return rawResponse.download
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Cloud methods
|
||||||
|
|
||||||
// Gets the user's torrent library
|
// Gets the user's torrent library
|
||||||
public func getUserTorrents() async throws -> [DebridCloudTorrent] {
|
public func getUserTorrents() async throws -> [DebridCloudTorrent] {
|
||||||
var request = URLRequest(url: URL(string: "\(baseApiUrl)/torrents")!)
|
var request = URLRequest(url: URL(string: "\(baseApiUrl)/torrents")!)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue