Просмотр исходного кода

Fueling service changes per Andy added startdate and enddate perameter as well as previous parameter

v2_uploadImages
Mike Carman 1 год назад
Родитель
Сommit
e1d679bf03
6 измененных файлов: 217 добавлений и 159 удалений
  1. Двоичные данные
      .swiftpm/xcode/package.xcworkspace/xcuserdata/mcarman.xcuserdatad/UserInterfaceState.xcuserstate
  2. +0
    -62
      .swiftpm/xcode/xcuserdata/mcarman.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  3. +149
    -96
      Sources/App/Controllers/FuelEntryV2Controller.swift
  4. +16
    -0
      Sources/App/Migrations/CreateFuelEntry.swift
  5. +50
    -0
      Sources/App/Models/FuelEntry.swift
  6. +2
    -1
      Sources/App/configure.swift

Двоичные данные
.swiftpm/xcode/package.xcworkspace/xcuserdata/mcarman.xcuserdatad/UserInterfaceState.xcuserstate Просмотреть файл


+ 0
- 62
.swiftpm/xcode/xcuserdata/mcarman.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist Просмотреть файл

@@ -3,66 +3,4 @@
uuid = "83CCDCAB-5627-45C3-BC68-1A59A1D654E0"
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "503D736B-E738-40DF-8DFC-FBACCAF425CE"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Sources/App/Controllers/FuelEntryV2Controller.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "30"
endingLineNumber = "30"
landmarkName = "index(req:)"
landmarkType = "7">
<Locations>
<Location
uuid = "503D736B-E738-40DF-8DFC-FBACCAF425CE - 7e13237d1c18fd17"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "(1) suspend resume partial function for App.FuelEntryV2Controller.index(req: Vapor.Request) async throws -&gt; Swift.Array&lt;App.FuelEntry&gt;"
moduleName = "App"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/mcarman/Projects/Vapor/fueling_v1/Sources/App/Controllers/FuelEntryV2Controller.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "30"
endingLineNumber = "30">
</Location>
<Location
uuid = "503D736B-E738-40DF-8DFC-FBACCAF425CE - 356e35258358ea8a"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "(2) await resume partial function for App.FuelEntryV2Controller.index(req: Vapor.Request) async throws -&gt; Swift.Array&lt;App.FuelEntry&gt;"
moduleName = "App"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/mcarman/Projects/Vapor/fueling_v1/Sources/App/Controllers/FuelEntryV2Controller.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "30"
endingLineNumber = "30">
</Location>
<Location
uuid = "503D736B-E738-40DF-8DFC-FBACCAF425CE - bb9b3e6730724091"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "(3) suspend resume partial function for App.FuelEntryV2Controller.index(req: Vapor.Request) async throws -&gt; Swift.Array&lt;App.FuelEntry&gt;"
moduleName = "App"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/mcarman/Projects/Vapor/fueling_v1/Sources/App/Controllers/FuelEntryV2Controller.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "30"
endingLineNumber = "30">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

+ 149
- 96
Sources/App/Controllers/FuelEntryV2Controller.swift Просмотреть файл

