From 7f12a3bbd82b9868fd6cc7fb84bbaac7fc5677f0 Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Mon, 2 Jun 2025 21:54:55 +0200 Subject: [PATCH] Add CCCHH events Closes #5 --- buba/__main__.py | 3 +- buba/animations/icalevents.py | 38 +++++++++++++++++ buba/bubaanimator.py | 1 + poetry.lock | 78 ++++++++++++++++++++++++++++++++++- pyproject.toml | 3 +- 5 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 buba/animations/icalevents.py diff --git a/buba/__main__.py b/buba/__main__.py index 9257af7..c35b646 100644 --- a/buba/__main__.py +++ b/buba/__main__.py @@ -5,6 +5,7 @@ from bottle_log import LoggingPlugin from bottle_websocket import websocket, GeventWebSocketServer from geventwebsocket.websocket import WebSocket +from buba.animations.icalevents import IcalEvents from buba.appconfig import AppConfig from buba.bubaanimator import BubaAnimator from buba.animations.time import BubaTime @@ -32,7 +33,7 @@ animator = BubaAnimator(buba) animator.add(BubaTime) animator.add(DBFAnimation, ds100="AHST", station="Holstenstraße") animator.add(DBFAnimation, ds100="AHS", station="Altona", count=9) - +animator.add(IcalEvents, url="https://cloud.hamburg.ccc.de/remote.php/dav/public-calendars/QJAdExziSnNJEz5g?export", title="CCCHH Events") @app.route("/static/") def server_static(filepath): diff --git a/buba/animations/icalevents.py b/buba/animations/icalevents.py new file mode 100644 index 0000000..32fbd39 --- /dev/null +++ b/buba/animations/icalevents.py @@ -0,0 +1,38 @@ +from datetime import timedelta, datetime +from time import sleep + +from buba.bubaanimator import BubaAnimation +import icalevents.icalevents + +from buba.bubacmd import BubaCmd + + +class IcalEvents(BubaAnimation): + def __init__(self, buba, url, title): + super().__init__(buba) + self.url = url + self.title = title + self.events = icalevents.icalevents.events(url) + self.log.debug(f"Events loaded {len(self.events)}") + + def __repr__(self): + return f"<{type(self).__name__}, {self.url}>" + + @staticmethod + def ellipsis(text, max=28): + if len(text) > max: + text = text[:max-3] + "..." + return text + + def run(self): + self.buba.text(page=0, row=0, col_start=0, col_end=119, text=self.title, align=BubaCmd.ALIGN_LEFT) + for (i, event) in enumerate(self.events[0:3]): + if event.start - datetime.now(event.start.tzinfo) < timedelta(hours=20): + when = event.start.strftime("%H:%M") + else: + when = event.start.strftime("%d.%m.") + self.log.info(f"event '{self.ellipsis(event.summary)} at {when}") + self.buba.text(page=0, row=i + 1, col_start=0, col_end=104, text=self.ellipsis(event.summary)) + self.buba.text(page=0, row=i + 1, col_start=105, col_end=119, + text=when, align=BubaCmd.ALIGN_RIGHT) + sleep(10) \ No newline at end of file diff --git a/buba/bubaanimator.py b/buba/bubaanimator.py index a6e29dc..a3eac49 100644 --- a/buba/bubaanimator.py +++ b/buba/bubaanimator.py @@ -7,6 +7,7 @@ from buba.bubacmd import BubaCmd class BubaAnimation: def __init__(self, buba: BubaCmd): + self.log = logging.getLogger(type(self).__name__) self.buba = buba pass diff --git a/poetry.lock b/poetry.lock index 5adf106..53ad563 100644 --- a/poetry.lock +++ b/poetry.lock @@ -399,6 +399,43 @@ files = [ docs = ["Sphinx", "furo"] test = ["objgraph", "psutil"] +[[package]] +name = "icalendar" +version = "6.3.1" +description = "iCalendar parser/generator" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "icalendar-6.3.1-py3-none-any.whl", hash = "sha256:7ea1d1b212df685353f74cdc6ec9646bf42fa557d1746ea645ce8779fdfbecdd"}, + {file = "icalendar-6.3.1.tar.gz", hash = "sha256:a697ce7b678072941e519f2745704fc29d78ef92a2dc53d9108ba6a04aeba466"}, +] + +[package.dependencies] +python-dateutil = "*" +tzdata = "*" + +[package.extras] +test = ["coverage", "hypothesis", "pytest", "pytz"] + +[[package]] +name = "icalevents" +version = "0.2.1" +description = "Simple Python 3 library to download, parse and query iCal sources." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "icalevents-0.2.1-py3-none-any.whl", hash = "sha256:c5186fea094a56d97ba01c805f6338875e299e7ebc4bc6bf8068399fbb7e5724"}, + {file = "icalevents-0.2.1.tar.gz", hash = "sha256:b7f2827b581269d4315b345b54cf7d661b4453a7b190f7dbef99e5ba8f5669e1"}, +] + +[package.dependencies] +icalendar = ">=5.0.0" +python-dateutil = ">=2.9,<3.0" +pytz = ">=2024.2" +urllib3 = ">=1.26.5" + [[package]] name = "idna" version = "3.10" @@ -646,6 +683,21 @@ files = [ [package.extras] cp2110 = ["hidapi"] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + [[package]] name = "pytz" version = "2025.2" @@ -701,6 +753,30 @@ enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "tzdata" +version = "2025.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +groups = ["main"] +files = [ + {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, + {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, +] + [[package]] name = "urllib3" version = "2.4.0" @@ -796,4 +872,4 @@ testing = ["coverage[toml]", "zope.event", "zope.testing"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4.0" -content-hash = "acf29f4ce322901a93ff75a105fbe8ba8ff40b944731aacd4f11cdb57f7d0481" +content-hash = "27b2de701a5436d05c6aa0095ce309f6fc9330b4be06b2966ee8d6f77baa2a56" diff --git a/pyproject.toml b/pyproject.toml index 540c3a0..74c5c18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,8 @@ dependencies = [ "gevent (>=25.5.1,<26.0.0)", "jinja2 (>=3.1.6,<4.0.0)", "deutschebahn (>=1.4.0,<2.0.0)", - "pytz (>=2025.2,<2026.0)" + "pytz (>=2025.2,<2026.0)", + "icalevents (>=0.2.1,<0.3.0)" ]