Modification de l'URL des infos de passage

L'identifiant de ligne est maintenant requis à la fin de l'URL.
Cette information n'étant pas utile auparavent, j'ai donc ajouté sa récupération et son stockage.
This commit is contained in:
Sasha MOREL 2023-08-26 11:33:49 +02:00
parent c2d3dab3ee
commit e81da464e5
9 changed files with 372 additions and 368 deletions

View File

@ -5,39 +5,39 @@ from stop_route import StopRoute
from datetime import datetime from datetime import datetime
if __name__ == "__main__": if __name__ == '__main__':
for word in sys.argv[1:]: for word in sys.argv [1:]:
for area in get_stop_areas_by_name(word): for area in get_stop_areas_by_name (word):
stop = get_stop_by_id(area.getId()) stop = get_stop_by_id (area.getId ())
for stopPoint in stop.getStopPoints(): for stopPoint in stop.getStopPoints ():
for route in stopPoint.getRoutes(): for route in stopPoint.getRoutes ():
if "Tram" in route.getLineName(): if 'Tram' in route.getLineName ():
stopRoute = StopRoute(stopPoint.getId(), route.getId()) stopRoute = StopRoute (stopPoint.getId (), route.getId (), route.getLineId ())
line = stopRoute.get_line() line = stopRoute.get_line ()
for vehicule in line.get_vehicles(): for vehicule in line.get_vehicles ():
v = line.get_vehicle(vehicule) v = line.get_vehicle (vehicule)
if v.getRealtime(): if v.getRealtime ():
print( print (
str(v.getWaitTimeText()) str (v.getWaitTimeText ())
+ " (" + ' ('
+ datetime.fromtimestamp(v.getArrival()).strftime( + datetime.fromtimestamp (v.getArrival ()).strftime (
"%H:%M" '%H:%M'
) )
+ ") → " + ') → '
+ v.getDestination() + v.getDestination ()
+ ", Curr location: " + ', Curr location: '
+ str(v.getLocation()) + str (v.getLocation ())
) )
else: else:
print( print (
"~" '~'
+ str(v.getWaitTimeText()) + str (v.getWaitTimeText ())
+ " (" + ' ('
+ datetime.fromtimestamp(v.getArrival()).strftime( + datetime.fromtimestamp (v.getArrival ()).strftime (
"%H:%M" '%H:%M'
) )
+ ") → " + ') → '
+ v.getDestination() + v.getDestination ()
+ ", Curr location: " + ', Curr location: '
+ str(v.getLocation()) + str (v.getLocation ())
) )

View File

@ -1,23 +1,27 @@
class Route: class Route:
def __init__(self, name, line_name): def __init__ (self, line_id, name, line_name):
self.id = None self.id = None
self.name = name self.name = name
self.line_name = line_name self.line_name = line_name
self.line_id = line_id
def getId(self): def getId (self):
return self.id return self.id
def getName(self): def getName (self):
return self.name return self.name
def getLineName(self): def getLineName (self):
return self.line_name return self.line_name
def setId(self, id): def getLineId (self):
return self.line_id
def setId (self, id):
self.id = id self.id = id
def __repr__(self): def __repr__ (self):
return self.name + " (" + self.line_name + ")" return self.name + ' (' + self.line_name + ')'
def __str__(self): def __str__ (self):
return self.name + " (" + self.line_name + ")" return self.name + ' (' + self.line_name + ')'

View File

