From eff9531e4b972771f76a19d2bc97788e11ae69d3 Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Thu, 11 Nov 2021 08:58:36 +0100 Subject: [PATCH] Add routes and configuration --- Sources/App/configure.swift | 122 ++++++++++++++++++++++++++++++++++++ Sources/App/routes.swift | 27 +++++++- 2 files changed, 147 insertions(+), 2 deletions(-) mode change 100644 => 100755 Sources/App/configure.swift mode change 100644 => 100755 Sources/App/routes.swift diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift old mode 100644 new mode 100755 index 800d36c..3d426d5 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -1,10 +1,132 @@ import Vapor +private var eventLogHandle: FileHandle? + +private var registeredGuests = Set() + +private var declinedGuests = Set() + +private var guestListPath: URL! + +private var declinedListPath: URL! + +let df: DateFormatter = { + let df = DateFormatter() + df.dateFormat = "dd.MM. HH:mm" + return df +}() + + +func add(guest: String) -> String { + registeredGuests.insert(guest) + declinedGuests.remove(guest) + defer { saveLists() } + return log(event: "\(guest) registered") +} + +func remove(guest: String) -> String { + registeredGuests.remove(guest) + declinedGuests.insert(guest) + defer { saveLists() } + return log(event: "\(guest) declined") +} + +private func saveLists() { + saveList(registeredGuests, named: "guest", to: guestListPath) + saveList(declinedGuests, named: "declined", to: declinedListPath) +} + +private func saveList(_ set: Set, named name: String, to url: URL) { + guard let list = set.sorted().joined(separator: "\n").data(using: .utf8) else { + print("Failed to save \(name) list, no data") + return + } + do { + try list.write(to: url) + print("Saved \(name) list with \(set.count) entries") + } catch { + print("Failed to write \(name) list: \(error)") + } +} + +private func loadList(from url: URL) throws -> Set { + let users = try String(contentsOf: url) + .split(separator: "\n") + .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } + .filter { !$0.isEmpty } + print("Loaded list \(url.path) (\(users.count) entries)") + return .init(users) +} + +private func log(event: String) -> String { + guard let handle = eventLogHandle else { + return "No handle" + } + let date = Date() + let dateString = df.string(from: date) + guard let entry = "[\(dateString)] \(event)\n".data(using: .utf8) else { + return "Invalid name" + } + guard #available(macOS 10.15.4, *) else { + handle.write(entry) + handle.synchronizeFile() + return "Success" + } + do { + try handle.write(contentsOf: entry) + handle.synchronizeFile() + return "Success" + } catch { + return "Save failed" + } +} + +private func createFileIfNeeded(at path: URL) throws { + guard !FileManager.default.fileExists(atPath: path.path) else { + return + } + try Data().write(to: path) +} + // configures your application public func configure(_ app: Application) throws { // uncomment to serve files from /Public folder // app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory)) + app.http.server.configuration.port = 9001 + + // let eventLog = app.directory.publicDirectory + "events.txt" + // let guestList = app.directory.publicDirectory + "registered.txt" + // let declinedList = app.directory.publicDirectory + "declined.txt" + let eventLog = "/blog/site/lists/events.txt" + let guestList = "/blog/site/lists/registered.txt" + let declinedList = "/blog/site/lists/declined.txt" + let eventLogPath = URL(fileURLWithPath: eventLog) + guestListPath = URL(fileURLWithPath: guestList) + declinedListPath = URL(fileURLWithPath: declinedList) + + // Create the files + try createFileIfNeeded(at: eventLogPath) + try createFileIfNeeded(at: guestListPath) + try createFileIfNeeded(at: declinedListPath) + + // Create handle to write events + eventLogHandle = FileHandle(forWritingAtPath: eventLog) + if #available(macOS 10.15.4, *) { + try eventLogHandle?.seekToEnd() + } else { + // Fallback on earlier versions + eventLogHandle?.seekToEndOfFile() + } + + registeredGuests = try loadList(from: guestListPath) + declinedGuests = try loadList(from: declinedListPath) + // register routes try routes(app) + + let date = Date() + let dateString = df.string(from: date) + print("[\(dateString)] Server started: \(registeredGuests.count) registered, \(declinedGuests.count) declined, event log open: \(eventLogHandle != nil)") + } diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift old mode 100644 new mode 100755 index 6bb9c5c..98807be --- a/Sources/App/routes.swift +++ b/Sources/App/routes.swift @@ -1,11 +1,34 @@ import Vapor +private func register(_ req: Request, isAttending: Bool) -> String { + guard let name = req.body.string?.trimmingCharacters(in: .whitespacesAndNewlines) else { + return "No Name" + } + if isAttending { + return add(guest: name) + } else { + return remove(guest: name) + } +} + func routes(_ app: Application) throws { app.get { req in return "It works!" } - app.get("hello") { req -> String in - return "Hello, world!" + app.get("festival", "api", "hello") { req in + return "It works!" + } + + app.get("hello") { req in + return "It works!" + } + + app.post("festival", "api", "register") { req -> String in + register(req, isAttending: true) + } + + app.post("festival", "api", "decline") { req -> String in + register(req, isAttending: false) } }