daily notify
This commit is contained in:
parent
f7d181f144
commit
7b8168e297
@ -4,8 +4,10 @@ from time import sleep
|
|||||||
from telebot.apihelper import ApiTelegramException
|
from telebot.apihelper import ApiTelegramException
|
||||||
|
|
||||||
from daemons.bot import bot
|
from daemons.bot import bot
|
||||||
from helpers import now
|
from helpers import now, get_next_daily_notify_time
|
||||||
|
from helpers.models import UserSchema
|
||||||
from helpers.mongo import mongo
|
from helpers.mongo import mongo
|
||||||
|
from helpers.ruz import ruz
|
||||||
|
|
||||||
|
|
||||||
def process():
|
def process():
|
||||||
@ -28,6 +30,27 @@ def process():
|
|||||||
except ApiTelegramException:
|
except ApiTelegramException:
|
||||||
pass
|
pass
|
||||||
mongo.lessons_collection.update_one({"_id": lesson['_id']}, {"$set": {"notified": True}})
|
mongo.lessons_collection.update_one({"_id": lesson['_id']}, {"$set": {"notified": True}})
|
||||||
|
time_now = now()
|
||||||
|
for user in mongo.users_collection.find({"next_daily_notify_time": {"$lte": time_now}}):
|
||||||
|
user_model = UserSchema().load(user)
|
||||||
|
if time_now.weekday() == 6:
|
||||||
|
mongo.users_collection.update_one(
|
||||||
|
{"chat_id": user["chat_id"]},
|
||||||
|
{"$set": {"next_daily_notify_time": get_next_daily_notify_time(user_model, time_now)}}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
lessons = mongo.get_today_lessons(user_model)
|
||||||
|
if len(lessons) == 0:
|
||||||
|
text = "Сегодня у тебя нет пар."
|
||||||
|
else:
|
||||||
|
text = ruz.schedule_builder(lessons)
|
||||||
|
try:
|
||||||
|
bot.send_message(
|
||||||
|
user["chat_id"],
|
||||||
|
"Уведомляю о занятиях!\n" + text
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def notify():
|
def notify():
|
||||||
|
@ -1,8 +1,26 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import zoneinfo
|
import zoneinfo
|
||||||
|
|
||||||
|
from helpers.models import User
|
||||||
|
|
||||||
|
|
||||||
def now():
|
def now():
|
||||||
zone = zoneinfo.ZoneInfo("Europe/Moscow")
|
zone = zoneinfo.ZoneInfo("Europe/Moscow")
|
||||||
today = datetime.datetime.now(zone) + datetime.timedelta(hours=3)
|
today = datetime.datetime.now(zone) + datetime.timedelta(hours=3)
|
||||||
return today
|
return today
|
||||||
|
|
||||||
|
|
||||||
|
def get_next_daily_notify_time(user: User, time_now: datetime.datetime | None = None) -> datetime.datetime:
|
||||||
|
if time_now is None:
|
||||||
|
time_now = now()
|
||||||
|
hours, minutes = map(int, user.daily_notify_time.split(":"))
|
||||||
|
next_time = datetime.datetime(
|
||||||
|
year=time_now.year,
|
||||||
|
month=time_now.month,
|
||||||
|
day=time_now.day,
|
||||||
|
hour=hours,
|
||||||
|
minute=minutes
|
||||||
|
)
|
||||||
|
if time_now.hour * 60 * time_now.minute < hours * 60 + minutes:
|
||||||
|
next_time = next_time + datetime.timedelta(days=1)
|
||||||
|
return next_time
|
||||||
|
@ -5,8 +5,9 @@ from telebot.types import Message
|
|||||||
|
|
||||||
from daemons.bot import bot
|
from daemons.bot import bot
|
||||||
from daemons.fetch import fetch_schedule_for_user
|
from daemons.fetch import fetch_schedule_for_user
|
||||||
from helpers import now
|
from helpers import now, get_next_daily_notify_time
|
||||||
from helpers.keyboards import main_keyboard, notify_keyboard, yes_no_keyboard, again_keyboard, groups_keyboard
|
from helpers.keyboards import main_keyboard, notify_keyboard, yes_no_keyboard, again_keyboard, groups_keyboard, \
|
||||||
|
no_daily_notify
|
||||||
from helpers.models import UserSchema, User
|
from helpers.models import UserSchema, User
|
||||||
from helpers.mongo import mongo
|
from helpers.mongo import mongo
|
||||||
from helpers.ruz import ruz
|
from helpers.ruz import ruz
|
||||||
@ -19,6 +20,9 @@ class BaseAnswer:
|
|||||||
user = User(chat_id=message.chat.id)
|
user = User(chat_id=message.chat.id)
|
||||||
mongo.users_collection.insert_one(UserSchema().dump(user))
|
mongo.users_collection.insert_one(UserSchema().dump(user))
|
||||||
else:
|
else:
|
||||||
|
# что-то со временем в маршмеллоу происходит, не знаю как решить
|
||||||
|
if 'next_daily_notify_time' in user:
|
||||||
|
user['next_daily_notify_time'] = str(user['next_daily_notify_time'])
|
||||||
user = UserSchema().load(user)
|
user = UserSchema().load(user)
|
||||||
attr = getattr(self, "handle_state_" + user.state, None)
|
attr = getattr(self, "handle_state_" + user.state, None)
|
||||||
if attr is None:
|
if attr is None:
|
||||||
@ -121,6 +125,14 @@ class Answer(BaseAnswer):
|
|||||||
)
|
)
|
||||||
self.set_state(user, "wait_for_notify")
|
self.set_state(user, "wait_for_notify")
|
||||||
return
|
return
|
||||||
|
elif message.text == "Ежедневные уведомления":
|
||||||
|
bot.send_message(
|
||||||
|
user.chat_id,
|
||||||
|
"Каждый день (кроме воскресенья) я буду присылать тебе расписание на день. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 09:30",
|
||||||
|
reply_markup=no_daily_notify()
|
||||||
|
)
|
||||||
|
self.set_state(user, "wait_for_daily_notify")
|
||||||
|
return
|
||||||
elif message.text == "Сброс настроек":
|
elif message.text == "Сброс настроек":
|
||||||
bot.send_message(user.chat_id, "Ты уверен что хочешь сбросить все настройки и больше не получать уведомления?", reply_markup=yes_no_keyboard())
|
bot.send_message(user.chat_id, "Ты уверен что хочешь сбросить все настройки и больше не получать уведомления?", reply_markup=yes_no_keyboard())
|
||||||
self.set_state(user, "reset")
|
self.set_state(user, "reset")
|
||||||
@ -160,6 +172,58 @@ class Answer(BaseAnswer):
|
|||||||
bot.send_message(user.chat_id, text, reply_markup=main_keyboard())
|
bot.send_message(user.chat_id, text, reply_markup=main_keyboard())
|
||||||
self.set_state(user, "ready")
|
self.set_state(user, "ready")
|
||||||
|
|
||||||
|
def _validate_time(self, line: str) -> bool:
|
||||||
|
if len(line) != 5:
|
||||||
|
return False
|
||||||
|
if line.count(":") != 1:
|
||||||
|
return False
|
||||||
|
hours, minutes = line.split(":")
|
||||||
|
try:
|
||||||
|
hours = int(hours)
|
||||||
|
minutes = int(minutes)
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
if hours < 0 or hours > 23 or minutes < 0 and minutes > 59:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def handle_state_wait_for_daily_notify(self, message: Message, user: User):
|
||||||
|
text = message.text
|
||||||
|
if text == "Не уведомлять":
|
||||||
|
mongo.users_collection.update_one(
|
||||||
|
{"chat_id": user.chat_id},
|
||||||
|
{"$set": {"daily_notify_time": None, "next_daily_notify_time": None}}
|
||||||
|
)
|
||||||
|
bot.send_message(
|
||||||
|
user.chat_id,
|
||||||
|
"Принято! Я не буду присылать тебе ежедневные уведомления.",
|
||||||
|
reply_markup=main_keyboard()
|
||||||
|
)
|
||||||
|
self.set_state(user, "ready")
|
||||||
|
return
|
||||||
|
if not self._validate_time(text):
|
||||||
|
bot.send_message(
|
||||||
|
user.chat_id,
|
||||||
|
"Ты прислал мне что-то неправильное. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 09:30",
|
||||||
|
reply_markup=no_daily_notify()
|
||||||
|
)
|
||||||
|
return
|
||||||
|
user.daily_notify_time = text
|
||||||
|
next_time = get_next_daily_notify_time(user)
|
||||||
|
bot.send_message(
|
||||||
|
user.chat_id,
|
||||||
|
f"Принято! Буду уведомлять тебя каждый день в {text}.",
|
||||||
|
reply_markup=main_keyboard()
|
||||||
|
)
|
||||||
|
mongo.users_collection.update_one(
|
||||||
|
{"chat_id": user.chat_id},
|
||||||
|
{"$set": {
|
||||||
|
"daily_notify_time": text,
|
||||||
|
"next_daily_notify_time": next_time,
|
||||||
|
"state": "ready"
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
|
||||||
def handle_state_reset(self, message: Message, user: User):
|
def handle_state_reset(self, message: Message, user: User):
|
||||||
if message.text == "Да":
|
if message.text == "Да":
|
||||||
mongo.users_collection.delete_one({"chat_id": user.chat_id})
|
mongo.users_collection.delete_one({"chat_id": user.chat_id})
|
||||||
|
@ -5,6 +5,7 @@ def main_keyboard():
|
|||||||
kb = telebot.types.ReplyKeyboardMarkup(True, False)
|
kb = telebot.types.ReplyKeyboardMarkup(True, False)
|
||||||
kb.row("Пары сегодня")
|
kb.row("Пары сегодня")
|
||||||
kb.row("Уведомления о парах")
|
kb.row("Уведомления о парах")
|
||||||
|
kb.row("Ежедневные уведомления")
|
||||||
kb.row("Сброс настроек")
|
kb.row("Сброс настроек")
|
||||||
return kb
|
return kb
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ class User:
|
|||||||
hse_id: Optional[int] = None
|
hse_id: Optional[int] = None
|
||||||
state: str = "new"
|
state: str = "new"
|
||||||
notify_minutes: Optional[int] = 10
|
notify_minutes: Optional[int] = 10
|
||||||
|
daily_notify_time: Optional[str] = None
|
||||||
|
next_daily_notify_time: Optional[datetime.datetime] = None
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unknown = EXCLUDE
|
unknown = EXCLUDE
|
||||||
|
@ -20,6 +20,9 @@ class Mongo:
|
|||||||
self.users_collection.create_index([
|
self.users_collection.create_index([
|
||||||
("notify_minutes", 1)
|
("notify_minutes", 1)
|
||||||
])
|
])
|
||||||
|
self.users_collection.create_index([
|
||||||
|
("next_daily_notify_time", 1)
|
||||||
|
])
|
||||||
self.lessons_collection.create_index([
|
self.lessons_collection.create_index([
|
||||||
("discipline", 1),
|
("discipline", 1),
|
||||||
("auditorium", 1),
|
("auditorium", 1),
|
||||||
@ -60,6 +63,7 @@ class Mongo:
|
|||||||
"begin": {"$gte": today, "$lte": tomorrow}}
|
"begin": {"$gte": today, "$lte": tomorrow}}
|
||||||
):
|
):
|
||||||
lessons.append(lesson)
|
lessons.append(lesson)
|
||||||
|
lessons.sort(key=lambda les: les["begin"])
|
||||||
return lessons
|
return lessons
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user