Shrink oversized images on startup

This commit is contained in:
Christoph Hagen 2023-10-25 13:42:54 +02:00
parent ec21c06581
commit cc7a3ec567

View File

@ -4,6 +4,8 @@ import Clairvoyant
final class CapServer { final class CapServer {
private let imageSize = 360
// MARK: Paths // MARK: Paths
private let imageFolder: URL private let imageFolder: URL
@ -115,6 +117,7 @@ final class CapServer {
updateGridCapCount() updateGridCapCount()
try ensureExistenceOfChangedImagesFile() try ensureExistenceOfChangedImagesFile()
organizeImages() organizeImages()
shrinkImages()
isOperational = true isOperational = true
} }
@ -611,4 +614,87 @@ final class CapServer {
private let imageCountMetric: Metric<Int> private let imageCountMetric: Metric<Int>
private let classifierMetric: Metric<Int> private let classifierMetric: Metric<Int>
// MARK: Maintenance
private func getMagickVersion() -> SemanticVersion? {
do {
let command = "convert -version"
let (code, output) = try safeShell(command)
guard code == 0,
let line = output.components(separatedBy: "\n").first,
line.hasPrefix("Version: ImageMagick ") else {
log("Missing dependency ImageMagick: " + output)
return nil
}
guard let versionString = line
.replacingOccurrences(of: "Version: ImageMagick ", with: "")
.components(separatedBy: "-").first else {
log("Invalid ImageMagick version: " + output)
return nil
}
guard let version = SemanticVersion(rawValue: versionString) else {
log("Invalid ImageMagick version: " + output)
return nil
}
return version
} catch {
log("Failed to check dependency ImageMagick: \(error)")
return nil
}
}
func shrinkImages() {
guard let version = getMagickVersion() else {
log("Failed to shrink images, missing dependency")
return
}
log("Shrinking images using ImageMagick \(version.rawValue)")
let imageFolders: [URL]
do {
imageFolders = try fm.contentsOfDirectory(at: imageFolder, includingPropertiesForKeys: nil)
} catch {
log("Failed to get all image folders")
return
}
for folder in imageFolders {
guard let images = try? self.images(in: folder) else {
continue
}
for imageUrl in images {
shrink(imageAt: imageUrl)
}
}
}
private func shrink(imageAt url: URL) {
do {
let command = "convert \(url.path) -resize '\(imageSize)x\(imageSize)>' \(url.path)"
let (code, output) = try safeShell(command)
if code != 0 {
print("Failed to shrink image: " + output)
}
} catch {
print("Failed to shrink image: \(error)")
}
}
private func safeShell(_ command: String) throws -> (code: Int32, output: String) {
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.arguments = ["-cl", command]
task.executableURL = URL(fileURLWithPath: "/bin/bash")
task.standardInput = nil
try task.run()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
return (task.terminationStatus, output)
}
} }