Spaces:
Sleeping
Sleeping
# coding: utf-8 | |
# Author: Du Mingzhe ([email protected]) | |
# Date: 2025/03/22 | |
import os | |
import json | |
import requests | |
import streamlit as st | |
nextbus_token = os.getenv("NEXTBUS_TOKEN") | |
def wide_space_default(): | |
st.set_page_config(layout='wide') | |
wide_space_default() | |
def get_all_stops(): | |
url = "https://nnextbus.nus.edu.sg/BusStops" | |
payload = {} | |
headers = { | |
'Host': 'nnextbus.nus.edu.sg', | |
'Content-Type': 'application/json', | |
'Connection': 'keep-alive', | |
'Accept': 'application/json', | |
'User-Agent': 'nusnextbusv2/1 CFNetwork/978.0.7 Darwin/18.7.0', | |
'Authorization': nextbus_token, | |
'Accept-Language': 'en-us', | |
'Accept-Encoding': 'br, gzip, deflate' | |
} | |
response = requests.request("GET", url, headers=headers, data=payload) | |
return response.json()["BusStopsResult"]["busstops"] | |
def get_bus_arrival(bus_stop_code): | |
url = f"https://nnextbus.nus.edu.sg/ShuttleService?busstopname={bus_stop_code}" | |
payload = {} | |
headers = { | |
'Host': 'nnextbus.nus.edu.sg', | |
'Content-Type': 'application/json', | |
'Connection': 'keep-alive', | |
'Accept': 'application/json', | |
'User-Agent': 'nusnextbusv2/1 CFNetwork/978.0.7 Darwin/18.7.0', | |
'Authorization': 'Basic TlVTbmV4dGJ1czoxM2RMP3pZLDNmZVdSXiJU', | |
'Accept-Language': 'en-us', | |
'Accept-Encoding': 'br, gzip, deflate' | |
} | |
response = requests.request("GET", url, headers=headers, data=payload) | |
return response.json()['ShuttleServiceResult']['shuttles'] | |
# stops = get_all_stops() | |
stops = [ | |
{ | |
"caption": "COM 3", | |
"name": "COM3", | |
"LongName": "COM 3", | |
"ShortName": "COM 3", | |
"latitude": 1.294431, | |
"longitude": 103.775217 | |
}, | |
{ | |
"caption": "Opp TCOMS", | |
"name": "TCOMS-OPP", | |
"LongName": "Opp TCOMS", | |
"ShortName": "Opp TCOMS", | |
"latitude": 1.293789, | |
"longitude": 103.776715 | |
}, | |
{ | |
"caption": "TCOMS", | |
"name": "TCOMS", | |
"LongName": "TCOMS", | |
"ShortName": "TCOMS", | |
"latitude": 1.293654, | |
"longitude": 103.776898 | |
}, | |
{ | |
"caption": "BIZ 2", | |
"name": "BIZ2", | |
"LongName": "BIZ 2", | |
"ShortName": "BIZ 2", | |
"latitude": 1.293273, | |
"longitude": 103.775074 | |
}, | |
{ | |
"caption": "University Town", | |
"name": "UTOWN", | |
"LongName": "University Town", | |
"ShortName": "UTown", | |
"latitude": 1.303623, | |
"longitude": 103.774388 | |
}, | |
{ | |
"caption": "Prince George's Park", | |
"name": "PGP", | |
"LongName": "Prince George's Park", | |
"ShortName": "PGP", | |
"latitude": 1.291765, | |
"longitude": 103.780419 | |
}, | |
{ | |
"caption": "Prince George's Park Foyer", | |
"name": "PGPR", | |
"LongName": "Prince George's Park Foyer", | |
"ShortName": "PGP Foyer", | |
"latitude": 1.290994, | |
"longitude": 103.781153 | |
}, | |
{ | |
"caption": "Opp Kent Ridge MRT", | |
"name": "KR-MRT-OPP", | |
"LongName": "Opp Kent Ridge MRT", | |
"ShortName": "Opp KR MRT", | |
"latitude": 1.294962, | |
"longitude": 103.784556 | |
}, | |
{ | |
"caption": "Kent Ridge MRT", | |
"name": "KR-MRT", | |
"LongName": "Kent Ridge MRT", | |
"ShortName": "KR MRT", | |
"latitude": 1.29482, | |
"longitude": 103.784413 | |
}, | |
] | |
st.write( | |
""" | |
<style> | |
[data-testid="stMetricDelta"] svg { | |
display: none; | |
} | |
</style> | |
""", | |
unsafe_allow_html=True, | |
) | |
for stop_info in stops: | |
shuttle_info = get_bus_arrival(stop_info['name']) | |
buses = list() | |
for shuttle in shuttle_info: | |
if shuttle["_etas"] is None: continue | |
for bus in shuttle["_etas"]: | |
plate = bus["plate"] | |
eta = bus["eta"] | |
shuttle_name = shuttle['name'] | |
buses.append({ | |
"shuttle_name": shuttle_name, | |
"plate": plate, | |
"eta": eta | |
}) | |
buses.sort(key=lambda x: x["eta"]) | |
with st.container(border=True): | |
cols = st.columns(6) | |
cols[0].metric("Bus Stop", stop_info['name']) | |
for i, bus in enumerate(buses[:5]): | |
cols[i+1].metric(bus['plate'], bus["shuttle_name"], str(bus["eta"])) | |