🗃️ Add basic database support using SQLAlchemy and Alembic
Some checks failed
ci / docker (push) Successful in 4m54s
Python formatting PEP8 / Python-PEP8 (push) Failing after 13s

This commit is contained in:
Finn Christiansen 2024-06-16 20:57:18 +02:00
parent d6792c91a8
commit 9a2a18172c
13 changed files with 325 additions and 13 deletions

View file

@ -0,0 +1 @@
from .models.user import User

View file

@ -6,6 +6,11 @@ import pytz
from typing import Dict
import os
from dotenv import load_dotenv
from .models.user import User
from sqlalchemy import create_engine
from sqlalchemy.sql import select
from sqlalchemy.orm import sessionmaker
load_dotenv()
@ -20,9 +25,10 @@ bot = botlib.Bot(creds)
PREFIX = '!'
utc = pytz.UTC
user_locations: dict = {}
user_reminders: dict = {}
user_room_ids: dict = {}
engine = create_engine(os.getenv("DB_URI"))
Session = sessionmaker(bind=engine)
session = Session()
@bot.listener.on_message_event
@ -42,13 +48,15 @@ async def times(room, message) -> None:
username = str(message).split(': ')[0]
response = ""
user = session.query(User).filter(User.username == username, User.location != "").one_or_none()
if match.is_not_from_this_bot() and match.prefix() and match.command("times"):
if username not in user_locations:
if not user:
response = "Please set your location first using *!set-location City, Country*"
else:
times = get_praying_times(datetime.datetime.today(), username)
response = "Today's praying times for {}:\n\n".format(user_locations[username])
response = "Today's praying times for {}:\n\n".format(user.location)
response += "\n".join("{}: {}".format(key, value) for key, value in times.items())
await bot.api.send_markdown_message(room.room_id, response)
@ -77,7 +85,15 @@ async def set_location(room, message) -> None:
if match.is_not_from_this_bot() and match.prefix() and match.command("set-location"):
location = " ".join(arg for arg in match.args())
username = str(message).split(': ')[0]
user_locations[username] = location
user = session.query(User).filter_by(username=username).one_or_none()
if not user:
# create new user
user = User(username=username, location=location)
session.add(user)
user.location = location
session.commit()
response = "Your location was set to: {}".format(location)
await bot.api.send_markdown_message(room.room_id, response)
@ -91,13 +107,14 @@ async def set_reminder(room, message) -> None:
if match.is_not_from_this_bot() and match.prefix() and match.command("set-reminder"):
minutes = int(match.args()[0])
username = str(message).split(': ')[0]
user = session.query(User).filter(User.username == username, User.location != "").one_or_none()
if username not in user_locations:
if not user:
response = "You did not set your location yet."
await bot.api.send_markdown_message(room.room_id, response)
else:
user_reminders[username] = minutes
user_room_ids[username] = room.room_id
user.reminder_time_in_minues = minutes
user.room_id = room.room_id
response = "Your reminder was set to {} minutes before praying.".format(minutes)
schedule_reminder(username)
await bot.api.send_markdown_message(room.room_id, response)
@ -107,15 +124,16 @@ def get_praying_times(date: datetime.date, username) -> Dict[str, str]:
day = date.day
month = date.month
year = date.year
times_api_url = 'http://api.aladhan.com/v1/timingsByAddress/{}-{}-{}?address={}&method=7&iso8601=true'.format(day, month, year, user_locations[username])
user = session.query(User).filter_by(username=username).one_or_none()
times_api_url = 'http://api.aladhan.com/v1/timingsByAddress/{}-{}-{}?address={}&method=7&iso8601=true'.format(day, month, year, user.location)
times = requests.get(times_api_url)
times = times.json()['data']['timings']
return times
def schedule_reminder(username) -> None:
# TODO: add peristence for reminders
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)
@ -124,12 +142,13 @@ def schedule_reminder(username) -> None:
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_reminders[username] * 60))
asyncio.ensure_future(remind(username, message, seconds - user.reminder_time_in_minues * 60))
async def remind(username, message, seconds) -> None:
await asyncio.sleep(seconds)
await bot.api.send_markdown_message(user_room_ids[username], message)
user = session.query(User).filter_by(username=username).one_or_none()
await bot.api.send_markdown_message(user.room_id, message)
bot.run()

View file

@ -0,0 +1,7 @@
import os
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()

View file

@ -0,0 +1,13 @@
from sqlalchemy import Column, String, Integer
from ..db import Base
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
username = Column(String)
location = Column(String)
room_id = Column(String)
reminder_time_in_minutes = Column(Integer)