Ferrite-backup/Ferrite/Models/DebridManagerModels.swift
kingbri 46e0687bd7 Scraping: Add new source methods
Some sources can be unique and require some extra parsing. Add the
ability to extract a magnet link instead of assuming that every
source provides a properly formatted one.

Signed-off-by: kingbri <bdashore3@proton.me>
2023-06-06 20:09:43 -04:00

126 lines
3.8 KiB
Swift

//
// DebridManagerModels.swift
// Ferrite
//
// Created by Brian Dashore on 11/27/22.
//
import Base32
import Foundation
// MARK: - Universal IA enum (IA = InstantAvailability)
public enum IAStatus: String, Codable, Hashable, Sendable, CaseIterable {
case full = "Cached"
case partial = "Batch"
case none = "Uncached"
}
// MARK: - Enum for debrid differentiation. 0 is nil
public enum DebridType: Int, Codable, Hashable, CaseIterable {
case realDebrid = 1
case allDebrid = 2
case premiumize = 3
func toString(abbreviated: Bool = false) -> String {
switch self {
case .realDebrid:
return abbreviated ? "RD" : "RealDebrid"
case .allDebrid:
return abbreviated ? "AD" : "AllDebrid"
case .premiumize:
return abbreviated ? "PM" : "Premiumize"
}
}
func website() -> String {
switch self {
case .realDebrid:
return "https://real-debrid.com"
case .allDebrid:
return "https://alldebrid.com"
case .premiumize:
return "https://premiumize.me"
}
}
}
// Wrapper struct for magnet links to contain both the link and hash for easy access
public struct Magnet: Codable, Hashable, Sendable {
var hash: String?
var link: String?
init(hash: String?, link: String?, title: String? = nil, trackers: [String]? = nil) {
if let hash, link == nil {
self.hash = parseHash(hash)
self.link = generateLink(hash: hash, title: title, trackers: trackers)
} else if let parsedLink = parseLink(link), hash == nil {
self.link = parsedLink
self.hash = parseHash(extractHash(link: parsedLink))
} else {
self.hash = parseHash(hash)
self.link = parseLink(link)
}
}
func generateLink(hash: String, title: String?, trackers: [String]?) -> String {
var magnetLinkArray = ["magnet:?xt=urn:btih:", hash]
if let title, let encodedTitle = title.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) {
magnetLinkArray.append("&dn=\(encodedTitle)")
}
if let trackers {
for trackerUrl in trackers {
if URL(string: trackerUrl) != nil,
let encodedUrlString = trackerUrl.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)
{
magnetLinkArray.append("&tr=\(encodedUrlString)")
}
}
}
return magnetLinkArray.joined()
}
func extractHash(link: String) -> String? {
if let firstSplit = link.split(separator: ":")[safe: 3],
let tempHash = firstSplit.split(separator: "&")[safe: 0]
{
return String(tempHash)
} else {
return nil
}
}
// Is this a Base32hex hash?
func parseHash(_ magnetHash: String?) -> String? {
guard let magnetHash else {
return nil
}
if magnetHash.count == 32 {
let decryptedMagnetHash = base32DecodeToData(String(magnetHash))
return decryptedMagnetHash?.hexEncodedString()
} else {
return String(magnetHash).lowercased()
}
}
func parseLink(_ link: String?) -> String? {
if let decodedLink = link?.removingPercentEncoding {
let separator = "magnet:?xt=urn:btih:"
if decodedLink.starts(with: separator) {
return decodedLink
} else if decodedLink.contains(separator) {
let splitLink = decodedLink.components(separatedBy: separator)
return splitLink.last.map { separator + $0 } ?? nil
} else {
return nil
}
} else {
return nil
}
}
}