Browse Source

Add handlers and fix serializing

master
Lev 3 years ago
parent
commit
bdeab03f4c
  1. 4
      README.md
  2. 10
      bot.py
  3. 16
      community.py
  4. 9
      templates.txt
  5. 24
      views.py

4
README.md

@ -10,3 +10,7 @@ Random meetings for chats, kind of like RandomCoffee.
2. The members of the chat open the bot 2. The members of the chat open the bot
3. Once a week the bot asks everyone about the number of meetings they want, adds the people to the pool 3. Once a week the bot asks everyone about the number of meetings they want, adds the people to the pool
4. The bot sends the matches and links to their Telegram accounts 4. The bot sends the matches and links to their Telegram accounts
TODO:
- Users with hidden profiles
- Scheduling

10
bot.py

@ -120,6 +120,7 @@ class Bot(telebot.TeleBot):
self.db.users.replace_one({'user_id': user.user_id}, user.dict()) self.db.users.replace_one({'user_id': user.user_id}, user.dict())
def save_community(self, community: Community): def save_community(self, community: Community):
print(community.dict())
self.db.communities.replace_one({'chat_id': community.chat_id}, community.dict()) self.db.communities.replace_one({'chat_id': community.chat_id}, community.dict())
def handle_commands(self, cmds: typing.List[str]): def handle_commands(self, cmds: typing.List[str]):
@ -156,13 +157,14 @@ class Bot(telebot.TeleBot):
args = query.data.strip()[len(name) + 1:] args = query.data.strip()[len(name) + 1:]
try: try:
return func(query, user, args.strip()) return func(query, user, args.strip())
except KeyboardInterrupt as e:
raise e
except Exception: except Exception:
print(f'An exception occured: {traceback.format_exc()}') print(f'An exception occured: {traceback.format_exc()}')
self.callback_query_handler( self.callback_query_handler(
lambda query: query.data.strip().startswith(name + '_') or query.data.strip() == name)(func_wrapped) lambda query: query.data.strip().startswith(name + '_') or query.data.strip() == name)(func_wrapped)
return func_wrapped return func_wrapped
return wrapper return wrapper
def inline_handler_(self, filter_func, **kwargs): def inline_handler_(self, filter_func, **kwargs):
@ -201,6 +203,12 @@ class Bot(telebot.TeleBot):
community.polled[user_id] = datetime.date.today() community.polled[user_id] = datetime.date.today()
self.save_community(community) self.save_community(community)
def send_meeting_info_in_community(self, community: Community):
for meeting in community.scheduled_meetings:
person_1, person_2 = self.get_chat(meeting[0]), self.get_chat(meeting[1])
self.send_template(meeting[0], 'meeting_info', community=community, meeting=meeting, person=person_2)
self.send_template(meeting[1], 'meeting_info', community=community, meeting=meeting, person=person_1)
def register_next_step_handler(self, message, callback, *args, **kwargs): def register_next_step_handler(self, message, callback, *args, **kwargs):
if isinstance(message, telebot.types.CallbackQuery): if isinstance(message, telebot.types.CallbackQuery):
message = message.message message = message.message

16
community.py

