Allow adding of thumbnails, update grid

This commit is contained in:
Christoph Hagen 2023-01-15 14:23:43 +01:00
parent b91d196a37
commit ba40cb0a17
3 changed files with 78 additions and 25 deletions

1
.gitignore vendored
View File

@ -9,6 +9,7 @@
Package.resolved
.swiftpm/
Public/images/
Public/thumbnails/
Public/classifier.version
Public/classifier.mlmodel
Public/caps.json

View File

@ -8,6 +8,11 @@ final class CapServer: ServerOwner {
private let imageFolder: URL
private let thumbnailFolder: URL
/// The file where the cap count is stored for the grid webpage
private let gridCountFile: URL
/// The file where the database of caps is stored
private let dbFile: URL
@ -73,6 +78,8 @@ final class CapServer: ServerOwner {
init(in folder: URL, writers: [String]) {
self.imageFolder = folder.appendingPathComponent("images")
self.thumbnailFolder = folder.appendingPathComponent("thumbnails")
self.gridCountFile = folder.appendingPathComponent("count.js")
self.dbFile = folder.appendingPathComponent("caps.json")
self.htmlFile = folder.appendingPathComponent("count.html")
self.classifierVersionFile = folder.appendingPathComponent("classifier.version")
@ -217,6 +224,10 @@ final class CapServer: ServerOwner {
func folder(of cap: Int) -> URL {
imageFolder.appendingPathComponent(String(format: "%04d", cap))
}
func thumbnail(of cap: Int) -> URL {
thumbnailFolder.appendingPathComponent(String(format: "%04d.jpg", cap))
}
func file(of cap: Int, version: Int) -> URL {
folder(of: cap).appendingPathComponent(String(format: "%04d-%02d.jpg", cap, version))
@ -384,6 +395,7 @@ final class CapServer: ServerOwner {
cap.classifierVersion = nextClassifierVersion
caps[cap.id] = cap
saveCapCountHTML()
updateGridCapCount()
log("Added cap \(cap.id) '\(cap.name)'")
}
@ -426,6 +438,29 @@ final class CapServer: ServerOwner {
classifierVersion = version
log("Updated classifier to version \(version)")
}
func getListOfMissingThumbnails() -> [Int] {
caps.keys.filter { !fm.fileExists(atPath: thumbnail(of: $0).path) }
}
func saveThumbnail(_ data: Data, for cap: Int) {
let url = thumbnail(of: cap)
do {
try data.write(to: url)
} catch {
log("Failed to save thumbnail \(cap): \(error)")
}
}
private func updateGridCapCount() {
do {
try "const numberOfCaps = \(capCount);"
.data(using: .utf8)!
.write(to: gridCountFile)
} catch {
log("Failed to save grid cap count: \(error)")
}
}
// MARK: ServerOwner

View File

@ -29,11 +29,8 @@ func routes(_ app: Application) {
// Add or change a cap
app.postCatching("cap") { request in
try authorize(request)
guard let buffer = request.body.data else {
log("Invalid body data")
throw CapError.invalidBody
}
let cap = try decoder.decode(Cap.self, from: buffer)
let data = try request.getBodyData()
let cap = try decoder.decode(Cap.self, from: data)
try server.addOrUpdate(cap)
}
@ -44,11 +41,7 @@ func routes(_ app: Application) {
log("Invalid parameter for cap")
throw Abort(.badRequest)
}
guard let buffer = request.body.data else {
log("Missing body data: \(request.body.description)")
throw CapError.invalidBody
}
let data = Data(buffer: buffer)
let data = try request.getBodyData()
try server.save(image: data, for: cap)
}
@ -62,11 +55,7 @@ func routes(_ app: Application) {
guard version > server.classifierVersion else {
throw Abort(.alreadyReported) // 208
}
guard let buffer = request.body.data else {
log("Missing body data: \(request.body.description)")
throw CapError.invalidBody
}
let data = Data(buffer: buffer)
let data = try request.getBodyData()
try server.save(classifier: data, version: version)
return .ok
}
@ -83,16 +72,44 @@ func routes(_ app: Application) {
}
try authorize(request)
guard let buffer = request.body.data else {
log("Missing body data: \(request.body.description)")
throw CapError.invalidBody
}
let data = Data(buffer: buffer)
guard let content = String(data: data, encoding: .utf8) else {
log("Invalid string body: \(request.body.description)")
throw CapError.invalidBody
}
server.updateTrainedClasses(content: content)
let body = try request.getStringBody()
server.updateTrainedClasses(content: body)
server.removeAllEntriesInImageChangeList(before: date)
}
// Get the list of missing thumbnails
app.get("thumbnails", "missing") { request in
let missingThumbnails = server.getListOfMissingThumbnails()
return missingThumbnails.map(String.init).joined(separator: ",")
}
app.postCatching("thumbnails", ":cap") { request in
guard let cap = request.parameters.get("cap", as: Int.self) else {
log("Invalid cap parameter for thumbnail upload")
throw Abort(.badRequest)
}
let data = try request.getBodyData()
server.saveThumbnail(data, for: cap)
}
}
private extension Request {
func getBodyData() throws -> Data {
guard let buffer = body.data else {
log("Missing body data")
throw CapError.invalidBody
}
return Data(buffer: buffer)
}
func getStringBody() throws -> String {
let data = try getBodyData()
guard let content = String(data: data, encoding: .utf8) else {
log("Invalid string body")
throw CapError.invalidBody
}
return content
}
}