@@ -16,10 +16,10 @@ struct FuelEntryV2Controller: RouteCollection {
let tokenAuthGroup = fuelEntries.grouped(tokenAuthMiddleware, guardMiddleware)
tokenAuthGroup.get(use: index)
tokenAuthGroup.get("test", use: filtered)
// fuelEntries.get("with-images", use: getAllEntriesWithImages)
tokenAuthGroup.get("rpm", use: rpm)
tokenAuthGroup.get("maxim", use: filtered)
tokenAuthGroup.post(use: create)
tokenAuthGroup.put( use: softdelete)
// fuelEntries.post("upload-image", use: uploadImage)
tokenAuthGroup.group(":fuelEntryID") { fuelEntry in
fuelEntry.delete(use: delete)
}
@@ -55,28 +55,134 @@ struct FuelEntryV2Controller: RouteCollection {
return response
}
fileprivate func parseDate(_ dateString: String, _ start: Bool = true) -> Date? {
if(dateString.count == 0){
return nil
} else {
let parts = dateString.split(separator: "-")
let year = Int(parts[0])!
let month = Int(parts[1])!
let day = Int(parts[2])!
var dateComponents = DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
if(start) {
dateComponents.hour = 0
dateComponents.minute = 0
dateComponents.second = 0
} else {
dateComponents.hour = 23
dateComponents.minute = 59
dateComponents.second = 59
}
let calendar = Calendar(identifier: .gregorian)
return calendar.date(from: dateComponents)
}
}
@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
let startdate = try parseDate(qstring.get(String?.self, at: "startdate") ?? "")
let enddate = try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false)
let image = try qstring.get(Bool?.self, at: "image") ?? false
let serial = try qstring.get(String?.self, at: "serial") ?? nil
let tank = try qstring.get(String?.self, at: "tank") ?? nil
let previous = try qstring.get(Bool?.self, at: "previous") ?? false
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)
.field(\.$loaddate)
//.filter(\.$image != nil)
} else {
image = false
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)
.field(\.$loaddate)
}
if let qserial = try? qstring.get(String.self, at: "serial"){
serial = qserial
} else {
serial = ""
query = query.group(.and){
grp in
if( startdate != nil) {
grp.filter(\.$loaddate >= startdate!)
}
if( enddate != nil) {
grp.filter(\.$loaddate <= enddate!)
}
if( serial != nil) {
grp.filter(\.$serialNumber == serial!)
}
if( tank != nil) {
grp.filter(\.$tankID == tank!)
}
if(!previous){
grp.filter(\.$pulldate == nil)
}
}
if let qtank = try? qstring.get(String.self, at: "tank"){
tank = qtank
query = query.sort(\.$loaddate, .ascending)
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!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date())
}
wimage.items.forEach{
_ = $0.toFuelEntry().save(on: req.db)
}
return try await wimage.encodeResponse(for: req)
} else {
tank = ""
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!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date())
}
woimage.items.forEach {
_ = $0.toFuelEntry().save(on: req.db)
}
return try await woimage.encodeResponse(for: req)
}
}
@Sendable
func rpm(req: Request) async throws -> Response {
let qstring = req.query
let startdate = try parseDate(qstring.get(String?.self, at: "startdate") ?? "")
let enddate = try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false)
let image = try qstring.get(Bool?.self, at: "image") ?? false
let serial = try qstring.get(String?.self, at: "serial") ?? nil
let tank = try qstring.get(String?.self, at: "tank") ?? nil
let previous = try qstring.get(Bool?.self, at: "previous") ?? false
var query = FuelEntry.query(on: req.db)
if(image){
@@ -96,6 +202,7 @@ struct FuelEntryV2Controller: RouteCollection {
.field(\.$longitude)
.field(\.$image)
.field(\.$downloaded)
.field(\.$loaddate)
//.filter(\.$image != nil)
} else {
@@ -114,44 +221,45 @@ struct FuelEntryV2Controller: RouteCollection {
.field(\.$latitude)
.field(\.$longitude)
.field(\.$downloaded)
.field(\.$loaddate)
}
if(serial.count > 0){
query = query
.filter(\.$serialNumber == serial)
}
if(tank.count > 0){
query = query
.filter(\.$tankID == tank)
query = query.group(.and){
grp in
if( startdate != nil) {
grp.filter(\.$loaddate >= startdate!)
}
if( enddate != nil) {
grp.filter(\.$loaddate <= enddate!)
}
if( serial != nil) {
grp.filter(\.$serialNumber == serial!)
}
if( tank != nil) {
grp.filter(\.$tankID == tank!)
}
if(!previous){
grp.filter(\.$pulldate == nil)
}
}
query = query.sort(\.$loaddate, .ascending).sort(\.$timestamp).sort(\.$serialNumber)
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!)
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!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date())
}
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!)
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!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date())
}
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)
@@ -159,37 +267,7 @@ struct FuelEntryV2Controller: RouteCollection {
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 {
@@ -198,31 +276,6 @@ struct FuelEntryV2Controller: RouteCollection {
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 {


+ 16
- 0
Sources/App/Migrations/CreateFuelEntry.swift Просмотреть файл

@@ -96,3 +96,19 @@ struct AddDownloadedBool: AsyncMigration {
}
}

struct AddLoadDateAndPullDate: AsyncMigration {
func prepare(on database: Database) async throws {
try await database.schema("fuel_entries")
.field("loadDate", .datetime)
.field("pullDate", .datetime)
.update()
}
func revert(on database: Database) async throws {
try await database.schema("fuel_entries")
.deleteField("loadDate")
.deleteField("pullDate")
.update()
}
}


+ 50
- 0
Sources/App/Models/FuelEntry.swift Просмотреть файл

@@ -26,6 +26,29 @@ final class FuelEntry: Model, Content {
let fuelType: String
let isOverride: Bool
let downloaded: Bool?
let loaddate: Date?
let pulldate: Date?
func toFuelEntry() -> FuelEntry {
var entry = FuelEntry()
entry.id = self.id
entry.timestamp = self.timestamp
entry.userID = self.userID
entry.latitude = self.latitude
entry.longitude = self.longitutde
entry.product = self.product
entry.make = self.make
entry.model = self.model
entry.serialNumber = self.serialNumber
entry.tankID = self.tankID
entry.fuelAmount = self.fuelAmount
entry.fuelType = self.fuelType
entry.isOverride = self.isOverride
entry.downloaded = self.downloaded
entry.loaddate = self.loaddate
entry.pulldate = self.pulldate
entry._$idExists = self.id == nil ? false : true
return entry
}
}
struct wimage: Content{
@@ -44,6 +67,30 @@ final class FuelEntry: Model, Content {
let isOverride: Bool
let image: Data?
let downloaded: Bool?
let loaddate: Date?
let pulldate: Date?
func toFuelEntry() -> FuelEntry {
var entry = FuelEntry()
entry.id = self.id
entry.timestamp = self.timestamp
entry.userID = self.userID
entry.latitude = self.latitude
entry.longitude = self.longitutde
entry.product = self.product
entry.make = self.make
entry.model = self.model
entry.serialNumber = self.serialNumber
entry.tankID = self.tankID
entry.fuelAmount = self.fuelAmount
entry.fuelType = self.fuelType
entry.isOverride = self.isOverride
entry.image = self.image
entry.downloaded = self.downloaded
entry.loaddate = self.loaddate
entry.pulldate = self.pulldate
entry._$idExists = self.id == nil ? false : true
return entry
}
}

@ID(key: .id)
@@ -91,6 +138,9 @@ final class FuelEntry: Model, Content {
@Field(key: "downloaded")
var downloaded: Bool?
@Timestamp(key: "loadDate", on: .create) var loaddate: Date?
@Timestamp(key: "pullDate", on: .none) var pulldate: Date?
// var imageData: Data?

init() {}


+ 2
- 1
Sources/App/configure.swift Просмотреть файл

@@ -10,7 +10,7 @@ public func configure(_ app: Application) async throws {
app.routes.defaultMaxBodySize = "128mb"
// let timeout = HTTPClient.Configuration.Timeout(connect: .seconds(300), read: .seconds(300))
// app.http.client.configuration.timeout = timeout
app.databases.use(.postgres(hostname: "127.0.0.1", port: 5432, username: "mcarman", password: "@ng31F@rm0823262", database: "fueling"), as: .psql)
app.databases.use(.postgres(hostname: "127.0.0.1", port: 5433, username: "mcarman", password: "@ng31F@rm0823262", database: "fueling"), as: .psql)
// app.databases.use(DatabaseConfigurationFactory.postgres(configuration: .init(
// hostname: Environment.get("DATABASE_HOST") ?? "localhost",
// port: Environment.get("DATABASE_PORT").flatMap(Int.init(_:)) ?? 5433,
@@ -31,6 +31,7 @@ public func configure(_ app: Application) async throws {
app.migrations.add(UpdateTokens1())
app.migrations.add(UpdateUser2_AddTokenfield())
app.migrations.add(UpdateUser3_RemoveTokenfield())
app.migrations.add(AddLoadDateAndPullDate())
try await app.autoMigrate().get()

// register routes


Загрузка…
Отмена
Сохранить