This commit is contained in:
Egor Matveev 2023-08-13 19:48:28 +00:00
parent 6a5a9a1a75
commit 5ec9bb4a7e
14 changed files with 272 additions and 412 deletions

View File

@ -46,6 +46,7 @@ deploy-prod:
- prod - prod
only: only:
- master - master
- hseapp
when: manual when: manual
script: script:
- docker stack deploy --with-registry-auth -c ./.deploy/deploy-prod.yaml ruz-bot - docker stack deploy --with-registry-auth -c ./.deploy/deploy-prod.yaml ruz-bot

View File

@ -13,7 +13,7 @@ def api():
all_users = mongo.users_collection.count_documents({}) all_users = mongo.users_collection.count_documents({})
teachers = mongo.users_collection.count_documents({"is_teacher": True}) teachers = mongo.users_collection.count_documents({"is_teacher": True})
text = f"Всего пользователей: {all_users}<br>" \ text = f"Всего пользователей: {all_users}<br>" \
f"Пользователей прошедших регистрацию: {mongo.users_collection.count_documents({'hse_id': {'$ne': None}})}<br>" \ f"Пользователей прошедших регистрацию: {mongo.users_collection.count_documents({'email': {'$ne': None}})}<br>" \
f"Студентов: {all_users - teachers}<br>" \ f"Студентов: {all_users - teachers}<br>" \
f"Преподавателей: {teachers}<br>" \ f"Преподавателей: {teachers}<br>" \
f"Отписались от уведомлений: {mongo.users_collection.count_documents({'notify_minutes': None})}<br>" \ f"Отписались от уведомлений: {mongo.users_collection.count_documents({'notify_minutes': None})}<br>" \
@ -22,13 +22,13 @@ def api():
f"<br>" \ f"<br>" \
f"<br>" \ f"<br>" \
f"Пользователей из Москвы: {mongo.users_collection.count_documents({'campus': 'Москва'}) + mongo.users_collection.count_documents({'campus': {'$exists': False}})}<br>" \ f"Пользователей из Москвы: {mongo.users_collection.count_documents({'campus': 'Москва'}) + mongo.users_collection.count_documents({'campus': {'$exists': False}})}<br>" \
f"Пользователей из Москвы (регистрация): {mongo.users_collection.count_documents({'campus': 'Москва', 'hse_id': {'$ne': None}}) + mongo.users_collection.count_documents({'campus': {'$exists': False}, 'hse_id': {'$ne': None}})}<br>" \ f"Пользователей из Москвы (регистрация): {mongo.users_collection.count_documents({'campus': 'Москва', 'email': {'$ne': None}}) + mongo.users_collection.count_documents({'campus': {'$exists': False}, 'email': {'$ne': None}})}<br>" \
f"Пользователей из Перми: {mongo.users_collection.count_documents({'campus': 'Пермь'})}<br>" \ f"Пользователей из Перми: {mongo.users_collection.count_documents({'campus': 'Пермь'})}<br>" \
f"Пользователей из Перми (регистрация): {mongo.users_collection.count_documents({'campus': 'Пермь', 'hse_id': {'$ne': None}})}<br>" \ f"Пользователей из Перми (регистрация): {mongo.users_collection.count_documents({'campus': 'Пермь', 'email': {'$ne': None}})}<br>" \
f"Пользователей из Нижнего Новгорода: {mongo.users_collection.count_documents({'campus': 'Нижний Новгород'})}<br>" \ f"Пользователей из Нижнего Новгорода: {mongo.users_collection.count_documents({'campus': 'Нижний Новгород'})}<br>" \
f"Пользователей из Нижнего Новгорода (регистрация): {mongo.users_collection.count_documents({'campus': 'Нижний Новгород', 'hse_id': {'$ne': None}})}<br>" \ f"Пользователей из Нижнего Новгорода (регистрация): {mongo.users_collection.count_documents({'campus': 'Нижний Новгород', 'email': {'$ne': None}})}<br>" \
f"Пользователей из Санкт-Петербурга: {mongo.users_collection.count_documents({'campus': 'Санкт-Петербург'})}<br>" \ f"Пользователей из Санкт-Петербурга: {mongo.users_collection.count_documents({'campus': 'Санкт-Петербург'})}<br>" \
f"Пользователей из Санкт-Петербурга (регистрация): {mongo.users_collection.count_documents({'campus': 'Санкт-Петербург', 'hse_id': {'$ne': None}})}<br>" f"Пользователей из Санкт-Петербурга (регистрация): {mongo.users_collection.count_documents({'campus': 'Санкт-Петербург', 'email': {'$ne': None}})}<br>"
return text return text
@app.route('/alice', methods=['POST']) @app.route('/alice', methods=['POST'])

View File

@ -16,5 +16,5 @@ def on_start(message: Message):
@bot.message_handler() @bot.message_handler()
def do_action(message: Message): def do_action(message: Message):
from helpers.answer import answer from helpers.answer import Answer
answer.process(message) Answer(message).process()

View File

