diff --git a/Ferrite/DataManagement/Classes/SourceHtmlParser+CoreDataProperties.swift b/Ferrite/DataManagement/Classes/SourceHtmlParser+CoreDataProperties.swift index 1cc03aa..e5f19bd 100644 --- a/Ferrite/DataManagement/Classes/SourceHtmlParser+CoreDataProperties.swift +++ b/Ferrite/DataManagement/Classes/SourceHtmlParser+CoreDataProperties.swift @@ -22,6 +22,7 @@ public extension SourceHtmlParser { @NSManaged var seedLeech: SourceSeedLeech? @NSManaged var size: SourceSize? @NSManaged var title: SourceTitle? + @NSManaged var subName: SourceSubName? } extension SourceHtmlParser: Identifiable {} diff --git a/Ferrite/DataManagement/Classes/SourceJsonParser+CoreDataProperties.swift b/Ferrite/DataManagement/Classes/SourceJsonParser+CoreDataProperties.swift index 84de4d3..81d7287 100644 --- a/Ferrite/DataManagement/Classes/SourceJsonParser+CoreDataProperties.swift +++ b/Ferrite/DataManagement/Classes/SourceJsonParser+CoreDataProperties.swift @@ -23,6 +23,7 @@ public extension SourceJsonParser { @NSManaged var seedLeech: SourceSeedLeech? @NSManaged var size: SourceSize? @NSManaged var title: SourceTitle? + @NSManaged var subName: SourceSubName? } extension SourceJsonParser: Identifiable {} diff --git a/Ferrite/DataManagement/Classes/SourceRssParser+CoreDataProperties.swift b/Ferrite/DataManagement/Classes/SourceRssParser+CoreDataProperties.swift index eef0e62..6e8cc8e 100644 --- a/Ferrite/DataManagement/Classes/SourceRssParser+CoreDataProperties.swift +++ b/Ferrite/DataManagement/Classes/SourceRssParser+CoreDataProperties.swift @@ -23,6 +23,7 @@ public extension SourceRssParser { @NSManaged var seedLeech: SourceSeedLeech? @NSManaged var size: SourceSize? @NSManaged var title: SourceTitle? + @NSManaged var subName: SourceSubName? } extension SourceRssParser: Identifiable {} diff --git a/Ferrite/DataManagement/FerriteDB.xcdatamodeld/FerriteDB_v2.xcdatamodel/contents b/Ferrite/DataManagement/FerriteDB.xcdatamodeld/FerriteDB_v2.xcdatamodel/contents index 6a3cdd0..305d94c 100644 --- a/Ferrite/DataManagement/FerriteDB.xcdatamodeld/FerriteDB_v2.xcdatamodel/contents +++ b/Ferrite/DataManagement/FerriteDB.xcdatamodeld/FerriteDB_v2.xcdatamodel/contents @@ -99,6 +99,7 @@ + @@ -110,6 +111,7 @@ + @@ -132,6 +134,7 @@ + @@ -151,6 +154,11 @@ + + + + + diff --git a/Ferrite/Models/SourceModels.swift b/Ferrite/Models/SourceModels.swift index fe676b3..3bb45b8 100644 --- a/Ferrite/Models/SourceModels.swift +++ b/Ferrite/Models/SourceModels.swift @@ -18,7 +18,7 @@ public struct SourceJson: Codable, Hashable, Sendable, PluginJson { let minVersion: String? let baseUrl: String? let fallbackUrls: [String]? - var dynamicBaseUrl: Bool? + let dynamicBaseUrl: Bool? let trackers: [String]? let api: SourceApiJson? let jsonParser: SourceJsonParserJson? @@ -62,10 +62,11 @@ public struct SourceJsonParserJson: Codable, Hashable, Sendable { let searchUrl: String let results: String? let subResults: String? - let magnetHash: SouceComplexQueryJson? - let magnetLink: SouceComplexQueryJson? - let title: SouceComplexQueryJson? - let size: SouceComplexQueryJson? + let magnetHash: SourceComplexQueryJson? + let magnetLink: SourceComplexQueryJson? + let subName: SourceComplexQueryJson? + let title: SourceComplexQueryJson? + let size: SourceComplexQueryJson? let sl: SourceSLJson? } @@ -73,10 +74,11 @@ public struct SourceRssParserJson: Codable, Hashable, Sendable { let rssUrl: String? let searchUrl: String let items: String - let magnetHash: SouceComplexQueryJson? - let magnetLink: SouceComplexQueryJson? - let title: SouceComplexQueryJson? - let size: SouceComplexQueryJson? + let magnetHash: SourceComplexQueryJson? + let magnetLink: SourceComplexQueryJson? + let subName: SourceComplexQueryJson? + let title: SourceComplexQueryJson? + let size: SourceComplexQueryJson? let sl: SourceSLJson? } @@ -84,12 +86,13 @@ public struct SourceHtmlParserJson: Codable, Hashable, Sendable { let searchUrl: String let rows: String let magnet: SourceMagnetJson - let title: SouceComplexQueryJson? - let size: SouceComplexQueryJson? + let subName: SourceComplexQueryJson? + let title: SourceComplexQueryJson? + let size: SourceComplexQueryJson? let sl: SourceSLJson? } -public struct SouceComplexQueryJson: Codable, Hashable, Sendable { +public struct SourceComplexQueryJson: Codable, Hashable, Sendable { let query: String let discriminator: String? let attribute: String? diff --git a/Ferrite/ViewModels/PluginManager.swift b/Ferrite/ViewModels/PluginManager.swift index f850e3d..02629c1 100644 --- a/Ferrite/ViewModels/PluginManager.swift +++ b/Ferrite/ViewModels/PluginManager.swift @@ -45,6 +45,7 @@ public class PluginManager: ObservableObject { minVersion: inputJson.minVersion, baseUrl: inputJson.baseUrl, fallbackUrls: inputJson.fallbackUrls, + dynamicBaseUrl: inputJson.dynamicBaseUrl, trackers: inputJson.trackers, api: inputJson.api, jsonParser: inputJson.jsonParser, @@ -257,7 +258,6 @@ public class PluginManager: ObservableObject { // If there's no base URL and it isn't dynamic, return before any transactions occur let dynamicBaseUrl = sourceJson.dynamicBaseUrl ?? false - if !dynamicBaseUrl, sourceJson.baseUrl == nil { await toastModel?.updateToastDescription("Not adding this source because base URL parameters are malformed. Please contact the source dev.") print("Not adding source \(sourceJson.name) because base URL parameters are malformed") @@ -401,6 +401,15 @@ public class PluginManager: ObservableObject { newSourceJsonParser.magnetHash = newSourceMagnetHash } + if let subNameJson = jsonParserJson.subName { + let newSourceSubName = SourceSubName(context: backgroundContext) + newSourceSubName.query = subNameJson.query + newSourceSubName.attribute = subNameJson.query + newSourceSubName.discriminator = subNameJson.discriminator + + newSourceJsonParser.subName = newSourceSubName + } + if let titleJson = jsonParserJson.title { let newSourceTitle = SourceTitle(context: backgroundContext) newSourceTitle.query = titleJson.query @@ -448,6 +457,7 @@ public class PluginManager: ObservableObject { newSourceMagnetLink.query = magnetLinkJson.query newSourceMagnetLink.attribute = magnetLinkJson.attribute ?? "text" newSourceMagnetLink.discriminator = magnetLinkJson.discriminator + newSourceMagnetLink.regex = magnetLinkJson.regex newSourceRssParser.magnetLink = newSourceMagnetLink } @@ -457,15 +467,27 @@ public class PluginManager: ObservableObject { newSourceMagnetHash.query = magnetHashJson.query newSourceMagnetHash.attribute = magnetHashJson.attribute ?? "text" newSourceMagnetHash.discriminator = magnetHashJson.discriminator + newSourceMagnetHash.regex = magnetHashJson.regex newSourceRssParser.magnetHash = newSourceMagnetHash } + if let subNameJson = rssParserJson.subName { + let newSourceSubName = SourceSubName(context: backgroundContext) + newSourceSubName.query = subNameJson.query + newSourceSubName.attribute = subNameJson.attribute ?? "text" + newSourceSubName.discriminator = subNameJson.discriminator + newSourceSubName.regex = subNameJson.regex + + newSourceRssParser.subName = newSourceSubName + } + if let titleJson = rssParserJson.title { let newSourceTitle = SourceTitle(context: backgroundContext) newSourceTitle.query = titleJson.query newSourceTitle.attribute = titleJson.attribute ?? "text" newSourceTitle.discriminator = titleJson.discriminator + newSourceTitle.regex = titleJson.regex newSourceRssParser.title = newSourceTitle } @@ -475,6 +497,7 @@ public class PluginManager: ObservableObject { newSourceSize.query = sizeJson.query newSourceSize.attribute = sizeJson.attribute ?? "text" newSourceSize.discriminator = sizeJson.discriminator + newSourceSize.regex = sizeJson.regex newSourceRssParser.size = newSourceSize } @@ -502,6 +525,15 @@ public class PluginManager: ObservableObject { newSourceHtmlParser.searchUrl = htmlParserJson.searchUrl newSourceHtmlParser.rows = htmlParserJson.rows + if let subNameJson = htmlParserJson.subName { + let newSourceSubName = SourceSubName(context: backgroundContext) + newSourceSubName.query = subNameJson.query + newSourceSubName.attribute = subNameJson.attribute ?? "text" + newSourceSubName.regex = subNameJson.regex + + newSourceHtmlParser.subName = newSourceSubName + } + // Adds a title complex query if present if let titleJson = htmlParserJson.title { let newSourceTitle = SourceTitle(context: backgroundContext) diff --git a/Ferrite/ViewModels/ScrapingViewModel.swift b/Ferrite/ViewModels/ScrapingViewModel.swift index e1fdab2..1abdbbe 100644 --- a/Ferrite/ViewModels/ScrapingViewModel.swift +++ b/Ferrite/ViewModels/ScrapingViewModel.swift @@ -399,6 +399,12 @@ class ScrapingViewModel: ObservableObject { } } + var subName: String? + if let subNameParser = jsonParser.subName { + let rawSubName = result[subNameParser.query.components(separatedBy: ".")].rawValue + subName = rawSubName is NSNull ? nil : String(describing: rawSubName) + } + var link: String? = existingSearchResult?.magnet.link if let magnetLinkParser = jsonParser.magnetLink, link == nil { let rawLink = result[magnetLinkParser.query.components(separatedBy: ".")].rawValue @@ -432,7 +438,7 @@ class ScrapingViewModel: ObservableObject { let result = SearchResult( title: title, - source: source.name, + source: subName.map { "\(source.name) - \($0)" } ?? source.name, size: size, magnet: Magnet(hash: magnetHash, link: link, title: title, trackers: source.trackers), seeders: seeders, @@ -474,6 +480,18 @@ class ScrapingViewModel: ObservableObject { ) } + // Fetches the subName for the source if there is one + var subName: String? + if let subNameParser = rssParser.subName { + subName = try? runRssComplexQuery( + item: item, + query: subNameParser.query, + attribute: subNameParser.attribute, + discriminator: subNameParser.discriminator, + regexString: subNameParser.regex + ) + } + var title: String? if let titleParser = rssParser.title { title = try? runRssComplexQuery( @@ -485,9 +503,9 @@ class ScrapingViewModel: ObservableObject { ) } - var link: String? + var href: String? if let magnetLinkParser = rssParser.magnetLink { - link = try? runRssComplexQuery( + href = try? runRssComplexQuery( item: item, query: magnetLinkParser.query, attribute: magnetLinkParser.attribute, @@ -498,10 +516,6 @@ class ScrapingViewModel: ObservableObject { continue } - guard let href = link, href.starts(with: "magnet:") else { - continue - } - var size: String? if let sizeParser = rssParser.size { size = try? runRssComplexQuery( @@ -543,7 +557,7 @@ class ScrapingViewModel: ObservableObject { let result = SearchResult( title: title ?? "No title", - source: source.name, + source: subName.map { "\(source.name) - \($0)" } ?? source.name, size: size ?? "", magnet: Magnet(hash: magnetHash, link: href, title: title, trackers: source.trackers), seeders: seeders, @@ -649,10 +663,6 @@ class ScrapingViewModel: ObservableObject { href = link } - if !href.starts(with: "magnet:") { - continue - } - // Fetches the episode/movie title var title: String? if let titleParser = htmlParser.title { @@ -664,8 +674,17 @@ class ScrapingViewModel: ObservableObject { ) } - // Fetches the torrent's size - // TODO: Add int translation + var subName: String? + if let subNameParser = htmlParser.subName { + subName = try? runHtmlComplexQuery( + row: row, + query: subNameParser.query, + attribute: subNameParser.attribute, + regexString: subNameParser.regex + ) + } + + // Fetches the size var size: String? if let sizeParser = htmlParser.size { size = try? runHtmlComplexQuery( @@ -718,7 +737,7 @@ class ScrapingViewModel: ObservableObject { let result = SearchResult( title: title ?? "No title", - source: source.name, + source: subName.map { "\(source.name) - \($0)" } ?? source.name, size: size ?? "", magnet: Magnet(hash: nil, link: href), seeders: seeders,