mirror of
https://github.com/miloszowi/everyone-mention-telegram-bot.git
synced 2025-05-20 09:14:07 +00:00
mongodb new structure, added new collection chats
This commit is contained in:
parent
9c8f5795f8
commit
e0916441b9
@ -7,6 +7,7 @@ from telegram.update import Update
|
|||||||
from bot.message.inboundMessage import InboundMessage
|
from bot.message.inboundMessage import InboundMessage
|
||||||
from bot.message.replier import Replier
|
from bot.message.replier import Replier
|
||||||
from exception.actionNotAllowedException import ActionNotAllowedException
|
from exception.actionNotAllowedException import ActionNotAllowedException
|
||||||
|
from exception.invalidActionException import InvalidActionException
|
||||||
from exception.invalidArgumentException import InvalidArgumentException
|
from exception.invalidArgumentException import InvalidArgumentException
|
||||||
from logger import Logger
|
from logger import Logger
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ from logger import Logger
|
|||||||
class AbstractHandler:
|
class AbstractHandler:
|
||||||
bot_handler: Handler
|
bot_handler: Handler
|
||||||
inbound: InboundMessage
|
inbound: InboundMessage
|
||||||
|
action: str
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||||
@ -25,7 +27,8 @@ class AbstractHandler:
|
|||||||
|
|
||||||
self.inbound = InboundMessage.create(update, context, group_specific)
|
self.inbound = InboundMessage.create(update, context, group_specific)
|
||||||
self.handle(update, context)
|
self.handle(update, context)
|
||||||
except (ActionNotAllowedException, InvalidArgumentException) as e:
|
Logger.action(self.inbound, self.action)
|
||||||
|
except (InvalidActionException, InvalidArgumentException, ActionNotAllowedException) as e:
|
||||||
Replier.markdown(update, str(e))
|
Replier.markdown(update, str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Logger.exception(e)
|
Logger.exception(e)
|
||||||
|
@ -5,26 +5,28 @@ from telegram.update import Update
|
|||||||
from bot.handler.abstractHandler import AbstractHandler
|
from bot.handler.abstractHandler import AbstractHandler
|
||||||
from bot.message.replier import Replier
|
from bot.message.replier import Replier
|
||||||
from config.contents import mention_failed
|
from config.contents import mention_failed
|
||||||
|
from exception.invalidActionException import InvalidActionException
|
||||||
from exception.notFoundException import NotFoundException
|
from exception.notFoundException import NotFoundException
|
||||||
from logger import Logger
|
from repository.chatRepository import ChatRepository
|
||||||
from repository.userRepository import UserRepository
|
from repository.userRepository import UserRepository
|
||||||
from utils.messageBuilder import MessageBuilder
|
from utils.messageBuilder import MessageBuilder
|
||||||
|
|
||||||
|
|
||||||
class EveryoneHandler(AbstractHandler):
|
class EveryoneHandler(AbstractHandler):
|
||||||
bot_handler: CommandHandler
|
bot_handler: CommandHandler
|
||||||
|
chat_repository: ChatRepository
|
||||||
user_repository: UserRepository
|
user_repository: UserRepository
|
||||||
action: str = 'everyone'
|
action: str = 'everyone'
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.bot_handler = CommandHandler(self.action, self.wrap)
|
self.bot_handler = CommandHandler(self.action, self.wrap)
|
||||||
|
self.chat_repository = ChatRepository()
|
||||||
self.user_repository = UserRepository()
|
self.user_repository = UserRepository()
|
||||||
|
|
||||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||||
try:
|
try:
|
||||||
users = self.user_repository.get_all_for_chat(self.inbound.chat_id)
|
users = self.chat_repository.get_users_for_group(self.inbound.chat_id, self.inbound.group_name)
|
||||||
|
|
||||||
Replier.markdown(update, MessageBuilder.mention_message(users))
|
Replier.markdown(update, MessageBuilder.mention_message(users))
|
||||||
Logger.action(self.inbound, self.action)
|
except NotFoundException as e:
|
||||||
except NotFoundException:
|
raise InvalidActionException(mention_failed) from e
|
||||||
Replier.markdown(update, mention_failed)
|
|
||||||
|
@ -5,29 +5,30 @@ from telegram.update import Update
|
|||||||
from bot.handler.abstractHandler import AbstractHandler
|
from bot.handler.abstractHandler import AbstractHandler
|
||||||
from bot.message.replier import Replier
|
from bot.message.replier import Replier
|
||||||
from config.contents import no_groups
|
from config.contents import no_groups
|
||||||
|
from exception.invalidActionException import InvalidActionException
|
||||||
from exception.notFoundException import NotFoundException
|
from exception.notFoundException import NotFoundException
|
||||||
from logger import Logger
|
from repository.chatRepository import ChatRepository
|
||||||
from repository.groupRepository import GroupRepository
|
|
||||||
from utils.messageBuilder import MessageBuilder
|
from utils.messageBuilder import MessageBuilder
|
||||||
|
|
||||||
|
|
||||||
class GroupsHandler(AbstractHandler):
|
class GroupsHandler(AbstractHandler):
|
||||||
bot_handler: CommandHandler
|
bot_handler: CommandHandler
|
||||||
group_repository: GroupRepository
|
chat_repository: ChatRepository
|
||||||
action: str = 'groups'
|
action: str = 'groups'
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.bot_handler = CommandHandler(self.action, self.wrap)
|
self.bot_handler = CommandHandler(self.action, self.wrap)
|
||||||
self.group_repository = GroupRepository()
|
self.chat_repository = ChatRepository()
|
||||||
|
|
||||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||||
try:
|
try:
|
||||||
groups = self.group_repository.get_by_chat_id(self.inbound.chat_id)
|
chat = self.chat_repository.get(self.inbound.chat_id)
|
||||||
Replier.html(update, MessageBuilder.group_message(groups))
|
if not chat.groups:
|
||||||
|
raise NotFoundException
|
||||||
|
|
||||||
Logger.action(self.inbound, self.action)
|
Replier.html(update, MessageBuilder.group_message(chat.groups))
|
||||||
except NotFoundException:
|
except NotFoundException:
|
||||||
Replier.markdown(update, no_groups)
|
raise InvalidActionException(no_groups)
|
||||||
|
|
||||||
def is_group_specific(self) -> bool:
|
def is_group_specific(self) -> bool:
|
||||||
return False
|
return False
|
||||||
|
@ -6,7 +6,7 @@ from telegram.inline.inputtextmessagecontent import InputTextMessageContent
|
|||||||
from telegram.update import Update
|
from telegram.update import Update
|
||||||
|
|
||||||
from bot.handler.abstractHandler import AbstractHandler
|
from bot.handler.abstractHandler import AbstractHandler
|
||||||
from entity.group import Group
|
from bot.message.inboundMessage import InboundMessage
|
||||||
from exception.actionNotAllowedException import ActionNotAllowedException
|
from exception.actionNotAllowedException import ActionNotAllowedException
|
||||||
from validator.accessValidator import AccessValidator
|
from validator.accessValidator import AccessValidator
|
||||||
|
|
||||||
@ -24,8 +24,8 @@ class InlineQueryHandler(AbstractHandler):
|
|||||||
update.inline_query.answer([])
|
update.inline_query.answer([])
|
||||||
return
|
return
|
||||||
|
|
||||||
group_display = update.inline_query.query or Group.default_name
|
group_display = update.inline_query.query or InboundMessage.default_group
|
||||||
group = '' if group_display == Group.default_name else group_display
|
group = '' if group_display == InboundMessage.default_group else group_display
|
||||||
|
|
||||||
results = [
|
results = [
|
||||||
InlineQueryResultArticle(
|
InlineQueryResultArticle(
|
||||||
|
@ -5,8 +5,8 @@ from telegram.update import Update
|
|||||||
from bot.handler.abstractHandler import AbstractHandler
|
from bot.handler.abstractHandler import AbstractHandler
|
||||||
from bot.message.replier import Replier
|
from bot.message.replier import Replier
|
||||||
from config.contents import joined, not_joined
|
from config.contents import joined, not_joined
|
||||||
from exception.notFoundException import NotFoundException
|
from exception.invalidActionException import InvalidActionException
|
||||||
from logger import Logger
|
from repository.chatRepository import ChatRepository
|
||||||
from repository.userRepository import UserRepository
|
from repository.userRepository import UserRepository
|
||||||
|
|
||||||
|
|
||||||
@ -18,18 +18,17 @@ class JoinHandler(AbstractHandler):
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.bot_handler = CommandHandler(self.action, self.wrap)
|
self.bot_handler = CommandHandler(self.action, self.wrap)
|
||||||
self.user_repository = UserRepository()
|
self.user_repository = UserRepository()
|
||||||
|
self.chat_repository = ChatRepository()
|
||||||
|
|
||||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||||
try:
|
user = self.user_repository.provide(self.inbound)
|
||||||
user = self.user_repository.get_by_id(self.inbound.user_id)
|
chat = self.chat_repository.provide(self.inbound)
|
||||||
|
users = chat.groups.get(self.inbound.group_name)
|
||||||
|
|
||||||
if user.is_in_chat(self.inbound.chat_id):
|
if user.user_id in users:
|
||||||
return Replier.markdown(update, Replier.interpolate(not_joined, self.inbound))
|
raise InvalidActionException(Replier.interpolate(not_joined, self.inbound))
|
||||||
|
|
||||||
user.add_to_chat(self.inbound.chat_id)
|
users.append(user.user_id)
|
||||||
self.user_repository.save(user)
|
self.chat_repository.save(chat)
|
||||||
except NotFoundException:
|
|
||||||
self.user_repository.save_by_inbound_message(self.inbound)
|
|
||||||
|
|
||||||
Replier.markdown(update, Replier.interpolate(joined, self.inbound))
|
Replier.markdown(update, Replier.interpolate(joined, self.inbound))
|
||||||
Logger.action(self.inbound, self.action)
|
|
||||||
|
@ -5,27 +5,34 @@ from telegram.update import Update
|
|||||||
from bot.handler.abstractHandler import AbstractHandler
|
from bot.handler.abstractHandler import AbstractHandler
|
||||||
from bot.message.replier import Replier
|
from bot.message.replier import Replier
|
||||||
from config.contents import left, not_left
|
from config.contents import left, not_left
|
||||||
from exception.notFoundException import NotFoundException
|
from exception.invalidActionException import InvalidActionException
|
||||||
from logger import Logger
|
|
||||||
from repository.userRepository import UserRepository
|
from repository.userRepository import UserRepository
|
||||||
|
from repository.chatRepository import ChatRepository
|
||||||
|
|
||||||
|
|
||||||
class LeaveHandler(AbstractHandler):
|
class LeaveHandler(AbstractHandler):
|
||||||
bot_handler: CommandHandler
|
bot_handler: CommandHandler
|
||||||
user_repository: UserRepository
|
user_repository: UserRepository
|
||||||
|
chat_repository: ChatRepository
|
||||||
action: str = 'leave'
|
action: str = 'leave'
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.bot_handler = CommandHandler(self.action, self.wrap)
|
self.bot_handler = CommandHandler(self.action, self.wrap)
|
||||||
self.user_repository = UserRepository()
|
self.user_repository = UserRepository()
|
||||||
|
self.chat_repository = ChatRepository()
|
||||||
|
|
||||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||||
try:
|
user = self.user_repository.provide(self.inbound)
|
||||||
user = self.user_repository.get_by_id_and_chat_id(self.inbound.user_id, self.inbound.chat_id)
|
chat = self.chat_repository.provide(self.inbound)
|
||||||
user.remove_from_chat(self.inbound.chat_id)
|
group = chat.groups.get(self.inbound.group_name)
|
||||||
self.user_repository.save(user)
|
|
||||||
|
|
||||||
Replier.markdown(update, Replier.interpolate(left, self.inbound))
|
if user.user_id not in group:
|
||||||
Logger.action(self.inbound, self.action)
|
raise InvalidActionException(Replier.interpolate(not_left, self.inbound))
|
||||||
except NotFoundException:
|
|
||||||
return Replier.markdown(update, Replier.interpolate(not_left, self.inbound))
|
group.remove(user.user_id)
|
||||||
|
if not group:
|
||||||
|
chat.groups.pop(self.inbound.group_name)
|
||||||
|
|
||||||
|
self.chat_repository.save(chat)
|
||||||
|
|
||||||
|
Replier.markdown(update, Replier.interpolate(left, self.inbound))
|
||||||
|
@ -6,7 +6,6 @@ import names
|
|||||||
from telegram.ext.callbackcontext import CallbackContext
|
from telegram.ext.callbackcontext import CallbackContext
|
||||||
from telegram.update import Update
|
from telegram.update import Update
|
||||||
|
|
||||||
from entity.group import Group
|
|
||||||
from validator.accessValidator import AccessValidator
|
from validator.accessValidator import AccessValidator
|
||||||
from validator.groupNameValidator import GroupNameValidator
|
from validator.groupNameValidator import GroupNameValidator
|
||||||
|
|
||||||
@ -18,22 +17,21 @@ class InboundMessage:
|
|||||||
group_name: str
|
group_name: str
|
||||||
username: str
|
username: str
|
||||||
|
|
||||||
|
default_group: str = 'default'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(update: Update, context: CallbackContext, group_specific: bool) -> InboundMessage:
|
def create(update: Update, context: CallbackContext, group_specific: bool) -> InboundMessage:
|
||||||
user_id = str(update.effective_user.id)
|
user_id = str(update.effective_user.id)
|
||||||
AccessValidator.validate(user_id)
|
AccessValidator.validate(user_id)
|
||||||
|
|
||||||
chat_id = str(update.effective_chat.id)
|
chat_id = str(update.effective_chat.id)
|
||||||
group_name = Group.default_name
|
group_name = InboundMessage.default_group
|
||||||
|
|
||||||
if context.args and context.args[0] and group_specific:
|
if context.args and context.args[0] and group_specific:
|
||||||
group_name = str(context.args[0]).lower()
|
group_name = str(context.args[0]).lower()
|
||||||
|
|
||||||
GroupNameValidator.validate(group_name)
|
GroupNameValidator.validate(group_name)
|
||||||
|
|
||||||
if group_name is not Group.default_name:
|
|
||||||
chat_id += f'~{group_name}'
|
|
||||||
|
|
||||||
username = update.effective_user.username or update.effective_user.first_name
|
username = update.effective_user.username or update.effective_user.first_name
|
||||||
|
|
||||||
if not username:
|
if not username:
|
||||||
|
@ -30,10 +30,11 @@ class Client(metaclass=Singleton):
|
|||||||
def find_many(self, collection: str, filter: dict) -> dict:
|
def find_many(self, collection: str, filter: dict) -> dict:
|
||||||
return self.database.get_collection(collection).find(filter)
|
return self.database.get_collection(collection).find(filter)
|
||||||
|
|
||||||
def update_one(self, collection: str, filter: dict, data: dict) -> None:
|
def save(self, collection: str, filter: dict, data: dict) -> None:
|
||||||
self.database.get_collection(collection).update_one(
|
self.database.get_collection(collection).update_one(
|
||||||
filter,
|
filter,
|
||||||
{"$set": data}
|
{"$set": data},
|
||||||
|
upsert=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def aggregate(self, collection, pipeline: list):
|
def aggregate(self, collection, pipeline: list):
|
||||||
|
32
src/entity/chat.py
Normal file
32
src/entity/chat.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Iterable
|
||||||
|
|
||||||
|
from bot.message.inboundMessage import InboundMessage
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Chat:
|
||||||
|
chat_id: str
|
||||||
|
groups: dict
|
||||||
|
|
||||||
|
mongo_chat_id_index: str = '_id'
|
||||||
|
mongo_groups_index: str = 'groups'
|
||||||
|
|
||||||
|
def to_mongo_document(self) -> dict:
|
||||||
|
return {
|
||||||
|
self.mongo_chat_id_index: self.chat_id,
|
||||||
|
self.mongo_groups_index: self.groups
|
||||||
|
}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_mongo_document(mongo_document: dict) -> Chat:
|
||||||
|
return Chat(
|
||||||
|
mongo_document[Chat.mongo_chat_id_index],
|
||||||
|
mongo_document[Chat.mongo_groups_index]
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_inbound_message(inbound: InboundMessage) -> Chat:
|
||||||
|
return Chat(inbound.chat_id, {inbound.group_name: []})
|
@ -1,12 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Group:
|
|
||||||
chat_id: str
|
|
||||||
group_name: str
|
|
||||||
users_count: int
|
|
||||||
|
|
||||||
default_name: str = 'default'
|
|
@ -1,40 +1,31 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import List
|
|
||||||
|
from bot.message.inboundMessage import InboundMessage
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class User:
|
class User:
|
||||||
user_id: str
|
user_id: str
|
||||||
username: str
|
username: str
|
||||||
chats: List[str]
|
|
||||||
|
|
||||||
collection: str = 'users'
|
mongo_user_id_index: str = '_id'
|
||||||
id_index: str = '_id'
|
mongo_username_index: str = 'username'
|
||||||
chats_index: str = 'chats'
|
|
||||||
username_index: str = 'username'
|
|
||||||
|
|
||||||
def is_in_chat(self, chat_id: str) -> bool:
|
|
||||||
return chat_id in self.chats
|
|
||||||
|
|
||||||
def add_to_chat(self, chat_id: str) -> None:
|
|
||||||
self.chats.append(chat_id)
|
|
||||||
|
|
||||||
def remove_from_chat(self, chat_id: str) -> None:
|
|
||||||
if chat_id in self.chats:
|
|
||||||
self.chats.remove(chat_id)
|
|
||||||
|
|
||||||
def to_mongo_document(self) -> dict:
|
def to_mongo_document(self) -> dict:
|
||||||
return {
|
return {
|
||||||
self.username_index: self.username,
|
self.mongo_user_id_index: self.user_id,
|
||||||
self.chats_index: self.chats
|
self.mongo_username_index: self.username
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_mongo_document(mongo_document: dict) -> User:
|
def from_mongo_document(mongo_document: dict) -> User:
|
||||||
return User(
|
return User(
|
||||||
mongo_document[User.id_index],
|
mongo_document[User.mongo_user_id_index],
|
||||||
mongo_document[User.username_index],
|
mongo_document[User.mongo_username_index]
|
||||||
mongo_document[User.chats_index]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_inbound_message(inbound: InboundMessage) -> User:
|
||||||
|
return User(inbound.user_id, inbound.username)
|
||||||
|
2
src/exception/invalidActionException.py
Normal file
2
src/exception/invalidActionException.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class InvalidActionException(Exception):
|
||||||
|
pass
|
9
src/repository/abstractRepository.py
Normal file
9
src/repository/abstractRepository.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from database.client import Client
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractRepository:
|
||||||
|
collection_name: str
|
||||||
|
database_client: Client
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.database_client = Client()
|
55
src/repository/chatRepository.py
Normal file
55
src/repository/chatRepository.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
from typing import Iterable
|
||||||
|
|
||||||
|
from bot.message.inboundMessage import InboundMessage
|
||||||
|
from entity.chat import Chat
|
||||||
|
from entity.user import User
|
||||||
|
from exception.notFoundException import NotFoundException
|
||||||
|
from repository.abstractRepository import AbstractRepository
|
||||||
|
from repository.userRepository import UserRepository
|
||||||
|
|
||||||
|
|
||||||
|
class ChatRepository(AbstractRepository):
|
||||||
|
collection_name: str = 'chats'
|
||||||
|
user_repository: UserRepository
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.user_repository = UserRepository()
|
||||||
|
|
||||||
|
def provide(self, inbound: InboundMessage) -> Chat:
|
||||||
|
try:
|
||||||
|
chat = self.get(inbound.chat_id)
|
||||||
|
if not chat.groups.get(inbound.group_name):
|
||||||
|
chat.groups[inbound.group_name] = []
|
||||||
|
except NotFoundException:
|
||||||
|
chat = Chat.from_inbound_message(inbound)
|
||||||
|
|
||||||
|
return chat
|
||||||
|
|
||||||
|
def get(self, chat_id: str) -> Chat:
|
||||||
|
chat = self.database_client.find_one(
|
||||||
|
self.collection_name,
|
||||||
|
{
|
||||||
|
Chat.mongo_chat_id_index: chat_id
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if not chat:
|
||||||
|
raise NotFoundException
|
||||||
|
|
||||||
|
return Chat.from_mongo_document(chat)
|
||||||
|
|
||||||
|
def get_users_for_group(self, chat_id: str, group: str) -> Iterable[User]:
|
||||||
|
chat = self.get(chat_id)
|
||||||
|
if not chat.groups.get(group):
|
||||||
|
raise NotFoundException
|
||||||
|
|
||||||
|
return [self.user_repository.get(user_id) for user_id in chat.groups.get(group)]
|
||||||
|
|
||||||
|
def save(self, chat: Chat) -> None:
|
||||||
|
self.database_client.save(
|
||||||
|
self.collection_name,
|
||||||
|
{Chat.mongo_chat_id_index: chat.chat_id},
|
||||||
|
chat.to_mongo_document()
|
||||||
|
)
|
||||||
|
|
@ -1,56 +0,0 @@
|
|||||||
import re
|
|
||||||
from typing import Iterable
|
|
||||||
|
|
||||||
from database.client import Client
|
|
||||||
from entity.group import Group
|
|
||||||
from entity.user import User
|
|
||||||
from exception.notFoundException import NotFoundException
|
|
||||||
|
|
||||||
|
|
||||||
class GroupRepository:
|
|
||||||
client: Client
|
|
||||||
|
|
||||||
count: str = 'count'
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
def get_by_chat_id(self, chat_id: str) -> Iterable[Group]:
|
|
||||||
groups = self.client.aggregate(
|
|
||||||
User.collection,
|
|
||||||
[
|
|
||||||
{"$unwind": f'${User.chats_index}'},
|
|
||||||
{
|
|
||||||
"$match": {
|
|
||||||
User.chats_index: {"$regex": re.compile(f'^{chat_id}.*$')},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$group": {
|
|
||||||
"_id": {
|
|
||||||
"$last": {"$split": [f'${User.chats_index}', "~"]},
|
|
||||||
},
|
|
||||||
self.count: {"$count": {}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$sort": {'_id': 1}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
result = []
|
|
||||||
for group in groups:
|
|
||||||
group_name = group['_id']
|
|
||||||
|
|
||||||
if group_name == chat_id:
|
|
||||||
group_name = Group.default_name
|
|
||||||
|
|
||||||
result.append(
|
|
||||||
Group(chat_id, group_name, group[self.count])
|
|
||||||
)
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
raise NotFoundException
|
|
||||||
|
|
||||||
return result
|
|
@ -1,74 +1,43 @@
|
|||||||
from typing import Iterable
|
|
||||||
|
|
||||||
from bot.message.inboundMessage import InboundMessage
|
from bot.message.inboundMessage import InboundMessage
|
||||||
from database.client import Client
|
|
||||||
from entity.user import User
|
from entity.user import User
|
||||||
from exception.notFoundException import NotFoundException
|
from exception.notFoundException import NotFoundException
|
||||||
|
from repository.abstractRepository import AbstractRepository
|
||||||
|
|
||||||
|
|
||||||
class UserRepository:
|
class UserRepository(AbstractRepository):
|
||||||
client: Client
|
collection_name: str = 'users'
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self):
|
||||||
self.client = Client()
|
super().__init__()
|
||||||
|
|
||||||
def get_by_id(self, user_id: str) -> User:
|
def provide(self, inbound: InboundMessage) -> User:
|
||||||
user = self.client.find_one(
|
user = User.from_inbound_message(inbound)
|
||||||
User.collection,
|
|
||||||
|
try:
|
||||||
|
entity = self.get(user.user_id)
|
||||||
|
if entity != user:
|
||||||
|
self.save(user)
|
||||||
|
except NotFoundException:
|
||||||
|
self.save(user)
|
||||||
|
|
||||||
|
return user
|
||||||
|
|
||||||
|
def get(self, user_id: str) -> User:
|
||||||
|
user = self.database_client.find_one(
|
||||||
|
self.collection_name,
|
||||||
{
|
{
|
||||||
User.id_index: user_id
|
User.mongo_user_id_index: user_id
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
raise NotFoundException(f'Could not find user with "{user_id}" id')
|
|
||||||
|
|
||||||
return User(
|
|
||||||
user[User.id_index],
|
|
||||||
user[User.username_index],
|
|
||||||
user[User.chats_index]
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_by_id_and_chat_id(self, user_id: str, chat_id: str) -> User:
|
|
||||||
user = self.get_by_id(user_id)
|
|
||||||
|
|
||||||
if not user.is_in_chat(chat_id):
|
|
||||||
raise NotFoundException
|
raise NotFoundException
|
||||||
|
|
||||||
return user
|
return User.from_mongo_document(user)
|
||||||
|
|
||||||
def save(self, user: User) -> None:
|
def save(self, user: User) -> None:
|
||||||
self.client.update_one(
|
self.database_client.save(
|
||||||
User.collection,
|
self.collection_name,
|
||||||
{User.id_index: user.user_id},
|
{User.mongo_user_id_index: user.user_id},
|
||||||
user.to_mongo_document()
|
user.to_mongo_document()
|
||||||
)
|
)
|
||||||
|
|
||||||
def save_by_inbound_message(self, inbound_message: InboundMessage) -> None:
|
|
||||||
self.client.insert_one(
|
|
||||||
User.collection,
|
|
||||||
{
|
|
||||||
User.id_index: inbound_message.user_id,
|
|
||||||
User.username_index: inbound_message.username,
|
|
||||||
User.chats_index: [inbound_message.chat_id]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_all_for_chat(self, chat_id: str) -> Iterable[User]:
|
|
||||||
result = []
|
|
||||||
users = self.client.find_many(
|
|
||||||
User.collection,
|
|
||||||
{
|
|
||||||
User.chats_index: {
|
|
||||||
"$in": [chat_id]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
for record in users:
|
|
||||||
result.append(User.from_mongo_document(record))
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
raise NotFoundException
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
@ -3,16 +3,16 @@ from typing import Iterable
|
|||||||
from prettytable import prettytable
|
from prettytable import prettytable
|
||||||
from telegram.utils.helpers import mention_markdown
|
from telegram.utils.helpers import mention_markdown
|
||||||
|
|
||||||
from entity.group import Group
|
|
||||||
from entity.user import User
|
from entity.user import User
|
||||||
|
|
||||||
|
|
||||||
class MessageBuilder:
|
class MessageBuilder:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def group_message(groups: Iterable[Group]) -> str:
|
def group_message(groups: dict) -> str:
|
||||||
table = prettytable.PrettyTable(['Name', 'Members'])
|
table = prettytable.PrettyTable(['Name', 'Members'])
|
||||||
|
|
||||||
table.add_rows([[record.group_name, record.users_count] for record in groups])
|
for group in groups:
|
||||||
|
table.add_row([group, len(groups[group])])
|
||||||
|
|
||||||
return f'<pre>{str(table)}</pre>'
|
return f'<pre>{str(table)}</pre>'
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user