@ -2,16 +2,14 @@ import datetime
import logging import logging
from time import sleep from time import sleep
from helpers import now, User from helpers import now, campus_timdelta
from helpers.models import UserSchema
from helpers.mongo import mongo from helpers.mongo import mongo
from helpers.ruz import ruz from helpers.ruz import ruz
def fetch_schedule_for_user(user: User): def fetch_schedule_for_user(user: dict):
today = now(user) today = now(user)
next_day = today + datetime.timedelta(days=7) schedule = ruz.get_schedule(user, today)
schedule = ruz.get_schedule(user, today, next_day)
if schedule is None: if schedule is None:
return False return False
saved_ids = [] saved_ids = []
@ -23,35 +21,35 @@ def fetch_schedule_for_user(user: User):
"discipline": element['discipline'], "discipline": element['discipline'],
"auditorium": element['auditorium'], "auditorium": element['auditorium'],
"link": element['url1'], "link": element['url1'],
"hse_user_id": user.hse_id, "user_email": user['email'],
"begin": datetime.datetime( "begin": datetime.datetime(
year=int(year), year=int(year),
month=int(month), month=int(month),
day=int(day), day=int(day),
hour=int(begin_hour), hour=int(begin_hour),
minute=int(begin_minute), minute=int(begin_minute),
) ) + datetime.timedelta(hours=campus_timdelta[user.get('campus', 'Москва')])
}) })
if lesson is None: if lesson is None:
result = mongo.lessons_collection.insert_one({ result = mongo.lessons_collection.insert_one({
"discipline": element['discipline'], "discipline": element['discipline'],
"auditorium": element['auditorium'], "auditorium": element['auditorium'],
"link": element['url1'], "link": element['url1'],
"hse_user_id": user.hse_id, "user_email": user['email'],
"begin": datetime.datetime( "begin": datetime.datetime(
year=int(year), year=int(year),
month=int(month), month=int(month),
day=int(day), day=int(day),
hour=int(begin_hour), hour=int(begin_hour),
minute=int(begin_minute), minute=int(begin_minute),
), ) + datetime.timedelta(hours=campus_timdelta[user.get('campus', 'Москва')]),
"end": datetime.datetime( "end": datetime.datetime(
year=int(year), year=int(year),
month=int(month), month=int(month),
day=int(day), day=int(day),
hour=int(end_hour), hour=int(end_hour),
minute=int(end_minute), minute=int(end_minute),
), ) + datetime.timedelta(hours=campus_timdelta[user.get('campus', 'Москва')]),
"building": element['building'], "building": element['building'],
"lecturer": element['lecturer'], "lecturer": element['lecturer'],
"notified": False, "notified": False,
@ -60,13 +58,17 @@ def fetch_schedule_for_user(user: User):
saved_ids.append(result.inserted_id) saved_ids.append(result.inserted_id)
else: else:
saved_ids.append(lesson['_id']) saved_ids.append(lesson['_id'])
mongo.lessons_collection.delete_many({"hse_user_id": user.hse_id, "_id": {"$nin": saved_ids}}) mongo.lessons_collection.delete_many({"user_email": user['email'], "_id": {"$nin": saved_ids}})
mongo.users_collection.update_one({"_id": user['_id']}, {"$set": {'last_schedule_fetch': datetime.datetime.now()}})
return True return True
def process(): def process():
for user in mongo.users_collection.find({"hse_id": {"$ne": None}}): for user in mongo.users_collection.find({"email": {"$exists": True, "$ne": None}}).sort([
fetch_schedule_for_user(UserSchema().load(user)) ("last_schedule_fetch", 1)
]):
fetch_schedule_for_user(user)
sleep(5)
def delete_old(): def delete_old():
@ -77,9 +79,12 @@ def fetch():
while True: while True:
logging.info("fetch start") logging.info("fetch start")
begin = datetime.datetime.now() begin = datetime.datetime.now()
if begin.hour > 22 or begin.hour < 7:
logging.info("Too late, sleeping")
sleep(30 * 60)
continue
process() process()
end = datetime.datetime.now() end = datetime.datetime.now()
logging.info('fetch finished') logging.info('fetch finished')
logging.info("time elapsed %s", (end - begin).total_seconds()) logging.info("time elapsed %s", (end - begin).total_seconds())
delete_old() delete_old()
sleep(60 * 5)

View File

@ -6,16 +6,15 @@ from telebot.apihelper import ApiTelegramException
from daemons.bot import bot from daemons.bot import bot
from helpers import now from helpers import now
from helpers.models import UserSchema
from helpers.mongo import mongo from helpers.mongo import mongo
from helpers.ruz import ruz from helpers.ruz import ruz
def process(): def process():
for user in mongo.users_collection.find({"notify_minutes": {"$ne": None}, "hse_id": {"$ne": None}}): for user in mongo.users_collection.find({"notify_minutes": {"$ne": None}, "email": {"$ne": None}}):
time_now = now(UserSchema().load(user)) time_now = now(user)
for lesson in mongo.lessons_collection.find({ for lesson in mongo.lessons_collection.find({
"hse_user_id": user["hse_id"], "user_email": user["email"],
"begin": {"$lte": time_now + datetime.timedelta(minutes=user["notify_minutes"])}, "begin": {"$lte": time_now + datetime.timedelta(minutes=user["notify_minutes"])},
"notified": False "notified": False
}): }):
@ -36,34 +35,33 @@ def process():
mongo.lessons_collection.update_one({"_id": lesson['_id']}, {"$set": {"notified": True}}) mongo.lessons_collection.update_one({"_id": lesson['_id']}, {"$set": {"notified": True}})
time_now = datetime.datetime.now() time_now = datetime.datetime.now()
for user in mongo.users_collection.find({"next_daily_notify_time": {"$lte": time_now}}): for user in mongo.users_collection.find({"next_daily_notify_time": {"$lte": time_now}}):
user_model = UserSchema().load(user) deny_weekday = 6 if user.get('daily_notify_today', True) else 5
deny_weekday = 6 if user_model.daily_notify_today else 5
if time_now.weekday() != deny_weekday: if time_now.weekday() != deny_weekday:
if user_model.daily_notify_today: if user.get('daily_notify_today', True):
lessons = mongo.get_today_lessons(user_model) lessons = mongo.get_today_lessons(user)
else: else:
lessons = mongo.get_tomorrow_lessons(user_model) lessons = mongo.get_tomorrow_lessons(user)
if len(lessons) == 0: if len(lessons) == 0:
text = f"{'Сегодня' if user_model.daily_notify_today else 'Завтра'} у тебя нет пар, отдыхай." text = f"{'Сегодня' if user.get('daily_notify_today', True) else 'Завтра'} у тебя нет пар, отдыхай."
else: else:
text = ruz.schedule_builder(lessons) text = ruz.schedule_builder(lessons)
try: try:
bot.send_message( bot.send_message(
user["chat_id"], user["chat_id"],
f"Уведомляю о занятиях! Твое расписание на {'сегодня' if user_model.daily_notify_today else 'завтра'}:\n" + text, f"Уведомляю о занятиях! Твое расписание на {'сегодня' if user.get('daily_notify_today', True) else 'завтра'}:\n" + text,
parse_mode='Markdown' parse_mode='Markdown'
) )
except: except:
pass pass
mongo.users_collection.update_one( mongo.users_collection.update_one(
{"chat_id": user["chat_id"]}, {"chat_id": user["chat_id"]},
{"$set": {"next_daily_notify_time": user_model.next_daily_notify_time + datetime.timedelta(days=1)}} {"$set": {"next_daily_notify_time": user['next_daily_notify_time'] + datetime.timedelta(days=1)}}
) )
for user in mongo.users_collection.find({"first_lesson_notify": {"$exists": True}, "first_lesson_notify": {"$ne": None}, "hse_id": {"$ne": None}}): for user in mongo.users_collection.find({"first_lesson_notify": {"$exists": True, "$ne": None}, "email": {"$ne": None}}):
time_now = now(UserSchema().load(user)) time_now = now(user)
for lesson in mongo.lessons_collection.find({ for lesson in mongo.lessons_collection.find({
"hse_user_id": user["hse_id"], "user_email": user["email"],
"begin": {"$lte": time_now + datetime.timedelta(minutes=user["first_lesson_notify"])}, "begin": {"$lte": time_now + datetime.timedelta(minutes=user["first_lesson_notify"])},
"notified_today": {"$ne": True} "notified_today": {"$ne": True}
}).sort("begin"): }).sort("begin"):
@ -92,7 +90,7 @@ def process():
except ApiTelegramException: except ApiTelegramException:
pass pass
start_of_day = datetime.datetime(year=time_now.year, month=time_now.month, day=time_now.day) start_of_day = datetime.datetime(year=time_now.year, month=time_now.month, day=time_now.day)
mongo.lessons_collection.update_many({"begin": {"$gte": start_of_day, "$lt": (start_of_day + datetime.timedelta(days=1))}, "hse_user_id": user["hse_id"]}, {"$set": {"notified_today": True}}) mongo.lessons_collection.update_many({"begin": {"$gte": start_of_day, "$lt": (start_of_day + datetime.timedelta(days=1))}, "user_email": user["email"]}, {"$set": {"notified_today": True}})
break break

View File

@ -1,9 +1,5 @@
import datetime import datetime
import logging import logging
import zoneinfo
from helpers.models import User
campus_timdelta = { campus_timdelta = {
"Москва": 3, "Москва": 3,
@ -12,14 +8,15 @@ campus_timdelta = {
"Пермь": 5 "Пермь": 5
} }
def now(user: User):
today = datetime.datetime.now() + datetime.timedelta(hours=campus_timdelta[user.campus]) def now(user: dict):
today = datetime.datetime.now() + datetime.timedelta(hours=campus_timdelta[user.get('campus', 'Москва')])
return today return today
def get_next_daily_notify_time(user: User) -> datetime.datetime: def get_next_daily_notify_time(user: dict) -> datetime.datetime:
time_now = now(user) time_now = now(user)
hours, minutes = map(int, user.daily_notify_time.split(":")) hours, minutes = map(int, user['daily_notify_time'].split(":"))
next_time = datetime.datetime( next_time = datetime.datetime(
year=time_now.year, year=time_now.year,
month=time_now.month, month=time_now.month,
@ -32,4 +29,4 @@ def get_next_daily_notify_time(user: User) -> datetime.datetime:
if time_now.hour * 60 + time_now.minute > hours * 60 + minutes: if time_now.hour * 60 + time_now.minute > hours * 60 + minutes:
logging.info('go to next day') logging.info('go to next day')
next_time = next_time + datetime.timedelta(days=1) next_time = next_time + datetime.timedelta(days=1)
return next_time - datetime.timedelta(hours=campus_timdelta[user.campus]) return next_time - datetime.timedelta(hours=campus_timdelta[user.get('campus', 'Москва')])

View File

@ -3,7 +3,6 @@ from typing import Optional
from daemons.bot import bot from daemons.bot import bot
from helpers import now from helpers import now
from helpers.models import UserSchema
from helpers.mongo import mongo from helpers.mongo import mongo
@ -40,7 +39,6 @@ class Processor:
def get_lesson_for_user(self, hse_id: int): def get_lesson_for_user(self, hse_id: int):
user = mongo.users_collection.find_one({"hse_id": hse_id}) user = mongo.users_collection.find_one({"hse_id": hse_id})
user = UserSchema().load(user)
t = now(user) t = now(user)
for lesson in mongo.lessons_collection.find({"hse_user_id": hse_id, "begin": {"$gte": t}}).sort([("begin", 1)]): for lesson in mongo.lessons_collection.find({"hse_user_id": hse_id, "begin": {"$gte": t}}).sort([("begin", 1)]):
return lesson return lesson

View File

@ -1,351 +1,266 @@
from telebot.types import Message import datetime
from telebot.types import Message, ReplyKeyboardRemove
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 get_next_daily_notify_time from helpers import 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, no_daily_notify, \
no_daily_notify, student_or_teacher_keyboard, campus_keyboard, daily_notify_type, notify_type, first_lesson_notify campus_keyboard, daily_notify_type, notify_type, first_lesson_notify
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
class BaseAnswer: class Answer:
def process(self, message: Message):
user: dict
message: Message
message_text: str
def __init__(self, message: Message):
self.message = message
self.message = message
self.message_text = message.text or message.caption or ""
user = mongo.users_collection.find_one({"chat_id": message.chat.id}) user = mongo.users_collection.find_one({"chat_id": message.chat.id})
if user is None: if user is None:
user = User(chat_id=message.chat.id) user = {
mongo.users_collection.insert_one(UserSchema().dump(user)) "chat_id": message.chat.id,
else: 'email': None,
user = UserSchema().load(user) 'state': 'new',
attr = getattr(self, "handle_state_" + user.state, None) 'notify_minutes': 10,
if attr is None: 'daily_notify_time': None,
raise NotImplementedError(f"handled state {user.state} but not implemented!") 'next_daily_notify_time': None,
attr(message, user) 'campus': "Москва",
'daily_notify_today': True,
'first_lesson_notify': None,
'last_schedule_fetch': datetime.datetime.now(),
'yandex_id': None
}
mongo.users_collection.insert_one(user)
self.user = user
def set_state(self, user: User, state: str): def process(self):
user.state = state getattr(
mongo.users_collection.update_one({"chat_id": user.chat_id}, {"$set": {"state": state}}) self,
"handle_state_" + self.user['state'],
self.handle_state_default
)()
def handle_state_default(self):
raise NotImplementedError(f"handled state {self.user['state']} but not implemented!")
class Answer(BaseAnswer): def send_message(self, text, reply_markup=None, remove_keyboard=True, **kwargs):
if reply_markup is None and remove_keyboard:
reply_markup = ReplyKeyboardRemove()
bot.send_message(self.user['chat_id'], text, reply_markup=reply_markup, **kwargs)
def handle_state_new(self, message: Message, user: User): def set_state(self, state: str):
bot.send_message( self.user['state'] = state
message.chat.id, mongo.users_collection.update_one({"chat_id": self.user['chat_id']}, {"$set": {"state": state}})
def handle_state_new(self):
self.send_message(
"Привет! Я буду помогать тебе выживать в вышке!\nИз какого ты кампуса?", "Привет! Я буду помогать тебе выживать в вышке!\nИз какого ты кампуса?",
reply_markup=campus_keyboard() reply_markup=campus_keyboard()
) )
self.set_state(user, "wait_for_campus") self.set_state("wait_for_campus")
def handle_state_wait_for_campus(self, message: Message, user: User): def handle_state_wait_for_campus(self):
if message.text not in ["Москва", "Санкт-Петербург", "Нижний Новгород", "Пермь"]: if self.message_text not in ["Москва", "Санкт-Петербург", "Нижний Новгород", "Пермь"]:
bot.send_message( self.send_message(
user.chat_id,
"Ты прислал мне что-то непонятное, используй кнопки. Из какого ты кампуса?", "Ты прислал мне что-то непонятное, используй кнопки. Из какого ты кампуса?",
reply_markup=campus_keyboard() reply_markup=campus_keyboard()
) )
return return
bot.send_message( self.send_message("Принято! А теперь отправь мне свою корпоративную почту.")
user.chat_id,
"Принято! Ты преподаватель или студент?",
reply_markup=student_or_teacher_keyboard()
)
mongo.users_collection.update_one( mongo.users_collection.update_one(
{"chat_id": user.chat_id}, {"chat_id": self.user['chat_id']},
{"$set": {"campus": message.text, "state": "wait_for_student_or_teacher"}} {"$set": {"campus": self.message_text, "state": "wait_for_email"}}
) )
def handle_state_wait_for_student_or_teacher(self, message: Message, user: User): def handle_state_wait_for_email(self):
if message.text == "Студент 👨‍🎓": self.user['email'] = self.message_text
bot.send_message(user.chat_id, "Принято! Теперь отправь мне свое ФИО.", reply_markup=again_keyboard()) schedule = fetch_schedule_for_user(self.user)
mongo.users_collection.update_one( if schedule is None:
{"chat_id": user.chat_id}, self.send_message("Возможно, в РУЗе какие-то сбои, либо твой email неправильный. Попробуй ввести email еще раз.")
{"$set": {"is_teacher": False, "state": "wait_for_name"}}
)
self.set_state(user, "wait_for_name")
elif message.text == "Преподаватель 👨‍🏫":
bot.send_message(user.chat_id, "Принято! Теперь отправь мне свое ФИО.", reply_markup=again_keyboard())
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"is_teacher": True, "state": "wait_for_name"}}
)
self.set_state(user, "wait_for_name")
elif message.text == "Начать заново 🔄":
bot.send_message(
message.chat.id,
"Привет! Я буду помогать тебе выживать в вышке!\nИз какого ты кампуса?",
reply_markup=campus_keyboard()
)
self.set_state(user, "wait_for_campus")
return return
else: mongo.users_collection.update_one({"chat_id": self.user['chat_id']}, {"$set": {
bot.send_message(user.chat_id, "Ты отправил мне что-то неправильное, используй кнопки. Ты преподаватель или студент?", reply_markup=student_or_teacher_keyboard()) "email": self.user['email'],
def handle_state_wait_for_name(self, message: Message, user: User):
if message.text == "Начать заново 🔄":
bot.send_message(
message.chat.id,
"Привет! Я буду помогать тебе выживать в вышке!\nИз какого ты кампуса?",
reply_markup=campus_keyboard()
)
self.set_state(user, "wait_for_campus")
return
user.name = message.text
data = ruz.find_person(user)
if data is None:
bot.send_message(
user.chat_id,
"В РУЗе какая-то поломка, попробуй еще раз позже."
)
return
if len(data) == 0:
bot.send_message(user.chat_id, "К сожалению, в РУЗе не нашлось такого человека, попробуй еще раз.")
return
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"name": user.name}})
if user.is_teacher:
bot.send_message(
user.chat_id,
"Отлично! Теперь выбери из списка свой департамент.",
reply_markup=groups_keyboard(data)
)
else:
bot.send_message(
user.chat_id,
"Отлично! Теперь выбери из списка свою группу.",
reply_markup=groups_keyboard(data)
)
self.set_state(user, "wait_for_group")
def handle_state_wait_for_group(self, message: Message, user: User):
if message.text == "Начать заново 🔄":
bot.send_message(
message.chat.id,
"Привет! Я буду помогать тебе выживать в вышке!\nИз какого ты кампуса?",
reply_markup=campus_keyboard()
)
self.set_state(user, "wait_for_campus")
return
group = message.text
data = ruz.find_person(user)
if data is None:
bot.send_message(
user.chat_id,
"В РУЗе какая-то поломка, попробуй еще раз позже."
)
return
for element in data:
if element['description'] == group:
user.hse_id = int(element['id'])
user.group = group
user.name = element['label']
break
if user.group is None:
bot.send_message(user.chat_id, "Ты ввел что-то неправильно, попробуй еще раз сначала. Из какого ты кампуса?", reply_markup=campus_keyboard())
self.set_state(user, "wait_for_campus")
return
mongo.users_collection.update_one({"chat_id": user.chat_id}, {"$set": {
"hse_id": user.hse_id,
"group": group,
"name": user.name
}}) }})
bot.send_message( self.send_message(
user.chat_id,
"Я нашел тебя в базе РУЗ. Я буду подсказывать тебе расписание, а также уведомлять о предстоящих парах.", "Я нашел тебя в базе РУЗ. Я буду подсказывать тебе расписание, а также уведомлять о предстоящих парах.",
) )
success = fetch_schedule_for_user(user) lessons = mongo.get_today_lessons(self.user)
if success: if len(lessons) == 0:
lessons = mongo.get_today_lessons(user) self.send_message(
if len(lessons) == 0: "Сегодня у тебя нет пар, отдыхай",
bot.send_message( reply_markup=main_keyboard()
user.chat_id, )
"Сегодня у тебя нет пар, отдыхай", else:
reply_markup=main_keyboard() self.send_message(
) "Твои пары сегодня:\n" + ruz.schedule_builder(lessons),
else: reply_markup=main_keyboard(),
bot.send_message( parse_mode='Markdown',
user.chat_id, )
"Твои пары сегодня:\n" + ruz.schedule_builder(lessons), self.set_state("ready")
reply_markup=main_keyboard(),
parse_mode='Markdown',
)
self.set_state(user, "ready")
def handle_state_ready(self, message: Message, user: User): def handle_state_ready(self):
if message.text == "Пары сегодня": if self.message_text == "Пары сегодня":
lessons = mongo.get_today_lessons(user) lessons = mongo.get_today_lessons(self.user)
if len(lessons) == 0: if len(lessons) == 0:
text = "Сегодня у тебя нет пар, отдыхай." text = "Сегодня у тебя нет пар, отдыхай."
else: else:
text = ruz.schedule_builder(lessons) text = ruz.schedule_builder(lessons)
elif message.text == "Пары завтра": elif self.message_text == "Пары завтра":
lessons = mongo.get_tomorrow_lessons(user) lessons = mongo.get_tomorrow_lessons(self.user)
if len(lessons) == 0: if len(lessons) == 0:
text = "Завтра у тебя нет пар, отдыхай." text = "Завтра у тебя нет пар, отдыхай."
else: else:
text = ruz.schedule_builder(lessons) text = ruz.schedule_builder(lessons)
elif message.text == "Расписание на неделю": elif self.message_text == "Расписание на неделю":
lessons = mongo.get_week_lessons(user) lessons = mongo.get_week_lessons(self.user)
if len(lessons) == 0: if len(lessons) == 0:
text = "На этой неделе у тебя нет пар, отдыхай." text = "На этой неделе у тебя нет пар, отдыхай."
else: else:
text = ruz.schedule_builder(lessons) text = ruz.schedule_builder(lessons)
elif message.text == "Напоминания о парах": elif self.message_text == "Напоминания о парах":
bot.send_message( self.send_message(
user.chat_id,
"Я умею напоминать о каждой паре и о первой паре. Что хочешь настроить?", "Я умею напоминать о каждой паре и о первой паре. Что хочешь настроить?",
reply_markup=notify_type() reply_markup=notify_type()
) )
self.set_state(user, "notify_type") self.set_state("notify_type")
return return
elif message.text == "Ежедневные уведомления": elif self.message_text == "Ежедневные уведомления":
bot.send_message( self.send_message(
user.chat_id,
"Я могу присылать тебе расписание на текущий день или на следующий. Как ты хочешь чтобы я тебя уведомлял?", "Я могу присылать тебе расписание на текущий день или на следующий. Как ты хочешь чтобы я тебя уведомлял?",
reply_markup=daily_notify_type() reply_markup=daily_notify_type()
) )
self.set_state(user, "wait_for_daily_notify_type") self.set_state("wait_for_daily_notify_type")
return return
elif message.text == "Сброс настроек": elif self.message_text == "Сброс настроек":
bot.send_message(user.chat_id, "Ты уверен что хочешь сбросить все настройки и больше не получать уведомления?", reply_markup=yes_no_keyboard()) self.send_message("Ты уверен что хочешь сбросить все настройки и больше не получать уведомления?", reply_markup=yes_no_keyboard())
self.set_state(user, "reset") self.set_state("reset")
return return
elif message.text == "Подключение Алисы": elif self.message_text == "Подключение Алисы":
if user.yandex_id is None: if self.user['yandex_id'] is None:
text = "Для того, чтобы подключить Яндекс.Алису, вызови навык \"Расписание вышки\" и назови этот код: " + str(user.hse_id) text = "Для того, чтобы подключить Яндекс.Алису, вызови навык \"Расписание вышки\" и назови этот код: " + str(self.user['hse_id'])
else: else:
text = "Янедкс.Алиса уже подключена. Чтобы узнать ближайшую пару, вызови навык \"Расписание вышки\"" text = "Янедкс.Алиса уже подключена. Чтобы узнать ближайшую пару, вызови навык \"Расписание вышки\""
else: else:
text = "Я не понимаю такой команды, используй кнопки." text = "Я не понимаю такой команды, используй кнопки."
bot.send_message( self.send_message(
user.chat_id,
text, text,
reply_markup=main_keyboard(), reply_markup=main_keyboard(),
parse_mode='Markdown' parse_mode='Markdown'
) )
def handle_state_notify_type(self, message: Message, user: User): def handle_state_notify_type(self):
text = message.text if self.message_text == "О каждой паре":
if text == "О каждой паре": self.send_message(
bot.send_message(
user.chat_id,
"Выбери за сколько минут мне нужно напомнить тебе о предстоящей паре", "Выбери за сколько минут мне нужно напомнить тебе о предстоящей паре",
reply_markup=notify_keyboard() reply_markup=notify_keyboard()
) )
self.set_state(user, "wait_for_notify") self.set_state("wait_for_notify")
elif text == "О первой паре": elif self.message_text == "О первой паре":
bot.send_message( self.send_message(
user.chat_id,
"Выбери за сколько минут мне нужно напоминать тебе о первой паре", "Выбери за сколько минут мне нужно напоминать тебе о первой паре",
reply_markup=first_lesson_notify() reply_markup=first_lesson_notify()
) )
self.set_state(user, "wait_for_first_notify") self.set_state("wait_for_first_notify")
elif text == "Назад": elif self.message_text == "Назад":
self.set_state(user, "ready") self.set_state("ready")
bot.send_message( self.send_message(
user.chat_id, self.message_text,
text,
reply_markup=main_keyboard() reply_markup=main_keyboard()
) )
else: else:
bot.send_message(user.chat_id, "Используй кнопки!", reply_markup=notify_type()) self.send_message("Используй кнопки!", reply_markup=notify_type())
def handle_state_wait_for_first_notify(self, message: Message, user: User): def handle_state_wait_for_first_notify(self):
text = message.text if self.message_text == "30 минут":
if text == "30 минут":
time_notify = 30 time_notify = 30
elif text == "1 час": elif self.message_text == "1 час":
time_notify = 60 time_notify = 60
elif text == "4 часа": elif self.message_text == "4 часа":
time_notify = 4 * 60 time_notify = 4 * 60
elif text == "12 часов": elif self.message_text == "12 часов":
time_notify = 12 * 60 time_notify = 12 * 60
elif text == "Не уведомлять": elif self.message_text == "Не уведомлять":
time_notify = None time_notify = None
else: else:
bot.send_message(user.chat_id, "Используй кнопки!", reply_markup=first_lesson_notify()) self.send_message("Используй кнопки!", reply_markup=first_lesson_notify())
return return
mongo.users_collection.update_one({"chat_id": user.chat_id}, {"$set": {"first_lesson_notify": time_notify}}) mongo.users_collection.update_one({"chat_id": self.user['chat_id']}, {"$set": {"first_lesson_notify": time_notify}})
self.set_state(user, "ready") self.set_state("ready")
bot.send_message(user.chat_id, "Запомнил!", reply_markup=main_keyboard()) self.send_message("Запомнил!", reply_markup=main_keyboard())
def handle_state_wait_for_daily_notify_type(self, message: Message, user: User): def handle_state_wait_for_daily_notify_type(self):
text = message.text if self.message_text == "Текущий день":
if text == "Текущий день": self.send_message(
bot.send_message(
user.chat_id,
"Каждый день (кроме воскресенья) я буду присылать тебе расписание на текущий день. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 09:30", "Каждый день (кроме воскресенья) я буду присылать тебе расписание на текущий день. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 09:30",
reply_markup=no_daily_notify() reply_markup=no_daily_notify()
) )
mongo.users_collection.update_one( mongo.users_collection.update_one(
{"chat_id": user.chat_id}, {"chat_id": self.user['chat_id']},
{"$set": {"daily_notify_today": True, "state": "wait_for_daily_notify"}} {"$set": {"daily_notify_today": True, "state": "wait_for_daily_notify"}}
) )
elif text == "Следующий день": elif self.message_text == "Следующий день":
bot.send_message( self.send_message(
user.chat_id,
"Каждый день (кроме субботы) я буду присылать тебе расписание на следующий день. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 20:30", "Каждый день (кроме субботы) я буду присылать тебе расписание на следующий день. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 20:30",
reply_markup=no_daily_notify() reply_markup=no_daily_notify()
) )
mongo.users_collection.update_one( mongo.users_collection.update_one(
{"chat_id": user.chat_id}, {"chat_id": self.user['chat_id']},
{"$set": {"daily_notify_today": False, "state": "wait_for_daily_notify"}} {"$set": {"daily_notify_today": False, "state": "wait_for_daily_notify"}}
) )
elif text == "Не уведомлять": elif self.message_text == "Не уведомлять":
bot.send_message( self.send_message(
user.chat_id,
"Принято! Я не буду уведомлять тебя.", "Принято! Я не буду уведомлять тебя.",
reply_markup=main_keyboard() reply_markup=main_keyboard()
) )
mongo.users_collection.update_one( mongo.users_collection.update_one(
{"chat_id": user.chat_id}, {"chat_id": self.user['chat_id']},
{"$set": {"next_daily_notify_time": None, "daily_notify_time": None, "state": "ready"}} {"$set": {"next_daily_notify_time": None, "daily_notify_time": None, "state": "ready"}}
) )
elif text == "Назад": elif self.message_text == "Назад":
bot.send_message( self.send_message(
user.chat_id,
"Возвращаюсь!", "Возвращаюсь!",
reply_markup=main_keyboard() reply_markup=main_keyboard()
) )
mongo.users_collection.update_one( mongo.users_collection.update_one(
{"chat_id": user.chat_id}, {"chat_id": self.user['chat_id']},
{"$set": {"next_daily_notify_time": None, "daily_notify_time": None, "state": "ready"}} {"$set": {"next_daily_notify_time": None, "daily_notify_time": None, "state": "ready"}}
) )
else: else:
bot.send_message( self.send_message(
user.chat_id,
"Ты прислал мне что-то неправильное, используй кнопки. Как ты хочешь чтобы я тебя уведомлял?", "Ты прислал мне что-то неправильное, используй кнопки. Как ты хочешь чтобы я тебя уведомлял?",
reply_markup=daily_notify_type() reply_markup=daily_notify_type()
) )
def handle_state_wait_for_notify(self, message: Message, user: User): def handle_state_wait_for_notify(self):
text = message.text if self.message_text == "Не уведомлять":
if text == "Не уведомлять": self.user['notify_minutes'] = None
user.notify_minutes = None elif self.message_text == "5 минут":
elif text == "5 минут": self.user['notify_minutes'] = 5
user.notify_minutes = 5 elif self.message_text == "10 минут":
elif text == "10 минут": self.user['notify_minutes'] = 10
user.notify_minutes = 10 elif self.message_text == "15 минут":
elif text == "15 минут": self.user['notify_minutes'] = 15
user.notify_minutes = 15 elif self.message_text == "20 минут":
elif text == "20 минут": self.user['notify_minutes'] = 20
user.notify_minutes = 20
else: else:
bot.send_message( self.send_message(
user.chat_id,
"Я не понимаю такой команды, используй кнопки.", "Я не понимаю такой команды, используй кнопки.",
reply_markup=notify_keyboard() reply_markup=notify_keyboard()
) )
return return
mongo.users_collection.update_one({"chat_id": user.chat_id}, {"$set": {"notify_minutes": user.notify_minutes}}) mongo.users_collection.update_one({"chat_id": self.user['chat_id']}, {"$set": {"notify_minutes": self.user['notify_minutes']}})
if user.notify_minutes is not None: if self.user['notify_minutes'] is not None:
text = f"Принято! Буду уведомлять тебя за {text}." text = f"Принято! Буду уведомлять тебя за {self.message_text}."
else: else:
text = f"Принято! Я не буду уведомлять тебя." text = f"Принято! Я не буду уведомлять тебя."
bot.send_message(user.chat_id, text, reply_markup=main_keyboard()) self.send_message(text, reply_markup=main_keyboard())
self.set_state(user, "ready") self.set_state("ready")
def _validate_time(self, line: str) -> bool: def _validate_time(self, line: str) -> bool:
if len(line) != 5: if len(line) != 5:
@ -362,53 +277,44 @@ class Answer(BaseAnswer):
return False return False
return True return True
def handle_state_wait_for_daily_notify(self, message: Message, user: User): def handle_state_wait_for_daily_notify(self):
text = message.text if self.message_text == "Не уведомлять":
if text == "Не уведомлять": self.send_message(
bot.send_message(
user.chat_id,
"Принято! Я не буду присылать тебе ежедневные уведомления.", "Принято! Я не буду присылать тебе ежедневные уведомления.",
reply_markup=main_keyboard() reply_markup=main_keyboard()
) )
mongo.users_collection.update_one( mongo.users_collection.update_one(
{"chat_id": user.chat_id}, {"chat_id": self.user['chat_id']},
{"$set": {"daily_notify_time": None, "next_daily_notify_time": None, "state": "ready"}} {"$set": {"daily_notify_time": None, "next_daily_notify_time": None, "state": "ready"}}
) )
return return
if not self._validate_time(text): if not self._validate_time(self.message_text):
bot.send_message( self.send_message(
user.chat_id,
"Ты прислал мне что-то неправильное. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 09:30", "Ты прислал мне что-то неправильное. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 09:30",
reply_markup=no_daily_notify() reply_markup=no_daily_notify()
) )
return return
user.daily_notify_time = text self.user['daily_notify_time'] = self.message_text
next_time = get_next_daily_notify_time(user) next_time = get_next_daily_notify_time(self.user)
bot.send_message( self.send_message(
user.chat_id, f"Принято! Буду уведомлять тебя каждый день в {self.message_text}.",
f"Принято! Буду уведомлять тебя каждый день в {text}.",
reply_markup=main_keyboard() reply_markup=main_keyboard()
) )
mongo.users_collection.update_one( mongo.users_collection.update_one(
{"chat_id": user.chat_id}, {"chat_id": self.user['chat_id']},
{"$set": { {"$set": {
"daily_notify_time": text, "daily_notify_time": self.message_text,
"next_daily_notify_time": next_time, "next_daily_notify_time": next_time,
"state": "ready" "state": "ready"
}} }}
) )
def handle_state_reset(self, message: Message, user: User): def handle_state_reset(self):
if message.text == "Да": if self.message_text == "Да":
mongo.users_collection.delete_one({"chat_id": user.chat_id}) mongo.users_collection.delete_one({"email": self.user['email']})
bot.send_message(user.chat_id, "Настройки сброшены, ждем твоего возвращения", reply_markup=again_keyboard()) self.send_message("Настройки сброшены, ждем твоего возвращения", reply_markup=again_keyboard())
elif message.text == "Нет": elif self.message_text == "Нет":
bot.send_message(user.chat_id, "Возращаюсь к прежнему режиму", reply_markup=main_keyboard()) self.send_message("Возращаюсь к прежнему режиму", reply_markup=main_keyboard())
self.set_state(user, "ready") self.set_state("ready")
else: else:
bot.send_message(user.chat_id, self.send_message("Я не понимаю, используй кнопки", reply_markup=yes_no_keyboard())
"Я не понимаю, используй кнопки",
reply_markup=yes_no_keyboard())
answer = Answer()

View File

@ -24,14 +24,6 @@ def campus_keyboard():
return kb return kb
def student_or_teacher_keyboard():
kb = telebot.types.ReplyKeyboardMarkup(True, False)
kb.row("Преподаватель 👨‍🏫")
kb.row("Студент 👨‍🎓")
kb.row("Начать заново 🔄")
return kb
def notify_keyboard(): def notify_keyboard():
kb = telebot.types.ReplyKeyboardMarkup(True, False) kb = telebot.types.ReplyKeyboardMarkup(True, False)
kb.row("Не уведомлять") kb.row("Не уведомлять")
@ -55,14 +47,6 @@ def again_keyboard():
return kb return kb
def groups_keyboard(data):
kb = telebot.types.ReplyKeyboardMarkup(True, False)
for entity in data:
kb.row(entity['description'])
kb.row("Начать заново 🔄")
return kb
def no_daily_notify(): def no_daily_notify():
kb = telebot.types.ReplyKeyboardMarkup(True, False) kb = telebot.types.ReplyKeyboardMarkup(True, False)
kb.row("Не уведомлять") kb.row("Не уведомлять")

View File

@ -1,42 +0,0 @@
import datetime
from dataclasses import dataclass
from typing import Optional
import marshmallow_dataclass
from marshmallow import EXCLUDE
@dataclass
class User:
chat_id: int
name: Optional[str] = None
group: Optional[str] = None
hse_id: Optional[int] = None
state: str = "new"
notify_minutes: Optional[int] = 10
daily_notify_time: Optional[str] = None
next_daily_notify_time: Optional[datetime.datetime] = None
is_teacher: bool = False
campus: str = "Москва"
daily_notify_today: bool = True
first_lesson_notify: Optional[float] = None
yandex_id: Optional[str] = None
class Meta:
unknown = EXCLUDE
@dataclass
class Lesson:
hse_id: int
USchema = marshmallow_dataclass.class_schema(User)
class UserSchema(USchema):
def load(self, entity, *args, **kwargs):
if entity.get('next_daily_notify_time', None) is not None:
entity['next_daily_notify_time'] = entity['next_daily_notify_time'].strftime("%Y-%m-%dT%H:%M:00.000+00:00")
return super().load(entity, *args, **kwargs)

View File

@ -5,7 +5,6 @@ import pymongo
import settings import settings
from helpers import now from helpers import now
from helpers.models import UserSchema, User
class Mongo: class Mongo:
@ -26,21 +25,19 @@ class Mongo:
("discipline", 1), ("discipline", 1),
("auditorium", 1), ("auditorium", 1),
("begin", 1), ("begin", 1),
("hse_user_id", 1), ("user_email", 1),
("link", 1) ("link", 1)
]) ])
self.lessons_collection.create_index([ self.lessons_collection.create_index([
("hse_user_id", 1), ("user_email", 1),
("begin", 1) ("begin", 1)
]) ])
self.lessons_collection.create_index([ self.lessons_collection.create_index([
("hse_user_id", 1), ("user_email", 1),
("begin", 1), ("begin", 1),
("notified", 1) ("notified", 1)
]) ])
def get_user(self, user_id: int) -> User:
return UserSchema().loads(self.users_collection.find_one({"id": user_id}))
def __getitem__(self, item): def __getitem__(self, item):
return self.database.get_collection(item) return self.database.get_collection(item)
@ -53,32 +50,32 @@ class Mongo:
def lessons_collection(self): def lessons_collection(self):
return self["lessons"] return self["lessons"]
def _get_lessons_on_date(self, user: User, date: datetime.datetime): def _get_lessons_on_date(self, user: dict, date: datetime.datetime):
date = datetime.datetime(year=date.year, month=date.month, day=date.day) date = datetime.datetime(year=date.year, month=date.month, day=date.day)
next_date = date + datetime.timedelta(days=1) next_date = date + datetime.timedelta(days=1)
lessons = [] lessons = []
for lesson in self.lessons_collection.find({ for lesson in self.lessons_collection.find({
"hse_user_id": user.hse_id, "user_email": user['email'],
"begin": {"$gte": date, "$lte": next_date}} "begin": {"$gte": date, "$lte": next_date}}
): ):
lessons.append(lesson) lessons.append(lesson)
lessons.sort(key=lambda les: les["begin"]) lessons.sort(key=lambda les: les["begin"])
return lessons return lessons
def get_today_lessons(self, user: User): def get_today_lessons(self, user: dict):
return self._get_lessons_on_date(user, now(user)) return self._get_lessons_on_date(user, now(user))
def get_tomorrow_lessons(self, user: User): def get_tomorrow_lessons(self, user: dict):
return self._get_lessons_on_date(user, now(user) + datetime.timedelta(days=1)) return self._get_lessons_on_date(user, now(user) + datetime.timedelta(days=1))
def get_week_lessons(self, user: User): def get_week_lessons(self, user: dict):
date = now(user) date = now(user)
date = datetime.datetime(year=date.year, month=date.month, day=date.day) date = datetime.datetime(year=date.year, month=date.month, day=date.day)
weekday = date.weekday() weekday = date.weekday()
next_date = date + datetime.timedelta(days=(6 - weekday)) next_date = date + datetime.timedelta(days=(6 - weekday))
lessons = [] lessons = []
for lesson in self.lessons_collection.find({ for lesson in self.lessons_collection.find({
"hse_user_id": user.hse_id, "user_email": user['email'],
"begin": {"$gte": date, "$lte": next_date}} "begin": {"$gte": date, "$lte": next_date}}
): ):
lessons.append(lesson) lessons.append(lesson)

