1 Commits

Author SHA1 Message Date
ae9b547426 Update dependency black to v23.12.1
Some checks failed
Tests / test (3.11) (pull_request) Has been cancelled
Tests / test (3.8) (pull_request) Has been cancelled
Tests / test (3.9) (pull_request) Has been cancelled
Tests / test (3.10) (pull_request) Has been cancelled
2024-03-26 15:30:23 +02:00
32 changed files with 84 additions and 177 deletions

View File

@@ -11,11 +11,11 @@ on:
jobs: jobs:
test: test:
runs-on: ubuntu-latest-de runs-on: ubuntu-latest
container: catthehacker/ubuntu:act-latest container: catthehacker/ubuntu:act-latest
strategy: strategy:
matrix: matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"] python-version: ["3.8", "3.9", "3.10", "3.11"]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

1
.gitignore vendored
View File

@@ -154,7 +154,6 @@ cython_debug/
# Custom # Custom
.mise.toml
.vscode/ .vscode/
.venv_linux/ .venv_linux/
.venv_windows/ .venv_windows/

View File

@@ -3,15 +3,6 @@
"extends": [ "extends": [
"config:base" "config:base"
], ],
"baseBranches": [
"dev"
],
"pip_requirements": {
"fileMatch": [
"requirements/.*\\.txt$"
],
"enabled": true
},
"packageRules": [ "packageRules": [
{ {
"matchUpdateTypes": [ "matchUpdateTypes": [

View File

@@ -10,7 +10,7 @@ Small module that makes your journey with RMV REST API somehow easier. Based ful
## Requirements ## Requirements
* RMV API key (Get it [here](https://opendata.rmv.de/site/start.html)) * RMV API key (Get it [here](https://opendata.rmv.de/site/start.html))
* Python 3.9+ * Python 3.8+
* git (Only for installation from source) * git (Only for installation from source)
## Installation ## Installation

View File

@@ -9,18 +9,18 @@ authors = [{ name = "Profitroll", email = "profitroll@end-play.xyz" }]
maintainers = [{ name = "Profitroll", email = "profitroll@end-play.xyz" }] maintainers = [{ name = "Profitroll", email = "profitroll@end-play.xyz" }]
description = "Small module that makes your journey with RMV REST API somehow easier." description = "Small module that makes your journey with RMV REST API somehow easier."
readme = "README.md" readme = "README.md"
requires-python = ">=3.9" requires-python = ">=3.8"
license = { text = "MIT" } license = { text = "GPL3" }
classifiers = [ classifiers = [
"Development Status :: 3 - Alpha", "Development Status :: 3 - Alpha",
"Intended Audience :: Developers", "Intended Audience :: Developers",
"License :: OSI Approved :: MIT License", "License :: OSI Approved :: MIT License",
"Operating System :: OS Independent", "Operating System :: OS Independent",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Utilities", "Topic :: Utilities",
] ]
@@ -38,14 +38,13 @@ dependencies = { file = "requirements/_.txt" }
[tool.setuptools.dynamic.optional-dependencies] [tool.setuptools.dynamic.optional-dependencies]
dev = { file = "requirements/dev.txt" } dev = { file = "requirements/dev.txt" }
dist = { file = "requirements/dist.txt" }
speed = { file = "requirements/speed.txt" } speed = { file = "requirements/speed.txt" }
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
where = ["src"] where = ["src"]
[tool.black] [tool.black]
target-version = ['py39', 'py310', 'py311', 'py312'] target-version = ['py38', 'py39', 'py310', 'py311']
line-length = 94 line-length = 94
[tool.isort] [tool.isort]
@@ -65,7 +64,7 @@ show_error_codes = true
[tool.pylint.main] [tool.pylint.main]
extension-pkg-whitelist = ["ujson"] extension-pkg-whitelist = ["ujson"]
py-version = 3.9 py-version = 3.8
[tool.coverage.run] [tool.coverage.run]
source = ["pyrmv"] source = ["pyrmv"]

View File

@@ -1,3 +1,3 @@
requests~=2.32.3 requests~=2.31.0
xmltodict~=0.14.0 xmltodict~=0.13.0
isodate~=0.7.0 isodate~=0.6.1

View File

@@ -1,12 +1,12 @@
black~=25.1.0 black==23.12.1
isort==5.13.2 build==1.0.3
mypy~=1.15.0 isort==5.12.0
pylint==3.3.7,<3.4.0 mypy==1.7.0
pytest-cov~=6.1.0 pylint==3.0.2
pytest~=8.3.2 pytest-asyncio==0.22.0
tox==4.25.0 pytest-cov==4.1.0
types-ujson~=5.10.0.20240515 pytest==7.4.4
tox==4.11.3
# Disabled async libraries for now twine==4.0.2
# types-aiofiles~=24.1.0.20240626 types-aiofiles==23.2.0.20240311
# pytest-asyncio~=0.24.0 types-ujson==5.8.0.1

View File

@@ -1,2 +0,0 @@
build==1.2.2.post1
twine~=6.1.0

View File

@@ -1 +1 @@
ujson~=5.10.0 ujson~=5.8.0

View File

@@ -21,7 +21,7 @@ trip = client.trip_find(origin_id=origin.id, dest_id=destination.id)
""" """
__name__ = "pyrmv" __name__ = "pyrmv"
__version__ = "0.5.0" __version__ = "0.4.0-rc.2"
__license__ = "MIT License" __license__ = "MIT License"
__author__ = "Profitroll" __author__ = "Profitroll"

View File

@@ -3,7 +3,6 @@ from .gis import Gis
from .journey import Journey from .journey import Journey
from .leg import Leg from .leg import Leg
from .message import Channel, Message, Url from .message import Channel, Message, Url
from .platform_type import PlatformType
from .stop import Stop, StopTrip from .stop import Stop, StopTrip
from .ticket import Ticket from .ticket import Ticket
from .trip import Trip from .trip import Trip

View File

@@ -1,10 +1,10 @@
from datetime import datetime from datetime import datetime
from typing import Any, List, Mapping, Union from typing import Any, List, Mapping, Union
from ..classes.journey import Journey from pyrmv.classes.journey import Journey
from ..classes.message import Message from pyrmv.classes.message import Message
from ..classes.stop import Stop from pyrmv.classes.stop import Stop
from ..utility import ref_upgrade from pyrmv.utility import ref_upgrade
class LineArrival: class LineArrival:

View File

@@ -1,7 +1,7 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, OrderedDict, Union from typing import List, OrderedDict, Union
from ..classes import ( from pyrmv.classes import (
BoardArrival, BoardArrival,
BoardDeparture, BoardDeparture,
Journey, Journey,
@@ -10,7 +10,7 @@ from ..classes import (
StopTrip, StopTrip,
Trip, Trip,
) )
from ..enums import ( from pyrmv.enums import (
AffectedJourneyMode, AffectedJourneyMode,
AffectedJourneyStopMode, AffectedJourneyStopMode,
BoardArrivalType, BoardArrivalType,
@@ -22,15 +22,15 @@ from ..enums import (
SearchMode, SearchMode,
SelectionMode, SelectionMode,
) )
from ..raw import board_arrival as raw_board_arrival from pyrmv.raw import board_arrival as raw_board_arrival
from ..raw import board_departure as raw_board_departure from pyrmv.raw import board_departure as raw_board_departure
from ..raw import him_search as raw_him_search from pyrmv.raw import him_search as raw_him_search
from ..raw import journey_detail as raw_journey_detail from pyrmv.raw import journey_detail as raw_journey_detail
from ..raw import stop_by_coords as raw_stop_by_coords from pyrmv.raw import stop_by_coords as raw_stop_by_coords
from ..raw import stop_by_name as raw_stop_by_name from pyrmv.raw import stop_by_name as raw_stop_by_name
from ..raw import trip_find as raw_trip_find from pyrmv.raw import trip_find as raw_trip_find
from ..raw import trip_recon as raw_trip_recon from pyrmv.raw import trip_recon as raw_trip_recon
from ..utility import find_exception from pyrmv.utility import find_exception
try: try:
from typing import Literal from typing import Literal
@@ -150,7 +150,7 @@ class Client:
boardType=board_type.code, boardType=board_type.code,
) )
find_exception(board_raw.copy()) find_exception(board_raw)
return BoardArrival( return BoardArrival(
board_raw, board_raw,
@@ -219,7 +219,7 @@ class Client:
boardType=board_type.code, boardType=board_type.code,
) )
find_exception(board_raw.copy()) find_exception(board_raw)
return BoardDeparture( return BoardDeparture(
board_raw, board_raw,
@@ -343,7 +343,7 @@ class Client:
minprio=priority_min, minprio=priority_min,
) )
find_exception(messages_raw.copy()) find_exception(messages_raw)
if "Message" in messages_raw: if "Message" in messages_raw:
messages.extend(Message(message) for message in messages_raw["Message"]) messages.extend(Message(message) for message in messages_raw["Message"])
@@ -402,7 +402,7 @@ class Client:
toIdx=to_index, toIdx=to_index,
) )
find_exception(journey_raw.copy()) find_exception(journey_raw)
return Journey(journey_raw) return Journey(journey_raw)
@@ -481,7 +481,7 @@ class Client:
locationSelectionMode=selection_mode, # type: ignore locationSelectionMode=selection_mode, # type: ignore
) )
find_exception(stops_raw.copy()) find_exception(stops_raw)
if "stopLocationOrCoordLocation" in stops_raw: if "stopLocationOrCoordLocation" in stops_raw:
for stop in stops_raw["stopLocationOrCoordLocation"]: for stop in stops_raw["stopLocationOrCoordLocation"]:
@@ -536,7 +536,7 @@ class Client:
accessId=self.access_id, inputString=query, lang=lang.code, maxNo=1 accessId=self.access_id, inputString=query, lang=lang.code, maxNo=1
) )
find_exception(stops_raw.copy()) find_exception(stops_raw)
if len(stops_raw["stopLocationOrCoordLocation"]) <= 0: if len(stops_raw["stopLocationOrCoordLocation"]) <= 0:
return None return None
@@ -642,7 +642,7 @@ class Client:
filterMode=filter_mode.code, filterMode=filter_mode.code,
) )
find_exception(stops_raw.copy()) find_exception(stops_raw)
if "stopLocationOrCoordLocation" in stops_raw: if "stopLocationOrCoordLocation" in stops_raw:
for stop in stops_raw["stopLocationOrCoordLocation"]: for stop in stops_raw["stopLocationOrCoordLocation"]:
@@ -833,7 +833,7 @@ class Client:
withFreq=frequency, withFreq=frequency,
) )
find_exception(trips_raw.copy()) find_exception(trips_raw)
if "Trip" in trips_raw: if "Trip" in trips_raw:
trips.extend(Trip(trip) for trip in trips_raw["Trip"]) trips.extend(Trip(trip) for trip in trips_raw["Trip"])
@@ -913,7 +913,7 @@ class Client:
trafficMessages=messages, trafficMessages=messages,
) )
find_exception(trips_raw.copy()) find_exception(trips_raw)
if "Trip" in trips_raw: if "Trip" in trips_raw:
trips.extend(Trip(trip) for trip in trips_raw["Trip"]) trips.extend(Trip(trip) for trip in trips_raw["Trip"])