@ -5,29 +5,29 @@ from re import search
from route import Route from route import Route
INFO_URL = "https://ws.infotbm.com/ws/1.0/network/stoparea-informations/%s" INFO_URL = 'https://ws.infotbm.com/ws/1.0/network/stoparea-informations/%s'
LINE_TRANSLATE = { LINE_TRANSLATE = {
"Tram A": "A", 'Tram A': 'A',
"Tram B": "B", 'Tram B': 'B',
"Tram C": "C", 'Tram C': 'C',
"Tram D": "D", 'Tram D': 'D',
"TBNight": "58", 'TBNight': '58',
"BAT3": "69", 'BAT3': '69',
} }
LINE_TYPES = ( LINE_TYPES = (
"Tram", 'Tram',
"Corol", 'Corol',
"Lianes", 'Lianes',
"Ligne", 'Ligne',
"Bus Relais", 'Bus Relais',
"Citéis", 'Citéis',
) )
class Stop: class Stop:
def __init__(self, id, name, latitude, longitude, city): def __init__ (self, id, name, latitude, longitude, city):
self.id = id self.id = id
self.name = name self.name = name
self.latitude = latitude self.latitude = latitude
@ -35,70 +35,70 @@ class Stop:
self.city = city self.city = city
self.stopPoints = [] self.stopPoints = []
def getId(self): def getId (self):
return self.id return self.id
def getName(self): def getName (self):
return self.name return self.name
def getLatitude(self): def getLatitude (self):
return self.latitude return self.latitude
def getLongitude(self): def getLongitude (self):
return self.longitude return self.longitude
def getCity(self): def getCity (self):
return self.city return self.city
def getStopPoints(self): def getStopPoints (self):
return self.stopPoints return self.stopPoints
def setStopPoints(self, stopPoints): def setStopPoints (self, stopPoints):
self.stopPoints = stopPoints self.stopPoints = stopPoints
def __repr__(self): def __repr__ (self):
return self.name + " (" + self.city + ")" + " (id: " + self.id + ")" return self.name + ' (' + self.city + ')' + ' (id: ' + self.id + ')'
def __str__(self): def __str__ (self):
return self.name + " (" + self.city + ")" + " (id: " + self.id + ")" return self.name + ' (' + self.city + ')' + ' (id: ' + self.id + ')'
def get_stop_by_id(id): def get_stop_by_id (id):
data = get_data_from_json(INFO_URL % quote(id)) data = get_data_from_json (INFO_URL % quote (id))
stop = Stop( stop = Stop (
data["id"], data ['id'],
data["name"], data ['name'],
float(data["latitude"]), float (data ['latitude']),
float(data["longitude"]), float (data ['longitude']),
data["city"], data ['city'],
) )
stopPoints = [] stopPoints = []
for i in data["stopPoints"]: for i in data ['stopPoints']:
stopPoint = StopPoint(i["name"]) stopPoint = StopPoint (i ['name'])
routes = [] routes = []
stopPoint.setId(int(search("[0-9]+$", i["id"]).group())) stopPoint.setId (int (search ('[0-9]+$', i ['id']).group ()))
for j in i["routes"]: for j in i ['routes']:
route = Route(j["name"], j["line"]["name"]) route = Route (j ['id'], j ['name'], j ['line'] ['name'])
add = False add = False
if route.getLineName() in LINE_TRANSLATE: if route.getLineName () in LINE_TRANSLATE:
line_id = LINE_TRANSLATE[route.getLineName()] line_id = LINE_TRANSLATE [route.getLineName ()]
add = True add = True
else: else:
try: try:
line_id = search("[0-9]+$", route.getLineName()).group() line_id = search ('[0-9]+$', route.getLineName ()).group ()
except AttributeError: except AttributeError:
continue continue
line_id = "%02d" % int(line_id) line_id = '%02d' % int (line_id)
for i in LINE_TYPES: for i in LINE_TYPES:
if route.getLineName()[0 : len(i)] == i: if route.getLineName () [0:len (i)] == i:
add = True add = True
break break
if add: if add:
route.setId(line_id) route.setId (line_id)
routes.append(route) routes.append (route)
stopPoint.setRoutes(routes) stopPoint.setRoutes (routes)
if stopPoint.getRoutes() != []: if stopPoint.getRoutes () != []:
stopPoints.append(stopPoint) stopPoints.append (stopPoint)
stop.setStopPoints(stopPoints) stop.setStopPoints (stopPoints)
return stop return stop

View File