View File

@ -4,47 +4,43 @@ import logging
from requests import get from requests import get
import settings import settings
from helpers import User
fields = [ fields = [
'discipline', 'discipline',
'building', 'building',
'auditorium', 'auditorium',
'date', 'date_start',
'beginLesson', 'date_end',
'endLesson', 'lecturer_profiles',
'lecturer', 'stream_links'
'url1'
] ]
class RUZ: class RUZ:
def find_person(self, user: User) -> dict | None: def reformat_data(self, col):
if user.is_teacher: for data in col:
person_type = "person" date_start = datetime.datetime.strptime(data['date_start'], "%Y-%m-%dT%H:%M:%SZ")
else: date_end = datetime.datetime.strptime(data['date_end'], "%Y-%m-%dT%H:%M:%SZ")
person_type = "student" data['date'] = date_start.strftime("%Y.%m.%d")
search_str = settings.RUZ_API + f"search?term={user.name}&type={person_type}" data['beginLesson'] = date_start.strftime("%H:%M")
try: data['endLesson'] = date_end.strftime("%H:%M")
data = get(search_str) try:
except: data['lecturer'] = data['lecturer_profiles'][0]["full_name"]
return None except:
if data.status_code == 200: data['lecturer'] = 'Неизвестный преподаватель'
data = data.json() try:
for index, value in enumerate(data): data['url1'] = data['stream_links'][0]['link']
data[index]['description'] = value['description'].capitalize() except:
return data data['url1'] = None
return None del data['date_start']
del data['date_end']
del data['lecturer_profiles']
del data['stream_links']
def get_schedule(self, user: User, begin_date: datetime.datetime, end_date: datetime.datetime): def get_schedule(self, user: dict, begin_date: datetime.datetime):
start_date_str = begin_date.strftime("%Y.%m.%d") start_date_str = begin_date.strftime("%Y.%m.%d")
end_date_str = end_date.strftime("%Y.%m.%d") search_str = settings.RUZ_API + f"v3/ruz/lessons?start={start_date_str}&offset=30&email={user['email']}"
if user.is_teacher:
person_type = "person"
else:
person_type = "student"
search_str = settings.RUZ_API + f"schedule/{person_type}/{user.hse_id}?start={start_date_str}&finish={end_date_str}&lng=1"
try: try:
data = get(search_str) data = get(search_str)
except: except:
@ -59,11 +55,12 @@ class RUZ:
return None return None
formatted_data = [ formatted_data = [
{ {
field: element[field] field: element.get(field)
for field in fields for field in fields
} }
for element in data for element in data
] ]
self.reformat_data(formatted_data)
return formatted_data return formatted_data
def _name_weekday(self, weekday: int) -> str: def _name_weekday(self, weekday: int) -> str:

