Generate pages, image descriptions

This commit is contained in:
Christoph Hagen
2024-12-06 21:59:36 +01:00
parent 18eb64f289
commit 5fb689ac7c
42 changed files with 1653 additions and 273 deletions

View File

@ -154,7 +154,7 @@ final class Storage {
let contentUrl = pageContentUrl(pageId: pageId, language: language)
guard fm.fileExists(atPath: contentUrl.path()) else {
print("No file at \(contentUrl.path())")
return "New file"
return ""
}
do {
return try String(contentsOf: contentUrl, encoding: .utf8)
@ -235,6 +235,34 @@ final class Storage {
// MARK: Files
private var imageDescriptionFilename: String {
"image-descriptions.json"
}
private var imageDescriptionUrl: URL {
baseFolder.appending(path: "image-descriptions.json")
}
func loadImageDescriptions() -> [ImageDescriptions] {
do {
return try read(relativePath: imageDescriptionFilename)
} catch {
print("Failed to read image descriptions: \(error)")
return []
}
}
@discardableResult
func save(imageDescriptions: [ImageDescriptions]) -> Bool {
do {
try writeIfChanged(imageDescriptions, to: imageDescriptionFilename)
return true
} catch {
print("Failed to write image descriptions: \(error)")
return false
}
}
/// The folder path where other files are stored (by their unique name)
var filesFolder: URL { subFolder("files") }
@ -251,6 +279,26 @@ final class Storage {
return copy(file: url, to: contentUrl, type: "file", id: fileId)
}
func copy(file fileId: String, to relativeOutputPath: String) -> Bool {
do {
try operate(in: .contentPath) { contentPath in
try operate(in: .outputPath) { outputPath in
let output = outputPath.appending(path: relativeOutputPath, directoryHint: .notDirectory)
if output.exists {
return
}
let input = contentPath.appending(path: "files/\(fileId)", directoryHint: .notDirectory)
try output.ensureParentFolderExistence()
try FileManager.default.copyItem(at: input, to: output)
}
}
return true
} catch {
print("Failed to copy file \(fileId) to output folder: \(error)")
return false
}
}
func loadAllFiles() throws -> [String : URL] {
try files(in: filesFolder).reduce(into: [:]) { files, url in
files[url.lastPathComponent] = url
@ -365,6 +413,30 @@ final class Storage {
}
}
private func writeIfChanged<T>(_ value: T, to relativePath: String) throws where T: Encodable {
try operate(in: .contentPath) { contentPath in
let url = contentPath.appending(path: relativePath, directoryHint: .notDirectory)
let data = try encoder.encode(value)
if fm.fileExists(atPath: url.path()) {
// Check if content is the same, to prevent unnecessary writes
do {
let oldData = try Data(contentsOf: url)
if data == oldData {
// File is the same, don't write
return
}
} catch {
print("Failed to read file \(url.path()) for equality check: \(error)")
// No check possible, write file
}
} else {
print("Writing new file \(url.path())")
}
try data.write(to: url)
print("Saved file \(url.path())")
}
}
/**
Encode a value and write it to a file, if the content changed
*/
@ -426,6 +498,14 @@ final class Storage {
return write(data: data, type: type, id: id, to: file)
}
private func read<T>(relativePath: String) throws -> T where T: Decodable {
try operate(in: .contentPath) { baseFolder in
let url = baseFolder.appending(path: relativePath, directoryHint: .notDirectory)
let data = try Data(contentsOf: url)
return try decoder.decode(T.self, from: data)
}
}
private func read<T>(at url: URL) throws -> T where T: Decodable {
let data = try Data(contentsOf: url)
return try decoder.decode(T.self, from: data)