@ -2,36 +2,36 @@ from utils import get_data_from_json
from urllib.parse import quote from urllib.parse import quote
STOP_URL = "https://ws.infotbm.com/ws/1.0/get-schedule/%s" STOP_URL = 'https://ws.infotbm.com/ws/1.0/get-schedule/%s'
class StopArea: class StopArea:
def __init__(self, id, name, city): def __init__ (self, id, name, city):
self.id = id self.id = id
self.name = name self.name = name
self.city = city self.city = city
def getId(self): def getId (self):
return self.id return self.id
def getName(self): def getName (self):
return self.name return self.name
def getCity(self): def getCity (self):
return self.city return self.city
def __repr__(self): def __repr__ (self):
return self.name + " (" + self.city + ")" + " (id: " + self.id + ")" return self.name + ' (' + self.city + ')' + ' (id: ' + self.id + ')'
def __str__(self): def __str__ (self):
return self.name + " (" + self.city + ")" + " (id: " + self.id + ")" return self.name + ' (' + self.city + ')' + ' (id: ' + self.id + ')'
# we on only treat stops of type "stop_area" # we on only treat stops of type "stop_area"
def get_stop_areas_by_name(keyword): def get_stop_areas_by_name (keyword):
data = get_data_from_json(STOP_URL % quote(keyword)) data = get_data_from_json (STOP_URL % quote (keyword))
stopAreas = [] stopAreas = []
for s in data: for s in data:
if s["type"] == "stop_area": if s ['type'] == 'stop_area':
stopAreas.append(StopArea(s["id"], s["name"], s["city"])) stopAreas.append (StopArea (s ['id'], s ['name'], s ['city']))
return stopAreas return stopAreas

View File

@ -1,26 +1,26 @@
class StopPoint: class StopPoint:
def __init__(self, name): def __init__ (self, name):
self.id = None self.id = None
self.name = name self.name = name
self.routes = [] self.routes = []
def getId(self): def getId (self):
return self.id return self.id
def getName(self): def getName (self):
return self.name return self.name
def getRoutes(self): def getRoutes (self):
return self.routes return self.routes
def setId(self, id): def setId (self, id):
self.id = id self.id = id
def setRoutes(self, routes): def setRoutes (self, routes):
self.routes = routes self.routes = routes
def __repr__(self): def __repr__ (self):
return self.name return self.name
def __str__(self): def __str__ (self):
return self.name return self.name

View File

@ -3,86 +3,87 @@ from time import time
from vehicle import Vehicle from vehicle import Vehicle
SCHEDULE_URL = "https://ws.infotbm.com/ws/1.0/get-realtime-pass/%d/%s" SCHEDULE_URL = 'https://ws.infotbm.com/ws/1.0/get-realtime-pass/%d/%s/%s'
class Line: class Line:
""" '''
Information on the line served at a stop. Information on the line served at a stop.
""" '''
def __init__(self, vehicles): def __init__ (self, vehicles):
self.vehicles = vehicles self.vehicles = vehicles
def get_vehicles(self): def get_vehicles (self):
if self.vehicles is not None: if self.vehicles is not None:
return list(range(0, len(self.vehicles))) return list (range (0, len (self.vehicles)))
return [] return []
def get_vehicle(self, vehicle_id): def get_vehicle (self, vehicle_id):
return self.vehicles[vehicle_id] return self.vehicles [vehicle_id]
class StopRoute: class StopRoute:
def __init__( def __init__ (
self, self,
number, number,
line, line,
auto_update_at_creation=True, line_id,
auto_update=False, auto_update_at_creation = True,
auto_update_delay=-1, auto_update = False,
auto_update_delay = -1,
): ):
self.number = number self.number = number
self.line = line self.line = line
self.line_id = line_id
self.last_update = 0 self.last_update = 0
self.data = None self.data = None
if auto_update_at_creation: if auto_update_at_creation:
self.update() self.update ()
def update(self, auto=False): def update (self, auto = False):
""" '''
Update data. Update data.
""" '''
data = get_data_from_json(SCHEDULE_URL % (self.number, self.line)) data = get_data_from_json (SCHEDULE_URL % (self.number, self.line, self.line_id))
if "destinations" in data: if 'destinations' in data:
data = data["destinations"] data = data ['destinations']
else: else:
return return
self.last_update = time() self.last_update = time ()
if type(data) == dict: if type (data) == dict:
self.data = [] self.data = []
# let's simplify the data
for i in data: for i in data:
for j in data[i]: for j in data [i]:
location = None location = None
try: try:
location = ( location = (
float(j["vehicle_lattitude"]), float (j ['vehicle_lattitude']),
float(j["vehicle_longitude"]), float (j ['vehicle_longitude']),
) )
except TypeError: except TypeError:
pass pass
vehicle = Vehicle( vehicle = Vehicle (
j["vehicle_id"], j ['vehicle_id'],
j["destination_name"], j ['destination_name'],
j["realtime"] == "1", j ['realtime'] == '1',
location, location,
hms2seconds(j["waittime"]), hms2seconds (j ['waittime']),
j["waittime_text"], j ['waittime_text'],
int(self.last_update + hms2seconds(j["waittime"])), int (self.last_update + hms2seconds (j ['waittime'])),
) )
self.data.append(vehicle) self.data.append (vehicle)
self.data = sorted(self.data, key=lambda vehicle: vehicle.getArrival()) self.data = sorted (self.data, key = lambda vehicle: vehicle.getArrival ())
else: else:
self.last_update = 0 self.last_update = 0
def data_age(self): def data_age (self):
""" '''
Returns the age of the data. Returns the age of the data.
""" '''
return time() - self.last_update return time () - self.last_update
def get_line(self): def get_line (self):
return Line(self.data) return Line (self.data)

