another one

This commit is contained in:
2023-11-29 12:32:23 +03:00
parent 2251d5a3e9
commit c0c10af937
2 changed files with 139 additions and 12 deletions

View File

@ -26,6 +26,7 @@ import keyboards
# DB # DB
from db.base import Session, engine, Base from db.base import Session, engine, Base
from db.models import User, Group, GroupMember, Fund, FundMember from db.models import User, Group, GroupMember, Fund, FundMember
from sqlalchemy.orm import joinedload
bot = AsyncTeleBot(token, state_storage=StatePickleStorage()) bot = AsyncTeleBot(token, state_storage=StatePickleStorage())
@ -35,6 +36,7 @@ session: Session = None
class States(StatesGroup): class States(StatesGroup):
default = State() default = State()
newfund_amount = State() newfund_amount = State()
newfund_description = State()
close_fund = State() close_fund = State()
@ -49,6 +51,7 @@ def get_fund_text(fund: Fund):
active="🟢" if fund.active else "🔴", active="🟢" if fund.active else "🔴",
name=fund.name, name=fund.name,
amount=fund.amount, amount=fund.amount,
description=fund.description,
personal_amount=personal_amount, personal_amount=personal_amount,
collected_amount=personal_amount * contributors, collected_amount=personal_amount * contributors,
contributors=contributors, contributors=contributors,
@ -87,9 +90,16 @@ def get_group(tg_chat: TgChat) -> Group:
async def start(msg: Message): async def start(msg: Message):
if msg.chat.type == "private": if msg.chat.type == "private":
user = get_user(msg.from_user) user = get_user(msg.from_user)
fund_members_count = (
session.query(FundMember)
.join(Fund)
.filter(Fund.owner_id == user.id, Fund.active == True)
.options(joinedload(FundMember.fund))
.count()
)
await bot.send_message( await bot.send_message(
chat_id=msg.chat.id, chat_id=msg.chat.id,
text=textbook.start_private.format(count=user.fund_members.count()), text=textbook.start_private.format(count=fund_members_count),
) )
elif msg.chat.type in ("group", "supergroup"): elif msg.chat.type in ("group", "supergroup"):
@ -183,22 +193,64 @@ async def cancel_newfund_amount(call: types.CallbackQuery):
) )
@bot.callback_query_handler(
func=lambda c: c.data == "cancel", state=States.newfund_description
)
async def cancel_newfund_description(call: types.CallbackQuery):
await bot.set_state(
user_id=call.from_user.id, chat_id=call.message.chat.id, state=States.default
)
await bot.delete_message(chat_id=call.message.chat.id, message_id=call.message.id)
await bot.answer_callback_query(
callback_query_id=call.id,
text=textbook.cancel,
)
@bot.message_handler(content_types=["text"], state=States.newfund_amount) @bot.message_handler(content_types=["text"], state=States.newfund_amount)
async def newfund_amount(msg: Message): async def newfund_amount(msg: Message):
if not session.query(User).filter(User.id == msg.from_user.id).first():
user = User(
id=msg.from_user.id,
name=msg.from_user.first_name,
username=msg.from_user.username,
)
session.add(user)
session.commit()
if msg.text.isdigit(): if msg.text.isdigit():
async with bot.retrieve_data(
user_id=msg.from_user.id, chat_id=msg.chat.id
) as state_data:
state_data["newfund_amount"] = int(msg.text)
await bot.set_state(
user_id=msg.from_user.id,
chat_id=msg.chat.id,
state=States.newfund_description,
)
await bot.send_message(
chat_id=msg.chat.id,
text=textbook.newfund_description,
reply_markup=keyboards.cancel(),
parse_mode="html",
)
else:
await bot.send_message(
chat_id=msg.chat.id,
text=textbook.not_number.format(user=user_link(msg.from_user)),
reply_markup=keyboards.cancel(),
parse_mode="html",
)
@bot.message_handler(content_types=["text"], state=States.newfund_description)
async def newfund_description(msg: Message):
if len(msg.text) < 121:
await bot.set_state( await bot.set_state(
user_id=msg.from_user.id, chat_id=msg.chat.id, state=States.default user_id=msg.from_user.id, chat_id=msg.chat.id, state=States.default
) )
async with bot.retrieve_data(
user_id=msg.from_user.id, chat_id=msg.chat.id
) as state_data:
amount = state_data.get("newfund_amount")
fund = Fund( fund = Fund(
owner_id=msg.from_user.id, group_id=msg.chat.id, amount=int(msg.text) owner_id=msg.from_user.id,
group_id=msg.chat.id,
description=msg.text,
amount=amount,
name=datetime.today().strftime("%d.%m"),
) )
session.add(fund) session.add(fund)
for group_member in session.query(GroupMember).filter( for group_member in session.query(GroupMember).filter(
@ -222,7 +274,7 @@ async def newfund_amount(msg: Message):
else: else:
await bot.send_message( await bot.send_message(
chat_id=msg.chat.id, chat_id=msg.chat.id,
text=textbook.not_number.format(user=user_link(msg.from_user)), text=textbook.newfund_description_too_long,
reply_markup=keyboards.cancel(), reply_markup=keyboards.cancel(),
parse_mode="html", parse_mode="html",
) )
@ -411,6 +463,72 @@ async def remind(msg: Message):
) )
@bot.message_handler(commands=["dmremind"])
async def dmremind(msg: Message):
if msg.chat.type in ("group", "supergroup"):
group = get_group(msg.chat)
if (
fund := session.query(Fund)
.filter(Fund.group_id == group.id, Fund.active == True)
.first()
):
not_contributed = fund.members.filter(FundMember.contributed == False).all()
if len(not_contributed):
counter = 0
not_sent = []
for member in not_contributed:
try:
await asyncio.sleep(0.1)
await bot.send_message(
chat_id=member.user.id,
text=textbook.dmremind.format(
fund_name=fund.name, chat_name=msg.chat.title
),
)
counter += 1
except Exception:
not_sent.append(member)
s = textbook.dmremind_completed.format(
sent_count=counter, members_count=len(not_contributed)
)
if not_sent:
s += "\n" + textbook.dmremind_not_sent_list.format(
members=", ".join([m.user.name for m in not_sent])
)
await bot.send_message(
chat_id=msg.chat.id,
text=s,
parse_mode="html",
)
else:
await bot.send_message(
chat_id=msg.chat.id,
text=textbook.remind_already.format(fund_name=fund.name),
parse_mode="html",
)
else:
await bot.send_message(
chat_id=msg.chat.id,
text=textbook.fund_not_found,
)
@bot.message_handler(commands=["setup_list"])
async def setup_list(msg: Message):
if msg.chat.type in ("group", "supergroup"):
group = get_group(msg.chat)
members = group.group_members
await bot.send_message(
chat_id=msg.chat.id,
text=textbook.setup_list.format(
count=members.count(),
members=", ".join(m.user.name for m in members.all()),
),
parse_mode="html",
)
@bot.message_handler(commands=["mystate"]) @bot.message_handler(commands=["mystate"])
async def mystate(msg: Message): async def mystate(msg: Message):
state = await bot.get_state(user_id=msg.from_user.id) state = await bot.get_state(user_id=msg.from_user.id)

