Allow adding of thumbnails, update grid
This commit is contained in:
parent
b91d196a37
commit
ba40cb0a17
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@
|
||||
Package.resolved
|
||||
.swiftpm/
|
||||
Public/images/
|
||||
Public/thumbnails/
|
||||
Public/classifier.version
|
||||
Public/classifier.mlmodel
|
||||
Public/caps.json
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user