ChWebsiteApp/CHDataManagement/Model/WebsiteGenerator.swift
2024-12-03 13:19:50 +01:00

103 lines
3.2 KiB
Swift

import Foundation
struct WebsiteGeneratorConfiguration {
let language: ContentLanguage
let postsPerPage: Int
let postFeedTitle: String
let postFeedDescription: String
let postFeedUrlPrefix: String
}
final class WebsiteGenerator {
let language: ContentLanguage
let content: Content
let postsPerPage: Int
let postFeedTitle: String
let postFeedDescription: String
let postFeedUrlPrefix: String
init(content: Content, configuration: WebsiteGeneratorConfiguration) {
self.content = content
self.language = configuration.language
self.postsPerPage = configuration.postsPerPage
self.postFeedTitle = configuration.postFeedTitle
self.postFeedDescription = configuration.postFeedDescription
self.postFeedUrlPrefix = configuration.postFeedUrlPrefix
}
func generateWebsite() {
createPostFeedPages()
}
private func createPostFeedPages() {
let totalCount = content.posts.count
guard totalCount > 0 else { return }
let navBarData = createNavigationBarData()
let numberOfPages = (totalCount + postsPerPage - 1) / postsPerPage // Round up
for pageIndex in 1...numberOfPages {
let startIndex = (pageIndex - 1) * postsPerPage
let endIndex = min(pageIndex * postsPerPage, totalCount)
let postsOnPage = content.posts[startIndex..<endIndex]
createPostFeedPage(pageIndex, pageCount: numberOfPages, posts: postsOnPage, bar: navBarData)
}
}
private func createNavigationBarData() -> NavigationBarData {
let data = content.websiteData.localized(in: language)
let navigationItems: [NavigationBarLink] = content.websiteData.navigationTags.map {
let localized = $0.localized(in: language)
return .init(text: localized.name, url: localized.urlComponent)
}
return NavigationBarData(
navigationIconPath: "/assets/icons/ch.svg",
iconDescription: data.iconDescription,
navigationItems: navigationItems)
}
private func createPostFeedPage(_ pageIndex: Int, pageCount: Int, posts: ArraySlice<Post>, bar: NavigationBarData) {
let posts = posts.map { $0.feedEntry(for: language) }
let feed = PageInFeed(
language: language,
title: postFeedTitle,
description: postFeedDescription,
navigationBarData: bar,
pageNumber: pageIndex,
totalPages: pageCount,
posts: posts)
let fileContent = feed.content
if pageIndex == 1 {
save(fileContent, to: "\(postFeedUrlPrefix).html")
} else {
save(fileContent, to: "\(postFeedUrlPrefix)-\(pageIndex).html")
}
}
private func save(_ content: String, to relativePath: String) {
Content.accessFolderFromBookmark(key: Storage.outputPathBookmarkKey) { folder in
let outputFile = folder.appendingPathComponent(relativePath, isDirectory: false)
do {
try content
.data(using: .utf8)!
.write(to: outputFile)
} catch {
print("Failed to save: \(error)")
}
}
}
}