// // FuelEntryController.swift // // // Created by Bill Ryckman on 4/24/23. // import Vapor import FluentKit struct FuelEntryV2Controller: RouteCollection { func boot(routes: RoutesBuilder) throws { let fuelEntries = routes.grouped("fuel_entries") let tokenAuthMiddleware = Token.authenticator() let guardMiddleware = User.guardMiddleware() let tokenAuthGroup = fuelEntries.grouped(tokenAuthMiddleware, guardMiddleware) tokenAuthGroup.get(use: index) tokenAuthGroup.get("test", use: filtered) // fuelEntries.get("with-images", use: getAllEntriesWithImages) tokenAuthGroup.post(use: create) tokenAuthGroup.put( use: softdelete) // fuelEntries.post("upload-image", use: uploadImage) tokenAuthGroup.group(":fuelEntryID") { fuelEntry in fuelEntry.delete(use: delete) } } func index(req: Request) async throws -> [FuelEntry] { return try await FuelEntry.query(on: req.db).all() } struct filteredreturn: Content{ var fuelentries: [FuelEntry] var pages: Int } struct dload: Content{ var id: UUID } @Sendable func softdelete(req: Request) async throws -> Response { let ids = try req.content.decode([dload].self) var msg: [String] = [] for id in ids { guard let fe = try await FuelEntry.find(id.id, on: req.db) else { msg.append("create error message for item") continue } fe.downloaded = true try await fe.save(on: req.db) } let response = Response(status: .ok, body: "good") return response } @Sendable func filtered(req: Request) async throws -> Response { var image: Bool var serial: String var tank: String let qstring = req.query if let qimage = try? qstring.get(Bool.self, at: "image"){ image = qimage } else { image = false } if let qserial = try? qstring.get(String.self, at: "serial"){ serial = qserial } else { serial = "" } if let qtank = try? qstring.get(String.self, at: "tank"){ tank = qtank } else { tank = "" } var query = FuelEntry.query(on: req.db) if(image){ query = query .field(\.$id) .field(\.$timestamp) .field(\.$userID) .field(\.$product) .field(\.$make) .field(\.$model) .field(\.$serialNumber) .field(\.$tankID) .field(\.$fuelAmount) .field(\.$fuelType) .field(\.$isOverride) .field(\.$latitude) .field(\.$longitude) .field(\.$image) .field(\.$downloaded) //.filter(\.$image != nil) } else { query = query .field(\.$id) .field(\.$timestamp) .field(\.$userID) .field(\.$product) .field(\.$make) .field(\.$model) .field(\.$serialNumber) .field(\.$tankID) .field(\.$fuelAmount) .field(\.$fuelType) .field(\.$isOverride) .field(\.$latitude) .field(\.$longitude) .field(\.$downloaded) } if(serial.count > 0){ query = query .filter(\.$serialNumber == serial) } if(tank.count > 0){ query = query .filter(\.$tankID == tank) } if(image){ //query = query.filter(\.$image) let wimage = try await query.paginate(for: req).map{ img in FuelEntry.wimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitutde: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, isOverride: img.isOverride, image: img.image == nil ? Data(): img.image, downloaded: img.downloaded == nil ? false : img.downloaded!) } return try await wimage.encodeResponse(for: req) } else { let woimage = try await query.paginate(for: req).map{ img in FuelEntry.woimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitutde: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, isOverride: img.isOverride, downloaded: img.downloaded == nil ? false : img.downloaded!) } return try await woimage.encodeResponse(for: req) } // let result = try await query.paginate(for: req) // return try await result.encodeResponse(for: req) } // 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 fuelEntry = try req.content.decode([FuelEntry].self) try await fuelEntry.create(on: req.db) return fuelEntry } //Create with image file written to server storage instead of database // 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") // } // } } struct PageRequest: Content { var page: Int var size: Int // Add any other properties needed for pagination init(page: Int, size: Int) { self.page = page self.size = size } }