Browse Source

User polling and matching functions

master
Lev 2 years ago
parent
commit
907adc6fd0
  1. 28
      bot.py
  2. 34
      community.py
  3. 10
      templates.txt

28
bot.py

@ -1,3 +1,5 @@
import datetime
import telebot
import pymongo
from functools import wraps
@ -66,7 +68,8 @@ class Bot(telebot.TeleBot):
as_reply: bool = False, locale_overwrite: typing.Optional[str] = None, **kwargs):
if isinstance(msg, telebot.types.CallbackQuery):
msg = msg.message
text, keyboard = self.render_message_for_user(self.get_user_by_msg(msg), template,
user = self.get_user_by_msg(msg)
text, keyboard = self.render_message_for_user(user, template,
tg_user=msg.from_user, locale_overwrite=locale_overwrite,
**kwargs)
if as_reply:
@ -74,6 +77,14 @@ class Bot(telebot.TeleBot):
else:
self.send_message(msg.chat.id, text, reply_markup=keyboard, parse_mode='HTML')
def send_template(self, user_id: int, template: str, locale_overwrite: typing.Optional[str] = None, **kwargs):
user = User.by_id(user_id, self)
tg_user = self.get_chat(user_id)
text, keyboard = self.render_message_for_user(user, template,
tg_user=tg_user, locale_overwrite=locale_overwrite,
**kwargs)
self.send_message(user_id, text, reply_markup=keyboard, parse_mode='HTML')
def get_user_from_db(self, request: dict) -> typing.Optional[User]:
data = self.db.users.find_one(request)
if data is None:
@ -175,6 +186,21 @@ class Bot(telebot.TeleBot):
for user_data in self.db.users.find():
yield User.from_dict(user_data)
def iter_communities(self) -> typing.Iterable[Community]:
for community_data in self.db.communities.find():
yield Community.from_dict(community_data)
def poll_users_in_community(self, community: Community):
for user_id in community.users_to_poll():
user = User.by_id(user_id, self)
if user is None:
continue
def_answer = community.default_answers.get(user_id, True)
self.send_template(user_id, 'poll_user', community=community, def_answer=def_answer)
community.pool += [user_id] * def_answer
community.polled[user_id] = datetime.date.today()
self.save_community(community)
def register_next_step_handler(self, message, callback, *args, **kwargs):
if isinstance(message, telebot.types.CallbackQuery):
message = message.message

34
community.py

@ -1,7 +1,8 @@
from __future__ import annotations
from dataclasses import dataclass, field, asdict
import typing
from datetime import date
import random
from datetime import date, timedelta
from telebot.types import ChatMember, Chat
import time
from threading import Thread
@ -15,10 +16,12 @@ class Community:
chat_id: int # Telegram chat id
name: str = ''
members: typing.List[int] = field(default_factory=list)
pool: typing.List[typing.Tuple[int, int]] = field(default_factory=list) # (user_id, number_of_copies)
pool: typing.List[int] = field(default_factory=list) # [user_id]
polled: typing.Dict[int, date] = field(default_factory=dict) # Days since the user was asked
scheduled_meetings: typing.List[typing.Tuple[int, int, date]] = field(
default_factory=list) # (user_id_1, user_id_2, meeting date)
archived_meetings: typing.List[typing.Tuple[int, int, date]] = field(default_factory=list)
default_answers: typing.Dict[int, bool] = field(default_factory=dict) # Last answers
start_timestamp: int = field(default_factory=lambda: int(time.time()))
def dict(self) -> dict:
@ -29,8 +32,8 @@ class Community:
def from_dict(cls, data: dict) -> Community:
data = getattr(data, '__dict__', data)
data_ = {key: data[key] for key in data.keys() if
key in ['chat_id', 'name', 'members', 'pool', 'scheduled_meetings', 'archived_meetings',
'start_timestamp']}
key in ['chat_id', 'name', 'members', 'pool', 'polled', 'scheduled_meetings',
'archived_meetings', 'start_timestamp', 'default_answers']}
self = cls(**data_)
return self
@ -55,3 +58,26 @@ class Community:
bot.save_community(self)
return True
return False
def users_to_poll(self) -> typing.List[int]:
return [
user_id for user_id in self.members
if user_id not in self.polled or self.polled[user_id] <= date.today() - timedelta(days=7)
]
def add_answer(self, user_id: int, answer: bool, bot: Bot):
if user_id not in self.users_to_poll():
return
self.pool.remove(user_id)
self.pool += [user_id] * answer
self.default_answers[user_id] = bool(answer)
bot.save_community(self)
def schedule_meetings(self):
random.shuffle(self.pool) # It's called RandomTea for a reason
today = date.today()
while len(self.pool) > 1:
user_id_1 = self.pool.pop()
while (user_id_2 := self.pool.pop()) == user_id_1:
continue
self.scheduled_meetings.append((user_id_1, user_id_2, today))

10
templates.txt

@ -35,6 +35,16 @@ You have joined the community, congrats!
//| ru |//
Вы присоединились к сообществу, хорошего дня!
||<| poll_user |>||
//| en |//
Do you want to have any meetings this week{% if community.name %} in the community <b>{{ community.name }}</b>{% endif %}?
>>| {{ "✅" * bool(def_answer) }} Yes :-: meetings_{{ community.chat_id }}_1 |<<
>>| {{ "✅" * (not def_answer) }} No :-: meetings_{{ community.chat_id }}_0 |<<
//| ru |//
Хотите ли вы сходить на встречи на этой неделе{% if community.name %} в сообществе <b>{{ community.name }}</b>{% endif %}?
>>| {{ "✅" * bool(def_answer) }} Да :-: meetings_{{ community.chat_id }}_1 |<<
>>| {{ "✅" * (not def_answer) }} Нет :-: meetings_{{ community.chat_id }}_0 |<<
||<| canceled |>||
//| en |//
Canceled

Loading…
Cancel
Save