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)! } }