From 3aeda820e4073e3af85023443a0ab4a1b878979b Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 25 Jun 2023 16:11:55 -0700 Subject: [PATCH] Remove FeedProviderManager and Feed Provider and remove references to them. --- .../CloudKit/CloudKitAccountDelegate.swift | 118 +----------------- .../Account/FeedProvider/FeedProvider.swift | 38 ------ .../FeedProvider/FeedProviderManager.swift | 42 ------- .../LocalAccount/LocalAccountDelegate.swift | 79 +----------- Account/Sources/Account/WebFeed.swift | 7 +- Mac/AppDelegate.swift | 1 - .../ExtensionPointManager.swift | 16 +-- Shared/Images/WebFeedIconDownloader.swift | 26 +--- 8 files changed, 12 insertions(+), 315 deletions(-) delete mode 100644 Account/Sources/Account/FeedProvider/FeedProvider.swift delete mode 100644 Account/Sources/Account/FeedProvider/FeedProviderManager.swift diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index 98baf7565..04c84723c 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -176,20 +176,14 @@ final class CloudKitAccountDelegate: AccountDelegate { } func createWebFeed(for account: Account, url urlString: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { - guard let url = URL(string: urlString), let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) else { + guard let url = URL(string: urlString) else { completion(.failure(LocalAccountDelegateError.invalidParameter)) return } let editedName = name == nil || name!.isEmpty ? nil : name - // Username should be part of the URL on new feed adds - if let feedProvider = FeedProviderManager.shared.best(for: urlComponents) { - createProviderWebFeed(for: account, urlComponents: urlComponents, editedName: editedName, container: container, feedProvider: feedProvider, completion: completion) - } else { - createRSSWebFeed(for: account, url: url, editedName: editedName, container: container, validateFeed: validateFeed, completion: completion) - } - + createRSSWebFeed(for: account, url: url, editedName: editedName, container: container, validateFeed: validateFeed, completion: completion) } func renameWebFeed(for account: Account, with feed: WebFeed, to name: String, completion: @escaping (Result) -> Void) { @@ -570,119 +564,15 @@ private extension CloudKitAccountDelegate { func combinedRefresh(_ account: Account, _ webFeeds: Set, completion: @escaping (Result) -> Void) { - var refresherWebFeeds = Set() let group = DispatchGroup() - var feedProviderError: Error? = nil - - for webFeed in webFeeds { - if let components = URLComponents(string: webFeed.url), let feedProvider = FeedProviderManager.shared.best(for: components) { - group.enter() - feedProvider.refresh(webFeed) { result in - switch result { - case .success(let parsedItems): - - account.update(webFeed.webFeedID, with: parsedItems) { result in - switch result { - case .success(let articleChanges): - self.storeArticleChanges(new: articleChanges.newArticles, updated: articleChanges.updatedArticles, deleted: articleChanges.deletedArticles) { - self.refreshProgress.completeTask() - group.leave() - } - case .failure(let error): - os_log(.error, log: self.log, "CloudKit Feed refresh update error: %@.", error.localizedDescription) - self.refreshProgress.completeTask() - group.leave() - } - - } - case .failure(let error): - os_log(.error, log: self.log, "CloudKit Feed refresh error: %@.", error.localizedDescription) - feedProviderError = error - self.refreshProgress.completeTask() - group.leave() - } - } - } else { - refresherWebFeeds.insert(webFeed) - } - } - group.enter() - refresher.refreshFeeds(refresherWebFeeds) { + refresher.refreshFeeds(webFeeds) { group.leave() } group.notify(queue: DispatchQueue.main) { - if let error = feedProviderError { - completion(.failure(error)) - } else { - completion(.success(())) - } - } - - } - - func createProviderWebFeed(for account: Account, urlComponents: URLComponents, editedName: String?, container: Container, feedProvider: FeedProvider, completion: @escaping (Result) -> Void) { - refreshProgress.addToNumberOfTasksAndRemaining(5) - - feedProvider.metaData(urlComponents) { result in - self.refreshProgress.completeTask() - switch result { - - case .success(let metaData): - - guard let urlString = urlComponents.url?.absoluteString else { - self.refreshProgress.completeTasks(4) - completion(.failure(AccountError.createErrorNotFound)) - return - } - - self.accountZone.createWebFeed(url: urlString, name: metaData.name, editedName: editedName, homePageURL: metaData.homePageURL, container: container) { result in - - self.refreshProgress.completeTask() - switch result { - case .success(let externalID): - - let feed = account.createWebFeed(with: metaData.name, url: urlString, webFeedID: urlString, homePageURL: metaData.homePageURL) - feed.editedName = editedName - feed.externalID = externalID - container.addWebFeed(feed) - - feedProvider.refresh(feed) { result in - self.refreshProgress.completeTask() - switch result { - case .success(let parsedItems): - - account.update(urlString, with: parsedItems) { result in - switch result { - case .success: - self.sendNewArticlesToTheCloud(account, feed) - self.refreshProgress.clear() - completion(.success(feed)) - case .failure(let error): - self.refreshProgress.completeTasks(2) - completion(.failure(error)) - } - - } - - case .failure: - self.refreshProgress.completeTasks(3) - completion(.failure(AccountError.createErrorNotFound)) - } - } - - case .failure(let error): - self.refreshProgress.completeTasks(4) - completion(.failure(error)) - } - } - - case .failure: - self.refreshProgress.completeTasks(4) - completion(.failure(AccountError.createErrorNotFound)) - } + completion(.success(())) } } diff --git a/Account/Sources/Account/FeedProvider/FeedProvider.swift b/Account/Sources/Account/FeedProvider/FeedProvider.swift deleted file mode 100644 index 065547372..000000000 --- a/Account/Sources/Account/FeedProvider/FeedProvider.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// FeedProvider.swift -// FeedProvider -// -// Created by Maurice Parker on 4/6/20. -// Copyright © 2020 Ranchero Software, LLC. All rights reserved. -// - -import Foundation -import RSCore -import RSParser - -public enum FeedProviderAbility { - case owner - case available - case none -} - -public struct FeedProviderFeedMetaData { - let name: String - let homePageURL: String? -} - -public protocol FeedProvider { - - /// Informs the caller of the ability for this feed provider to service the given URL - func ability(_ urlComponents: URLComponents) -> FeedProviderAbility - - /// Provide the iconURL of the given URL - func iconURL(_ urlComponents: URLComponents, completion: @escaping (Result) -> Void) - - /// Construct the associated metadata for the new feed - func metaData(_ urlComponents: URLComponents, completion: @escaping (Result) -> Void) - - /// Refresh all the article entries (ParsedItems) - func refresh(_ webFeed: WebFeed, completion: @escaping (Result, Error>) -> Void) - -} diff --git a/Account/Sources/Account/FeedProvider/FeedProviderManager.swift b/Account/Sources/Account/FeedProvider/FeedProviderManager.swift deleted file mode 100644 index f4b6e1cf4..000000000 --- a/Account/Sources/Account/FeedProvider/FeedProviderManager.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// FeedProviderManager.swift -// Account -// -// Created by Maurice Parker on 4/16/20. -// Copyright © 2020 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -public protocol FeedProviderManagerDelegate: AnyObject { - var activeFeedProviders: [FeedProvider] { get } -} - -public final class FeedProviderManager { - - public static let shared = FeedProviderManager() - public weak var delegate: FeedProviderManagerDelegate? - - public func best(for offered: URLComponents) -> FeedProvider? { - if let owner = feedProviderMatching(offered, ability: .owner) { - return owner - } - return feedProviderMatching(offered, ability: .available) - } - -} - -private extension FeedProviderManager { - - func feedProviderMatching(_ offered: URLComponents, ability: FeedProviderAbility) -> FeedProvider? { - if let delegate = delegate { - for feedProvider in delegate.activeFeedProviders { - if feedProvider.ability(offered) == ability { - return feedProvider - } - } - } - return nil - } - -} diff --git a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift index 456c8b738..0accce9dd 100644 --- a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift @@ -50,48 +50,20 @@ final class LocalAccountDelegate: AccountDelegate { return } - var refresherWebFeeds = Set() let webFeeds = account.flattenedWebFeeds() refreshProgress.addToNumberOfTasksAndRemaining(webFeeds.count) let group = DispatchGroup() - var feedProviderError: Error? = nil - - for webFeed in webFeeds { - if let components = URLComponents(string: webFeed.url), let feedProvider = FeedProviderManager.shared.best(for: components) { - group.enter() - feedProvider.refresh(webFeed) { result in - switch result { - case .success(let parsedItems): - account.update(webFeed.webFeedID, with: parsedItems) { _ in - self.refreshProgress.completeTask() - group.leave() - } - case .failure(let error): - os_log(.error, log: self.log, "Feed Provider refresh error: %@.", error.localizedDescription) - feedProviderError = error - self.refreshProgress.completeTask() - group.leave() - } - } - } else { - refresherWebFeeds.insert(webFeed) - } - } - + group.enter() - refresher?.refreshFeeds(refresherWebFeeds) { + refresher?.refreshFeeds(webFeeds) { group.leave() } group.notify(queue: DispatchQueue.main) { self.refreshProgress.clear() account.metadata.lastArticleFetchEndTime = Date() - if let error = feedProviderError { - completion(.failure(error)) - } else { - completion(.success(())) - } + completion(.success(())) } } @@ -156,12 +128,7 @@ final class LocalAccountDelegate: AccountDelegate { return } - // Username should be part of the URL on new feed adds - if let feedProvider = FeedProviderManager.shared.best(for: urlComponents) { - createProviderWebFeed(for: account, urlComponents: urlComponents, editedName: name, container: container, feedProvider: feedProvider, completion: completion) - } else { - createRSSWebFeed(for: account, url: url, editedName: name, container: container, completion: completion) - } + createRSSWebFeed(for: account, url: url, editedName: name, container: container, completion: completion) } func renameWebFeed(for account: Account, with feed: WebFeed, to name: String, completion: @escaping (Result) -> Void) { @@ -264,44 +231,6 @@ extension LocalAccountDelegate: LocalAccountRefresherDelegate { private extension LocalAccountDelegate { - func createProviderWebFeed(for account: Account, urlComponents: URLComponents, editedName: String?, container: Container, feedProvider: FeedProvider, completion: @escaping (Result) -> Void) { - refreshProgress.addToNumberOfTasksAndRemaining(2) - - feedProvider.metaData(urlComponents) { result in - self.refreshProgress.completeTask() - switch result { - - case .success(let metaData): - - guard let urlString = urlComponents.url?.absoluteString else { - completion(.failure(AccountError.createErrorNotFound)) - return - } - - let feed = account.createWebFeed(with: metaData.name, url: urlString, webFeedID: urlString, homePageURL: metaData.homePageURL) - feed.editedName = editedName - container.addWebFeed(feed) - - feedProvider.refresh(feed) { result in - self.refreshProgress.completeTask() - switch result { - case .success(let parsedItems): - account.update(urlString, with: parsedItems) { _ in - completion(.success(feed)) - } - case .failure(let error): - self.refreshProgress.clear() - completion(.failure(error)) - } - } - - case .failure: - self.refreshProgress.clear() - completion(.failure(AccountError.createErrorNotFound)) - } - } - } - func createRSSWebFeed(for account: Account, url: URL, editedName: String?, container: Container, completion: @escaping (Result) -> Void) { // We need to use a batch update here because we need to assign add the feed to the diff --git a/Account/Sources/Account/WebFeed.swift b/Account/Sources/Account/WebFeed.swift index 3b4bda23c..1bcfc8596 100644 --- a/Account/Sources/Account/WebFeed.swift +++ b/Account/Sources/Account/WebFeed.swift @@ -233,11 +233,8 @@ public final class WebFeed: Feed, Renamable, Hashable { let components = URLComponents(url: webfeedURL, resolvingAgainstBaseURL: false) else { return false } - - if FeedProviderManager.shared.best(for: components) == nil { - return false - } - return true + + return false } } diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index 8adf6b39e..002e975bc 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -123,7 +123,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, SecretsManager.provider = Secrets() AccountManager.shared = AccountManager(accountsFolder: Platform.dataSubfolder(forApplication: nil, folderName: "Accounts")!) ArticleThemesManager.shared = ArticleThemesManager(folderPath: Platform.dataSubfolder(forApplication: nil, folderName: "Themes")!) - FeedProviderManager.shared.delegate = ExtensionPointManager.shared NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(inspectableObjectsDidChange(_:)), name: .InspectableObjectsDidChange, object: nil) diff --git a/Shared/ExtensionPoints/ExtensionPointManager.swift b/Shared/ExtensionPoints/ExtensionPointManager.swift index 557894e62..964d7aaa7 100644 --- a/Shared/ExtensionPoints/ExtensionPointManager.swift +++ b/Shared/ExtensionPoints/ExtensionPointManager.swift @@ -27,7 +27,7 @@ public enum ExtensionPointManagerError: LocalizedError { } -final class ExtensionPointManager: FeedProviderManagerDelegate { +final class ExtensionPointManager { static let shared = ExtensionPointManager() @@ -65,10 +65,6 @@ final class ExtensionPointManager: FeedProviderManagerDelegate { return commands } - var activeFeedProviders: [FeedProvider] { - return activeExtensionPoints.values.compactMap({ return $0 as? FeedProvider }) - } - init() { possibleExtensionPointTypes = [] loadExtensionPoints() @@ -126,14 +122,4 @@ private extension ExtensionPointManager { #endif } } - - func feedProviderMatching(_ offered: URLComponents, ability: FeedProviderAbility) -> FeedProvider? { - for extensionPoint in activeExtensionPoints.values { - if let feedProvider = extensionPoint as? FeedProvider, feedProvider.ability(offered) == ability { - return feedProvider - } - } - return nil - } - } diff --git a/Shared/Images/WebFeedIconDownloader.swift b/Shared/Images/WebFeedIconDownloader.swift index 30027baef..7790b6292 100644 --- a/Shared/Images/WebFeedIconDownloader.swift +++ b/Shared/Images/WebFeedIconDownloader.swift @@ -118,31 +118,7 @@ public final class WebFeedIconDownloader { return nil } - if let components = URLComponents(string: feed.url), let feedProvider = FeedProviderManager.shared.best(for: components) { - guard !urlsInProgress.contains(feed.url) else { - return nil - } - urlsInProgress.insert(feed.url) - - feedProvider.iconURL(components) { result in - self.urlsInProgress.remove(feed.url) - switch result { - case .success(let feedProviderURL): - self.feedURLToIconURLCache[feed.url] = feedProviderURL - self.feedURLToIconURLCacheDirty = true - self.icon(forURL: feedProviderURL, feed: feed) { (image) in - if let image = image { - self.postFeedIconDidBecomeAvailableNotification(feed) - self.cache[feed] = IconImage(image) - } - } - case .failure: - checkFeedIconURL() - } - } - } else { - checkFeedIconURL() - } + checkFeedIconURL() return nil }