164 lines
5.0 KiB
JavaScript
164 lines
5.0 KiB
JavaScript
const DAY_IN_MS = 8.64e+7;
|
|
|
|
class StopId {
|
|
constructor(stopIdString){
|
|
let [lineId, direction, stopId] = stopIdString.split(/\//)
|
|
this.lineId = lineId
|
|
this.stopId = stopId
|
|
this.direction = direction
|
|
}
|
|
}
|
|
|
|
async function getNextTripJSON(stop_id){
|
|
let res = await fetch(`/api/interface/tcl/next-trips/stops/${encodeURIComponent(stop_id.stopId)}/${encodeURIComponent(stop_id.lineId)}/${stop_id.direction}`);
|
|
if(!res.ok){
|
|
throw new Error(`Server responded with ${res.status} ${res.statusText}`)
|
|
}
|
|
|
|
let result = await res.json();
|
|
|
|
if(!result.data){
|
|
throw new Error(`Stop ${stop_id.stopId} not found`)
|
|
}
|
|
|
|
return result.data[0]
|
|
}
|
|
|
|
async function getStopsJSON(stop_id){
|
|
let res = await fetch(`/api/interface/tcl/lines/${encodeURIComponent(stop_id.lineId)}/stops`);
|
|
if(!res.ok){
|
|
throw new Error(`Server responded with ${res.status} ${res.statusText}`)
|
|
}
|
|
|
|
let result = await res.json();
|
|
|
|
if(!result.data){
|
|
throw new Error(`Line ${stop_id.lineId} not found`)
|
|
}
|
|
|
|
return result.data
|
|
}
|
|
|
|
async function getTimetableJSON(stop_id, date){
|
|
let res = await fetch(`/api/interface/tcl/timetables/${encodeURIComponent(stop_id.stopId)}/${encodeURIComponent(stop_id.lineId)}/${stop_id.direction}?date=${date.getFullYear()}-${(date.getMonth()+1).toString().padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`);
|
|
if(!res.ok){
|
|
throw new Error(`Server responded with ${res.status} ${res.statusText}`)
|
|
}
|
|
|
|
let result = await res.json();
|
|
|
|
if(!result.data){
|
|
throw new Error(`Timetable for ${stop_id.lineId} not found`)
|
|
}
|
|
|
|
return result.data
|
|
}
|
|
|
|
async function getLineDetailsJSON(stop_id){
|
|
let res = await fetch(`/api/interface/tcl/lines/${encodeURIComponent(stop_id.lineId)}`);
|
|
if(!res.ok){
|
|
throw new Error(`Server responded with ${res.status} ${res.statusText}`)
|
|
}
|
|
|
|
let result = await res.json();
|
|
|
|
if(!result.data){
|
|
throw new Error(`Line ${stop_id.lineId} not found`)
|
|
}
|
|
|
|
return result.data
|
|
}
|
|
|
|
function getIconURL(stop_id){
|
|
return new URL(`/api/valkyrie/assets/lines/${stop_id.lineId}.svg?type=image%2Fsvg%2Bxml`, window.location).toString()
|
|
}
|
|
|
|
async function getLineDetails(stop_id){
|
|
let line_json = await getLineDetailsJSON(stop_id)
|
|
|
|
let route = line_json.routes.find(it => it.direction == stop_id.direction)
|
|
|
|
let line = {
|
|
id: stop_id.lineId,
|
|
displayName: route?.name,
|
|
picto: getIconURL(stop_id),
|
|
name: line_json.code,
|
|
direction: route?.name,
|
|
timetable: null
|
|
}
|
|
|
|
return line
|
|
}
|
|
|
|
async function getTimetable(stop_id, date){
|
|
let timetable_json = await getTimetableJSON(stop_id, date)
|
|
|
|
let timetable = []
|
|
for(let scheduled_time of timetable_json.scheduleTimes){
|
|
let time = new Date(scheduled_time.dateTime)
|
|
timetable.push({
|
|
displayHours: time.getHours().toString().padStart(2, "0"),
|
|
displayMinutes: time.getMinutes().toString().padStart(2, "0"),
|
|
displayTime: `${time.getHours().toString().padStart(2, "0")}h${time.getMinutes().toString().padStart(2, "0")}`,
|
|
time
|
|
})
|
|
}
|
|
|
|
return timetable
|
|
}
|
|
|
|
/**
|
|
* Get next Bus/Metro/Tram passage of given stop description
|
|
* @param {String} stop_description Stop description string
|
|
*
|
|
* To get stop description go to https://carte-interactive.tcl.fr/public-transport/lines/
|
|
* then find your line and your stop in this line.
|
|
* Your URL must look like something like this
|
|
* https://carte-interactive.tcl.fr/public-transport/lines/line:SYTNEX:C/forward/stop_point:SYTNEX:10787
|
|
* Stop description is everything after "lines/" ("line:SYTNEX:C/forward/stop_point:SYTNEX:10787" in example above)
|
|
*/
|
|
export async function getNextPassage(stop_description, options = {
|
|
timetable: +2 // Today and tomorrow
|
|
}){
|
|
let stopId = new StopId(stop_description);
|
|
|
|
let proms = [
|
|
getLineDetails(stopId),
|
|
getNextTripJSON(stopId),
|
|
getStopsJSON(stopId),
|
|
Promise.resolve([])
|
|
]
|
|
|
|
let timeTableAmount = options?.timetable || +2;
|
|
if(timeTableAmount){
|
|
for(let dayOffset = 0; dayOffset<timeTableAmount; dayOffset++){
|
|
let now = new Date(Date.now()+(dayOffset*DAY_IN_MS))
|
|
proms.push(await getTimetable(stopId, now))
|
|
}
|
|
}
|
|
|
|
let [line, next_trip, line_stops, ...all_timetables] = await Promise.all(proms);
|
|
|
|
console.log(stopId)
|
|
console.log("line", line)
|
|
console.log("next trip", next_trip)
|
|
console.log("stop", line_stops)
|
|
console.log("timetable", all_timetables)
|
|
|
|
let line_timetables = []
|
|
for(let timetable of all_timetables){
|
|
line_timetables.push(...timetable)
|
|
}
|
|
line.timetable = line_timetables
|
|
|
|
let stop = line_stops.find(it => it.id == stopId.stopId)
|
|
|
|
let nextPassage = {
|
|
line,
|
|
displayName: stop?.name,
|
|
displayTime: "<unsupported>",
|
|
time: next_trip.schedules?.[0] ? new Date(next_trip.schedules?.[0].dateTime) : null
|
|
}
|
|
|
|
return nextPassage
|
|
} |