Content scanner also checks for thumbnails (#5911)

* scan also thumbnails for medias

* pr suggestion
This commit is contained in:
Mauro
2026-07-22 16:43:08 +02:00
committed by GitHub
parent cff46137b9
commit 6967f99626
12 changed files with 155 additions and 17 deletions
@@ -25,3 +25,47 @@ nonisolated protocol ContentScannerServiceProtocol: Sendable {
@discardableResult
func loadScanResultFromSource(_ source: MediaSourceProxy) async -> Result<Bool, ContentScannerServiceError>
}
nonisolated extension ContentScannerServiceProtocol {
/// The combined cached verdict for several sources (e.g. a media source and its thumbnail, both
/// downloaded through the scanner): `false` if any is unsafe, `true` if all are safe, or `nil`
/// when any of them hasn't been scanned yet.
func scanResultFromSources(_ sources: [MediaSourceProxy]) -> Bool? {
let results = sources.map { scanResultFromSource($0) }
if results.contains(false) {
return false
}
if results.contains(where: { $0 == nil }) {
return nil
}
return true
}
/// Scans several sources concurrently, resolving as soon as one comes back non-safe (unsafe or
/// failed) since a single failure is enough to flag the media - the remaining scans are then
/// ignored. Resolves as safe only when every source is safe.
@discardableResult
func loadScanResultFromSources(_ sources: [MediaSourceProxy]) async -> Result<Bool, ContentScannerServiceError> {
await withTaskGroup(of: Result<Bool, ContentScannerServiceError>.self) { group in
for source in sources {
group.addTask { await loadScanResultFromSource(source) }
}
for await result in group where !result.isSafe {
group.cancelAll()
return result
}
return .success(true)
}
}
}
private nonisolated extension Result where Success == Bool {
var isSafe: Bool {
if case .success(true) = self {
return true
}
return false
}
}