Compare commits

..

4 commits

Author SHA1 Message Date
f5f44852d3 🐛 Fixing initial scheduling
Some checks failed
ci / docker (push) Successful in 4m59s
Python formatting PEP8 / Python-PEP8 (push) Failing after 15s
2024-06-17 21:32:59 +02:00
f25cd833f8 🐛 Fix typo which causes crash
Some checks failed
ci / docker (push) Successful in 4m55s
Python formatting PEP8 / Python-PEP8 (push) Failing after 18s
2024-06-17 07:37:14 +02:00
1f1ae5077e Added periodic reminders and included alembic migration in container
Some checks failed
ci / docker (push) Successful in 4m43s
Python formatting PEP8 / Python-PEP8 (push) Failing after 13s
2024-06-16 22:45:24 +02:00
86a5dd19b5 🐛 Fix database connection for container by exposing environment variable
Some checks failed
ci / docker (push) Successful in 4m43s
Python formatting PEP8 / Python-PEP8 (push) Failing after 13s
2024-06-16 21:44:14 +02:00
8 changed files with 76 additions and 13 deletions

View file

@ -1,3 +1,4 @@
.env .env
bin bin
lib lib
include

View file

@ -10,4 +10,4 @@ RUN pip3 install -r requirements.txt
COPY . . COPY . .
CMD ["python", "-m", "matrix_bot_praying_times"] ENTRYPOINT ["/bot/entrypoint.sh"]

View file

@ -6,6 +6,8 @@ from sqlalchemy import pool
from alembic import context from alembic import context
from dotenv import load_dotenv
load_dotenv()
# this is the Alembic Config object, which provides # this is the Alembic Config object, which provides
# access to the values within the .ini file in use. # access to the values within the .ini file in use.

View file

@ -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 ###

View file

@ -8,5 +8,6 @@ services:
- BOT_HOMESERVER - BOT_HOMESERVER
- BOT_USERNAME - BOT_USERNAME
- BOT_PASSWORD - BOT_PASSWORD
- DB_URI
volumes: volumes:
- ./data/:/bot/data - ./data/:/bot/data

3
entrypoint.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
alembic upgrade head
python -m matrix_bot_praying_times

View file

@ -5,6 +5,7 @@ import asyncio
import pytz import pytz
from typing import Dict from typing import Dict
import os import os
import logging
from dotenv import load_dotenv from dotenv import load_dotenv
from .models.user import User from .models.user import User
@ -29,6 +30,20 @@ engine = create_engine(os.getenv("DB_URI"))
Session = sessionmaker(bind=engine) Session = sessionmaker(bind=engine)
session = Session() session = Session()
logging.basicConfig(level=logging.INFO)
@bot.listener.on_startup
async def initial_schedule(room_id):
logging.info("starting praying times bot")
users = session.query(User).filter(User.location != "", User.reminder_time_in_minutes is not None).all()
for user in users:
logging.info("scheduling initial reminder for {}".format(user.username))
# reset last reminder schedule time
user.current_reminder_date = None
session.add(user)
session.commit()
schedule_reminder(user.username)
@bot.listener.on_message_event @bot.listener.on_message_event
@ -72,7 +87,7 @@ async def usage(room, message) -> None:
- **!set-reminder** <X> where X is the number of minutes you want to receive the reminder before praying - **!set-reminder** <X> where X is the number of minutes you want to receive the reminder before praying
""" """
if match.is_not_from_this_bot() and not match.prefix(): if match.is_not_from_this_bot() and not match.prefix() and room.room_id:
await bot.api.send_markdown_message(room.room_id, response) await bot.api.send_markdown_message(room.room_id, response)
@ -113,8 +128,10 @@ async def set_reminder(room, message) -> None:
response = "You did not set your location yet." response = "You did not set your location yet."
await bot.api.send_markdown_message(room.room_id, response) await bot.api.send_markdown_message(room.room_id, response)
else: else:
user.reminder_time_in_minues = minutes user.reminder_time_in_minutes = minutes
user.room_id = room.room_id user.room_id = room.room_id
session.add(user)
session.commit()
response = "Your reminder was set to {} minutes before praying.".format(minutes) response = "Your reminder was set to {} minutes before praying.".format(minutes)
schedule_reminder(username) schedule_reminder(username)
await bot.api.send_markdown_message(room.room_id, response) await bot.api.send_markdown_message(room.room_id, response)
@ -132,22 +149,30 @@ def get_praying_times(date: datetime.date, username) -> Dict[str, str]:
def schedule_reminder(username) -> None: def schedule_reminder(username) -> None:
logging.info("scheduling reminder for {}".format(username))
now = datetime.datetime.now(datetime.UTC) now = datetime.datetime.now(datetime.UTC)
user = session.query(User).filter_by(username=username).one_or_none() user = session.query(User).filter_by(username=username).one_or_none()
# as a workaround until it's finished schedule the next 7 days user.current_reminder_date = datetime.date.today()
for i in range(7): session.add(user)
times = get_praying_times(datetime.date.today() + datetime.timedelta(days=i), username) session.commit()
times = get_praying_times(datetime.date.today(), username)
for prayer, time in times.items(): for prayer, time in times.items():
praying_time = datetime.datetime.fromisoformat(time) praying_time = datetime.datetime.fromisoformat(time)
if praying_time > now: if praying_time > now:
# schedule praying times but skip the ones which already have been passed today
seconds = int((praying_time - now).total_seconds()) seconds = int((praying_time - now).total_seconds())
message = "{} is at {}".format(prayer, praying_time.strftime("%H:%M")) message = "{} is at {}".format(prayer, praying_time.strftime("%H:%M"))
asyncio.ensure_future(remind(username, message, seconds - user.reminder_time_in_minues * 60)) logging.info("scheduling reminder for {} with message: {}".format(username, message))
asyncio.ensure_future(remind(username, message, seconds - user.reminder_time_in_minutes * 60))
# save date of last schedule for user
async def remind(username, message, seconds) -> None: async def remind(username, message, seconds) -> None:
await asyncio.sleep(seconds) await asyncio.sleep(seconds)
user = session.query(User).filter_by(username=username).one_or_none() 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) await bot.api.send_markdown_message(user.room_id, message)

View file

@ -1,4 +1,4 @@
from sqlalchemy import Column, String, Integer from sqlalchemy import Column, String, Integer, Date
from ..db import Base from ..db import Base
@ -11,3 +11,4 @@ class User(Base):
location = Column(String) location = Column(String)
room_id = Column(String) room_id = Column(String)
reminder_time_in_minutes = Column(Integer) reminder_time_in_minutes = Column(Integer)
current_reminder_date = Column(Date)