2017-05-22 22:27:54 +02:00
|
|
|
//
|
|
|
|
// FeedSpecifier.swift
|
2019-07-09 07:58:19 +02:00
|
|
|
// NetNewsWire
|
2017-05-22 22:27:54 +02:00
|
|
|
//
|
|
|
|
// Created by Brent Simmons on 8/7/16.
|
2017-05-29 22:17:58 +02:00
|
|
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
2017-05-22 22:27:54 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
2018-08-26 02:03:10 +02:00
|
|
|
struct FeedSpecifier: Hashable {
|
2017-05-22 22:27:54 +02:00
|
|
|
|
2018-08-26 02:03:10 +02:00
|
|
|
enum Source: Int {
|
2017-05-22 22:27:54 +02:00
|
|
|
case UserEntered = 0, HTMLHead, HTMLLink
|
|
|
|
|
|
|
|
func equalToOrBetterThan(_ otherSource: Source) -> Bool {
|
|
|
|
return self.rawValue <= otherSource.rawValue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public let title: String?
|
|
|
|
public let urlString: String
|
|
|
|
public let source: Source
|
|
|
|
public var score: Int {
|
2018-02-14 22:14:25 +01:00
|
|
|
return calculatedScore()
|
2017-05-22 22:27:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func feedSpecifierByMerging(_ feedSpecifier: FeedSpecifier) -> FeedSpecifier {
|
|
|
|
// Take the best data (non-nil title, better source) to create a new feed specifier;
|
|
|
|
|
|
|
|
let mergedTitle = title ?? feedSpecifier.title
|
|
|
|
let mergedSource = source.equalToOrBetterThan(feedSpecifier.source) ? source : feedSpecifier.source
|
|
|
|
|
|
|
|
return FeedSpecifier(title: mergedTitle, urlString: urlString, source: mergedSource)
|
|
|
|
}
|
|
|
|
|
|
|
|
public static func bestFeed(in feedSpecifiers: Set<FeedSpecifier>) -> FeedSpecifier? {
|
|
|
|
if feedSpecifiers.isEmpty {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if feedSpecifiers.count == 1 {
|
|
|
|
return feedSpecifiers.anyObject()
|
|
|
|
}
|
|
|
|
|
2019-06-03 18:11:16 +02:00
|
|
|
var currentHighScore = Int.min
|
2017-10-22 01:23:51 +02:00
|
|
|
var currentBestFeed: FeedSpecifier? = nil
|
2017-05-22 22:27:54 +02:00
|
|
|
|
|
|
|
for oneFeedSpecifier in feedSpecifiers {
|
|
|
|
let oneScore = oneFeedSpecifier.score
|
|
|
|
if oneScore > currentHighScore {
|
|
|
|
currentHighScore = oneScore
|
|
|
|
currentBestFeed = oneFeedSpecifier
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return currentBestFeed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private extension FeedSpecifier {
|
|
|
|
|
|
|
|
func calculatedScore() -> Int {
|
|
|
|
var score = 0
|
|
|
|
|
|
|
|
if source == .UserEntered {
|
|
|
|
return 1000
|
|
|
|
}
|
|
|
|
else if source == .HTMLHead {
|
|
|
|
score = score + 50
|
|
|
|
}
|
|
|
|
|
2020-01-17 03:09:18 +01:00
|
|
|
if urlString.caseInsensitiveContains("comments") {
|
2017-05-22 22:27:54 +02:00
|
|
|
score = score - 10
|
|
|
|
}
|
2020-03-13 18:57:43 +01:00
|
|
|
if urlString.caseInsensitiveContains("podcast") {
|
|
|
|
score = score - 10
|
|
|
|
}
|
2020-01-17 03:09:18 +01:00
|
|
|
if urlString.caseInsensitiveContains("rss") {
|
2017-05-22 22:27:54 +02:00
|
|
|
score = score + 5
|
|
|
|
}
|
|
|
|
if urlString.hasSuffix("/feed/") {
|
|
|
|
score = score + 5
|
|
|
|
}
|
|
|
|
if urlString.hasSuffix("/feed") {
|
|
|
|
score = score + 4
|
|
|
|
}
|
2020-01-17 03:09:18 +01:00
|
|
|
if urlString.caseInsensitiveContains("json") {
|
2017-11-26 01:47:36 +01:00
|
|
|
score = score + 6
|
|
|
|
}
|
2017-05-22 22:27:54 +02:00
|
|
|
|
|
|
|
if let title = title {
|
2020-01-17 03:09:18 +01:00
|
|
|
if title.caseInsensitiveContains("comments") {
|
2017-05-22 22:27:54 +02:00
|
|
|
score = score - 10
|
|
|
|
}
|
2020-01-17 03:09:18 +01:00
|
|
|
if title.caseInsensitiveContains("json") {
|
2017-11-26 01:47:36 +01:00
|
|
|
score = score + 1
|
|
|
|
}
|
2017-05-22 22:27:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return score
|
|
|
|
}
|
|
|
|
}
|