View File

@@ -1,8 +1,8 @@
from typing import Any, List, Mapping, Union from typing import Any, List, Mapping, Union
from ..classes.message import Message from pyrmv.classes.message import Message
from ..classes.stop import Stop from pyrmv.classes.stop import Stop
from ..utility import ref_upgrade from pyrmv.utility import ref_upgrade
class Journey: class Journey:

View File

@@ -3,9 +3,9 @@ from typing import Any, List, Mapping, Union
from isodate import Duration, parse_duration from isodate import Duration, parse_duration
from ..classes.gis import Gis from pyrmv.classes.gis import Gis
from ..classes.message import Message from pyrmv.classes.message import Message
from ..classes.stop import StopTrip from pyrmv.classes.stop import StopTrip
class Leg: class Leg:

View File

@@ -3,7 +3,7 @@ from typing import Any, List, Mapping, Union
from isodate import Duration, parse_duration from isodate import Duration, parse_duration
from ..classes.stop import Stop from pyrmv.classes.stop import Stop
class Url: class Url:
@@ -59,9 +59,9 @@ class Message:
self.channels.extend(Channel(channel) for channel in data["channel"]) self.channels.extend(Channel(channel) for channel in data["channel"])
self.id: str = data["id"] self.id: str = data["id"]
self.active: bool = data["act"] self.active: bool = data["act"]
self.head: str = "" if "head" not in data else data["head"] self.head: str = data["head"]
self.lead: str = "" if "lead" not in data else data["lead"] self.lead: str = data["lead"]
self.text: str = "" if "text" not in data else data["text"] self.text: str = data["text"]
self.company: Union[str, None] = data.get("company") self.company: Union[str, None] = data.get("company")
self.category: Union[str, None] = data.get("category") self.category: Union[str, None] = data.get("category")
self.priority: Union[int, None] = data.get("priority") self.priority: Union[int, None] = data.get("priority")
@@ -81,10 +81,8 @@ class Message:
f"{data['validToDate']} {data['validToTime']}", "%Y-%m-%d %H:%M:%S" f"{data['validToDate']} {data['validToTime']}", "%Y-%m-%d %H:%M:%S"
) )
) )
self.date_start_alt: Union[str, None] = ( self.date_start_alt: str = data["altStart"]
None if "altStart" not in data else data["altStart"] self.date_end_alt: str = data["altEnd"]
)
self.date_end_alt: Union[str, None] = None if "altEnd" not in data else data["altEnd"]
self.time_modified: Union[datetime, None] = ( self.time_modified: Union[datetime, None] = (
None None
if "modDate" not in data or "modTime" not in data if "modDate" not in data or "modTime" not in data

View File

@@ -1,17 +0,0 @@
from typing import Any, Mapping, Union
from ..enums.platform_type_type import PlatformTypeType
class PlatformType:
"""Platform information."""
def __init__(self, data: Mapping[str, Any]):
self.type: PlatformTypeType = (
PlatformTypeType.U if "type" not in data else PlatformTypeType(data.get("type"))
)
self.text: Union[str, None] = data.get("text")
self.hidden: bool = bool(data.get("hidden"))
self.lon: float = data["lon"]
self.lat: float = data["lat"]
self.alt: int = data["alt"]

View File

@@ -3,8 +3,8 @@ from typing import List, Union
from isodate import Duration, parse_duration from isodate import Duration, parse_duration
from ..classes.leg import Leg from pyrmv.classes.leg import Leg
from ..classes.stop import StopTrip from pyrmv.classes.stop import StopTrip
class Trip: class Trip:
@@ -19,10 +19,8 @@ class Trip:
self.index: int = data["idx"] self.index: int = data["idx"]
self.id: str = data["tripId"] self.id: str = data["tripId"]
self.ctx_recon: str = data["ctxRecon"] self.ctx_recon: str = data["ctxRecon"]
self.duration: Union[Duration, timedelta, None] = ( self.duration: Union[Duration, timedelta] = parse_duration(data["duration"])
None if "duration" not in data else parse_duration(data["duration"]) self.real_time_duration: Union[Duration, timedelta] = (
)
self.real_time_duration: Union[Duration, timedelta, None] = (
None if "rtDuration" not in data else parse_duration(data["rtDuration"]) None if "rtDuration" not in data else parse_duration(data["rtDuration"])
) )
self.checksum: str = data["checksum"] self.checksum: str = data["checksum"]

View File

@@ -4,7 +4,6 @@ from .board_type import BoardArrivalType, BoardDepartureType
from .filter_mode import FilterMode from .filter_mode import FilterMode
from .lang import Language from .lang import Language
from .location_type import LocationType from .location_type import LocationType
from .platform_type_type import PlatformTypeType
from .product import Product from .product import Product
from .rt_mode import RealTimeMode from .rt_mode import RealTimeMode
from .search_mode import SearchMode from .search_mode import SearchMode

View File

@@ -3,7 +3,7 @@
from enum import Enum from enum import Enum
from ..const import PRODUCTS from pyrmv.const import PRODUCTS
class AutoName(Enum): class AutoName(Enum):

View File

@@ -1,51 +0,0 @@
from enum import Enum, auto
class PlatformTypeType(Enum):
"""Enumeration used to declare types of platform type.
* U - Undefined
* PL - Platform/track at train station
* ST - Stop at bus or tram station
* GA - Terminal/Gate at airport
* PI - Pier if ship or ferry
* SL - Slot/parking space if bike or car
* FL - Floor in buildings or at footpath
* CI - Check-in/entrance
* CO - Check-out/exit
* X - No explicit type
* H - Hide platform information
"""
U = auto()
"Undefined"
PL = auto()
"Platform/track at train station"
ST = auto()
"Stop at bus or tram station"
GA = auto()
"Terminal/Gate at airport"
PI = auto()
"Pier if ship or ferry"
SL = auto()
"Slot/parking space if bike or car"
FL = auto()
"Floor in buildings or at footpath"
CI = auto()
"Check-in/entrance"
CO = auto()
"Check-out/exit"
X = auto()
"No explicit type"
H = auto()
"Hide platform information"

View File

@@ -64,7 +64,7 @@ def board_arrival(
payload = {} payload = {}
headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"} headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"}
for var, val in locals().copy().items(): for var, val in locals().items():
if str(var) == "date": if str(var) == "date":
if val != None: if val != None:
if isinstance(val, datetime): if isinstance(val, datetime):

View File

@@ -65,7 +65,7 @@ def board_departure(
payload = {} payload = {}
headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"} headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"}
for var, val in locals().copy().items(): for var, val in locals().items():
if str(var) == "date": if str(var) == "date":
if val != None: if val != None:
if isinstance(val, datetime): if isinstance(val, datetime):

View File

@@ -4,7 +4,7 @@ from typing import OrderedDict, Union
from requests import get from requests import get
from xmltodict import parse as xmlparse from xmltodict import parse as xmlparse
from ..utility import weekdays_bitmask from pyrmv.utility import weekdays_bitmask
try: try:
from typing import Literal from typing import Literal
@@ -97,7 +97,7 @@ def him_search(
payload = {} payload = {}
headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"} headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"}
for var, val in locals().copy().items(): for var, val in locals().items():
if str(var) in {"dateB", "dateE"}: if str(var) in {"dateB", "dateE"}:
if val != None: if val != None:
if isinstance(val, datetime): if isinstance(val, datetime):

View File

@@ -55,7 +55,7 @@ def journey_detail(
payload = {} payload = {}
headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"} headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"}
for var, val in locals().copy().items(): for var, val in locals().items():
if str(var) == "rtMode": if str(var) == "rtMode":
if val != None: if val != None:
payload["rtMode"] = val.upper() payload["rtMode"] = val.upper()

View File

@@ -54,7 +54,7 @@ def stop_by_coords(
payload = {} payload = {}
headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"} headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"}
for var, val in locals().copy().items(): for var, val in locals().items():
if str(var) == "stopType": if str(var) == "stopType":
if val != None: if val != None:
payload["type"] = val.upper() payload["type"] = val.upper()

View File

@@ -65,7 +65,7 @@ def stop_by_name(
payload = {} payload = {}
headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"} headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"}
for var, val in locals().copy().items(): for var, val in locals().items():
if str(var) == "inputString": if str(var) == "inputString":
if val != None: if val != None:
payload["input"] = val payload["input"] = val

View File

@@ -201,7 +201,7 @@ def trip_find(
payload = {} payload = {}
headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"} headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"}
for var, val in locals().copy().items(): for var, val in locals().items():
if str(var) == "date": if str(var) == "date":
if val != None: if val != None:
if isinstance(val, datetime): if isinstance(val, datetime):

View File

@@ -87,7 +87,7 @@ def trip_recon(
payload = {} payload = {}
headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"} headers = {"Accept": "application/json"} if json else {"Accept": "application/xml"}
for var, val in locals().copy().items(): for var, val in locals().items():
if str(var) == "date": if str(var) == "date":
if val != None: if val != None:
if isinstance(val, datetime): if isinstance(val, datetime):

View File

@@ -1,4 +1,4 @@
from ..errors import ( from pyrmv.errors import (
ApiAuthError, ApiAuthError,
ApiFormatError, ApiFormatError,
ApiParamError, ApiParamError,
@@ -26,7 +26,6 @@ from ..errors import (
SvcNoResultError, SvcNoResultError,
SvcProductError, SvcProductError,
SvcSearchError, SvcSearchError,
SvcParamError,
UnknownError, UnknownError,
) )
@@ -87,9 +86,6 @@ def find_exception(data: dict):
elif data["errorCode"] == "SVC_CTX": elif data["errorCode"] == "SVC_CTX":
raise SvcContextError() raise SvcContextError()
elif data["errorCode"] == "SVC_PARAM":
raise SvcParamError(errorCode=data["errorCode"], errorText=data["errorText"])
elif data["errorCode"] == "SVC_NO_RESULT": elif data["errorCode"] == "SVC_NO_RESULT":
raise SvcNoResultError() raise SvcNoResultError()

View File

@@ -20,12 +20,9 @@ def test_board_departure(api_client: Client, sample_stop_id: str):
def test_him_search(api_client: Client): def test_him_search(api_client: Client):
response = api_client.him_search(time_end=datetime.now() + timedelta(days=10)) assert isinstance(
api_client.him_search(time_end=datetime.now() + timedelta(days=10))[0], Message
if len(response) != 0: )
assert isinstance(response[0], Message)
else:
assert isinstance(response, list)
def test_journey_detail(api_client: Client, sample_journey_id: str): def test_journey_detail(api_client: Client, sample_journey_id: str):

View File

@@ -1,14 +1,14 @@
[tox] [tox]
minversion = 3.9.0 minversion = 3.8.0
envlist = py39, py310, py311, py312 envlist = py38, py39, py310, py311
isolated_build = true isolated_build = true
[gh-actions] [gh-actions]
python = python =
3.8: py38
3.9: py39 3.9: py39
3.10: py310 3.10: py310
3.11: py311 3.11: py311
3.12: py312
[testenv] [testenv]
setenv = setenv =
@@ -21,3 +21,4 @@ deps =
-r{toxinidir}/requirements/speed.txt -r{toxinidir}/requirements/speed.txt
commands = commands =
pytest --basetemp={envtmpdir} --cov=pyrmv --cov-report term-missing pytest --basetemp={envtmpdir} --cov=pyrmv --cov-report term-missing