From 1f1ae5077edff44c184aed59bf34b2d193ca2eaa Mon Sep 17 00:00:00 2001 From: Finn Christiansen Date: Sun, 16 Jun 2024 22:45:24 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Added=20periodic=20reminders=20and?= =?UTF-8?q?=20included=20alembic=20migration=20in=20container?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 1 + Dockerfile | 2 +- alembic/env.py | 2 ++ .../c2bcd940c9e8_add_current_reminder_date.py | 30 ++++++++++++++++++ entrypoint.sh | 3 ++ matrix_bot_praying_times/__main__.py | 31 +++++++++++++------ matrix_bot_praying_times/models/user.py | 3 +- 7 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 alembic/versions/c2bcd940c9e8_add_current_reminder_date.py create mode 100755 entrypoint.sh diff --git a/.dockerignore b/.dockerignore index a7ff473..1a3a766 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ .env bin lib +include diff --git a/Dockerfile b/Dockerfile index ce0950f..f812f0d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,4 +10,4 @@ RUN pip3 install -r requirements.txt COPY . . -CMD ["python", "-m", "matrix_bot_praying_times"] +ENTRYPOINT ["/bot/entrypoint.sh"] diff --git a/alembic/env.py b/alembic/env.py index 0d79cb1..f2ba3a7 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -6,6 +6,8 @@ from sqlalchemy import pool from alembic import context +from dotenv import load_dotenv +load_dotenv() # this is the Alembic Config object, which provides # access to the values within the .ini file in use. diff --git a/alembic/versions/c2bcd940c9e8_add_current_reminder_date.py b/alembic/versions/c2bcd940c9e8_add_current_reminder_date.py new file mode 100644 index 0000000..a8db828 --- /dev/null +++ b/alembic/versions/c2bcd940c9e8_add_current_reminder_date.py @@ -0,0 +1,30 @@ +"""Add current reminder date + +Revision ID: c2bcd940c9e8 +Revises: 12669d9a145b +Create Date: 2024-06-16 22:21:27.188128 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = 'c2bcd940c9e8' +down_revision: Union[str, None] = '12669d9a145b' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('user', sa.Column('current_reminder_date', sa.Date(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('user', 'current_reminder_date') + # ### end Alembic commands ### diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..d9e2035 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh +alembic upgrade head +python -m matrix_bot_praying_times diff --git a/matrix_bot_praying_times/__main__.py b/matrix_bot_praying_times/__main__.py index 361253d..52b37a9 100644 --- a/matrix_bot_praying_times/__main__.py +++ b/matrix_bot_praying_times/__main__.py @@ -30,6 +30,13 @@ Session = sessionmaker(bind=engine) session = Session() +@bot.listener.on_reaction_event +def initial_schedule() -> None: + users = session.query(User).filter(User.location != "").all() + for user in users: + schedule_reminder(user.username) + + @bot.listener.on_message_event async def echo(room, message) -> None: @@ -134,20 +141,26 @@ def get_praying_times(date: datetime.date, username) -> Dict[str, str]: def schedule_reminder(username) -> None: now = datetime.datetime.now(datetime.UTC) user = session.query(User).filter_by(username=username).one_or_none() - # as a workaround until it's finished schedule the next 7 days - for i in range(7): - times = get_praying_times(datetime.date.today() + datetime.timedelta(days=i), username) - for prayer, time in times.items(): - praying_time = datetime.datetime.fromisoformat(time) - if praying_time > now: - seconds = int((praying_time - now).total_seconds()) - message = "{} is at {}".format(prayer, praying_time.strftime("%H:%M")) - asyncio.ensure_future(remind(username, message, seconds - user.reminder_time_in_minues * 60)) + user.current_reminder_date = datetime.date.today() + session.add(user) + session.commit() + times = get_praying_times(datetime.date.today(), username) + for prayer, time in times.items(): + praying_time = datetime.datetime.fromisoformat(time) + if praying_time > now: + # schedule praying times but skip the ones which already have been passed today + seconds = int((praying_time - now).total_seconds()) + message = "{} is at {}".format(prayer, praying_time.strftime("%H:%M")) + asyncio.ensure_future(remind(username, message, seconds - user.reminder_time_in_minues * 60)) + # save date of last schedule for user async def remind(username, message, seconds) -> None: await asyncio.sleep(seconds) user = session.query(User).filter_by(username=username).one_or_none() + # check if a new reminder has to be scheduled + if user.current_reminder_date < datetime.date.today(): + schedule_reminder(user.username) await bot.api.send_markdown_message(user.room_id, message) diff --git a/matrix_bot_praying_times/models/user.py b/matrix_bot_praying_times/models/user.py index a7acfdd..fc1fdcc 100644 --- a/matrix_bot_praying_times/models/user.py +++ b/matrix_bot_praying_times/models/user.py @@ -1,4 +1,4 @@ -from sqlalchemy import Column, String, Integer +from sqlalchemy import Column, String, Integer, Date from ..db import Base @@ -11,3 +11,4 @@ class User(Base): location = Column(String) room_id = Column(String) reminder_time_in_minutes = Column(Integer) + current_reminder_date = Column(Date)