Generate first feed pages, images

This commit is contained in:
Christoph Hagen
2024-12-04 08:10:45 +01:00
parent dc7b7a0e90
commit b3cc4a57db
25 changed files with 928 additions and 272 deletions

View File

@ -1,5 +1,12 @@
import Foundation
enum SecurityScopeBookmark: String {
case outputPath = "outputPathBookmark"
case contentPath = "contentPathBookmark"
}
/**
A class that handles the storage of the website data.
@ -13,9 +20,6 @@ import Foundation
*/
final class Storage {
static let outputPathBookmarkKey = "outputPathBookmark"
static let contentPathBookmarkKey = "contentPathBookmark"
private(set) var baseFolder: URL
private let encoder = JSONEncoder()
@ -60,14 +64,9 @@ final class Storage {
// MARK: Folders
func update(baseFolder: URL, moveContent: Bool) throws {
let oldFolder = self.baseFolder
func update(baseFolder: URL) throws {
self.baseFolder = baseFolder
try createFolderStructure()
guard moveContent else {
return
}
// TODO: Move all files
}
private func create(folder: URL) throws {
@ -213,7 +212,7 @@ final class Storage {
// MARK: Files
/// The folder path where other files are stored (by their unique name)
private var filesFolder: URL { subFolder("files") }
var filesFolder: URL { subFolder("files") }
private func fileUrl(file: String) -> URL {
filesFolder.appending(path: file, directoryHint: .notDirectory)
@ -250,6 +249,70 @@ final class Storage {
write(websiteData, type: "Website Data", id: "-", to: websiteDataUrl)
}
// MARK: Image generation data
private var generatedImagesListUrl: URL {
baseFolder.appending(component: "generated-images.json", directoryHint: .notDirectory)
}
func loadListOfGeneratedImages() -> [String : [String]] {
let url = generatedImagesListUrl
guard url.exists else {
return [:]
}
do {
return try read(at: url)
} catch {
print("Failed to read list of generated images: \(error)")
return [:]
}
}
func save(listOfGeneratedImages: [String : [String]]) -> Bool {
write(listOfGeneratedImages, type: "generated images list", id: "-", to: generatedImagesListUrl)
}
// MARK: Folder access
func save(folderUrl url: URL, in bookmark: SecurityScopeBookmark) {
do {
let bookmarkData = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
UserDefaults.standard.set(bookmarkData, forKey: bookmark.rawValue)
} catch {
print("Failed to create security-scoped bookmark: \(error)")
}
}
func write(in scope: SecurityScopeBookmark, operation: (URL) -> Bool) -> Bool {
guard let bookmarkData = UserDefaults.standard.data(forKey: scope.rawValue) else {
print("No bookmark data to access folder")
return false
}
var isStale = false
let folderURL: URL
do {
// Resolve the bookmark to get the folder URL
folderURL = try URL(resolvingBookmarkData: bookmarkData, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
} catch {
print("Failed to resolve bookmark: \(error)")
return false
}
if isStale {
print("Bookmark is stale, consider saving a new bookmark.")
}
// Start accessing the security-scoped resource
if folderURL.startAccessingSecurityScopedResource() {
let result = operation(folderURL)
folderURL.stopAccessingSecurityScopedResource()
return result
} else {
print("Failed to access folder: \(folderURL.path)")
return false
}
}
// MARK: Writing files
private func deleteFiles(in folder: URL, notIn fileSet: Set<String>) throws {