Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Schedule #79

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions Sources/App/Jobs/GPXImportingJob.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Shuttle Tracker Server
//
// Created by Gabriel Jacoby-Cooper on 10/20/20.
// Modified by Dylan Zhou on 10/10/23.
//

import Foundation
Expand All @@ -27,6 +28,7 @@ struct GPXImportingJob: AsyncScheduledJob {
.filter { (url) in
return url.pathExtension == "gpx"
}

let routes = try await Route
.query(on: context.application.db(.sqlite))
.all()
Expand All @@ -39,9 +41,27 @@ struct GPXImportingJob: AsyncScheduledJob {
for stop in stops {
try await stop.delete(on: context.application.db(.sqlite))
}

let scheduleInfoData = try Data(
contentsOf: URL(fileURLWithPath: FileManager.default.currentDirectoryPath)
.appendingPathComponent("Public", isDirectory: true)
.appendingPathComponent("schedule.json", isDirectory: false)
)
let schedules = try await Schedule
.query(on: context.application.db(.sqlite))
.all()
for schedule in schedules {
try await schedule.delete(on: context.application.db(.sqlite))
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let infoSchedules = try decoder.decode([ScheduleInfo].self, from: scheduleInfoData) /// decodes data into array of individual schedules
for infoSchedule in infoSchedules {
try await Schedule(from: infoSchedule)!
.save(on: context.application.db(.sqlite))
}

for routesFileURL in routesFileURLs {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let schedule: MapSchedule
do {
let routesInfoData = try routesInfoParser.get(dataAt: routesFileURL.lastPathComponent, asCollection: [String: Any].self)
Expand Down
30 changes: 30 additions & 0 deletions Sources/App/Migrations/CreateSchedules.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// CreateSchedules.swift
// Shuttle Tracker Server
//
// Created by Dylan Zhou on 10/06/23.
//

import Fluent

/// A migration to create `Schedule` records.
struct CreateSchedules: AsyncMigration {

func prepare(on database: any Database) async throws {
try await database
.schema(Schedule.schema)
.id()
.field("name", .string, .required)
.field("start", .date, .required)
.field("end", .date, .required)
.field("content", .array(of: .custom(ScheduleInfo.Content.self)), .required)
.create()
}

func revert(on database: any Database) async throws {
try await database
.schema(Schedule.schema)
.delete()
}

}
57 changes: 57 additions & 0 deletions Sources/App/Models/Schedule.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// Schedule.swift
// Shuttle Tracker Server
//
// Created by Dylan Zhou on 10/06/23.
//

import CoreGPX
import FluentKit
import JSONParser
import Vapor

/// A representation of a schedule.
final class Schedule: Model, Content {

static let schema = "schedules"

@ID
var id: UUID?

/// The human-readable name of this stop.
@Field(key: "name")
var name: String

/// The start date of the schedule
@Field(key: "start")
var startDate: Date

/// The end date of the schedule
@Field(key: "end")
var endDate: Date

/// The actual schedule of when busses run
@Field(key: "content")
var content: ScheduleInfo.Content

init() { }

init?(from infoSchedule: ScheduleInfo) {
self.name = infoSchedule.name
self.startDate = infoSchedule.start
self.endDate = infoSchedule.end
self.content = infoSchedule.content
}

var isActive: Bool {
get {
if endDate > Date.now {
return true
} else {
return false
}
}
}


}
54 changes: 54 additions & 0 deletions Sources/App/ScheduleInfo.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// ScheduleInfo.swift
// Shuttle Tracker
//
// Created by Emily Ngo on 2/15/22.
// Modified by Dylan Zhou on 10/10/23.
//

import Foundation

final class ScheduleInfo: Codable {

struct Content: Codable {

struct DaySchedule: Codable {

let start: String

let end: String

}

let monday: DaySchedule

let tuesday: DaySchedule

let wednesday: DaySchedule

let thursday: DaySchedule

let friday: DaySchedule

let saturday: DaySchedule

let sunday: DaySchedule

}

let name: String

let start: Date

let end: Date

let content: Content

init(name: String, start: Date, end: Date, content: Content) {
self.name = name
self.start = start
self.end = end
self.content = content
}

}
2 changes: 1 addition & 1 deletion Sources/App/Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ enum Constants {
/// The current version number for the API.
///
/// - Remark: Increment this value every time a breaking change is made to the public-facing API.
static let apiVersion: UInt = 3
static let apiVersion: UInt = 4

/// The URL of the GPS data-feed.
static let datafeedURL: URL = {
Expand Down
1 change: 1 addition & 0 deletions Sources/App/configure.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public func configure(_ application: Application) async throws {
CreateBuses(),
CreateRoutes(),
CreateStops(),
CreateSchedules(),
JobMetadataMigrate(),
to: .sqlite
) // Add to the SQLite database
Expand Down
16 changes: 15 additions & 1 deletion Sources/App/routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,21 @@ func routes(_ application: Application) throws {
return Constants.apiVersion
}

// Return all known schedules
application.get("schedule") { (request) in
return request.redirect(to: "/schedule.json")
let schedules = try await Schedule
.query(on: request.db(.sqlite))
.all()
return Array(schedules)
}

// Return only currently active schedule
application.get("schedule","active") { (request) in
let schedules = try await Schedule
.query(on: request.db(.sqlite))
.all()
.filter { $0.isActive == true}
return Array(schedules)
}

// Get the current milestones
Expand Down Expand Up @@ -115,6 +128,7 @@ func routes(_ application: Application) throws {
guard let milestone = milestone else {
throw Abort(.notFound)
}

milestone.progress += 1 // Increment the milestone’s counter
try await milestone.update(on: request.db(.psql)) // Update the milestone on the database
return milestone
Expand Down