diff --git a/bot.py b/bot.py
index 66e7423..1f7514b 100644
--- a/bot.py
+++ b/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
diff --git a/community.py b/community.py
index 1f43c2d..09afc7f 100644
--- a/community.py
+++ b/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))
diff --git a/templates.txt b/templates.txt
index 1bbf197..4337d70 100644
--- a/templates.txt
+++ b/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 {{ community.name }}{% endif %}?
+>>| {{ "✅" * bool(def_answer) }} Yes :-: meetings_{{ community.chat_id }}_1 |<<
+>>| {{ "✅" * (not def_answer) }} No :-: meetings_{{ community.chat_id }}_0 |<<
+//| ru |//
+Хотите ли вы сходить на встречи на этой неделе{% if community.name %} в сообществе {{ community.name }}{% endif %}?
+>>| {{ "✅" * bool(def_answer) }} Да :-: meetings_{{ community.chat_id }}_1 |<<
+>>| {{ "✅" * (not def_answer) }} Нет :-: meetings_{{ community.chat_id }}_0 |<<
+
||<| canceled |>||
//| en |//
Canceled