NetNewsWire/Frameworks/Account/FeedFinder/FeedSpecifier.swift

103 lines
2.2 KiB
Swift

//
// FeedSpecifier.swift
// NetNewsWire
//
// Created by Brent Simmons on 8/7/16.
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
//
import Foundation
struct FeedSpecifier: Hashable {
enum Source: Int {
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 {
return calculatedScore()
}
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()
}
var currentHighScore = Int.min
var currentBestFeed: FeedSpecifier? = nil
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
}
if urlString.caseInsensitiveContains("comments") {
score = score - 10
}
if urlString.caseInsensitiveContains("podcast") {
score = score - 10
}
if urlString.caseInsensitiveContains("rss") {
score = score + 5
}
if urlString.hasSuffix("/feed/") {
score = score + 5
}
if urlString.hasSuffix("/feed") {
score = score + 4
}
if urlString.caseInsensitiveContains("json") {
score = score + 6
}
if let title = title {
if title.caseInsensitiveContains("comments") {
score = score - 10
}
if title.caseInsensitiveContains("json") {
score = score + 1
}
}
return score
}
}