Skip to content

Commit

Permalink
fix formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
hbruch committed Dec 10, 2023
1 parent 56fac0c commit 792a723
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 41 deletions.
15 changes: 8 additions & 7 deletions new/stuttgart.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ class Stuttgart(DatexScraperMixin, ScraperBase):
In case this information will not be provided soon, the geojson will need to be enhanced manually :-/
"""

POOL = PoolInfo(
id="stuttgart",
name="Stuttgart",
public_url="https://service.mdm-portal.de/mdm-portal-application/publDetail.do?publicationId=3059002",
source_url="https://data.mfdz.de/DATEXII_Parkdaten_dynamisch_Stuttgart/body.xml",
attribution_contributor="Landeshauptstadt Stuttgart, Tiefbauamt, mirrored by MFDZ",
attribution_license="dl-de/by-2-0",
id='stuttgart',
name='Stuttgart',
public_url='https://service.mdm-portal.de/mdm-portal-application/publDetail.do?publicationId=3059002',
source_url='https://data.mfdz.de/DATEXII_Parkdaten_dynamisch_Stuttgart/body.xml',
attribution_contributor='Landeshauptstadt Stuttgart, Tiefbauamt, mirrored by MFDZ',
attribution_license='dl-de/by-2-0',
)

STATIC_LOTS_URL = "https://data.mfdz.de/DATEXII_Parkdaten_statisch_Stuttgart/body.xml"
STATIC_LOTS_URL = 'https://data.mfdz.de/DATEXII_Parkdaten_statisch_Stuttgart/body.xml'

UTM32_PROJ = pyproj.Proj(proj='utm', zone=32, ellps='WGS84', preserve_units=True)

Expand Down
63 changes: 29 additions & 34 deletions util/datex.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,59 @@
from typing import List

from .structs import LotInfo, LotData
from .strings import name_to_legacy_id, guess_lot_type, parse_geojson
from .strings import guess_lot_type, name_to_legacy_id, parse_geojson
from .structs import LotData, LotInfo


class DatexScraperMixin:
"""
This Mixin defines provides an implementation of get_lot_data and
This Mixin defines provides an implementation of get_lot_data and
get_lot_infos that should work with most DATEXII ParkingFacility publications.
Subclasses should provide the dynamic parking facility publication url as POOl.source_url
Subclasses should provide the dynamic parking facility publication url as POOl.source_url
and the static parking facility publication as class variable:
STATIC_LOTS_URL: str
See stuttgart.py for an example.
"""

def get_lot_data(self) -> List[LotData]:
now = self.now()
soup = self.request_soup(self.POOL.source_url, encoding='UTF-8', parser='xml')


last_updated = self.to_utc_datetime(soup.find("publicationTime").text)
last_updated = self.to_utc_datetime(soup.find('publicationTime').text)

lots = []

for facility in soup.select("parkingFacilityTableStatusPublication > parkingFacilityStatus"):
lot_id = facility.find("parkingFacilityReference")["id"]
for facility in soup.select('parkingFacilityTableStatusPublication > parkingFacilityStatus'):
lot_id = facility.find('parkingFacilityReference')['id']

capacity_shorttermoverride = facility.find("totalParkingCapacityShorttermOverride")
capacity_shorttermoverride = facility.find('totalParkingCapacityShorttermOverride')

parkingFacilityStatusTime = facility.find("parkingFacilityStatusTime")
parkingFacilityStatusTime = facility.find('parkingFacilityStatusTime')
try:
lot_timestamp = self.to_utc_datetime(parkingFacilityStatusTime.text) if parkingFacilityStatusTime else last_updated
lot_timestamp = self.to_utc_datetime(parkingFacilityStatusTime.text) if parkingFacilityStatusTime else last_updated
except:
lot_timestamp = last_updated
# TODO: Need not find out difference between
# totalNumberOfOccupiedParkingSpaces and totalNumberOfVacantParkingSpaces
# e.g. first goes to zero or might disappear when closed while second remains
try:
lot_occupied = int(facility.find("totalNumberOfOccupiedParkingSpaces").text)
lot_occupied = int(facility.find('totalNumberOfOccupiedParkingSpaces').text)
except:
lot_occupied = None

try:
lot_free = int(facility.find("totalNumberOfVacantParkingSpaces").text)
lot_free = int(facility.find('totalNumberOfVacantParkingSpaces').text)
except:
lot_free = None

state = facility.find("parkingFacilityStatus")
state = facility.find('parkingFacilityStatus')

if state and state.text in [LotData.Status.open, LotData.Status.closed]:
state = state.text
elif state and state.text == "spacesAvailable":
elif state and state.text == 'spacesAvailable':
state = LotData.Status.open
else:
state = LotData.Status.nodata
Expand All @@ -74,19 +75,19 @@ def get_lot_data(self) -> List[LotData]:
def get_lot_infos(self) -> List[LotInfo]:
url = self.STATIC_LOTS_URL
soup = self.request_soup(url, encoding='UTF-8', parser='xml')

lots = []
for facility in soup.find_all("parkingFacility"):
for facility in soup.find_all('parkingFacility'):
coord = self._get_facility_coords(facility)
lots.append(
LotInfo(
id=name_to_legacy_id(self.POOL.id, facility["id"]),
id=name_to_legacy_id(self.POOL.id, facility['id']),
name=self._get_facility_name(facility),
type=LotInfo.Types.unknown, # there's no data
source_url=self.POOL.source_url,
latitude=coord["latitude"] if coord else None,
longitude=coord["longitude"] if coord else None,
capacity=int(facility.find("totalParkingCapacity").text),
latitude=coord['latitude'] if coord else None,
longitude=coord['longitude'] if coord else None,
capacity=int(facility.find('totalParkingCapacity').text),
has_live_capacity=True,
)
)
Expand All @@ -95,28 +96,22 @@ def get_lot_infos(self) -> List[LotInfo]:

def _get_facility_name(self, facility):
# Try name (used by Stuttgart)
pfname = facility.select_one("parkingFacilityName > values > value")
pfname = facility.select_one('parkingFacilityName > values > value')
if pfname:
return pfname.text

# If not, try parkingfacilitydescription (as (misused?) by Frankfurt)
dfdesc = facility.find("parkingfacilitydescription")
dfdesc = facility.find('parkingfacilitydescription')
if dfdesc:
return dfdesc.text

return None

def _get_facility_coords(self, facility):


point = facility.find("pointCoordinates")
point = facility.find('pointCoordinates')
if not point:
point = facility.find("locationForDisplay")
point = facility.find('locationForDisplay')
if not point:
return None

else:
return {
"latitude": float(point.find("latitude").text),
"longitude": float(point.find("longitude").text)
}

return {'latitude': float(point.find('latitude').text), 'longitude': float(point.find('longitude').text)}

0 comments on commit 792a723

Please sign in to comment.