diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..eba1110 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c444a7f --- /dev/null +++ b/.gitignore @@ -0,0 +1,123 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..654f538 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2020 Klaas Schoute + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..44fe56a --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +## Python API fetching latest parkinggarages numbers in Amsterdam. \ No newline at end of file diff --git a/garagesamsterdam/__init__.py b/garagesamsterdam/__init__.py new file mode 100644 index 0000000..baaa0b9 --- /dev/null +++ b/garagesamsterdam/__init__.py @@ -0,0 +1,82 @@ +"""Fetch latest parking garage information from Amsterdam.""" +from aiohttp import ClientSession, ClientResponseError +from dataclasses import dataclass +import logging + +@dataclass +class AmsterdamCase: + """Class for garages Amsterdam""" + + URL = "http://opd.it-t.nl/data/amsterdam/ParkingLocation.json" + NAME = "Garages Amsterdam" + + id: str + garageName: str + state: str + freeSpaceShort: int + freeSpaceLong: int + shortCapacity: int + longCapacity: int + + @staticmethod + def from_json(item): + attrs = item["properties"] + id = item + return AmsterdamCase( + id=id["Id"], + garageName=correctName(attrs["Name"]), + state=attrs["State"], + freeSpaceShort=attrs["FreeSpaceShort"], + freeSpaceLong=attrs["FreeSpaceLong"], + shortCapacity=attrs["ShortCapacity"], + longCapacity=attrs["LongCapacity"], + ) + +DEFAULT_SOURCE = AmsterdamCase + +def correctName(name): + """Change parking garage name for consistency if needed.""" + filter = ["CE-","ZD-","ZO-","ZU-"] + corrections = ["P1 ", "P3 "] + + if any(x in name for x in filter): + name = name[3:] + if any(y in name for y in corrections): + return name[:1] + '0' + name[1:] + else: + return name + else: + return name + +async def get_cases(session: ClientSession, *, source=DEFAULT_SOURCE): + """Fetch parking garage data.""" + resp = await session.get(source.URL) + data = await resp.json(content_type=None) + + if 'error' in data: + raise ClientResponseError( + resp.request_info, + resp.history, + status=data['error']['code'], + message=data['error']['message'], + headers=resp.headers + ) + + results = [] + wrongKeys = ['FP','Fiets'] + + # results = [ + # source.from_json(item) + # for item in data["features"] + # if not any(x in item["properties"]["Name"] for x in wrongKeys) + # ] + + for item in data["features"]: + try: + if not any(x in item["properties"]["Name"] for x in wrongKeys): + results.append(source.from_json(item)) + except KeyError: + logging.getLogger(__name__).warning("Got wrong data: %s", item) + + # print(results) + return results \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..4b59dda --- /dev/null +++ b/setup.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +"""The setup script""" +import os +import re +import sys + +from setuptools import find_packages, setup + +def read(*parts): + """Read file.""" + filename = os.path.join(os.path.abspath(os.path.dirname(__file__)), *parts) + sys.stdout.write(filename) + with open(filename, encoding="utf-8", mode="rt") as fp: + return fp.read() + +with open("README.md") as readme_file: + readme = readme_file.read() + +setup( + author="Klaas Schoute", + author_email="hello@student-techlife.com", + classifiers=[ + "Framework :: AsyncIO", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3", + "Topic :: Software Development :: Libraries :: Python Modules", + ], + description="Asynchronous Python client for getting garage occupancy in Amsterdam", + include_package_data=True, + install_requires=["aiohttp>=3.0.0"], + keywords=["garages", "amsterdam", "occupancy", "api", "async", "client"], + license="MIT license", + long_description_content_type="text/markdown", + long_description=readme, + name="garagesamsterdam", + packages=find_packages(include=["garagesamsterdam"]), + url="https://github.com/klaasnicolaas/garagesamsterdam", + version="1.0.0", + zip_safe=False, +) \ No newline at end of file