From d464fa0c38c4085937cb13164195c33e12af9c10 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 24 Nov 2017 10:45:22 -0800 Subject: [PATCH] Make progress on favicons. --- Evergreen/Favicons/FaviconDownloader.swift | 50 +++++++++++++++++++--- Evergreen/Favicons/FaviconMetadata.swift | 29 ++++++++++++- Evergreen/Favicons/ImageDownloader.swift | 2 +- 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/Evergreen/Favicons/FaviconDownloader.swift b/Evergreen/Favicons/FaviconDownloader.swift index d18e17201..032946c63 100644 --- a/Evergreen/Favicons/FaviconDownloader.swift +++ b/Evergreen/Favicons/FaviconDownloader.swift @@ -13,12 +13,13 @@ import RSWeb extension Notification.Name { - static let FaviconDidBecomeAvailable = Notification.Name("FaviconDidBecomeAvailableNotification") // userInfo keys: homePageURL, faviconURL, image + static let FaviconDidBecomeAvailable = Notification.Name("FaviconDidBecomeAvailableNotification") // userInfo keys, one or more of which will be present: homePageURL, faviconURL } final class FaviconDownloader { - private var seekingFaviconCache: [String: SeekingFavicon]() // homePageURL: SeekingFavicon + private var imageCache = [String: NSImage]() + private var seekingFaviconCache = [String: SeekingFavicon]() // homePageURL: SeekingFavicon private var cache = ThreadSafeCache() // faviconURL: NSImage private var faviconURLCache = ThreadSafeCache() // homePageURL: faviconURL private let folder: String @@ -46,20 +47,57 @@ final class FaviconDownloader { func favicon(for feed: Feed) -> NSImage? { assert(Thread.isMainThread) + + if let faviconURL = feed.faviconURL { + // JSON Feeds may include the faviconURL in the feed, + // so we don’t have to hunt for it. + return favicon(withURL: faviconURL) + } + guard let homePageURL = feed.homePageURL else { return nil } + return favicon(withHomePageURL: homePageURL) + } - if let favicon = cachedInMemoryFavicon(for: feed) { - return favicon + func favicon(withURL faviconURL: String) -> NSImage? { + + if let cachedImage = imageCache[faviconURL] { + return cachedImage + } + + let controller = faviconController(withURL: faviconURL) + return favicon(withController: controller) + } + + func faviconController(withURL faviconURL: String) -> FaviconController { + + if let controller = faviconControllerCache[faviconURL] { + return controller + } + let controller = FaviconController(faviconURL: faviconURL) + faviconControllerCache[faviconURL] = controller + return controller + } + + func favicon(withController controller: FaviconController) -> NSImage? { + + if let image = controller.image { + return image + } + + controller.readFromDisk(binaryCache) { (image) in + + if let image = image { + post + } } - findFavicon(for: feed) } func findFavicon(for feed: Feed) { - if let faviconMetadata = cachedFaviconMetadata +// if let faviconMetadata = cachedFaviconMetadata if let faviconURL = faviconURL(for: feed) { // It might be on disk. diff --git a/Evergreen/Favicons/FaviconMetadata.swift b/Evergreen/Favicons/FaviconMetadata.swift index 8e25a1215..953071c25 100644 --- a/Evergreen/Favicons/FaviconMetadata.swift +++ b/Evergreen/Favicons/FaviconMetadata.swift @@ -7,8 +7,9 @@ // import AppKit +import RSCore -final class FaviconMetadata { +final class FaviconController { enum DiskStatus { case unknown, notOnDisk, onDisk @@ -17,10 +18,34 @@ final class FaviconMetadata { let faviconURL: String var lastDownloadAttemptDate: Date? var diskStatus = DiskStatus.unknown + let diskCache: RSBinaryCache var image: NSImage? - init?(faviconURL: String) { + init?(faviconURL: String, _ diskCache: RSBinaryCache) { self.faviconURL = faviconURL + self.diskCache = diskCache + findFavicon() } } + +private extension FaviconController { + + func findFavicon() { + + readFromDisk { (image) in + self.image = image + } + + } + + func readFromDisk(_ callback: (NSImage?) -> Void) { + + if diskStatus == .notOnDisk { + callback(nil) + return + } + + } + +} diff --git a/Evergreen/Favicons/ImageDownloader.swift b/Evergreen/Favicons/ImageDownloader.swift index 2cca8b84b..375fea74c 100644 --- a/Evergreen/Favicons/ImageDownloader.swift +++ b/Evergreen/Favicons/ImageDownloader.swift @@ -41,7 +41,7 @@ final class ImageDownloader { } } -private extension ImageDownload { +private extension ImageDownloader { func shouldDownloadImage(_ url: String) -> Bool {