View File

@ -3,26 +3,26 @@ from urllib import request
from urllib.error import HTTPError from urllib.error import HTTPError
def get_data_from_json(url): def get_data_from_json (url):
""" '''
Gets data from json at url. Gets data from json at url.
""" '''
opener = request.build_opener() opener = request.build_opener ()
try: try:
return read_json(opener.open(url).read().decode("utf8")) return read_json (opener.open (url).read ().decode ('utf8'))
except HTTPError: except HTTPError:
return None return None
def hms2seconds(hhmmss): def hms2seconds (hhmmss):
""" '''
Convert H:M:S string to time in seconds. Convert H:M:S string to time in seconds.
""" '''
try: try:
cut_string = hhmmss.split(":") cut_string = hhmmss.split (':')
cut_time = (int(cut_string[0]), int(cut_string[1]), int(cut_string[2])) cut_time = (int (cut_string [0]), int (cut_string [1]), int (cut_string [2]))
return 3600 * cut_time[0] + 60 * cut_time[1] + cut_time[2] return 3600 * cut_time [0] + 60 * cut_time [1] + cut_time [2]
except (IndexError, ValueError, TypeError): except (IndexError, ValueError, TypeError):
return None return None

View File

@ -6,109 +6,108 @@ from utils import get_data_from_json
from time import time from time import time
vcub_url = "https://ws.infotbm.com/ws/1.0/vcubs" vcub_url = 'https://ws.infotbm.com/ws/1.0/vcubs'
class Vcub: class Vcub:
""" '''
Retrieves information from stations. Retrieves information from stations.
""" '''
def __init__( def __init__ (
self, self,
autoupdate_at_creation=None, autoupdate_at_creation = None,
autoupdate=False, autoupdate = False,
autoupdate_delay=-1, autoupdate_delay = -1,
data=None, data = None,
): ):
self.last_update = 0 self.last_update = 0
if type(data) == dict: if type (data) == dict:
self.data = self.update(data=data) self.data = self.update (data = data)
else: else:
self.data = None self.data = None
if autoupdate_at_creation or ( if autoupdate_at_creation or (
autoupdate_at_creation is None and self.data is None autoupdate_at_creation is None and self.data is None
): ):
self.update() self.update ()
def update(self, auto=False, data=None): def update (self, auto = False, data = None):
""" '''
Updates data. Updates data.
""" '''
if data is None or type(data) != dict: if data is None or type (data) != dict:
d = get_data_from_json(vcub_url) d = get_data_from_json (vcub_url)
else: else:
d = data d = data
# the original format is awfull, so I change it a little if type (d) == dict:
if type(d) == dict:
self.data = {} self.data = {}
d = d["lists"] d = d ['lists']
for i in d: for i in d:
e = { e = {
"name": i["name"], 'name': i ['name'],
"online": i["connexionState"] == "CONNECTEE", 'online': i ['connexionState'] == 'CONNECTEE',
"plus": i["typeVlsPlus"] == "VLS_PLUS", 'plus': i ['typeVlsPlus'] == 'VLS_PLUS',
"empty": int(i["nbPlaceAvailable"]), 'empty': int (i ['nbPlaceAvailable']),
"bikes": int(i["nbBikeAvailable"]), 'bikes': int (i ['nbBikeAvailable']),
"ebikes": int(i["nbElectricBikeAvailable"]), 'ebikes': int (i ['nbElectricBikeAvailable']),
"location": (float(i["latitude"]), float(i["longitude"])), 'location': (float (i ['latitude']), float (i ['longitude'])),
} }
self.data[int(i["id"])] = e self.data [int (i ['id'])] = e
self.last_update = time() self.last_update = time ()
def data_age(self): def data_age (self):
""" '''
Computes the data's age. Computes the data's age.
""" '''
return time() - self.last_update return time () - self.last_update
def get_names(self): def get_names (self):
""" '''
Returns all names in a dict with id as data. Returns all names in a dict with id as data.
""" '''
r = {} r = {}
for i in self.data: for i in self.data:
r[self.data[i]["name"]] = i r [self.data [i] ['name']] = i
return r return r
def get_locations(self): def get_locations (self):
""" '''
Returns all locations in a dict with id as data. Returns all locations in a dict with id as data.
""" '''
r = {} r = {}
for i in self.data: for i in self.data:
r[self.data[i]["location"]] = i r [self.data [i] ["location"]] = i
return r return r
def get_by_id(self, id): def get_by_id (self, id):
""" '''
Returns a station by its id. Returns a station by its id.
""" '''
class Station: class Station:
""" '''
A station A station
""" '''
def __init__(self, data, id): def __init__ (self, data, id):
self.data = data self.data = data
self.id = id self.id = id
self.name = self.data["name"] self.name = self.data ['name']
self.location = self.data["location"] self.location = self.data ['location']
self.online = self.data["online"] self.online = self.data ['online']
self.isplus = self.data["plus"] self.isplus = self.data ['plus']
self.bikes = self.data["bikes"] self.bikes = self.data ['bikes']
self.ebikes = self.data["ebikes"] self.ebikes = self.data ['ebikes']
self.empty = self.data["empty"] self.empty = self.data ['empty']
def __int__(self): def __int__ (self):
return self.id return self.id
return Station(self.data[id], id) return Station (self.data [id], id)
def get_all_ids(self): def get_all_ids (self):
return tuple(self.data.keys()) return tuple (self.data.keys ())

View File

@ -1,5 +1,5 @@
class Vehicle: class Vehicle:
def __init__( def __init__ (
self, id, destination, realtime, location, wait_time, wait_time_text, arrival self, id, destination, realtime, location, wait_time, wait_time_text, arrival
): ):
self.id = id self.id = id
@ -10,23 +10,23 @@ class Vehicle:
self.wait_time_text = wait_time_text self.wait_time_text = wait_time_text
self.arrival = arrival self.arrival = arrival
def getId(self): def getId (self):
return self.id return self.id
def getDestination(self): def getDestination (self):
return self.destination return self.destination
def getRealtime(self): def getRealtime (self):
return self.realtime return self.realtime
def getLocation(self): def getLocation (self):
return self.location return self.location
def getWaitTime(self): def getWaitTime (self):
return self.wait_time return self.wait_time
def getWaitTimeText(self): def getWaitTimeText (self):
return self.wait_time_text return self.wait_time_text
def getArrival(self): def getArrival (self):
return self.arrival return self.arrival