Create and use HTMLMetadataDownloader.cachedMetadata function.

This commit is contained in:
Brent Simmons
2024-10-15 20:39:24 -07:00
parent 8b230e48c0
commit cc6445bc73
3 changed files with 36 additions and 47 deletions

View File

@@ -27,9 +27,10 @@ import UniformTypeIdentifiers
guard let _ = URL(string: homePageURL) else {
return nil
}
print("findFaviconURLs \(homePageURL)")
// If the favicon has an explicit type, check that for an ignored type; otherwise, check the file extension.
let htmlMetadata = await HTMLMetadataDownloader.downloadMetadata(for: homePageURL)
let htmlMetadata = HTMLMetadataDownloader.cachedMetadata(for: homePageURL)
let faviconURLs = htmlMetadata?.favicons?.compactMap { favicon -> String? in
shouldAllowFavicon(favicon) ? favicon.urlString : nil

View File

@@ -56,7 +56,6 @@ public extension Notification.Name {
return Set(["https://www.macsparky.com/", "https://xkcd.com/"])
}()
private var urlsInProgress = Set<String>()
private var cache = [Feed: IconImage]()
private var waitingForFeedURLs = [String: Feed]()
@@ -164,15 +163,24 @@ private extension FeedIconDownloader {
func icon(forHomePageURL homePageURL: String, feed: Feed) async -> RSImage? {
if homePagesWithNoIconURLCache.contains(homePageURL) || homePagesWithUglyIcons.contains(homePageURL) {
return nil
}
if let iconURL = cachedIconURL(for: homePageURL) {
return await icon(forURL: iconURL, feed: feed)
}
findIconURLForHomePageURL(homePageURL, feed: feed)
if homePagesWithNoIconURLCache.contains(homePageURL) || homePagesWithUglyIcons.contains(homePageURL) {
return nil
}
guard let metadata = HTMLMetadataDownloader.cachedMetadata(for: homePageURL) else {
return nil
}
if let url = metadata.bestWebsiteIconURL() {
cacheIconURL(for: homePageURL, url)
return await icon(forURL: url, feed: feed)
}
homePagesWithNoIconURLCache.insert(homePageURL)
return nil
}
@@ -207,39 +215,6 @@ private extension FeedIconDownloader {
homePageToIconURLCacheDirty = true
}
func findIconURLForHomePageURL(_ homePageURL: String, feed: Feed) {
guard !urlsInProgress.contains(homePageURL) else {
return
}
urlsInProgress.insert(homePageURL)
Task { @MainActor in
let metadata = await HTMLMetadataDownloader.downloadMetadata(for: homePageURL)
self.urlsInProgress.remove(homePageURL)
guard let metadata else {
return
}
self.pullIconURL(from: metadata, homePageURL: homePageURL, feed: feed)
}
}
func pullIconURL(from metadata: HTMLMetadata, homePageURL: String, feed: Feed) {
if let url = metadata.bestWebsiteIconURL() {
cacheIconURL(for: homePageURL, url)
Task { @MainActor in
await icon(forURL: url, feed: feed)
}
return
}
homePagesWithNoIconURLCache.insert(homePageURL)
homePagesWithNoIconURLCacheDirty = true
}
func loadFeedURLToIconURLCache() {
guard let data = try? Data(contentsOf: feedURLToIconURLCachePath) else {
return

View File

@@ -16,17 +16,26 @@ public struct HTMLMetadataDownloader {
nonisolated(unsafe) private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "HTMLMetadataDownloader")
private static let debugLoggingEnabled = false
private static let cache = HTMLMetadataCache()
public static func downloadMetadata(for url: String) async -> HTMLMetadata? {
public static func cachedMetadata(for url: String) -> HTMLMetadata? {
if debugLoggingEnabled {
logger.debug("HTMLMetadataDownloader requested download for \(url)")
logger.debug("HTMLMetadataDownloader requested cached metadata for \(url)")
}
if let htmlMetadata = cache[url] {
if debugLoggingEnabled {
logger.debug("HTMLMetadataDownloader returning cached metadata for \(url)")
}
guard let htmlMetadata = cache[url] else {
return nil
}
if debugLoggingEnabled {
logger.debug("HTMLMetadataDownloader returning cached metadata for \(url)")
}
return htmlMetadata
}
public static func downloadMetadata(for url: String) async -> HTMLMetadata? {
if let htmlMetadata = cachedMetadata(for: url) {
return htmlMetadata
}
@@ -34,6 +43,10 @@ public struct HTMLMetadataDownloader {
return nil
}
if debugLoggingEnabled {
logger.debug("HTMLMetadataDownloader downloading for \(url)")
}
let downloadRecord = try? await DownloadWithCacheManager.shared.download(actualURL)
let data = downloadRecord?.data
let response = downloadRecord?.response