Christoph Hagen 0989f06d87 First version
2024-10-14 19:22:32 +02:00

135 lines
4.9 KiB
Swift

import Foundation
struct ImportedContent {
let posts: [Post]
let categories: [Tag]
}
final class Importer {
var posts: [Post] = []
var pages: [Page] = []
var tags: [Tag] = []
var images: [ImageResource] = []
var foldersToSearch: [(path: String, tag: String)] = [
("/Users/ch/Downloads/Website/projects/electronics", "electronics"),
("/Users/ch/Downloads/Website/projects/endeavor", "endeavor"),
("/Users/ch/Downloads/Website/projects/furniture", "furniture"),
("/Users/ch/Downloads/Website/projects/lighting", "lighting"),
("/Users/ch/Downloads/Website/projects/other", "other"),
("/Users/ch/Downloads/Website/projects/sewing", "sewing"),
("/Users/ch/Downloads/Website/projects/software", "software"),
("/Users/ch/Downloads/Website/articles", "articles"),
("/Users/ch/Downloads/Website/photography", "photography"),
("/Users/ch/Downloads/Website/travel", "travel")
]
func importOldContent() throws {
for (folder, tagName) in foldersToSearch {
let url = URL(filePath: folder)
let tag = try importTag(name: tagName, folder: url)
try importEntries(in: url, tag: tag)
tags.append(tag)
}
posts.sort { $0.startDate > $1.startDate }
//pages.sort { $0.startDate > $1.startDate }
tags.sort()
}
private func importTag(name: String, folder: URL) throws -> Tag {
let metadataUrl = folder.appending(path: "metadata.json", directoryHint: .notDirectory)
let data = try Data(contentsOf: metadataUrl)
let meta = try JSONDecoder().decode(ImportableTag.self, from: data)
return .init(
en: meta.info(for: .english)!.title,
de: meta.info(for: .german)!.title)
}
private func importEntries(in folder: URL, tag: Tag) throws {
try FileManager.default
.contentsOfDirectory(at: folder, includingPropertiesForKeys: [.isDirectoryKey])
.filter { $0.hasDirectoryPath }
.forEach { try importEntry(at: $0, tag: tag) }
}
private func importEntry(at url: URL, tag: Tag) throws {
let metadataUrl = url.appending(path: "metadata.json", directoryHint: .notDirectory)
guard FileManager.default.fileExists(atPath: metadataUrl.path()) else {
//print("No entry at \(url.path())")
return
}
let data = try Data(contentsOf: metadataUrl)
let meta = try JSONDecoder().decode(GenericMetadata.self, from: data)
let page = Page(
id: meta.customId ?? url.lastPathComponent,
isDraft: meta.state == "draft",
metadata: meta.languages!.map(convertPageContent),
externalFiles: meta.externalFiles ?? [],
requiredFiles: meta.requiredFiles ?? [],
images: meta.images ?? [])
pages.append(page)
let de = meta.languages!.first { $0.language == "de" }!
let en = meta.languages!.first { $0.language == "en" }!
let thumbnailImageName = meta.thumbnailPath ?? "thumbnail.jpg"
let thumbnailImageUrl = url.appending(path: thumbnailImageName, directoryHint: .notDirectory)
var images: [ImageResource] = []
if tag.id != "articles" {
if FileManager.default.fileExists(atPath: thumbnailImageUrl.path()) {
let thumbnail = ImageResource(
uniqueId: meta.customId ?? url.lastPathComponent,
altText: .init(en: "An image about \(en.title!)", de: "Ein Bild zu \(de.title!)"),
fileUrl: thumbnailImageUrl)
images.append(thumbnail)
self.images.append(thumbnail)
} else {
print("Thumbnail \(thumbnailImageUrl.path()) not found")
}
}
let lastPostId = posts.last?.id ?? 0
let post = Post(
id: lastPostId + 1,
isDraft: meta.state == "draft" || meta.state == "hidden",
startDate: meta.date!.toDate(),
endDate: meta.endDate?.toDate(),
title: .init(en: en.linkPreviewTitle ?? en.title!,
de: de.linkPreviewTitle ?? de.title!),
text: .init(en: en.linkPreviewDescription ?? en.description ?? "No description",
de: de.linkPreviewDescription ?? de.description ?? "Keine Beschreibung"),
tags: [tag],
images: images)
posts.append(post)
}
private func convertPageContent(_ meta: GenericMetadata.LocalizedMetadata) -> LocalizedPage {
.init(language: ContentLanguage(rawValue: meta.language!)!,
urlString: nil,
headline: meta.title!)
}
}
private extension String {
private static let metadataDate: DateFormatter = {
let df = DateFormatter()
df.dateFormat = "dd.MM.yy"
return df
}()
func toDate() -> Date {
String.metadataDate.date(from: self)!
}
}