ChWebsiteApp/CHDataManagement/Model/Content+Save.swift
2024-12-26 15:01:01 +01:00

170 lines
4.8 KiB
Swift

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.tagFile, 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 },
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)
}
}
private extension Tag {
var tagFile: TagFile {
.init(id: id,
isVisible: isVisible,
german: german.tagFile,
english: english.tagFile)
}
}
private extension LocalizedTag {
var tagFile: LocalizedTagFile {
.init(urlComponent: urlComponent,
name: name,
subtitle: subtitle,
description: description,
thumbnail: linkPreviewImage?.id,
originalURL: originalUrl)
}
}
extension Settings {
var file: SettingsFile {
.init(
paths: paths.file,
navigationItems: navigationItems.map { $0.itemType.id },
posts: posts.file,
pages: pages.file,
german: german.file,
english: english.file)
}
}
private extension PostSettings {
var file: PostSettingsFile {
.init(postsPerPage: postsPerPage,
contentWidth: contentWidth,
swiperCssFile: swiperCssFile?.id,
swiperJsFile: swiperJsFile?.id,
defaultCssFile: defaultCssFile?.id)
}
}
private extension LocalizedPostSettings {
var file: LocalizedPostSettingsFile {
.init(
feedTitle: title,
feedDescription: description,
feedUrlPrefix: feedUrlPrefix)
}
}