diff --git a/Modules/Images/Package.swift b/Modules/Images/Package.swift index 17dd61c24..2064d9d89 100644 --- a/Modules/Images/Package.swift +++ b/Modules/Images/Package.swift @@ -13,7 +13,8 @@ let package = Package( dependencies: [ .package(path: "../Core"), .package(path: "../Articles"), - .package(path: "../Account") + .package(path: "../Account"), + .package(path: "../Web") ], targets: [ .target( @@ -21,7 +22,8 @@ let package = Package( dependencies: [ "Core", "Articles", - "Account" + "Account", + "Web" ] // Disabled due to Sendable warnings about RSImage (NSImage). // TODO: check if Swift 6 will allow us to deal with these warnings. diff --git a/Modules/Images/Sources/Images/HTMLMetadataDownloader.swift b/Modules/Images/Sources/Images/HTMLMetadataDownloader.swift index d5ac35405..d86620594 100644 --- a/Modules/Images/Sources/Images/HTMLMetadataDownloader.swift +++ b/Modules/Images/Sources/Images/HTMLMetadataDownloader.swift @@ -11,21 +11,29 @@ import os import Web import Parser -struct HTMLMetadataDownloader { +public struct HTMLMetadataDownloader { nonisolated(unsafe) private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "HTMLMetadataDownloader") private static let debugLoggingEnabled = true - - static func downloadMetadata(for url: String) async -> HTMLMetadata? { + private static let cache = HTMLMetadataCache() + + public static func downloadMetadata(for url: String) async -> HTMLMetadata? { if debugLoggingEnabled { logger.debug("HTMLMetadataDownloader download for \(url)") } + if let htmlMetadata = cache[url] { + if debugLoggingEnabled { + logger.debug("HTMLMetadataDownloader returning cached metadata for \(url)") + } + return htmlMetadata + } + guard let actualURL = URL(string: url) else { return nil } - + let downloadRecord = try? await DownloadWithCacheManager.shared.download(actualURL) let data = downloadRecord?.data let response = downloadRecord?.response @@ -34,11 +42,19 @@ struct HTMLMetadataDownloader { let urlToUse = response.url ?? actualURL let parserData = ParserData(url: urlToUse.absoluteString, data: data) - if debugLoggingEnabled { - logger.debug("HTMLMetadataDownloader parsing metadata for \(url)") + if let htmlMetadata = await parseMetadata(with: parserData) { + if debugLoggingEnabled { + logger.debug("HTMLMetadataDownloader caching parsed metadata for \(url)") + } + cache[url] = htmlMetadata + return htmlMetadata } - return await parseMetadata(with: parserData) + if debugLoggingEnabled { + logger.debug("HTMLMetadataDownloader parser returned nil for \(url)") + } + + return nil } if debugLoggingEnabled { diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 1c682d0fe..dee7869aa 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -243,7 +243,6 @@ 51C45297226509E300C03939 /* DefaultFeedsImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97591ED9EB0D007D329B /* DefaultFeedsImporter.swift */; }; 51C4529922650A0000C03939 /* ArticleThemesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97881ED9ECEF007D329B /* ArticleThemesManager.swift */; }; 51C4529A22650A0400C03939 /* ArticleTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97871ED9ECEF007D329B /* ArticleTheme.swift */; }; - 51C452A322650A1E00C03939 /* HTMLMetadataDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8426119D1FCB6ED40086A189 /* HTMLMetadataDownloader.swift */; }; 51C452A422650A2D00C03939 /* ArticleUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97581ED9EB0D007D329B /* ArticleUtilities.swift */; }; 51C452A522650A2D00C03939 /* SmallIconProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84411E701FE5FBFA004B527F /* SmallIconProvider.swift */; }; 51C452A622650A3500C03939 /* Node-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97971ED9EFAA007D329B /* Node-Extensions.swift */; }; @@ -324,7 +323,6 @@ 841CECDC2BAD04BF0001EE72 /* Tree in Frameworks */ = {isa = PBXBuildFile; productRef = 841CECDB2BAD04BF0001EE72 /* Tree */; }; 841CECDE2BAD06D10001EE72 /* Tree in Frameworks */ = {isa = PBXBuildFile; productRef = 841CECDD2BAD06D10001EE72 /* Tree */; }; 84216D0322128B9D0049B9B9 /* DetailWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84216D0222128B9D0049B9B9 /* DetailWebViewController.swift */; }; - 8426119E1FCB6ED40086A189 /* HTMLMetadataDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8426119D1FCB6ED40086A189 /* HTMLMetadataDownloader.swift */; }; 8426DBB82BFDAD8500E98109 /* Core in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 84DCA5242BABBB5A00792720 /* Core */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 8426DBB92BFDAD9200E98109 /* Core in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 84DCA5282BABBB6A00792720 /* Core */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 8426DBBB2BFDADD700E98109 /* Core in Frameworks */ = {isa = PBXBuildFile; productRef = 8426DBBA2BFDADD700E98109 /* Core */; }; @@ -953,7 +951,6 @@ 841ABA5D20145E9200980E11 /* FolderInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderInspectorViewController.swift; sourceTree = ""; }; 841ABA5F20145EC100980E11 /* BuiltinSmartFeedInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuiltinSmartFeedInspectorViewController.swift; sourceTree = ""; }; 84216D0222128B9D0049B9B9 /* DetailWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailWebViewController.swift; sourceTree = ""; }; - 8426119D1FCB6ED40086A189 /* HTMLMetadataDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLMetadataDownloader.swift; sourceTree = ""; }; 842E45CD1ED8C308000A8B52 /* AppNotifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppNotifications.swift; sourceTree = ""; }; 842E45DC1ED8C54B000A8B52 /* Browser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Browser.swift; sourceTree = ""; }; 84308B512CB1A42D004AF552 /* NetNewsWire_macapp_target _debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "NetNewsWire_macapp_target _debug.xcconfig"; sourceTree = ""; }; @@ -1698,14 +1695,6 @@ path = "NetNewsWire-iOSTests"; sourceTree = ""; }; - 8426119C1FCB6ED40086A189 /* HTMLMetadata */ = { - isa = PBXGroup; - children = ( - 8426119D1FCB6ED40086A189 /* HTMLMetadataDownloader.swift */, - ); - path = HTMLMetadata; - sourceTree = ""; - }; 842E45E11ED8C681000A8B52 /* MainWindow */ = { isa = PBXGroup; children = ( @@ -2051,7 +2040,6 @@ 51FE0FF9234552490056195D /* UserNotifications */, 84F2D5341FC22FCB00998D64 /* SmartFeeds */, 51B5C85A23F22A7A00032075 /* ShareExtension */, - 8426119C1FCB6ED40086A189 /* HTMLMetadata */, 5183CCEA226F70350010922C /* Timer */, 512E08DD22687FA000BDCFDD /* Tree */, 849A97561ED9EB0D007D329B /* Extensions */, @@ -3211,7 +3199,6 @@ 5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */, 519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */, FFD43E412340F488009E5CA3 /* MarkAsReadAlertController.swift in Sources */, - 51C452A322650A1E00C03939 /* HTMLMetadataDownloader.swift in Sources */, 51C4528D2265095F00C03939 /* AddFolderViewController.swift in Sources */, 51C452782265091600C03939 /* TimelineCellData.swift in Sources */, 5148F4552336DB7000F8CD8B /* TimelineTitleView.swift in Sources */, @@ -3342,7 +3329,6 @@ 510C417F24E5D1AE008226FD /* ExtensionContainersFile.swift in Sources */, 84C9FC7A22629E1200D921D6 /* PreferencesTableViewBackgroundView.swift in Sources */, 84CAFCAF22BC8C35007694F0 /* FetchRequestOperation.swift in Sources */, - 8426119E1FCB6ED40086A189 /* HTMLMetadataDownloader.swift in Sources */, 849A976E1ED9EBC8007D329B /* TimelineViewController.swift in Sources */, 5183CCE6226F4E110010922C /* RefreshInterval.swift in Sources */, 849A97771ED9EC04007D329B /* TimelineCellData.swift in Sources */,