|
- #!/usr/bin/python3
- import requests
- import sys
- import textwrap
- import pprint
- from pathlib import Path
- try:
- from simplejson.errors import JSONDecodeError
- except ImportError:
- from json.decoder import JSONDecodeError
-
- api = 'http://parkering.linkoping.se/'
- key = Path('key-parking').read_text().strip()
-
- # Fetch JSON from url and run it through transform, pretty printing errors
- # and the data worked on as exhaustively as possible.
- def json_query(url, transform, params={}):
- try:
- result = requests.get(url, params)
- except requests.exceptions.ConnectionError:
- print("Network connection error.")
- sys.exit(1)
- try:
- data = result.json()
- except JSONDecodeError as err:
- print('Error when decoding JSON:\nFrom endpoint ' + url + ':\n' + str(err) + '\n' + str(result) + '\n')
- sys.exit(1)
- try:
- return transform(data)
- except (IndexError, KeyError) as err:
- print('Error when traversing JSON:\nFrom endpoint ' + url + ':\n' + str(err))
- pprint.PrettyPrinter(indent=2).pprint(data)
- sys.exit(1)
-
- # Get parking lots from the municipal server.
- # The timestamp part of this API does not work as expected, if non-zero it will return all computer parking terminal lots
- # in ParkingAreaUpdateList regardless of their status, up to a timestamp of less than one hour into the future, after which it will return nothing.
- def get_parking_lots():
- return json_query(api + 'Parkeringsdata/ParkeringsdataV1.svc/GetParkeringsytaList/' + key + '/0', lambda data: data['ParkingAreaNewList'], {})
-
- # The key ParkingSpacesAvailable is only present for those lots that are tracked by computer parking terminals.
- # All other lots only have static information available.
- def computerized(lot):
- return 'ParkingSpacesAvailable' in lot
-
- # The parking type '4' means handicap spots, whoever organized this put handicap spots as separate lots with duplicate names.
- def only_has_handicap_spots(lot):
- return lot['ParkingTypes'] == [4]
-
- # The downtown parking lots are equipped with electric charging stations and the API has a parking type for this
- # but the lot data has not been updated to reflect this, so this function always returns False.
- def electric_car_lot(lot):
- return 3 in lot['ParkingTypes']
-
- def main():
- print('Parking spaces available:')
- for lot in sorted(get_parking_lots(), key=lambda lot: lot['Name']):
- if computerized(lot) and not only_has_handicap_spots(lot):
- print("{Name}: {ParkingSpacesAvailable}/{ParkingSpaces}".format(**lot))
-
- if __name__ == '__main__':
- main()
|