mirror of
https://github.com/Faridik/Carolyn.git
synced 2026-07-08 05:11:52 +00:00
Добавил sub и unsub
This commit is contained in:
parent
549aaeafd2
commit
9a89cde748
@ -87,7 +87,23 @@ def grades():
|
||||
@superuser
|
||||
def broadcast(student):
|
||||
"""Выполняет рассылку студентам."""
|
||||
return flask.jsonify(app.db.get_all_groups())
|
||||
return flask.jsonify(app.db.get_all_groups_only_sub_students())
|
||||
|
||||
|
||||
@app.route("/sub")
|
||||
@availability
|
||||
def sub():
|
||||
tg_id = flask.request.args.get("tg_id", None)
|
||||
is_subbed = app.db.sub_by_tg_id(tg_id)
|
||||
return flask.jsonify(dict(is_subbed=is_subbed))
|
||||
|
||||
@app.route("/unsub")
|
||||
@availability
|
||||
def unsub():
|
||||
tg_id = flask.request.args.get("tg_id", None)
|
||||
is_unsubbed = app.db.unsub_by_tg_id(tg_id)
|
||||
return flask.jsonify(dict(is_unsubbed=is_unsubbed))
|
||||
|
||||
|
||||
|
||||
@app.errorhandler(StudentAlreadyAuthed)
|
||||
@ -104,6 +120,13 @@ def show_error(err):
|
||||
def show_error(err):
|
||||
return flask.jsonify({"error": type(err).__name__, "message": err.message}), 404
|
||||
|
||||
@app.errorhandler(StudentAlreadySubbed)
|
||||
def show_error(err):
|
||||
return flask.jsonify({"error": type(err).__name__, "message": err.message}), 405
|
||||
|
||||
@app.errorhandler(StudentAlreadyUnsubbed)
|
||||
def show_error(err):
|
||||
return flask.jsonify({"error": type(err).__name__, "message": err.message}), 406
|
||||
|
||||
@app.errorhandler(BadRequest)
|
||||
def show_error(err):
|
||||
|
||||
@ -18,8 +18,9 @@ STUDENT_NUMBERS = 0
|
||||
STUDENT_NAMES = 1
|
||||
GROUP_IDS = 2 # for StudentList and AssignmentList
|
||||
STUDENT_SUBJECTS = 3
|
||||
TELEGRAM_IDS = 4
|
||||
STUDENT_TELEGRAM_IDS = 4
|
||||
AUTH_TOKEN = 5
|
||||
STUDENT_SUBSCRIPTION = 6
|
||||
ASSIGNMENT_NAMES = 1
|
||||
ASSIGNMENT_GROUP = 2
|
||||
ASSIGNMENT_SUBJECT = 3
|
||||
@ -62,6 +63,15 @@ class AnotherStudentAlreadyAuthed(Exception):
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
|
||||
class StudentAlreadySubbed(Exception):
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
|
||||
class StudentAlreadyUnsubbed(Exception):
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
|
||||
class Manager:
|
||||
"""Позволяет выполнять операции с Google таблицами."""
|
||||
@ -148,7 +158,7 @@ class Manager:
|
||||
int(row[STUDENT_NUMBERS]),
|
||||
row[STUDENT_NAMES],
|
||||
group_id,
|
||||
row[TELEGRAM_IDS],
|
||||
row[STUDENT_TELEGRAM_IDS],
|
||||
)
|
||||
)
|
||||
|
||||
@ -162,11 +172,32 @@ class Manager:
|
||||
groups[row[GROUP_IDS]].group_id = row[GROUP_IDS]
|
||||
groups[row[GROUP_IDS]].add_student(
|
||||
Student(
|
||||
int(row[STUDENT_NUMBERS]),
|
||||
row[STUDENT_NAMES],
|
||||
row[GROUP_IDS],
|
||||
row[TELEGRAM_IDS],
|
||||
row[STUDENT_SUBJECTS].split(',')
|
||||
number=int(row[STUDENT_NUMBERS]),
|
||||
name=row[STUDENT_NAMES],
|
||||
group_id=row[GROUP_IDS],
|
||||
tg_id=row[STUDENT_TELEGRAM_IDS],
|
||||
subjects=row[STUDENT_SUBJECTS].split(','),
|
||||
is_subbed=bool(int(row[STUDENT_SUBSCRIPTION])),
|
||||
)
|
||||
)
|
||||
|
||||
return groups
|
||||
|
||||
def get_all_groups_only_sub_students(self) -> list:
|
||||
"""Получить список всех групп."""
|
||||
values = self.get_values()
|
||||
groups = defaultdict(lambda: Group("0"))
|
||||
f = lambda row: row[STUDENT_SUBSCRIPTION] == '1'
|
||||
for row in filter(f,values):
|
||||
groups[row[GROUP_IDS]].group_id = row[GROUP_IDS]
|
||||
groups[row[GROUP_IDS]].add_student(
|
||||
Student(
|
||||
number=int(row[STUDENT_NUMBERS]),
|
||||
name=row[STUDENT_NAMES],
|
||||
group_id=row[GROUP_IDS],
|
||||
tg_id=row[STUDENT_TELEGRAM_IDS],
|
||||
subjects=row[STUDENT_SUBJECTS].split(','),
|
||||
is_subbed=bool(int(row[STUDENT_SUBSCRIPTION])),
|
||||
)
|
||||
)
|
||||
|
||||
@ -183,7 +214,7 @@ class Manager:
|
||||
return Student(
|
||||
int(row[STUDENT_NUMBERS]), name,
|
||||
row[GROUP_IDS],
|
||||
row[TELEGRAM_IDS],
|
||||
row[STUDENT_TELEGRAM_IDS],
|
||||
row[STUDENT_SUBJECTS].split(',')
|
||||
)
|
||||
except StopIteration:
|
||||
@ -194,7 +225,7 @@ class Manager:
|
||||
|
||||
values = self.get_values("StudentList")
|
||||
|
||||
f = lambda row: tg_id == row[TELEGRAM_IDS]
|
||||
f = lambda row: tg_id == row[STUDENT_TELEGRAM_IDS]
|
||||
try:
|
||||
row = next(filter(f, values))
|
||||
return Student(
|
||||
@ -242,13 +273,13 @@ class Manager:
|
||||
f = lambda row: token == row[AUTH_TOKEN]
|
||||
try:
|
||||
row = next(filter(f, values))
|
||||
if row[TELEGRAM_IDS] == tg_id:
|
||||
if row[STUDENT_TELEGRAM_IDS] == tg_id:
|
||||
raise StudentAlreadyAuthed("Студент уже зарегистрировался")
|
||||
elif row[TELEGRAM_IDS]:
|
||||
elif row[STUDENT_TELEGRAM_IDS]:
|
||||
raise AnotherStudentAlreadyAuthed(
|
||||
"Другой студент зарегистрировался по token"
|
||||
)
|
||||
row[TELEGRAM_IDS] = tg_id
|
||||
row[STUDENT_TELEGRAM_IDS] = tg_id
|
||||
self.write_values(values, "StudentList")
|
||||
return Student(
|
||||
int(row[STUDENT_NUMBERS]),
|
||||
@ -258,3 +289,40 @@ class Manager:
|
||||
)
|
||||
except StopIteration:
|
||||
raise StudentNotFound("Не могу найти студента по token")
|
||||
|
||||
|
||||
def sub_by_tg_id(self, tg_id: str) -> bool:
|
||||
"""Подписка пользователя по tg_id"""
|
||||
|
||||
values = self.get_values("StudentList")
|
||||
|
||||
f = lambda row: tg_id == row[STUDENT_TELEGRAM_IDS]
|
||||
try:
|
||||
row = next(filter(f, values))
|
||||
if row[STUDENT_SUBSCRIPTION] == '1':
|
||||
raise StudentAlreadySubbed("Студент уже подписался")
|
||||
|
||||
row[STUDENT_SUBSCRIPTION] = 1
|
||||
self.write_values(values, "StudentList")
|
||||
return True
|
||||
except StopIteration:
|
||||
raise StudentNotFound("Не могу найти студента по tg_id")
|
||||
|
||||
def unsub_by_tg_id(self, tg_id: str) -> bool:
|
||||
"""Подписка пользователя по tg_id"""
|
||||
|
||||
values = self.get_values("StudentList")
|
||||
|
||||
f = lambda row: tg_id == row[STUDENT_TELEGRAM_IDS]
|
||||
try:
|
||||
row = next(filter(f, values))
|
||||
if row[STUDENT_SUBSCRIPTION] == '0':
|
||||
raise StudentAlreadyUnsubbed(
|
||||
"Студент уже не подписан (или никогда не был)"
|
||||
)
|
||||
|
||||
row[STUDENT_SUBSCRIPTION] = 0
|
||||
self.write_values(values, "StudentList")
|
||||
return True
|
||||
except StopIteration:
|
||||
raise StudentNotFound("Не могу найти студента по tg_id")
|
||||
|
||||
@ -66,7 +66,7 @@ def start(update: Update, context: CallbackContext):
|
||||
return
|
||||
|
||||
if req.status_code != 200:
|
||||
LOG.error(f"Ошибка авторизации, у пользователя @{username} {data}")
|
||||
LOG.error(f"Ошибка авторизации у пользователя @{username} {data}")
|
||||
err = data.get("error", "")
|
||||
update.message.reply_text(text=MESSAGES.Auth.failure(err))
|
||||
update.message.reply_sticker(MESSAGES.Stickers.DEAD)
|
||||
@ -176,7 +176,6 @@ def grades_view(update: Update, context: CallbackContext):
|
||||
|
||||
return GRADES_ASSNT
|
||||
|
||||
|
||||
def broadcast(update: Update, context: CallbackContext):
|
||||
"""Команда: разослать студентам."""
|
||||
access_message = update.message.reply_text("🔐 Проверка доступа...")
|
||||
@ -244,6 +243,68 @@ def cancel(update: Update, context: CallbackContext):
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def sub(update: Update, context: CallbackContext):
|
||||
"""Стартовое сообщение (к команде /start)"""
|
||||
|
||||
user_id = update.message.from_user.id
|
||||
username = update.message.from_user.username
|
||||
|
||||
# Длинная операция, сообщим о запущенном процессе.
|
||||
update.message.reply_text(text=MESSAGES.Sub.START)
|
||||
|
||||
LOG.info(f"Subcripting {user_id}")
|
||||
|
||||
try:
|
||||
req = requests.get(
|
||||
f"{HOST}/sub",
|
||||
params={"tg_id": user_id},
|
||||
)
|
||||
data = req.json()
|
||||
except requests.exceptions.RequestException:
|
||||
LOG.exception("@{user_id} вызвал: Ошибка подключения к сервису Spreadsheets.")
|
||||
update.message.reply_sticker(MESSAGES.Stickers.DEAD)
|
||||
return
|
||||
|
||||
if req.status_code != 200:
|
||||
LOG.error(f"Ошибка подписки, у пользователя @{username} {data}")
|
||||
err = data.get("error", "")
|
||||
update.message.reply_text(text=MESSAGES.Sub.failure(err))
|
||||
update.message.reply_sticker(MESSAGES.Stickers.bad())
|
||||
return
|
||||
|
||||
update.message.reply_text(text=MESSAGES.Sub.SUBBED)
|
||||
|
||||
def unsub(update: Update, context: CallbackContext):
|
||||
"""Стартовое сообщение (к команде /start)"""
|
||||
|
||||
user_id = update.message.from_user.id
|
||||
username = update.message.from_user.username
|
||||
|
||||
# Длинная операция, сообщим о запущенном процессе.
|
||||
update.message.reply_text(text=MESSAGES.Unsub.START)
|
||||
|
||||
LOG.info(f"Unsubcripting {user_id}")
|
||||
|
||||
try:
|
||||
req = requests.get(
|
||||
f"{HOST}/unsub",
|
||||
params={"tg_id": user_id},
|
||||
)
|
||||
data = req.json()
|
||||
except requests.exceptions.RequestException:
|
||||
LOG.exception("@{user_id} вызвал: Ошибка подключения к сервису Spreadsheets.")
|
||||
update.message.reply_sticker(MESSAGES.Stickers.DEAD)
|
||||
return
|
||||
|
||||
if req.status_code != 200:
|
||||
LOG.error(f"Ошибка отписки, у пользователя @{username} {data}")
|
||||
err = data.get("error", "")
|
||||
update.message.reply_text(text=MESSAGES.Unsub.failure(err))
|
||||
update.message.reply_sticker(MESSAGES.Stickers.bad())
|
||||
return
|
||||
|
||||
update.message.reply_text(text=MESSAGES.Unsub.UNSUBBED)
|
||||
|
||||
# ==================================================================== HANDLERS
|
||||
|
||||
|
||||
@ -272,9 +333,14 @@ def main() -> None:
|
||||
fallbacks=[CommandHandler("cancel", cancel)],
|
||||
)
|
||||
|
||||
sub_handler = CommandHandler("sub", sub)
|
||||
unsub_handler = CommandHandler("unsub", unsub)
|
||||
|
||||
dispatcher.add_handler(start_handler)
|
||||
dispatcher.add_handler(grades_handler)
|
||||
dispatcher.add_handler(broadcast_handler)
|
||||
dispatcher.add_handler(sub_handler)
|
||||
dispatcher.add_handler(unsub_handler)
|
||||
|
||||
# Начало работы бота
|
||||
updater.start_polling()
|
||||
|
||||
@ -55,6 +55,32 @@ class Messages:
|
||||
def timeit(t: float):
|
||||
return f"⏱ Посмотрели за {t:.2f}с"
|
||||
|
||||
class Sub:
|
||||
START = "📜✍ Оформляю подписку на уведомления..."
|
||||
SUBBED = "👌 Подписка на уведомления оформлена"
|
||||
|
||||
@staticmethod
|
||||
def failure(err: str):
|
||||
cases = {
|
||||
"StudentNotFound": "⛔ Для подписки нужно зарегистрироваться."
|
||||
+ "Команда /start поможет с регистрацией",
|
||||
"StudentAlreadySubbed": "💁♀️ Подписка уже оформлена ранее",
|
||||
}
|
||||
return cases.get(err, "😟 Возникли неполадки")
|
||||
|
||||
class Unsub:
|
||||
START = "📜✍ Оформляю отписку от уведомлений..."
|
||||
UNSUBBED = "🙄 Подписка на уведомления отменена"
|
||||
|
||||
@staticmethod
|
||||
def failure(err: str):
|
||||
cases = {
|
||||
"StudentNotFound": "⛔ Для отпидски от уведомлений нужно зарегистрироваться."
|
||||
+ "Команда /start поможет с регистрацией",
|
||||
"StudentAlreadyUnsubbed": "💁♀️ Подписка на уведомления не была оформлена или уже отменена",
|
||||
}
|
||||
return cases.get(err, "😟 Возникли неполадки")
|
||||
|
||||
class Spreadsheets:
|
||||
pass
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user