ChWebsiteApp/CHDataManagement/Model/Content+Load.swift
2024-12-16 21:01:38 +01:00

176 lines
6.6 KiB
Swift

import Foundation
extension Content {
private func convert(_ tag: LocalizedTagFile, images: [String : FileResource]) -> LocalizedTag {
LocalizedTag(
content: self,
urlComponent: tag.urlComponent,
name: tag.name,
subtitle: tag.subtitle,
description: tag.description,
thumbnail: tag.thumbnail.map { images[$0] },
originalUrl: tag.originalURL)
}
private func convert(_ post: LocalizedPostFile, images: [String : FileResource]) -> LocalizedPost {
LocalizedPost(
content: self,
title: post.title,
text: post.content,
lastModified: post.lastModifiedDate,
images: post.images.compactMap { images[$0] },
linkPreviewImage: post.linkPreviewImage.map { images[$0] },
linkPreviewTitle: post.linkPreviewTitle,
linkPreviewDescription: post.linkPreviewDescription)
}
private func convert(_ page: LocalizedPageFile, images: [String : FileResource]) -> LocalizedPage {
LocalizedPage(
content: self,
urlString: page.url,
title: page.title,
lastModified: page.lastModifiedDate,
originalUrl: page.originalURL,
files: Set(page.files),
externalFiles: Set(page.externalFiles),
requiredFiles: Set(page.requiredFiles),
linkPreviewImage: page.linkPreviewImage.map { images[$0] },
linkPreviewTitle: page.linkPreviewTitle,
linkPreviewDescription: page.linkPreviewDescription)
}
func loadFromDisk() throws {
guard storageIsInitialized else {
print("Storage not initialized, not loading content")
return
}
let settings = try storage.loadSettings()
let imageDescriptions = try storage.loadFileDescriptions().reduce(into: [:]) { descriptions, description in
descriptions[description.fileId] = description
}
let tagData = try storage.loadAllTags()
let pagesData = try storage.loadAllPages()
let postsData = try storage.loadAllPosts()
let fileList = try storage.loadAllFiles()
let externalFiles = try storage.loadExternalFileList()
let tagOverviewData = try storage.loadTagOverview()
var files: [String : FileResource] = fileList.reduce(into: [:]) { files, fileId in
let descriptions = imageDescriptions[fileId]
files[fileId] = FileResource(
content: self,
id: fileId,
isExternallyStored: false,
en: descriptions?.english ?? "",
de: descriptions?.german ?? "")
}
for fileId in externalFiles {
let descriptions = imageDescriptions[fileId]
files[fileId] = FileResource(
content: self,
id: fileId,
isExternallyStored: true,
en: descriptions?.english ?? "",
de: descriptions?.german ?? "")
}
let images = files.filter { $0.value.type.isImage }
let tags = tagData.reduce(into: [:]) { (tags, data) in
tags[data.key] = Tag(
content: self,
id: data.value.id,
isVisible: data.value.isVisible,
german: convert(data.value.german, images: images),
english: convert(data.value.english, images: images))
}
let pages: [String : Page] = loadPages(pagesData, tags: tags, images: images)
let posts = postsData.map { postId, post in
let linkedPage = post.linkedPageId.map { pages[$0] }
let german = convert(post.german, images: images)
let english = convert(post.english, images: images)
return Post(
content: self,
id: postId,
isDraft: post.isDraft,
createdDate: post.createdDate,
startDate: post.startDate,
endDate: post.endDate,
tags: post.tags.map { tags[$0]! },
german: german,
english: english,
linkedPage: linkedPage)
}
let tagOverview = tagOverviewData.map { file in
TagOverviewPage(
content: self,
german: .init(content: self, file: file.german, image: file.german.linkPreviewImage.map { files[$0] }),
english: .init(content: self, file: file.english, image: file.english.linkPreviewImage.map { files[$0] }))
}
self.tags = tags.values.sorted()
self.pages = pages.values.sorted(ascending: false) { $0.startDate }
self.files = files.values.sorted { $0.id }
self.posts = posts.sorted(ascending: false) { $0.startDate }
self.tagOverview = tagOverview
self.settings = makeSettings(settings, tags: tags, pages: pages, files: files)
}
private func makeSettings(_ settings: SettingsFile, tags: [String : Tag], pages: [String : Page], files: [String : FileResource]) -> Settings {
#warning("Notify about missing links")
let navigationItems: [Item] = settings.navigationItems.compactMap {
switch $0.type {
case .tag:
return tags[$0.id]
case .page:
return pages[$0.id]
case .tagOverview:
return tagOverview
default:
return nil
}
}
let posts = PostSettings(file: settings.posts, files: files)
let pages = PageSettings(file: settings.pages, files: files)
let paths = PathSettings(file: settings.paths)
return Settings(
paths: paths,
navigationItems: navigationItems,
posts: posts,
pages: pages,
german: .init(file: settings.german),
english: .init(file: settings.english))
}
private func loadPages(_ pagesData: [String : PageFile], tags: [String : Tag], images: [String : FileResource]) -> [String : Page] {
pagesData.reduce(into: [:]) { pages, data in
let (pageId, page) = data
pages[pageId] = Page(
content: self,
id: pageId,
externalLink: page.externalLink,
isDraft: page.isDraft,
createdDate: page.createdDate,
startDate: page.startDate,
endDate: page.endDate,
german: convert(page.german, images: images),
english: convert(page.english, images: images),
tags: page.tags.map { tags[$0]! })
}
}
}