|
|
@ -1,7 +1,8 @@ |
|
|
|
from __future__ import annotations |
|
|
|
from __future__ import annotations |
|
|
|
from dataclasses import dataclass, field, asdict |
|
|
|
from dataclasses import dataclass, field, asdict |
|
|
|
import typing |
|
|
|
import typing |
|
|
|
from datetime import date |
|
|
|
import random |
|
|
|
|
|
|
|
from datetime import date, timedelta |
|
|
|
from telebot.types import ChatMember, Chat |
|
|
|
from telebot.types import ChatMember, Chat |
|
|
|
import time |
|
|
|
import time |
|
|
|
from threading import Thread |
|
|
|
from threading import Thread |
|
|
@ -15,10 +16,12 @@ class Community: |
|
|
|
chat_id: int # Telegram chat id |
|
|
|
chat_id: int # Telegram chat id |
|
|
|
name: str = '' |
|
|
|
name: str = '' |
|
|
|
members: typing.List[int] = field(default_factory=list) |
|
|
|
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( |
|
|
|
scheduled_meetings: typing.List[typing.Tuple[int, int, date]] = field( |
|
|
|
default_factory=list) # (user_id_1, user_id_2, meeting date) |
|
|
|
default_factory=list) # (user_id_1, user_id_2, meeting date) |
|
|
|
archived_meetings: typing.List[typing.Tuple[int, int, date]] = field(default_factory=list) |
|
|
|
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())) |
|
|
|
start_timestamp: int = field(default_factory=lambda: int(time.time())) |
|
|
|
|
|
|
|
|
|
|
|
def dict(self) -> dict: |
|
|
|
def dict(self) -> dict: |
|
|
@ -29,8 +32,8 @@ class Community: |
|
|
|
def from_dict(cls, data: dict) -> Community: |
|
|
|
def from_dict(cls, data: dict) -> Community: |
|
|
|
data = getattr(data, '__dict__', data) |
|
|
|
data = getattr(data, '__dict__', data) |
|
|
|
data_ = {key: data[key] for key in data.keys() if |
|
|
|
data_ = {key: data[key] for key in data.keys() if |
|
|
|
key in ['chat_id', 'name', 'members', 'pool', 'scheduled_meetings', 'archived_meetings', |
|
|
|
key in ['chat_id', 'name', 'members', 'pool', 'polled', 'scheduled_meetings', |
|
|
|
'start_timestamp']} |
|
|
|
'archived_meetings', 'start_timestamp', 'default_answers']} |
|
|
|
self = cls(**data_) |
|
|
|
self = cls(**data_) |
|
|
|
return self |
|
|
|
return self |
|
|
|
|
|
|
|
|
|
|
@ -55,3 +58,26 @@ class Community: |
|
|
|
bot.save_community(self) |
|
|
|
bot.save_community(self) |
|
|
|
return True |
|
|
|
return True |
|
|
|
return False |
|
|
|
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)) |
|
|
|