NetNewsWire/Shared/Favicons/FaviconURLFinder.swift
2024-04-10 20:49:55 -07:00

61 lines
1.6 KiB
Swift

//
// FaviconURLFinder.swift
// NetNewsWire
//
// Created by Brent Simmons on 11/20/17.
// Copyright © 2017 Ranchero Software. All rights reserved.
//
import Foundation
import CoreServices
import Parser
import UniformTypeIdentifiers
// The favicon URLs may be specified in the head section of the home page.
struct FaviconURLFinder {
/// Uniform types to ignore when finding favicon URLs.
static let ignoredTypes = [UTType.svg]
/// Finds favicon URLs in a web page.
/// - Parameters:
/// - homePageURL: The page to search.
/// - urls: An array of favicon URLs as strings.
@MainActor static func findFaviconURLs(with homePageURL: String) async -> [String]? {
guard let _ = URL(unicodeString: homePageURL) else {
return nil
}
// If the favicon has an explicit type, check that for an ignored type; otherwise, check the file extension.
let htmlMetadata = try? await HTMLMetadataDownloader.downloadMetadata(for: homePageURL)
let faviconURLs = htmlMetadata?.favicons.compactMap { favicon -> String? in
shouldAllowFavicon(favicon) ? favicon.urlString : nil
}
return faviconURLs
}
static func shouldAllowFavicon(_ favicon: RSHTMLMetadataFavicon) -> Bool {
// Check mime type.
if let mimeType = favicon.type, let utType = UTType(mimeType: mimeType) {
if ignoredTypes.contains(utType) {
return false
}
}
// Check file extension.
if let urlString = favicon.urlString, let url = URL(string: urlString), let utType = UTType(filenameExtension: url.pathExtension) {
if ignoredTypes.contains(utType) {
return false
}
}
return true
}
}