View File

@ -10,6 +10,10 @@ user_left = "Вы отказались от участия в сборах в э
newfund_already_exists = "Предыдущий сбор все еще активен! Пропишите /fund, чтобы показать его, и завершите его, если необходимо создать новый!" newfund_already_exists = "Предыдущий сбор все еще активен! Пропишите /fund, чтобы показать его, и завершите его, если необходимо создать новый!"
newfund_amount = 'Отлично, новый сбор. {user}, напишите сумму сбора <b>ответом на это сообщение</b>, или нажмите кнопку "❌ Отменить"' newfund_amount = 'Отлично, новый сбор. {user}, напишите сумму сбора <b>ответом на это сообщение</b>, или нажмите кнопку "❌ Отменить"'
newfund_description = "Хорошо, теперь напишите описание сбора <b>ответом на это сообщение</b> (не более 120 символов). Это может быть номер или ссылка куда кидать деньги, к примеру."
newfund_description_too_long = (
"Слишком длинное описание, лимит - 120 символов, попробуйте еще раз!"
)
cancel = "Хорошо, проехали" cancel = "Хорошо, проехали"
not_number = 'Вы ввели не число. {user}, напишите сумму сбора <b>ответом на это сообщение</b>, или нажмите кнопку "❌ Отменить"' not_number = 'Вы ввели не число. {user}, напишите сумму сбора <b>ответом на это сообщение</b>, или нажмите кнопку "❌ Отменить"'
fund_created = "Создан новый сбор: {fund}" fund_created = "Создан новый сбор: {fund}"
@ -17,7 +21,7 @@ fund_created = "Создан новый сбор: {fund}"
fund_not_found = "На данный момент в этом чате сборов нет! Создать новый - /newfund" fund_not_found = "На данный момент в этом чате сборов нет! Создать новый - /newfund"
fund = "{active} {name}\n\n💵 Сумма: {amount}р\n\n<b>Каждый скидывает по {personal_amount}р</b>\nУже собрано: {collected_amount}р\n👥 Скинули: {contributors}/{count} чел." fund = "{active} {name}\n\n💵 Сумма сбора: {amount}р\n\n{description}\n\n<b>Каждый скидывает по {personal_amount}р</b>\nУже собрано: {collected_amount}р\n👥 Скинули: {contributors}/{count} чел."
close_fund_prompt = "Вы уверены? Это завершит <b>активный в данный момент сбор</b>!" close_fund_prompt = "Вы уверены? Это завершит <b>активный в данный момент сбор</b>!"
fund_closed = 'Сбор "<b>{name}</b>" закрыт! Вот его данные:\n\n{fund_text}' fund_closed = 'Сбор "<b>{name}</b>" закрыт! Вот его данные:\n\n{fund_text}'
@ -33,3 +37,8 @@ remind_already = "На сбор <b>{fund_name}</b> уже все скинули
fund_completed = ( fund_completed = (
"Сбор <b>{fund_name}</b> завершен, поздравляю всех, и в особенности {owner_str} 🎉" "Сбор <b>{fund_name}</b> завершен, поздравляю всех, и в особенности {owner_str} 🎉"
) )
dmremind = "Ты забыл(а) скинуться на {fund_name} в чате {chat_name}!"
dmremind_completed = "Сообщение разослано {sent_count} из {members_count} юзерам!"
dmremind_not_sent_list = "Не получилось разослать юзерам:\n\n<b>{members}</b>\n\nМожешь написать им в личку сам(а)? Они забыли активировать меня в лс("
setup_list = "В сборах в этом чате сейчас участвует {count} человек. Вот они, слева направо:\n\n<b>{members}</b>\n\nДля добавления новых пропишите /setup и нажмите на кнопочку"