19
migrate.py Normal file
View File

@ -0,0 +1,19 @@
import settings
from daemons.bot import bot
from helpers.keyboards import campus_keyboard
from helpers.mongo import mongo
from requests import get
for user in mongo.users_collection.find({'$or': [{'hse_id': None}, {'hse_id': {'$exists': False}}], "state": {"$ne": "wait_for_campus"}}):
try:
bot.send_message(
user['chat_id'],
"Время закончить регистрацию! Выбери свой кампус обучения.",
reply_markup=campus_keyboard()
)
except Exception as e:
print(e)
continue
print('sent to', user['chat_id'])
mongo.users_collection.update_one({"_id": user['_id']}, {"$set": {"state": "wait_for_campus"}})

View File

@ -7,7 +7,7 @@ MONGO_PASSWORD = os.getenv("MONGO_PASSWORD", "password")
MONGO_HOST = os.getenv("MONGO_HOST", "localhost") MONGO_HOST = os.getenv("MONGO_HOST", "localhost")
DEBUG = os.getenv("DEBUG", "true") == "true" DEBUG = os.getenv("DEBUG", "true") == "true"
RUZ_API = "https://ruz.hse.ru/api/" RUZ_API = "https://api.hseapp.ru/"
MOSCOW_TIMEZONE = zoneinfo.ZoneInfo("Europe/Moscow") MOSCOW_TIMEZONE = zoneinfo.ZoneInfo("Europe/Moscow")
logging_config = { logging_config = {