// // FuelEntryController.swift // // // Created by Bill Ryckman on 4/24/23. // import Vapor struct FuelEntryV2Controller: RouteCollection { func boot(routes: RoutesBuilder) throws { let fuelEntries = routes.grouped("fuel_entries") fuelEntries.get(use: index) fuelEntries.get("with-images", use: getAllEntriesWithImages) fuelEntries.post(use: create) fuelEntries.post("upload-image", use: uploadImage) fuelEntries.group(":fuelEntryID") { fuelEntry in fuelEntry.delete(use: delete) } } func index(req: Request) async throws -> [FuelEntry] { try await FuelEntry.query(on: req.db).all() } func getAllEntriesWithImages(req: Request) async throws -> [FuelEntry] { let fuelEntries = try await FuelEntry.query(on: req.db).all() for var fuelEntry in fuelEntries { if let imagePath = fuelEntry.image { let fileURL = URL(fileURLWithPath: imagePath) if let imageData = try? Data(contentsOf: fileURL) { fuelEntry.imageData = imageData } } } return fuelEntries } func create(req: Request) async throws -> [FuelEntry] { let fuelEntries = try await req.content.decode([FuelEntry].self) let directory = DirectoryConfiguration.detect().workingDirectory + "Images/" var updatedFuelEntries: [FuelEntry] = [] for fuelEntry in fuelEntries { let updatedFuelEntry = try await { () async throws -> FuelEntry in var updatedFuelEntry = fuelEntry if let imageData = updatedFuelEntry.imageData { let imageFilename = "\(updatedFuelEntry.id!).png" let tempImageURL = URL(fileURLWithPath: directory + imageFilename) try await imageData.write(to: tempImageURL) updatedFuelEntry.image = tempImageURL.absoluteString } do { _ = try await updatedFuelEntry.save(on: req.db) return updatedFuelEntry } catch { throw Abort(.internalServerError, reason: "Error saving FuelEntry: \(error)") } }() updatedFuelEntries.append(updatedFuelEntry) } return updatedFuelEntries } func delete(req: Request) async throws -> HTTPStatus { guard let fuelEntry = try await FuelEntry.find(req.parameters.get("fuelEntryID"), on: req.db) else { throw Abort(.notFound) } try await fuelEntry.delete(on: req.db) return .noContent } func uploadImage(req: Request) async throws -> FuelEntry { let fuelEntryID: UUID = try req.parameters.require("id") let file = try await req.content.decode(File.self) let filename = fuelEntryID.uuidString + ".png" // Generate a unique filename for the uploaded image let directory = DirectoryConfiguration.detect().workingDirectory + "Images/" if let imageData = file.data.getData(at: 0, length: file.data.readableBytes) { do { try Data(imageData).write(to: URL(fileURLWithPath: directory + filename)) // Save the uploaded image to server } catch { throw Abort(.internalServerError, reason: "Failed to save image file") } // Update FuelEntry model after saving the image if let fuelEntry = try await FuelEntry.find(fuelEntryID, on: req.db) { return fuelEntry } else { throw Abort(.notFound, reason: "FuelEntry not found") } } else { throw Abort(.badRequest, reason: "Failed to extract image data") } } }