import Foundation extension Content { func saveToDisk() throws { guard storage.contentScope != nil else { print("Storage not initialized, not saving content") return } var failedSaves = 0 failedSaves += pages.count { !storage.save(pageMetadata: $0.pageFile, for: $0.id) } failedSaves += posts.count { !storage.save(post: $0.postFile, for: $0.id) } failedSaves += tags.count { !storage.save(tagMetadata: $0.file, for: $0.id) } failedSaves.increment(!storage.save(settings: settings.file)) let fileDescriptions: [FileDescriptions] = files.sorted().compactMap { file in guard !file.english.isEmpty || !file.german.isEmpty else { return nil } return FileDescriptions( fileId: file.id, german: file.german.nonEmpty, english: file.english.nonEmpty) } failedSaves.increment(!storage.save(fileDescriptions: fileDescriptions)) failedSaves.increment(!storage.save(tagOverview: tagOverview?.file)) let externalFileList = files.filter { $0.isExternallyStored }.map { $0.id } failedSaves.increment(!storage.save(externalFileList: externalFileList)) if failedSaves > 0 { print("Save partially failed with \(failedSaves) errors") } } func removeUnlinkedFiles() -> Bool { var success = true if !storage.deletePostFiles(notIn: posts.map { $0.id }) { success = false } if !storage.deletePageFiles(notIn: pages.map { $0.id }) { success = false } if !storage.deleteTagFiles(notIn: tags.map { $0.id }) { success = false } if !storage.deleteFileResources(notIn: files.map { $0.id }) { success = false } return success } } private extension Page { var pageFile: PageFile { .init(isDraft: isDraft, externalLink: externalLink, tags: tags.map { $0.id }, hideDate: hideDate ? true : nil, createdDate: createdDate, startDate: startDate, endDate: hasEndDate ? endDate : nil, german: german.pageFile, english: english.pageFile, requiredFiles: requiredFiles.nonEmpty?.map { $0.id }.sorted()) } } private extension LocalizedPage { var pageFile: LocalizedPageFile { .init(url: urlString, title: title, linkPreviewImage: linkPreviewImage?.id, linkPreviewTitle: linkPreviewTitle, linkPreviewDescription: linkPreviewDescription, lastModifiedDate: lastModified, originalURL: originalUrl, hideTitle: hideTitle ? true : nil) } } private extension Post { var postFile: PostFile { .init( isDraft: isDraft, createdDate: createdDate, startDate: startDate, endDate: hasEndDate ? endDate : nil, tags: tags.map { $0.id }, german: german.postFile, english: english.postFile, linkedPageId: linkedPage?.id) } } private extension LocalizedPost { var postFile: LocalizedPostFile { .init(images: images.map { $0.id }, title: title.nonEmpty, content: text, lastModifiedDate: lastModified, linkPreviewImage: linkPreviewImage?.id, linkPreviewTitle: linkPreviewTitle, linkPreviewDescription: linkPreviewDescription) } }