From 848ff21134555f61a63124e16d0d58327ee0e30a Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Wed, 25 Oct 2023 15:38:22 +0200 Subject: [PATCH] Create thumbnails on server --- Sources/App/CapServer.swift | 58 ++++++++++++++++++++++++++++++------- Sources/App/configure.swift | 6 +++- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/Sources/App/CapServer.swift b/Sources/App/CapServer.swift index 64382ed..46aa813 100644 --- a/Sources/App/CapServer.swift +++ b/Sources/App/CapServer.swift @@ -6,6 +6,8 @@ final class CapServer { private let imageSize = 360 + private let thumbnailSize = 100 + // MARK: Paths private let imageFolder: URL @@ -36,6 +38,8 @@ final class CapServer { /// Indicates that the data is loaded private(set) var isOperational = false + private(set) var canResizeImages = false + // MARK: Caps @@ -117,7 +121,12 @@ final class CapServer { updateGridCapCount() try ensureExistenceOfChangedImagesFile() organizeImages() - shrinkImages() + if let version = getMagickVersion() { + log("Using ImageMagick \(version.rawValue)") + canResizeImages = true + } + // shrinkImages() + createMissingThumbnails() isOperational = true } @@ -363,6 +372,10 @@ final class CapServer { let count = try count(of: cap) caps[cap]!.count = count addChangedImageToLog(cap: cap, image: id) + if canResizeImages { + shrink(imageAt: capImageUrl, size: imageSize, destination: capImageUrl) + createThumbnail(for: cap) + } log("Added image \(id) for cap \(cap) (\(count) total)") } @@ -453,6 +466,9 @@ final class CapServer { throw CapError.invalidFile } caps[cap]?.mainImage = version + if canResizeImages { + createThumbnail(for: cap) + } log("Switched cap \(cap) to version \(version)") } @@ -606,6 +622,30 @@ final class CapServer { log("Failed to save grid cap count: \(error)") } } + + func createMissingThumbnails() { + let thumbnailsToCreate = getListOfMissingThumbnails() + guard !thumbnailsToCreate.isEmpty else { + return + } + guard canResizeImages else { + log("Can't create thumbnails, missing ImageMagick") + return + } + log("Creating \(thumbnailsToCreate.count) thumbnails") + for cap in thumbnailsToCreate { + createThumbnail(for: cap) + } + } + + func createThumbnail(for cap: Int) { + guard let version = caps[cap]?.mainImage else { + return + } + let mainImageUrl = imageUrl(of: cap, version: version) + let thumbnailUrl = thumbnail(of: cap) + shrink(imageAt: mainImageUrl, size: thumbnailSize, destination: thumbnailUrl) + } // MARK: Monitoring @@ -645,12 +685,10 @@ final class CapServer { } func shrinkImages() { - guard let version = getMagickVersion() else { - log("Failed to shrink images, missing dependency") + guard canResizeImages else { + log("Can't resize images, missing ImageMagick") return } - log("Shrinking images using ImageMagick \(version.rawValue)") - let imageFolders: [URL] do { imageFolders = try fm.contentsOfDirectory(at: imageFolder, includingPropertiesForKeys: nil) @@ -663,20 +701,20 @@ final class CapServer { continue } for imageUrl in images { - shrink(imageAt: imageUrl) + shrink(imageAt: imageUrl, size: imageSize, destination: imageUrl) } } } - private func shrink(imageAt url: URL) { + private func shrink(imageAt url: URL, size: Int, destination: URL) { do { - let command = "convert \(url.path) -resize '\(imageSize)x\(imageSize)>' \(url.path)" + let command = "convert \(url.path) -resize '\(size)x\(size)>' \(destination.path)" let (code, output) = try safeShell(command) if code != 0 { - print("Failed to shrink image: " + output) + log("Failed to shrink image \(url.path): " + output) } } catch { - print("Failed to shrink image: \(error)") + log("Failed to shrink image \(url.path): \(error)") } } diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 52ca1d6..6cab2bb 100755 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -47,7 +47,11 @@ public func configure(_ app: Application) async throws { } catch { try await status.update(.initializationFailure) } - try await status.update(.nominal) + if server.canResizeImages { + try await status.update(.nominal) + } else { + try await status.update(.reducedFunctionality) + } } func log(_ message: String) {