@ -11,6 +11,12 @@ if typing.TYPE_CHECKING:
from bot import Bot from bot import Bot
def convert_to_date(x: typing.Union[int, date]) -> date:
if isinstance(x, int):
return date.fromordinal(x)
return x
@dataclass @dataclass
class Community: class Community:
chat_id: int # Telegram chat id chat_id: int # Telegram chat id
@ -26,6 +32,10 @@ class Community:
def dict(self) -> dict: def dict(self) -> dict:
data = asdict(self) data = asdict(self)
data['polled'] = {str(k): self.polled[k].toordinal() for k in self.polled}
data['default_answers'] = {str(k): self.default_answers[k] for k in self.default_answers}
data['scheduled_meetings'] = [(l, m, r.toordinal()) for l, m, r in self.scheduled_meetings]
data['archived_meetings'] = [(l, m, r.toordinal()) for l, m, r in self.archived_meetings]
return data return data
@classmethod @classmethod
@ -35,6 +45,10 @@ class Community:
key in ['chat_id', 'name', 'members', 'pool', 'polled', 'scheduled_meetings', key in ['chat_id', 'name', 'members', 'pool', 'polled', 'scheduled_meetings',
'archived_meetings', 'start_timestamp', 'default_answers']} 'archived_meetings', 'start_timestamp', 'default_answers']}
self = cls(**data_) self = cls(**data_)
self.polled = {int(k): convert_to_date(self.polled[k]) for k in self.polled}
self.default_answers = {int(k): self.default_answers[k] for k in self.default_answers}
self.scheduled_meetings = [(int(l), int(m), convert_to_date(r)) for l, m, r in self.scheduled_meetings]
self.archived_meetings = [(int(l), int(m), convert_to_date(r)) for l, m, r in self.archived_meetings]
return self return self
@classmethod @classmethod
@ -66,8 +80,10 @@ class Community:
] ]
def add_answer(self, user_id: int, answer: bool, bot: Bot): def add_answer(self, user_id: int, answer: bool, bot: Bot):
answer = bool(answer)
if user_id not in self.users_to_poll(): if user_id not in self.users_to_poll():
return return
if user_id in self.pool:
self.pool.remove(user_id) self.pool.remove(user_id)
self.pool += [user_id] * answer self.pool += [user_id] * answer
self.default_answers[user_id] = bool(answer) self.default_answers[user_id] = bool(answer)

9
templates.txt

@ -45,6 +45,15 @@ Do you want to have any meetings this week{% if community.name %} in the communi
>>| {{ "✅" * bool(def_answer) }} Да :-: meetings_{{ community.chat_id }}_1 |<< >>| {{ "✅" * bool(def_answer) }} Да :-: meetings_{{ community.chat_id }}_1 |<<
>>| {{ "✅" * (not def_answer) }} Нет :-: meetings_{{ community.chat_id }}_0 |<< >>| {{ "✅" * (not def_answer) }} Нет :-: meetings_{{ community.chat_id }}_0 |<<
||<| meeting_info |>||
//| en |//
You have a meeting this week with <a href="tg://user?id={{ person.id }}">{{ person.first_name }}</a> from <i>{{ community.name }}</i>.
You should meet in person or online. It is recommended to contact your partner in advance
//| ru |//
На этой неделе у Вас встреча с <a href="tg://user?id={{ person.id }}">{{ person.first_name }}</a> из <i>{{ community.name }}</i>.
Вам предлагается встретиться лично за чашкой <s>кофе</s> чая. Рекомендуем написать человеку заранее
||<| canceled |>|| ||<| canceled |>||
//| en |// //| en |//
Canceled Canceled

24
views.py

@ -53,3 +53,27 @@ def views(bot: Bot):
community: Community = Community.by_id(chat_id, bot) community: Community = Community.by_id(chat_id, bot)
# send welcome message to the chat (if we can) - and if we should # send welcome message to the chat (if we can) - and if we should
bot.reply_with_template(upd, 'welcome', community=community) bot.reply_with_template(upd, 'welcome', community=community)
@bot.handle_callback('meetings')
def handle_meetings_answer(query, user, args):
community_id, answer = args.split('_')
community = Community.by_id(int(community_id), bot)
community.add_answer(user.user_id, int(answer), bot)
bot.answer_callback_query(query.id, text='👍👍👍')
# todo: edit the keyboard
@bot.handle_commands(['/send_polls'])
def send_polls(msg, _user, _args):
community: Community = Community.by_id(msg.chat.id, bot)
bot.poll_users_in_community(community)
@bot.handle_commands(['/send_meetings'])
def send_meetings(msg, _user, _args):
community: Community = Community.by_id(msg.chat.id, bot)
bot.send_meeting_info_in_community(community)
@bot.handle_commands(['/schedule_meetings'])
def schedule_meetings(msg, _user, _args):
community: Community = Community.by_id(msg.chat.id, bot)
community.schedule_meetings()
bot.save_community(community)

Loading…
Cancel
Save