Improve storage, paths
This commit is contained in:
@ -20,41 +20,12 @@ extension Content {
|
||||
return generateInternal(page, in: language)
|
||||
}
|
||||
|
||||
private func startGenerating() -> Bool {
|
||||
guard !isGeneratingWebsite else {
|
||||
return false
|
||||
}
|
||||
// TODO: Fix bug where multiple generating operations can be started
|
||||
// due to dispatch of locking property on main queue
|
||||
DispatchQueue.main.async {
|
||||
self.isGeneratingWebsite = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private func endGenerating() {
|
||||
DispatchQueue.main.async {
|
||||
self.isGeneratingWebsite = false
|
||||
}
|
||||
}
|
||||
|
||||
private func generateInternal(_ page: Page, in language: ContentLanguage) -> Bool {
|
||||
let generator = LocalizedWebsiteGenerator(
|
||||
content: self,
|
||||
language: language)
|
||||
if !generator.generate(page: page) {
|
||||
print("Generation failed")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
// MARK: Paths to items
|
||||
|
||||
private func makeCleanAbsolutePath(_ path: String) -> String {
|
||||
("/" + path).replacingOccurrences(of: "//", with: "/")
|
||||
}
|
||||
|
||||
// MARK: Paths to items
|
||||
|
||||
func absoluteUrlPrefixForTag(_ tag: Tag, language: ContentLanguage) -> String {
|
||||
makeCleanAbsolutePath(settings.paths.tagsOutputFolderPath + "/" + tag.localized(in: language).urlComponent)
|
||||
}
|
||||
@ -101,4 +72,86 @@ extension Content {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// MARK: Generation
|
||||
|
||||
private func startGenerating() -> Bool {
|
||||
guard !isGeneratingWebsite else {
|
||||
return false
|
||||
}
|
||||
// TODO: Fix bug where multiple generating operations can be started
|
||||
// due to dispatch of locking property on main queue
|
||||
DispatchQueue.main.async {
|
||||
self.isGeneratingWebsite = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private func endGenerating() {
|
||||
DispatchQueue.main.async {
|
||||
self.isGeneratingWebsite = false
|
||||
}
|
||||
}
|
||||
|
||||
private func generateInternal(_ page: Page, in language: ContentLanguage) -> Bool {
|
||||
let pagesFolder = settings.paths.pagesOutputFolderPath
|
||||
guard storage.create(folder: pagesFolder, in: .outputPath) else {
|
||||
print("Failed to generate output folder")
|
||||
return false
|
||||
}
|
||||
let imageGenerator = ImageGenerator(
|
||||
storage: storage,
|
||||
settings: settings)
|
||||
|
||||
let pageGenerator = PageGenerator(
|
||||
content: self,
|
||||
imageGenerator: imageGenerator)
|
||||
|
||||
let content: String
|
||||
let results: PageGenerationResults
|
||||
do {
|
||||
(content, results) = try pageGenerator.generate(page: page, language: language)
|
||||
} catch {
|
||||
print("Failed to generate page \(page.id) in language \(language): \(error)")
|
||||
return false
|
||||
}
|
||||
guard !content.trimmed.isEmpty else {
|
||||
#warning("Generate page with placeholder content")
|
||||
return true
|
||||
}
|
||||
|
||||
let path = page.absoluteUrl(in: language) + ".html"
|
||||
do {
|
||||
try storage.write(content: content, to: path)
|
||||
} catch {
|
||||
print("Failed to save page \(page.id): \(error)")
|
||||
return false
|
||||
}
|
||||
guard imageGenerator.runJobs(callback: { _ in }) else {
|
||||
return false
|
||||
}
|
||||
guard copy(requiredFiles: results.files) else {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return true
|
||||
}
|
||||
|
||||
private func copy(requiredFiles: Set<FileResource>) -> Bool {
|
||||
//print("Copying \(requiredVideoFiles.count) files...")
|
||||
for file in requiredFiles {
|
||||
guard !file.isExternallyStored else {
|
||||
continue
|
||||
}
|
||||
|
||||
do {
|
||||
try storage.copy(file: file.id, to: file.absoluteUrl)
|
||||
} catch {
|
||||
print("Failed to copy file \(file.id): \(error)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,7 +41,10 @@ extension Content {
|
||||
}
|
||||
|
||||
func loadFromDisk() throws {
|
||||
let storage = Storage(baseFolder: URL(filePath: contentPath))
|
||||
guard storageIsInitialized else {
|
||||
print("Storage not initialized, not loading content")
|
||||
return
|
||||
}
|
||||
|
||||
let settings = try storage.loadSettings()
|
||||
let imageDescriptions = try storage.loadFileDescriptions().reduce(into: [:]) { descriptions, description in
|
||||
|
@ -3,6 +3,10 @@ import Foundation
|
||||
extension Content {
|
||||
|
||||
func saveToDisk() throws {
|
||||
guard storageIsInitialized else {
|
||||
print("Storage not initialized, not saving content")
|
||||
return
|
||||
}
|
||||
//print("Starting save")
|
||||
for page in pages {
|
||||
try storage.save(pageMetadata: page.pageFile, for: page.id)
|
||||
|
@ -4,6 +4,11 @@ import Combine
|
||||
|
||||
final class Content: ObservableObject {
|
||||
|
||||
let storage = Storage()
|
||||
|
||||
@Published
|
||||
var storageIsInitialized = false
|
||||
|
||||
@Published
|
||||
var settings: Settings
|
||||
|
||||
@ -28,48 +33,23 @@ final class Content: ObservableObject {
|
||||
@Published
|
||||
var isGeneratingWebsite = false
|
||||
|
||||
@AppStorage("contentPath")
|
||||
private var storedContentPath: String = ""
|
||||
|
||||
@Published
|
||||
var contentPath: String = "" {
|
||||
didSet {
|
||||
storedContentPath = contentPath
|
||||
}
|
||||
}
|
||||
|
||||
let storage: Storage
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
init(settings: Settings,
|
||||
posts: [Post],
|
||||
pages: [Page],
|
||||
tags: [Tag],
|
||||
files: [FileResource],
|
||||
tagOverview: TagOverviewPage?,
|
||||
storedContentPath: String) {
|
||||
tagOverview: TagOverviewPage?) {
|
||||
self.settings = settings
|
||||
self.posts = posts
|
||||
self.pages = pages
|
||||
self.tags = tags
|
||||
self.files = files
|
||||
self.tagOverview = tagOverview
|
||||
self.storedContentPath = storedContentPath
|
||||
self.contentPath = storedContentPath
|
||||
self.storage = Storage(baseFolder: URL(filePath: storedContentPath))
|
||||
do {
|
||||
try storage.createFolderStructure()
|
||||
} catch {
|
||||
print(error)
|
||||
return
|
||||
}
|
||||
observeContentPath()
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
init() {
|
||||
self.storage = Storage(baseFolder: URL(filePath: ""))
|
||||
|
||||
self.settings = .mock
|
||||
self.posts = []
|
||||
self.pages = []
|
||||
@ -77,29 +57,24 @@ final class Content: ObservableObject {
|
||||
self.files = []
|
||||
self.tagOverview = nil
|
||||
|
||||
contentPath = storedContentPath
|
||||
do {
|
||||
try storage.createFolderStructure()
|
||||
} catch {
|
||||
print(error)
|
||||
initialize()
|
||||
}
|
||||
|
||||
private func initialize() {
|
||||
guard storage.check(contentPath: settings.paths.contentDirectoryPath) == .nominal else {
|
||||
storageIsInitialized = false
|
||||
return
|
||||
}
|
||||
|
||||
try? storage.update(baseFolder: URL(filePath: contentPath))
|
||||
observeContentPath()
|
||||
}
|
||||
storage.check(outputPath: settings.paths.outputDirectoryPath)
|
||||
|
||||
private func observeContentPath() {
|
||||
$contentPath.sink { newValue in
|
||||
let url = URL(filePath: newValue)
|
||||
do {
|
||||
try self.storage.update(baseFolder: url)
|
||||
try self.loadFromDisk()
|
||||
} catch {
|
||||
print("Failed to switch content path: \(error)")
|
||||
}
|
||||
do {
|
||||
try storage.createFolderStructure()
|
||||
storageIsInitialized = true
|
||||
} catch {
|
||||
print("Failed to initialize storage: \(error)")
|
||||
storageIsInitialized = false
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
var images: [FileResource] {
|
||||
|
@ -2,6 +2,9 @@ import Foundation
|
||||
|
||||
final class PathSettings: ObservableObject {
|
||||
|
||||
@Published
|
||||
var contentDirectoryPath: String
|
||||
|
||||
@Published
|
||||
var outputDirectoryPath: String
|
||||
|
||||
@ -24,6 +27,7 @@ final class PathSettings: ObservableObject {
|
||||
var tagsOutputFolderPath: String
|
||||
|
||||
init(file: PathSettingsFile) {
|
||||
self.contentDirectoryPath = file.contentDirectoryPath
|
||||
self.assetsOutputFolderPath = file.assetsOutputFolderPath
|
||||
self.outputDirectoryPath = file.outputDirectoryPath
|
||||
self.pagesOutputFolderPath = file.pagesOutputFolderPath
|
||||
@ -34,7 +38,8 @@ final class PathSettings: ObservableObject {
|
||||
}
|
||||
|
||||
var file: PathSettingsFile {
|
||||
.init(outputDirectoryPath: outputDirectoryPath,
|
||||
.init(contentDirectoryPath: contentDirectoryPath,
|
||||
outputDirectoryPath: outputDirectoryPath,
|
||||
assetsOutputFolderPath: assetsOutputFolderPath,
|
||||
pagesOutputFolderPath: pagesOutputFolderPath,
|
||||
imagesOutputFolderPath: imagesOutputFolderPath,
|
||||
|
Reference in New Issue
Block a user