Use single route to change and add caps

This commit is contained in:
Christoph Hagen 2022-05-28 21:59:32 +02:00
parent f4ab09a6f6
commit d037042563
3 changed files with 47 additions and 35 deletions

View File

@ -163,11 +163,10 @@ final class CapServer {
Automatically creates the image name with the current image count.
- Parameter data: The image data
- Parameter cap: The id of the cap.
- Returns: The new image count for the cap
- Throws: `CapError.unknownId`, if the cap doesn't exist. `CapError.dataInconsistency` if an image already exists for the current count.
*/
func save(image data: Data, for cap: Int) throws -> Int {
guard var count = caps[cap]?.count else {
func save(image data: Data, for cap: Int) throws {
guard caps[cap] != nil else {
throw CapError.unknownId
}
var id = 0
@ -177,10 +176,8 @@ final class CapServer {
f = file(of: cap, version: id)
}
try data.write(to: f)
count += 1
caps[cap]!.count = count
caps[cap]!.count += 1
log("Added image \(id) for cap \(cap)")
return count
}
func switchMainImage(to version: Int, for cap: Int) throws {
@ -192,4 +189,34 @@ final class CapServer {
caps[cap]?.mainImage = version
log("Switched cap \(cap) to version \(version)")
}
func addOrUpdate(_ cap: Cap) throws {
if let existingCap = caps[cap.id] {
try update(existingCap, with: cap)
} else {
try add(cap)
}
}
private func add(_ cap: Cap) throws {
guard cap.mainImage == 0, cap.count == 0 else {
throw CapError.invalidData
}
caps[cap.id] = cap
}
private func update(_ existingCap: Cap, with cap: Cap) throws {
var updatedCap = existingCap
if cap.name != "" {
updatedCap.name = cap.name
}
let url = file(of: cap.id, version: cap.mainImage)
if fm.fileExists(atPath: url.path) {
updatedCap.mainImage = cap.mainImage
}
if let color = cap.color {
updatedCap.color = color
}
caps[cap.id] = updatedCap
}
}

View File

@ -15,6 +15,7 @@ enum CapError: Error {
case dataInconsistency
case invalidFile
case invalidConfiguration
case invalidData
var response: HTTPResponseStatus {
switch self {
@ -22,6 +23,8 @@ enum CapError: Error {
case .unknownId: return .notFound
/// 400
case .invalidBody: return .badRequest
/// 406
case .invalidData: return .notAcceptable
/// 409
case .dataInconsistency: return .conflict
/// 412

View File

@ -1,5 +1,8 @@
import Vapor
/// The decoder to extract caps from JSON payloads given to the `cap` route.
private let decoder = JSONDecoder()
private func authorize(_ request: Request) throws {
let key = try request.query.get(String.self, at: "key")
guard server.hasAuthorization(for: key) else {
@ -7,27 +10,21 @@ private func authorize(_ request: Request) throws {
}
}
/// Register your application's routes here.
///
/// [Learn More ](https://docs.vapor.codes/3.0/getting-started/structure/#routesswift)
func routes(_ app: Application) throws {
// Set the name of a cap
app.postCatching("name", ":n") { request in
// Add or change a cap
app.postCatching("cap") { request in
try authorize(request)
guard let cap = request.parameters.get("n", as: Int.self) else {
log("Invalid parameter for cap")
throw Abort(.badRequest)
}
guard let buffer = request.body.data, let name = String(data: Data(buffer: buffer), encoding: .utf8) else {
guard let buffer = request.body.data else {
log("Invalid body data")
throw CapError.invalidBody
}
try server.set(name: name, for: cap)
let cap = try decoder.decode(Cap.self, from: buffer)
try server.addOrUpdate(cap)
}
// Upload an image
app.postCatching("images", ":n") { request -> Data in
app.postCatching("images", ":n") { request in
try authorize(request)
guard let cap = request.parameters.get("n", as: Int.self) else {
log("Invalid parameter for cap")
@ -38,21 +35,6 @@ func routes(_ app: Application) throws {
throw CapError.invalidBody
}
let data = Data(buffer: buffer)
let newCount = try server.save(image: data, for: cap)
return "\(newCount)".data(using: .utf8)!
}
// Set a different version as the main image
app.getCatching("switch", ":n", ":v") { request in
try authorize(request)
guard let cap = request.parameters.get("n", as: Int.self), cap >= 0 else {
log("Invalid parameter for cap")
throw Abort(.badRequest)
}
guard let version = request.parameters.get("v", as: Int.self), version >= 0 else {
log("Invalid parameter for cap version")
throw Abort(.badRequest)
}
try server.switchMainImage(to: version, for: cap)
try server.save(image: data, for: cap)
}
}