RIT-Dining/TigerDine/Components/FoodTruckParsers.swift
NinjaCheetah 23ebc9d848
Replace all instances of "RIT Dining" with "TigerDine"
The project and some files were still named that way, so that's been fixed now. The bundle ID is stuck that way forever but oh well. Nobody will see that.
2025-12-24 16:41:18 -05:00

98 lines
4.3 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// FoodTruckParsers.swift
// TigerDine
//
// Created by Campbell on 11/3/25.
//
import Foundation
import SwiftSoup
// This code is actually miserable and might break sometimes. Sorry. Parse the HTML of the RIT food trucks web page and build
// a list of food trucks that are going to be there the next time they're there. This is not a good way to get this data but it's
// unfortunately the best way that I think I could make it happen. Sorry again for both my later self and anyone else who tries to
// work on this code.
func parseWeekendFoodTrucks(htmlString: String) -> [FoodTruckEvent] {
do {
let doc = try SwiftSoup.parse(htmlString)
var events: [FoodTruckEvent] = []
let now = Date()
let calendar = Calendar.current
let paragraphs = try doc.select("p:has(strong)")
for p in paragraphs {
let text = try p.text()
let parts = text.components(separatedBy: .whitespaces).joined(separator: " ")
let dateRegex = /(?:(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\s+[A-Za-z]+\s+\d+)/
let date = parts.firstMatch(of: dateRegex).map { String($0.0) } ?? ""
if date.isEmpty { continue }
let timeRegex = /(\d{1,2}(:\d{2})?\s*[-]\s*\d{1,2}(:\d{2})?\s*p\.m\.)/
let time = parts.firstMatch(of: timeRegex).map { String($0.0) } ?? ""
let locationRegex = /A-Z Lot/
let location = parts.firstMatch(of: locationRegex).map { String($0.0) } ?? ""
let year = Calendar.current.component(.year, from: Date())
let fullDateString = "\(date) \(year)"
let formatter = DateFormatter()
formatter.dateFormat = "EEEE, MMMM d yyyy"
formatter.locale = Locale(identifier: "en_US_POSIX")
let dateParsed = formatter.date(from: fullDateString) ?? now
let timeStrings = time.split(separator: "-", maxSplits: 1)
print("raw open range: \(timeStrings)")
var openTime = Date()
var closeTime = Date()
if let openString = timeStrings.first?.trimmingCharacters(in: .whitespaces) {
// If the time is NOT in the morning, add 12 hours.
let openHour = if openString.contains("a.m") {
Int(openString.filter("0123456789".contains))!
} else {
Int(openString)! + 12
}
let openTimeComponents = DateComponents(hour: openHour, minute: 0, second: 0)
openTime = calendar.date(
bySettingHour: openTimeComponents.hour!,
minute: openTimeComponents.minute!,
second: openTimeComponents.second!,
of: now)!
}
if let closeString = timeStrings.last?.filter(":0123456789".contains) {
// I've chosen to assume that no visiting chef will ever close in the morning. This could bad choice but I have
// yet to see any evidence of a visiting chef leaving before noon so far.
let closeStringComponents = closeString.split(separator: ":", maxSplits: 1)
let closeTimeComponents = DateComponents(
hour: Int(closeStringComponents[0])! + 12,
minute: closeStringComponents.count > 1 ? Int(closeStringComponents[1]) : 0,
second: 0)
closeTime = calendar.date(
bySettingHour: closeTimeComponents.hour!,
minute: closeTimeComponents.minute!,
second: closeTimeComponents.second!,
of: now)!
}
if let ul = try p.nextElementSibling(), ul.tagName() == "ul" {
let trucks = try ul.select("li").array().map { try $0.text() }
events.append(FoodTruckEvent(
date: dateParsed,
openTime: openTime,
closeTime: closeTime,
location: location,
trucks: trucks
))
print(events)
}
}
return events
} catch {
print(error)
return []
}
}