Browse Source

Add handlers and fix serializing

master
Lev 2 years ago
parent
commit
bdeab03f4c
  1. 4
      README.md
  2. 10
      bot.py
  3. 18
      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
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
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())
def save_community(self, community: Community):
print(community.dict())
self.db.communities.replace_one({'chat_id': community.chat_id}, community.dict())
def handle_commands(self, cmds: typing.List[str]):
@ -156,13 +157,14 @@ class Bot(telebot.TeleBot):
args = query.data.strip()[len(name) + 1:]
try:
return func(query, user, args.strip())
except KeyboardInterrupt as e:
raise e
except Exception:
print(f'An exception occured: {traceback.format_exc()}')
self.callback_query_handler(
lambda query: query.data.strip().startswith(name + '_') or query.data.strip() == name)(func_wrapped)
return func_wrapped
return wrapper
def inline_handler_(self, filter_func, **kwargs):
@ -201,6 +203,12 @@ class Bot(telebot.TeleBot):
community.polled[user_id] = datetime.date.today()
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):
if isinstance(message, telebot.types.CallbackQuery):
message = message.message

18
community.py

@ -11,6 +11,12 @@ if typing.TYPE_CHECKING:
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
class Community:
chat_id: int # Telegram chat id
@ -26,6 +32,10 @@ class Community:
def dict(self) -> dict:
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
@classmethod
@ -35,6 +45,10 @@ class Community:
key in ['chat_id', 'name', 'members', 'pool', 'polled', 'scheduled_meetings',
'archived_meetings', 'start_timestamp', 'default_answers']}
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
@classmethod
@ -66,9 +80,11 @@ class Community:
]
def add_answer(self, user_id: int, answer: bool, bot: Bot):
answer = bool(answer)
if user_id not in self.users_to_poll():
return
self.pool.remove(user_id)
if user_id in self.pool:
self.pool.remove(user_id)
self.pool += [user_id] * answer
self.default_answers[user_id] = bool(answer)
bot.save_community(self)

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 |<<
>>| {{ "✅" * (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 |>||
//| en |//
Canceled

24
views.py

@ -53,3 +53,27 @@ def views(bot: Bot):
community: Community = Community.by_id(chat_id, bot)
# send welcome message to the chat (if we can) - and if we should
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