mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Remove ParserData from FeedParser API, so clients won’t need to import SAX.
This commit is contained in:
@@ -88,4 +88,3 @@ let package = Package(
|
||||
resources: [.copy("Resources")]),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@@ -7,16 +7,15 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SAX
|
||||
|
||||
// FeedParser handles RSS, Atom, JSON Feed, and RSS-in-JSON.
|
||||
// You don’t need to know the type of feed.
|
||||
|
||||
public struct FeedParser {
|
||||
|
||||
public static func canParse(_ parserData: ParserData) -> Bool {
|
||||
public static func canParse(_ data: Data) -> Bool {
|
||||
|
||||
let type = FeedType.feedType(parserData.data)
|
||||
let type = FeedType.feedType(data)
|
||||
|
||||
switch type {
|
||||
case .jsonFeed, .rssInJSON, .rss, .atom:
|
||||
@@ -26,24 +25,24 @@ public struct FeedParser {
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse(_ parserData: ParserData) throws -> ParsedFeed? {
|
||||
public static func parse(urlString: String, data: Data) throws -> ParsedFeed? {
|
||||
|
||||
let type = FeedType.feedType(parserData.data)
|
||||
let type = FeedType.feedType(data)
|
||||
|
||||
switch type {
|
||||
|
||||
case .jsonFeed:
|
||||
return try JSONFeedParser.parse(parserData)
|
||||
return try JSONFeedParser.parse(urlString: urlString, data: data)
|
||||
|
||||
case .rssInJSON:
|
||||
return try RSSInJSONParser.parse(parserData)
|
||||
return try RSSInJSONParser.parse(urlString: urlString, data: data)
|
||||
|
||||
case .rss:
|
||||
let feed = RSSParser.parsedFeed(with: parserData)
|
||||
let feed = RSSParser.parsedFeed(urlString: urlString, data: data)
|
||||
return RSSFeedTransformer.parsedFeed(with: feed, feedType: .rss)
|
||||
|
||||
case .atom:
|
||||
let feed = AtomParser.parsedFeed(with: parserData)
|
||||
let feed = AtomParser.parsedFeed(urlString: urlString, data: data)
|
||||
return RSSFeedTransformer.parsedFeed(with: feed, feedType: .atom)
|
||||
|
||||
case .unknown, .notAFeed:
|
||||
|
||||
@@ -51,9 +51,9 @@ public struct JSONFeedParser {
|
||||
|
||||
static let jsonFeedVersionMarker = "://jsonfeed.org/version/" // Allow for the mistake of not getting the scheme exactly correct.
|
||||
|
||||
public static func parse(_ parserData: ParserData) throws -> ParsedFeed? {
|
||||
public static func parse(urlString: String, data: Data) throws -> ParsedFeed? {
|
||||
|
||||
guard let d = JSONUtilities.dictionary(with: parserData.data) else {
|
||||
guard let d = JSONUtilities.dictionary(with: data) else {
|
||||
throw FeedParserError(.invalidJSON)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public struct JSONFeedParser {
|
||||
|
||||
let authors = parseAuthors(d)
|
||||
let homePageURL = d[Key.homePageURL] as? String
|
||||
let feedURL = d[Key.feedURL] as? String ?? parserData.url
|
||||
let feedURL = d[Key.feedURL] as? String ?? urlString
|
||||
let feedDescription = d[Key.feedDescription] as? String
|
||||
let nextURL = d[Key.nextURL] as? String
|
||||
let iconURL = d[Key.icon] as? String
|
||||
@@ -78,7 +78,7 @@ public struct JSONFeedParser {
|
||||
let hubs = parseHubs(d)
|
||||
let language = d[Key.language] as? String
|
||||
|
||||
let items = parseItems(itemsArray, parserData.url)
|
||||
let items = parseItems(itemsArray, urlString)
|
||||
|
||||
return ParsedFeed(type: .jsonFeed, title: title, homePageURL: homePageURL, feedURL: feedURL, language: language, feedDescription: feedDescription, nextURL: nextURL, iconURL: iconURL, faviconURL: faviconURL, authors: authors, expired: expired, hubs: hubs, items: items)
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@ import DateParser
|
||||
|
||||
public struct RSSInJSONParser {
|
||||
|
||||
public static func parse(_ parserData: ParserData) throws -> ParsedFeed? {
|
||||
public static func parse(urlString: String, data: Data) throws -> ParsedFeed? {
|
||||
|
||||
do {
|
||||
guard let parsedObject = try JSONSerialization.jsonObject(with: parserData.data) as? JSONDictionary else {
|
||||
guard let parsedObject = try JSONSerialization.jsonObject(with: data) as? JSONDictionary else {
|
||||
throw FeedParserError(.invalidJSON)
|
||||
}
|
||||
guard let rssObject = parsedObject["rss"] as? JSONDictionary else {
|
||||
@@ -46,11 +46,11 @@ public struct RSSInJSONParser {
|
||||
|
||||
let title = channelObject["title"] as? String
|
||||
let homePageURL = channelObject["link"] as? String
|
||||
let feedURL = parserData.url
|
||||
let feedURL = urlString
|
||||
let feedDescription = channelObject["description"] as? String
|
||||
let feedLanguage = channelObject["language"] as? String
|
||||
|
||||
let items = parseItems(itemsObject!, parserData.url)
|
||||
let items = parseItems(itemsObject!, urlString)
|
||||
|
||||
return ParsedFeed(type: .rssInJSON, title: title, homePageURL: homePageURL, feedURL: feedURL, language: feedLanguage, feedDescription: feedDescription, nextURL: nil, iconURL: nil, faviconURL: nil, authors: nil, expired: false, hubs: nil, items: items)
|
||||
|
||||
|
||||
@@ -13,14 +13,8 @@ import DateParser
|
||||
|
||||
final class AtomParser {
|
||||
|
||||
private var parserData: ParserData
|
||||
private var feedURL: String {
|
||||
parserData.url
|
||||
}
|
||||
private var data: Data {
|
||||
parserData.data
|
||||
}
|
||||
|
||||
private var feedURL: String
|
||||
private let data: Data
|
||||
private let feed: RSSFeed
|
||||
|
||||
private var articles = [RSSArticle]()
|
||||
@@ -43,16 +37,17 @@ final class AtomParser {
|
||||
private var parsingSource = false
|
||||
private var endFeedFound = false
|
||||
|
||||
static func parsedFeed(with parserData: ParserData) -> RSSFeed {
|
||||
static func parsedFeed(urlString: String, data: Data) -> RSSFeed {
|
||||
|
||||
let parser = AtomParser(parserData)
|
||||
let parser = AtomParser(urlString: urlString, data: data)
|
||||
parser.parse()
|
||||
return parser.feed
|
||||
}
|
||||
|
||||
init(_ parserData: ParserData) {
|
||||
self.parserData = parserData
|
||||
self.feed = RSSFeed(urlString: parserData.url)
|
||||
init(urlString: String, data: Data) {
|
||||
self.feedURL = urlString
|
||||
self.data = data
|
||||
self.feed = RSSFeed(urlString: urlString)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,14 +13,8 @@ import DateParser
|
||||
|
||||
public final class RSSParser {
|
||||
|
||||
private var parserData: ParserData
|
||||
private var feedURL: String {
|
||||
parserData.url
|
||||
}
|
||||
private var data: Data {
|
||||
parserData.data
|
||||
}
|
||||
|
||||
private let feedURL: String
|
||||
private let data: Data
|
||||
private let feed: RSSFeed
|
||||
private var articles = [RSSArticle]()
|
||||
private var currentArticle: RSSArticle? {
|
||||
@@ -34,16 +28,17 @@ public final class RSSParser {
|
||||
private var parsingAuthor = false
|
||||
private var currentAttributes: StringDictionary?
|
||||
|
||||
static func parsedFeed(with parserData: ParserData) -> RSSFeed {
|
||||
static func parsedFeed(urlString: String, data: Data) -> RSSFeed {
|
||||
|
||||
let parser = RSSParser(parserData)
|
||||
let parser = RSSParser(urlString: urlString, data: data)
|
||||
parser.parse()
|
||||
return parser.feed
|
||||
}
|
||||
|
||||
init(_ parserData: ParserData) {
|
||||
self.parserData = parserData
|
||||
self.feed = RSSFeed(urlString: parserData.url)
|
||||
init(urlString: String, data: Data) {
|
||||
self.feedURL = urlString
|
||||
self.data = data
|
||||
self.feed = RSSFeed(urlString: urlString)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import SAX
|
||||
import FeedParser
|
||||
|
||||
final class RSSInJSONParserTests: XCTestCase {
|
||||
@@ -26,3 +27,11 @@ final class RSSInJSONParserTests: XCTestCase {
|
||||
XCTAssertEqual(parsedFeed.language, "en-us")
|
||||
}
|
||||
}
|
||||
|
||||
extension FeedParser {
|
||||
|
||||
static func parse(_ parserData: ParserData) throws -> ParsedFeed? {
|
||||
|
||||
try FeedParser.parse(urlString: parserData.url, data: parserData.data)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user