2024-12-25 18:06:05 +01:00

83 lines
2.5 KiB
Swift

import Foundation
final class PageIssueChecker: ObservableObject {
@Published
var isCheckingPages: Bool = false
@Published
var issues: Set<PageIssue> = []
init() {
}
func check(pages: [Page], clearListBeforeStart: Bool = true) {
guard !isCheckingPages else {
return
}
isCheckingPages = true
if clearListBeforeStart {
issues = []
}
DispatchQueue.global(qos: .userInitiated).async {
for language in ContentLanguage.allCases {
self.check(pages: pages, in: language)
}
DispatchQueue.main.async {
self.isCheckingPages = false
}
}
}
private func check(pages: [Page], in language: ContentLanguage) {
for page in pages {
analyze(page: page, in: language)
}
}
func check(page: Page, in language: ContentLanguage) {
guard !isCheckingPages else {
return
}
isCheckingPages = true
DispatchQueue.global(qos: .userInitiated).async {
self.analyze(page: page, in: language)
DispatchQueue.main.async {
self.isCheckingPages = false
}
}
}
private func analyze(page: Page, in language: ContentLanguage) {
let results = page.content.results.makeResults(for: page, in: language)
let parser = PageContentParser(content: page.content, language: language, results: results)
let hasPreviousIssues = issues.contains { $0.page == page && $0.language == language }
let pageIssues: [PageIssue]
if let rawPageContent = page.content.storage.pageContent(for: page.id, language: language) {
_ = parser.generatePage(from: rawPageContent)
pageIssues = []
} else {
let message = GenerationAnomaly.failedToLoadContent
let error = PageIssue(page: page, language: language, message: message)
pageIssues = [error]
}
guard hasPreviousIssues || !pageIssues.isEmpty else {
return
}
update(issues: pageIssues, for: page, in: language)
}
private func update(issues: [PageIssue], for page: Page, in language: ContentLanguage) {
let newIssues = self.issues
.filter { $0.page != page || $0.language != language }
.union(issues)
DispatchQueue.main.async {
self.issues = newIssues
}
}
}