diff --git a/Package.swift b/Package.swift index fa2ac49..e11f7fb 100755 --- a/Package.swift +++ b/Package.swift @@ -5,10 +5,9 @@ let package = Package( name: "CapCollectorServer", dependencies: [ .package(url: "https://github.com/vapor/vapor.git", .upToNextMinor(from: "3.3.0")), - .package(url: "https://github.com/stephencelis/SQLite.swift", from: "0.12.0"), ], targets: [ - .target(name: "App", dependencies: ["Vapor", "SQLite"]), + .target(name: "App", dependencies: ["Vapor"]), .target(name: "Run", dependencies: ["App"]), .testTarget(name: "AppTests", dependencies: ["App"]), ] diff --git a/Sources/App/Router+Extensions.swift b/Sources/App/Router+Extensions.swift index bb7931f..9eb1368 100644 --- a/Sources/App/Router+Extensions.swift +++ b/Sources/App/Router+Extensions.swift @@ -36,7 +36,7 @@ private func catching(_ path: PathComponentsRepresentable..., request: Reques log("\(route): Error \(error)") return HTTPResponse(status: error.response) } catch { - log("\(route): Unhandled error \(error)") + log("\(route): Unhandled error: \(error)") return HTTPResponse(status: .internalServerError) } } diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift index 9b1e04f..d105f17 100755 --- a/Sources/App/routes.swift +++ b/Sources/App/routes.swift @@ -1,6 +1,5 @@ import Routing import Vapor -import SQLite // MARK: Paths @@ -12,7 +11,7 @@ private let publicFolder = baseFolder.appendingPathComponent("Public") private let imageFolder = publicFolder.appendingPathComponent("images") -private let dbFile = publicFolder.appendingPathComponent("db.sqlite3").path +private let nameFile = publicFolder.appendingPathComponent("names.txt") private let tempImageFile = publicFolder.appendingPathComponent("temp.jpg") @@ -20,26 +19,18 @@ private let tempImageFile = publicFolder.appendingPathComponent("temp.jpg") private let fm = FileManager.default -private var db: Connection! +private var caps = [String]() // MARK: SQLite -private let id = Expression("id") - -private let name = Expression("name") - -private let table = Table("caps") - -func loadDatabase() throws { - db = try Connection(dbFile) +func loadCapNames() throws { + let s = try String(contentsOf: nameFile) + caps = s.components(separatedBy: "\n") + log("\(caps.count) caps loaded") } // MARK: Helper -private func select(_ cap: Int) -> Table { - table.filter(id == cap) -} - private func folder(of cap: Int) -> URL { imageFolder.appendingPathComponent(String(format: "%04d", cap)) } @@ -68,27 +59,36 @@ private func count(of cap: Int) throws -> Int { public func routes(_ router: Router) throws { try Log.set(logFile: logFile) + try loadCapNames() // Get the name of a cap router.getCatching("name", Int.parameter) { request -> Data in let cap = try request.parameters.next(Int.self) - guard let row = try db.pluck(table.select(name).filter(id == cap)) else { + guard cap < caps.count else { throw CapError.unknownId } - return row[name].data(using: .utf8)! + return caps[cap].data(using: .utf8)! } // Set the name of a cap router.postCatching("name", Int.parameter) { request in let cap = try request.parameters.next(Int.self) - guard let data = request.http.body.data, let string = String(data: data, encoding: .utf8) else { + guard let data = request.http.body.data, let name = String(data: data, encoding: .utf8) else { throw CapError.invalidBody } - guard let _ = try db.pluck(select(cap)) else { - try db.run(select(cap).insert(id <- cap, name <- string)) - return + guard cap <= caps.count else { + throw CapError.unknownId } - try db.run(select(cap).update(name <- string)) + + if cap == caps.count { + caps.append(name) + // Create image folder + let url = folder(of: cap) + try fm.createDirectory(at: url, withIntermediateDirectories: false) + } else { + caps[cap] = name + } + try caps.joined(separator: "\n").data(using: .utf8)!.write(to: nameFile) } // Upload an image @@ -114,17 +114,8 @@ public func routes(_ router: Router) throws { } // Get the count of all caps - router.getCatching("count", "all") { request -> Data in - let counts: [(id: Int, count: Int)] = try fm.contentsOfDirectory(at: imageFolder, includingPropertiesForKeys: nil).compactMap { folder in - guard let id = Int(folder.lastPathComponent) else { - return nil - } - guard let count = try? countImages(in: folder) else { - return nil - } - return (id, count) - } - return counts.map { "\($0.id)#\($0.count)"}.joined(separator: ";").data(using: .utf8)! + router.getCatching("counts") { request -> Data in + try (1...caps.count).map { UInt8(try count(of: $0)) }.convertToData() } // Set a different version as the main image