Take order on the page into consideration when searching for the best feed identifier
This commit is contained in:
parent
b504c88948
commit
aa73b24291
|
@ -20,7 +20,7 @@ class FeedFinder {
|
||||||
if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), urlComponents.host == "micro.blog" {
|
if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), urlComponents.host == "micro.blog" {
|
||||||
urlComponents.path = "\(urlComponents.path).json"
|
urlComponents.path = "\(urlComponents.path).json"
|
||||||
if let newURLString = urlComponents.url?.absoluteString {
|
if let newURLString = urlComponents.url?.absoluteString {
|
||||||
let microblogFeedSpecifier = FeedSpecifier(title: nil, urlString: newURLString, source: .HTMLLink)
|
let microblogFeedSpecifier = FeedSpecifier(title: nil, urlString: newURLString, source: .HTMLLink, orderFound: 1)
|
||||||
completion(.success(Set([microblogFeedSpecifier])))
|
completion(.success(Set([microblogFeedSpecifier])))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +45,7 @@ class FeedFinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if FeedFinder.isFeed(data, url.absoluteString) {
|
if FeedFinder.isFeed(data, url.absoluteString) {
|
||||||
let feedSpecifier = FeedSpecifier(title: nil, urlString: url.absoluteString, source: .UserEntered)
|
let feedSpecifier = FeedSpecifier(title: nil, urlString: url.absoluteString, source: .UserEntered, orderFound: 1)
|
||||||
completion(.success(Set([feedSpecifier])))
|
completion(.success(Set([feedSpecifier])))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -120,11 +120,11 @@ private extension FeedFinder {
|
||||||
// It’s also fairly common for /index.xml to work.
|
// It’s also fairly common for /index.xml to work.
|
||||||
if let url = URL(string: urlString) {
|
if let url = URL(string: urlString) {
|
||||||
let feedURL = url.appendingPathComponent("feed", isDirectory: true)
|
let feedURL = url.appendingPathComponent("feed", isDirectory: true)
|
||||||
let wordpressFeedSpecifier = FeedSpecifier(title: nil, urlString: feedURL.absoluteString, source: .HTMLLink)
|
let wordpressFeedSpecifier = FeedSpecifier(title: nil, urlString: feedURL.absoluteString, source: .HTMLLink, orderFound: 1)
|
||||||
feedSpecifiers.insert(wordpressFeedSpecifier)
|
feedSpecifiers.insert(wordpressFeedSpecifier)
|
||||||
|
|
||||||
let indexXMLURL = url.appendingPathComponent("index.xml", isDirectory: false)
|
let indexXMLURL = url.appendingPathComponent("index.xml", isDirectory: false)
|
||||||
let indexXMLFeedSpecifier = FeedSpecifier(title: nil, urlString: indexXMLURL.absoluteString, source: .HTMLLink)
|
let indexXMLFeedSpecifier = FeedSpecifier(title: nil, urlString: indexXMLURL.absoluteString, source: .HTMLLink, orderFound: 1)
|
||||||
feedSpecifiers.insert(indexXMLFeedSpecifier)
|
feedSpecifiers.insert(indexXMLFeedSpecifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ struct FeedSpecifier: Hashable {
|
||||||
public let title: String?
|
public let title: String?
|
||||||
public let urlString: String
|
public let urlString: String
|
||||||
public let source: Source
|
public let source: Source
|
||||||
|
public let orderFound: Int
|
||||||
public var score: Int {
|
public var score: Int {
|
||||||
return calculatedScore()
|
return calculatedScore()
|
||||||
}
|
}
|
||||||
|
@ -30,8 +31,9 @@ struct FeedSpecifier: Hashable {
|
||||||
|
|
||||||
let mergedTitle = title ?? feedSpecifier.title
|
let mergedTitle = title ?? feedSpecifier.title
|
||||||
let mergedSource = source.equalToOrBetterThan(feedSpecifier.source) ? source : feedSpecifier.source
|
let mergedSource = source.equalToOrBetterThan(feedSpecifier.source) ? source : feedSpecifier.source
|
||||||
|
let mergedOrderFound = orderFound >= feedSpecifier.orderFound ? orderFound : feedSpecifier.orderFound
|
||||||
|
|
||||||
return FeedSpecifier(title: mergedTitle, urlString: urlString, source: mergedSource)
|
return FeedSpecifier(title: mergedTitle, urlString: urlString, source: mergedSource, orderFound: mergedOrderFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func bestFeed(in feedSpecifiers: Set<FeedSpecifier>) -> FeedSpecifier? {
|
public static func bestFeed(in feedSpecifiers: Set<FeedSpecifier>) -> FeedSpecifier? {
|
||||||
|
@ -69,6 +71,8 @@ private extension FeedSpecifier {
|
||||||
score = score + 50
|
score = score + 50
|
||||||
}
|
}
|
||||||
|
|
||||||
|
score = score - ((orderFound - 1) * 5)
|
||||||
|
|
||||||
if urlString.caseInsensitiveContains("comments") {
|
if urlString.caseInsensitiveContains("comments") {
|
||||||
score = score - 10
|
score = score - 10
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,21 @@ class HTMLFeedFinder {
|
||||||
|
|
||||||
init(parserData: ParserData) {
|
init(parserData: ParserData) {
|
||||||
let metadata = RSHTMLMetadataParser.htmlMetadata(with: parserData)
|
let metadata = RSHTMLMetadataParser.htmlMetadata(with: parserData)
|
||||||
|
var orderFound = 0
|
||||||
|
|
||||||
for oneFeedLink in metadata.feedLinks {
|
for oneFeedLink in metadata.feedLinks {
|
||||||
if let oneURLString = oneFeedLink.urlString?.normalizedURL {
|
if let oneURLString = oneFeedLink.urlString?.normalizedURL {
|
||||||
let oneFeedSpecifier = FeedSpecifier(title: oneFeedLink.title, urlString: oneURLString, source: .HTMLHead)
|
orderFound = orderFound + 1
|
||||||
|
let oneFeedSpecifier = FeedSpecifier(title: oneFeedLink.title, urlString: oneURLString, source: .HTMLHead, orderFound: orderFound)
|
||||||
addFeedSpecifier(oneFeedSpecifier)
|
addFeedSpecifier(oneFeedSpecifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let bodyLinks = RSHTMLLinkParser.htmlLinks(with: parserData)
|
let bodyLinks = RSHTMLLinkParser.htmlLinks(with: parserData)
|
||||||
for oneBodyLink in bodyLinks {
|
for oneBodyLink in bodyLinks {
|
||||||
|
|
||||||
if linkMightBeFeed(oneBodyLink), let normalizedURL = oneBodyLink.urlString?.normalizedURL {
|
if linkMightBeFeed(oneBodyLink), let normalizedURL = oneBodyLink.urlString?.normalizedURL {
|
||||||
let oneFeedSpecifier = FeedSpecifier(title: oneBodyLink.text, urlString: normalizedURL, source: .HTMLLink)
|
orderFound = orderFound + 1
|
||||||
|
let oneFeedSpecifier = FeedSpecifier(title: oneBodyLink.text, urlString: normalizedURL, source: .HTMLLink, orderFound: orderFound)
|
||||||
addFeedSpecifier(oneFeedSpecifier)
|
addFeedSpecifier(oneFeedSpecifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -986,27 +986,22 @@ private extension FeedbinAccountDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
func decideBestFeedChoice(account: Account, url: String, name: String?, container: Container, choices: [FeedbinSubscriptionChoice], completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
func decideBestFeedChoice(account: Account, url: String, name: String?, container: Container, choices: [FeedbinSubscriptionChoice], completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
||||||
|
var orderFound = 0
|
||||||
|
|
||||||
let feedSpecifiers: [FeedSpecifier] = choices.map { choice in
|
let feedSpecifiers: [FeedSpecifier] = choices.map { choice in
|
||||||
let source = url == choice.url ? FeedSpecifier.Source.UserEntered : FeedSpecifier.Source.HTMLLink
|
let source = url == choice.url ? FeedSpecifier.Source.UserEntered : FeedSpecifier.Source.HTMLLink
|
||||||
let specifier = FeedSpecifier(title: choice.name, urlString: choice.url, source: source)
|
orderFound = orderFound + 1
|
||||||
|
let specifier = FeedSpecifier(title: choice.name, urlString: choice.url, source: source, orderFound: orderFound)
|
||||||
return specifier
|
return specifier
|
||||||
}
|
}
|
||||||
|
|
||||||
if let bestSpecifier = FeedSpecifier.bestFeed(in: Set(feedSpecifiers)) {
|
if let bestSpecifier = FeedSpecifier.bestFeed(in: Set(feedSpecifiers)) {
|
||||||
if let bestSubscription = choices.filter({ bestSpecifier.urlString == $0.url }).first {
|
createWebFeed(for: account, url: bestSpecifier.urlString, name: name, container: container, completion: completion)
|
||||||
createWebFeed(for: account, url: bestSubscription.url, name: name, container: container, completion: completion)
|
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
completion(.failure(FeedbinAccountDelegateError.invalidParameter))
|
completion(.failure(FeedbinAccountDelegateError.invalidParameter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
completion(.failure(FeedbinAccountDelegateError.invalidParameter))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFeed( account: Account, subscription sub: FeedbinSubscription, name: String?, container: Container, completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
func createFeed( account: Account, subscription sub: FeedbinSubscription, name: String?, container: Container, completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
||||||
|
|
|
@ -828,30 +828,6 @@ private extension ReaderAPIAccountDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func decideBestFeedChoice(account: Account, url: String, name: String?, container: Container, choices: [ReaderAPISubscriptionChoice], completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
|
||||||
|
|
||||||
let feedSpecifiers: [FeedSpecifier] = choices.map { choice in
|
|
||||||
let source = url == choice.url ? FeedSpecifier.Source.UserEntered : FeedSpecifier.Source.HTMLLink
|
|
||||||
let specifier = FeedSpecifier(title: choice.name, urlString: choice.url, source: source)
|
|
||||||
return specifier
|
|
||||||
}
|
|
||||||
|
|
||||||
if let bestSpecifier = FeedSpecifier.bestFeed(in: Set(feedSpecifiers)) {
|
|
||||||
if let bestSubscription = choices.filter({ bestSpecifier.urlString == $0.url }).first {
|
|
||||||
createWebFeed(for: account, url: bestSubscription.url, name: name, container: container, completion: completion)
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func createFeed( account: Account, subscription sub: ReaderAPISubscription, name: String?, container: Container, completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
func createFeed( account: Account, subscription sub: ReaderAPISubscription, name: String?, container: Container, completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
|
Loading…
Reference in New Issue