├── .gitignore ├── LICENSE ├── README.md ├── pydsb └── __init__.py └── pyproject.toml /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | # PyCharm 107 | .idea/ 108 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 sn0wmanmj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pydsb 2.3.0 2 | pydsb provides a Python API for DSBmobile. 3 | 4 | Heinekingmedia (the creators of DSBmobile) shut down the API pydsb was previously using so I had to use the app-API. That required a complete rewrite so some features are currently not implemented yet. See below for the current featureset. 5 | I strongly recommend that users of version 1.0 upgrade to 2.0, because it doesn't work anymore. Some syntax has changed too, so be aware of that. 6 | 7 | ## Features 8 | 9 | - [x] Getting plans 10 | - [x] Getting news (maybe not always working due to limited sample data) 11 | - [x] Getting postings (Aushänge) 12 | 13 | ## Installation 14 | 15 | pip install pydsb 16 | 17 | ## Usage 18 | 19 | from pydsb import PyDSB 20 | 21 | dsb = PyDSB("username", "password") 22 | 23 | print(dsb.get_plans()) 24 | print(dsb.get_postings()) 25 | print(dsb.get_news()) 26 | -------------------------------------------------------------------------------- /pydsb/__init__.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | BASE_URL = "https://mobileapi.dsbcontrol.de" 4 | 5 | 6 | class PyDSB: 7 | def __init__(self, username: str = None, password: str = None): 8 | 9 | params = { 10 | "bundleid": "de.heinekingmedia.dsbmobile", 11 | "appversion": "35", 12 | "osversion": "22", 13 | "pushid": "", 14 | "user": username, 15 | "password": password 16 | } 17 | 18 | r = requests.get(BASE_URL + "/authid", params=params) 19 | 20 | if r.text == "\"\"": # Me when http status code is always 200 :trollface: 21 | raise Exception("Invalid Credentials") 22 | else: 23 | self.token = r.text.replace("\"", "") 24 | 25 | def get_plans(self) -> list: 26 | raw_plans = requests.get(BASE_URL + "/dsbtimetables", params={"authid": self.token}).json() 27 | plans = [] 28 | 29 | for plan in raw_plans: 30 | for i in plan["Childs"]: 31 | plans.append({ 32 | "id": i["Id"], 33 | "is_html": True if i["ConType"] == 6 else False, 34 | "uploaded_date": i["Date"], 35 | "title": i["Title"], 36 | "url": i["Detail"], 37 | "preview_url": "https://light.dsbcontrol.de/DSBlightWebsite/Data/" + i["Preview"], 38 | } 39 | ) 40 | 41 | return plans 42 | 43 | def get_news(self) -> list: 44 | raw_news = requests.get(BASE_URL + "/newstab", params={"authid": self.token}).json() 45 | news = [] 46 | for i in raw_news: 47 | news.append({ 48 | "title": i["Title"], "date": i["Date"], "content": i["Detail"] 49 | }) 50 | return news 51 | 52 | def get_postings(self) -> list: 53 | raw_postings = requests.get(BASE_URL + "/dsbdocuments", params={"authid": self.token}).json() 54 | postings = [] 55 | for posting in raw_postings: 56 | for i in posting["Childs"]: 57 | postings.append({ 58 | "id": i["Id"], 59 | "uploaded_date": i["Date"], 60 | "title": i["Title"], 61 | "url": i["Detail"], 62 | "preview_url": "https://light.dsbcontrol.de/DSBlightWebsite/Data/" + i["Preview"], 63 | } 64 | ) 65 | 66 | return postings 67 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["hatchling"] 3 | build-backend = "hatchling.build" 4 | 5 | [project] 6 | name = "pydsb" 7 | version = "2.3.0" 8 | authors = [ 9 | { name = "Moritz Jannasch", email = "contact@moritzj.de" }, 10 | ] 11 | description = "Python API for DSBmobile" 12 | readme = "README.md" 13 | requires-python = ">=3.7" 14 | dependencies = [ 15 | "requests", 16 | ] 17 | classifiers = [ 18 | "Programming Language :: Python :: 3", 19 | "License :: OSI Approved :: MIT License", 20 | "Operating System :: OS Independent", 21 | ] 22 | 23 | [project.urls] 24 | "Homepage" = "https://github.com/mojansch/pydsb" 25 | "Bug Tracker" = "https://github.com/mojansch/pydsb/issues" --------------------------------------------------------------------------------