PK!_bavaria/__init__.pyfrom .feed import create_feed PK!bavaria/api/__init__.pyPK!%>)~bavaria/api/messages.pyfrom dataclasses import dataclass, field from datetime import datetime from typing import List def to_dataclass(data): for name, cls in _source_to_class.items(): if data['content'] == None: return None if name in data['source']: if name in ['websocket', 'newsticker']: return cls(**data['content']) return cls(**data['content']['properties']) return None @dataclass class NewsItem: updated: datetime images: field(repr=False) title: str tracks: field(default_factory=list) content: str def __post_init__(self): self.updated = datetime.fromisoformat(self.updated) @dataclass class NewsTicker: incident_program: bool messages: List[NewsItem] = field(default_factory=list) def __post_init__(self): messages = [] for message in self.messages: messages.append(NewsItem(**message)) self.messages = messages @dataclass class Station: name: str uic: int @dataclass class Websocket: status: str _source_to_class = { "station ": Station, "websocket": Websocket, "newsticker": NewsTicker } PK!G//bavaria/exceptions.pyclass UnknownStationError(Exception): pass PK!5bavaria/feed.pyimport json import asyncio import websockets from bavaria.api.messages import to_dataclass URL = 'wss://tralis.sbahnm.geops.de/ws' async def create_feed(url=URL): f = Feed(url) await f.connect() return f class Feed: def __init__(self, url=URL): self.url = url self.channel = set() async def connect(self): self._connection = await websockets.connect(self.url) async def get(self, channel): """ Get current info on channel. """ await self._connection.send(f'GET {channel}') async def subscribe(self, channel): """ Subscribe to channel. """ if channel not in self.channel: await self._connection.send(f'SUB {channel}') self.channel.add(channel) async def disconnect(self): await self._connection.disconnect() def __aiter__(self): return self async def __anext__(self): msg = await self._connection.recv() data = json.loads(msg) return to_dataclass(data) PK!:bavaria/message.pyfrom dataclasses import dataclass, field from dataclasses import dataclass, is_dataclass def nested_dataclass(*args, **kwargs): def wrapper(cls): cls = dataclass(cls, **kwargs) original_init = cls.__init__ def __init__(self, *args, **kwargs): for name, value in kwargs.items(): field_type = cls.__annotations__.get(name, None) if is_dataclass(field_type) and isinstance(value, dict): new_obj = field_type(**value) kwargs[name] = new_obj original_init(self, *args, **kwargs) cls.__init__ = __init__ return cls return wrapper(args[0]) if args else wrapper class TimeTable: train_type: str train_numer: int @dataclass class Line: color: str name: str id: int text_color: str @nested_dataclass class Properties: rake: str train_id: int original_train_number: int line: Line time_since_update: int calls_stack: field(default_factory=list) time_intervals: field(default_factory=list) stop_point_ds100: str state: str transmitting_vehicle: str raw_coordinates: field(default_factory=list) event_timestamp: float vehicle_number: int event: str delay: float position_correction: int timestamp: float train_number: int ride_state: str aimed_time_offset: float @nested_dataclass class Content: properties: Properties geometry: field(default_factory=dict) type: field(default_factory=dict) @nested_dataclass class Message: source: str timestamp: float content: Content client_reference: str PK!mƻbavaria/news.pyfrom dataclasses import dataclass, field @dataclass class Message: updated: str images: field(default_factory=list) title: str # tracks content: str title: str PK!klbavaria/station.pyfrom dataclasses import dataclass from bavaria.exceptions import UnknownStationError @dataclass(frozen=True) class Station: # Name of the station. name: str # UIC, is a unique, european identifier of the railway station. uic: int def by_name(name: str) -> Station: """ Find station by name. """ for station in stations: if station.name == name: return station raise UnknownStationError(f'Station with name "{name}" doesn\'t exists.') def by_uic(uic: int) -> Station: """ Find station by UIC. """ for station in stations: if station.uic== uic: return station raise UnknownStationError(f'Station with UIC "{uic}" doesn\'t exists.') stations = [ Station(name='Geltendorf', uic=8000119), Station(name='München Hbf', uic=8000261), Station(name='München Ost', uic=8000262), Station(name='Altenerding', uic=8000524), Station(name='Altomünster', uic=8000556), Station(name='Arnbach', uic=8000603), Station(name='Aufhausen(b Erding)', uic=8000653), Station(name='Aying', uic=8000675), Station(name='Bachern', uic=8000685), Station(name='Baierbrunn', uic=8000781), Station(name='Baldham', uic=8000785), Station(name='Buchenau(Oberbay)', uic=8001229), Station(name='Buchenhain', uic=8001231), Station(name='Dachau Bahnhof', uic=8001354), Station(name='Dachau Stadt', uic=8001355), Station(name='Deisenhofen', uic=8001404), Station(name='Dürrnhaar', uic=8001578), Station(name='Ebenhausen-Schäftlarn', uic=8001621), Station(name='Ebersberg(Oberbay)', uic=8001634), Station(name='Eching', uic=8001647), Station(name='Eglharting', uic=8001682), Station(name='Eichenau(Oberbay)', uic=8001702), Station(name='Erding', uic=8001825), Station(name='Erdweg', uic=8001829), Station(name='Vierkirchen-Esterhofen', uic=8001922), Station(name='Fasanenpark', uic=8001963), Station(name='Feldafing', uic=8001970), Station(name='Feldkirchen(b München)', uic=8001973), Station(name='Esting', uic=8001996), Station(name='Freising', uic=8002078), Station(name='Fürstenfeldbruck', uic=8002141), Station(name='Furth(b Deisenhofen)', uic=8002161), Station(name='Gauting', uic=8002198), Station(name='Geisenbrunn', uic=8002210), Station(name='Gernlinden', uic=8002247), Station(name='Gilching-Argelsried', uic=8002275), Station(name='Gräfelfing', uic=8002339), Station(name='Grafing Bahnhof', uic=8002347), Station(name='Grafing Stadt', uic=8002348), Station(name='Grafrath', uic=8002351), Station(name='Gröbenzell', uic=8002377), Station(name='Gronsdorf', uic=8002383), Station(name='Großhelfendorf', uic=8002420), Station(name='Großhesselohe Isartalbf', uic=8002422), Station(name='Grub(Oberbay)', uic=8002435), Station(name='Haar', uic=8002491), Station(name='Hallbergmoos', uic=8002534), Station(name='Harthaus', uic=8002610), Station(name='Heimstetten', uic=8002715), Station(name='Herrsching', uic=8002792), Station(name='Höhenkirchen-Siegertsbrunn', uic=8002894), Station(name='Höllriegelskreuth', uic=8002899), Station(name='Hohenbrunn', uic=8002940), Station(name='Hohenschäftlarn', uic=8002955), Station(name='Holzkirchen', uic=8002980), Station(name='Icking', uic=8003039), Station(name='Markt Indersdorf', uic=8003072), Station(name='Ismaning', uic=8003092), Station(name='Kirchseeon', uic=8003290), Station(name='Kleinberghofen', uic=8003317), Station(name='Kreuzstraße', uic=8003438), Station(name='Lochham', uic=8003720), Station(name='Lohhof', uic=8003735), Station(name='Maisach', uic=8003824), Station(name='Malching(Oberbay)', uic=8003828), Station(name='Markt Schwaben', uic=8003879), Station(name='München Donnersbergerbrücke', uic=8004128), Station(name='München Hackerbrücke', uic=8004129), Station(name='München Harras', uic=8004130), Station(name='München Isartor', uic=8004131), Station(name='München Karlsplatz', uic=8004132), Station(name='München Leienfelsstr.', uic=8004133), Station(name='München Leuchtenbergring', uic=8004134), Station(name='München Marienplatz', uic=8004135), Station(name='München Rosenheimer Platz', uic=8004136), Station(name='München Siemenswerke', uic=8004137), Station(name='München St.Martin-Str.', uic=8004138), Station(name='München-Untermenzing', uic=8004139), Station(name='München-Allach', uic=8004140), Station(name='München-Aubing', uic=8004141), Station(name='München-Berg am Laim', uic=8004142), Station(name='München-Daglfing', uic=8004143), Station(name='München-Englschalking', uic=8004144), Station(name='München-Fasanerie', uic=8004145), Station(name='München-Fasangarten', uic=8004146), Station(name='München-Feldmoching', uic=8004147), Station(name='München-Giesing', uic=8004148), Station(name='München-Johanneskirchen', uic=8004149), Station(name='München-Karlsfeld', uic=8004150), Station(name='München-Laim', uic=8004151), Station(name='München-Langwied', uic=8004152), Station(name='München-Lochhausen', uic=8004153), Station(name='München-Mittersendling', uic=8004154), Station(name='München-Moosach', uic=8004155), Station(name='München-Neuaubing', uic=8004156), Station(name='München-Obermenzing', uic=8004157), Station(name='München-Pasing', uic=8004158), Station(name='München-Perlach', uic=8004159), Station(name='München-Riem', uic=8004160), Station(name='München-Solln', uic=8004161), Station(name='München-Trudering', uic=8004162), Station(name='München-Westkreuz', uic=8004163), Station(name='München Flughafen Besucherpark', uic=8004167), Station(name='München Flughafen Terminal', uic=8004168), Station(name='München Hirschgarten', uic=8004179), Station(name='München-Freiham', uic=8004181), Station(name='Mammendorf', uic=8004204), Station(name='Neugilching', uic=8004249), Station(name='Neubiberg', uic=8004252), Station(name='Neufahrn(b Freising)', uic=8004279), Station(name='Niederroth', uic=8004404), Station(name='Oberschleißheim', uic=8004580), Station(name='Olching', uic=8004667), Station(name='Ottenhofen(Oberbay)', uic=8004723), Station(name='Otterfing', uic=8004726), Station(name='Ottobrunn', uic=8004733), Station(name='Peiß', uic=8004761), Station(name='Petershausen(Obb)', uic=8004775), Station(name='Planegg', uic=8004827), Station(name='Poing', uic=8004854), Station(name='Possenhofen', uic=8004874), Station(name='Puchheim', uic=8004893), Station(name='Pullach', uic=8004899), Station(name='Pulling(b Freising)', uic=8004900), Station(name='Röhrmoos', uic=8005127), Station(name='Sauerlach', uic=8005299), Station(name='Schöngeising', uic=8005406), Station(name='München Heimeranplatz', uic=8005419), Station(name='Schwabhausen(b Dachau)', uic=8005442), Station(name='Seefeld-Hechendorf', uic=8005504), Station(name='St Koloman', uic=8005652), Station(name='Starnberg Nord', uic=8005675), Station(name='Starnberg', uic=8005676), Station(name='Steinebach', uic=8005699), Station(name='Stockdorf', uic=8005735), Station(name='Taufkirchen', uic=8005831), Station(name='Türkenfeld', uic=8005920), Station(name='Tutzing', uic=8005927), Station(name='Unterföhring', uic=8005986), Station(name='Unterhaching', uic=8005991), Station(name='Germering-Unterpfaffenhofen', uic=8006006), Station(name='Vaterstetten', uic=8006059), Station(name='Wächterhof', uic=8006131), Station(name='Hebertshausen', uic=8006189), Station(name='Weßling(Oberbay)', uic=8006359), Station(name='Wolfratshausen', uic=8006550), Station(name='Zorneding', uic=8006671), Station(name='Unterschleißheim', uic=8006688), Station(name='München-Neuperlach Süd', uic=8006696), ] PK![88bavaria-0.1.0.dist-info/LICENSEMIT License Copyright (c) 2018 Auke Willem Oosterhoff 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. PK!HnHTUbavaria-0.1.0.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]\fi4WZ^EgM_-]#0(q7PK!H* bavaria-0.1.0.dist-info/METADATAOO1sSY evaۮFx6f~o [uh׼2T$`{ٯ>O*((``mBi,,E} hSV=qؑf8{2x˞:csYvivk4`i'['9!tg,|a/%h'F71CRR\b\`ڶi۽cHnMeQ)+GdGtoRW sG8x薧W PK!H$Ї.}bavaria-0.1.0.dist-info/RECORDuǎP< 8Y`rl׀H3#e^階e#Iʶd߱H)YjD%4ɴXÝԡD&ގRڗӶk;I71Zqވ?T>4MiL+.n7r;I8ʙw2O$>=tP?]V2ft -XN?*za A#rVؖ{ZgN/JK2Gߪ(Ӫf7b헚$I"mٝac$A1Os e\OF fpJO RFZt}ӣ63 ~fB+#!]6F؏jT;ʃjz1/Fw OpqbCnͩflK*_4{A[.V2sWgLFw4{7Re9DFpšn} ^oT3UQ̷,32G9<8x),%<*چ.|`ؖu}Er}~PK!_bavaria/__init__.pyPK!Obavaria/api/__init__.pyPK!%>)~bavaria/api/messages.pyPK!G//Qbavaria/exceptions.pyPK!5bavaria/feed.pyPK!: bavaria/message.pyPK!mƻbavaria/news.pyPK!kl~bavaria/station.pyPK![8841bavaria-0.1.0.dist-info/LICENSEPK!HnHTU5bavaria-0.1.0.dist-info/WHEELPK!H* 86bavaria-0.1.0.dist-info/METADATAPK!H$Ї.}7bavaria-0.1.0.dist-info/RECORDPK :9