Merge pull request 'v0.5.0' (#87) from dev into master

Reviewed-on: #87
This commit is contained in:
2025-05-05 01:06:48 +03:00
25 changed files with 78 additions and 72 deletions

View File

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

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.8+ * Python 3.9+
* git (Only for installation from source) * git (Only for installation from source)
## Installation ## Installation

View File

@@ -9,7 +9,7 @@ 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.8" requires-python = ">=3.9"
license = { text = "MIT" } license = { text = "MIT" }
classifiers = [ classifiers = [
"Development Status :: 3 - Alpha", "Development Status :: 3 - Alpha",
@@ -17,7 +17,6 @@ classifiers = [
"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",
@@ -46,7 +45,7 @@ speed = { file = "requirements/speed.txt" }
where = ["src"] where = ["src"]
[tool.black] [tool.black]
target-version = ['py38', 'py39', 'py310', 'py311', 'py312'] target-version = ['py39', 'py310', 'py311', 'py312']
line-length = 94 line-length = 94
[tool.isort] [tool.isort]
@@ -66,7 +65,7 @@ show_error_codes = true
[tool.pylint.main] [tool.pylint.main]
extension-pkg-whitelist = ["ujson"] extension-pkg-whitelist = ["ujson"]
py-version = 3.8 py-version = 3.9
[tool.coverage.run] [tool.coverage.run]
source = ["pyrmv"] source = ["pyrmv"]

View File

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

View File

@@ -1,10 +1,10 @@
black~=24.8.0 black~=25.1.0
isort==5.13.2 isort==5.13.2
mypy~=1.11.2 mypy~=1.15.0
pylint==3.2.7 pylint==3.3.7,<3.4.0
pytest-cov~=5.0.0 pytest-cov~=6.1.0
pytest~=8.3.2 pytest~=8.3.2
tox==4.18.1 tox==4.25.0
types-ujson~=5.10.0.20240515 types-ujson~=5.10.0.20240515
# Disabled async libraries for now # Disabled async libraries for now

View File

@@ -1,2 +1,2 @@
build==1.2.2 build==1.2.2.post1
twine~=5.1.1 twine~=6.1.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.4.0" __version__ = "0.5.0"
__license__ = "MIT License" __license__ = "MIT License"
__author__ = "Profitroll" __author__ = "Profitroll"

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 pyrmv.classes.journey import Journey from ..classes.journey import Journey
from pyrmv.classes.message import Message from ..classes.message import Message
from pyrmv.classes.stop import Stop from ..classes.stop import Stop
from pyrmv.utility import ref_upgrade from ..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 pyrmv.classes import ( from ..classes import (
BoardArrival, BoardArrival,
BoardDeparture, BoardDeparture,
Journey, Journey,
@@ -10,7 +10,7 @@ from pyrmv.classes import (
StopTrip, StopTrip,
Trip, Trip,
) )
from pyrmv.enums import ( from ..enums import (
AffectedJourneyMode, AffectedJourneyMode,
AffectedJourneyStopMode, AffectedJourneyStopMode,
BoardArrivalType, BoardArrivalType,
@@ -22,15 +22,15 @@ from pyrmv.enums import (
SearchMode, SearchMode,
SelectionMode, SelectionMode,
) )
from pyrmv.raw import board_arrival as raw_board_arrival from ..raw import board_arrival as raw_board_arrival
from pyrmv.raw import board_departure as raw_board_departure from ..raw import board_departure as raw_board_departure
from pyrmv.raw import him_search as raw_him_search from ..raw import him_search as raw_him_search
from pyrmv.raw import journey_detail as raw_journey_detail from ..raw import journey_detail as raw_journey_detail
from pyrmv.raw import stop_by_coords as raw_stop_by_coords from ..raw import stop_by_coords as raw_stop_by_coords
from pyrmv.raw import stop_by_name as raw_stop_by_name from ..raw import stop_by_name as raw_stop_by_name
from pyrmv.raw import trip_find as raw_trip_find from ..raw import trip_find as raw_trip_find
from pyrmv.raw import trip_recon as raw_trip_recon from ..raw import trip_recon as raw_trip_recon
from pyrmv.utility import find_exception from ..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) find_exception(board_raw.copy())
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) find_exception(board_raw.copy())
return BoardDeparture( return BoardDeparture(
board_raw, board_raw,
@@ -343,7 +343,7 @@ class Client:
minprio=priority_min, minprio=priority_min,
) )
find_exception(messages_raw) find_exception(messages_raw.copy())
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) find_exception(journey_raw.copy())
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) find_exception(stops_raw.copy())
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) find_exception(stops_raw.copy())
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) find_exception(stops_raw.copy())
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) find_exception(trips_raw.copy())
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) find_exception(trips_raw.copy())
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 pyrmv.classes.message import Message from ..classes.message import Message
from pyrmv.classes.stop import Stop from ..classes.stop import Stop
from pyrmv.utility import ref_upgrade from ..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 pyrmv.classes.gis import Gis from ..classes.gis import Gis
from pyrmv.classes.message import Message from ..classes.message import Message
from pyrmv.classes.stop import StopTrip from ..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 pyrmv.classes.stop import Stop from ..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 = data["head"] self.head: str = "" if "head" not in data else data["head"]
self.lead: str = data["lead"] self.lead: str = "" if "lead" not in data else data["lead"]
self.text: str = data["text"] self.text: str = "" if "text" not in data else 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,8 +81,10 @@ 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: str = data["altStart"] self.date_start_alt: Union[str, None] = (
self.date_end_alt: str = data["altEnd"] None if "altStart" not in data else data["altStart"]
)
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,6 +1,6 @@
from typing import Any, Mapping, Union from typing import Any, Mapping, Union
from pyrmv.enums.platform_type_type import PlatformTypeType from ..enums.platform_type_type import PlatformTypeType
class PlatformType: class PlatformType:

View File

@@ -3,8 +3,8 @@ from typing import List, Union
from isodate import Duration, parse_duration from isodate import Duration, parse_duration
from pyrmv.classes.leg import Leg from ..classes.leg import Leg
from pyrmv.classes.stop import StopTrip from ..classes.stop import StopTrip
class Trip: class Trip:
@@ -19,8 +19,10 @@ 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] = parse_duration(data["duration"]) self.duration: Union[Duration, timedelta, None] = (
self.real_time_duration: Union[Duration, timedelta] = ( None if "duration" not in data else parse_duration(data["duration"])
)
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

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

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().items(): for var, val in locals().copy().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().items(): for var, val in locals().copy().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 pyrmv.utility import weekdays_bitmask from ..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().items(): for var, val in locals().copy().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().items(): for var, val in locals().copy().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().items(): for var, val in locals().copy().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().items(): for var, val in locals().copy().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().items(): for var, val in locals().copy().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().items(): for var, val in locals().copy().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 pyrmv.errors import ( from ..errors import (
ApiAuthError, ApiAuthError,
ApiFormatError, ApiFormatError,
ApiParamError, ApiParamError,
@@ -26,6 +26,7 @@ from pyrmv.errors import (
SvcNoResultError, SvcNoResultError,
SvcProductError, SvcProductError,
SvcSearchError, SvcSearchError,
SvcParamError,
UnknownError, UnknownError,
) )
@@ -86,6 +87,9 @@ 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

@@ -1,11 +1,10 @@
[tox] [tox]
minversion = 3.8.0 minversion = 3.9.0
envlist = py38, py39, py310, py311, py312 envlist = py39, py310, py311, py312
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