Ferrite-backup/Ferrite/Models/DebridManagerModels.swift
kingbri 5a4e98f10d Ferrite: Switch to a Magnet struct
Magnets are expressed in two different ways: a hash and a link. Both
of these mean the same thing with a magnet link giving more information
if required.

However, there was a disconnect if a hash was present or a link was
present and required many steps to check which was available. Unify
magnets by creating a parent structure that attempts to extract
the hash or create a link in the event that either parameter isn't
provided.

Replace everything except bookmarks (to prevent CoreData complaints
and unnecessary abstraction) to use the new Magnet system.

Signed-off-by: kingbri <bdashore3@proton.me>
2023-01-04 12:49:20 -05:00

99 lines
2.9 KiB
Swift

//
// DebridManagerModels.swift
// Ferrite
//
// Created by Brian Dashore on 11/27/22.
//
import Foundation
import Base32
// MARK: - Universal IA enum (IA = InstantAvailability)
public enum IAStatus: Codable, Hashable, Sendable {
case full
case partial
case none
}
// 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"
}
}
}
// 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 = hash, link == nil {
self.hash = parseHash(hash)
self.link = generateLink(hash: hash, title: title, trackers: trackers)
} else if let link = link, hash == nil {
self.link = link
self.hash = parseHash(extractHash(link: link))
} else {
self.hash = parseHash(hash)
self.link = 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()
}
}
}