mirror of
https://github.com/miloszowi/everyone-mention-telegram-bot.git
synced 2025-05-20 17:24:06 +00:00
PEP-8 coding standards, used dataclasses for User and UpdateData classes
This commit is contained in:
parent
2b0728b58c
commit
bbb1706dbe
@ -14,15 +14,15 @@ class App:
|
|||||||
self.updater = Updater(BOT_TOKEN)
|
self.updater = Updater(BOT_TOKEN)
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
self.registerHandlers()
|
self.register_handlers()
|
||||||
|
|
||||||
self.updater.start_polling()
|
self.updater.start_polling()
|
||||||
self.updater.idle()
|
self.updater.idle()
|
||||||
|
|
||||||
def registerHandlers(self) -> None:
|
def register_handlers(self) -> None:
|
||||||
for handler in AbstractHandler.__subclasses__():
|
for handler in AbstractHandler.__subclasses__():
|
||||||
self.updater.dispatcher.add_handler(
|
self.updater.dispatcher.add_handler(
|
||||||
handler().getBotHandler()
|
handler().get_bot_handler()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from pymongo.database import Database
|
|||||||
|
|
||||||
|
|
||||||
class Client():
|
class Client():
|
||||||
mongoClient: MongoClient
|
mongo_client: MongoClient
|
||||||
database: Database
|
database: Database
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
@ -17,19 +17,19 @@ class Client():
|
|||||||
MONGODB_HOSTNAME, MONGODB_PORT, MONGODB_DATABASE
|
MONGODB_HOSTNAME, MONGODB_PORT, MONGODB_DATABASE
|
||||||
)
|
)
|
||||||
|
|
||||||
self.mongoClient = MongoClient(uri)
|
self.mongo_client = MongoClient(uri)
|
||||||
self.database = self.mongoClient[MONGODB_DATABASE]
|
self.database = self.mongo_client[MONGODB_DATABASE]
|
||||||
|
|
||||||
def insertOne(self, collection: str, data: dict) -> None:
|
def insert_one(self, collection: str, data: dict) -> None:
|
||||||
self.database.get_collection(collection).insert_one(data)
|
self.database.get_collection(collection).insert_one(data)
|
||||||
|
|
||||||
def findOne(self, collection: str, query: dict) -> dict:
|
def find_one(self, collection: str, query: dict) -> dict:
|
||||||
return self.database.get_collection(collection).find_one(query)
|
return self.database.get_collection(collection).find_one(query)
|
||||||
|
|
||||||
def findMany(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 updateOne(self, collection: str, filter: dict, data: dict) -> None:
|
def update_one(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 }
|
||||||
|
@ -1,52 +1,40 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class User():
|
class User():
|
||||||
collection: str = 'users'
|
user_id: str
|
||||||
idIndex: str = '_id'
|
|
||||||
chatsIndex: str = 'chats'
|
|
||||||
usernameIndex: str = 'username'
|
|
||||||
|
|
||||||
userId: str
|
|
||||||
username: str
|
username: str
|
||||||
chats: Iterable[str]
|
chats: Iterable[str]
|
||||||
|
|
||||||
def __init__(self, userId, username, chats) -> None:
|
collection: str = 'users'
|
||||||
self.userId = userId
|
id_index: str = '_id'
|
||||||
self.username = username
|
chats_index: str = 'chats'
|
||||||
self.chats = chats
|
username_index: str = 'username'
|
||||||
|
|
||||||
def getUserId(self) -> str:
|
def is_in_chat(self, chat_id: str) -> bool:
|
||||||
return self.userId
|
return chat_id in self.chats
|
||||||
|
|
||||||
def getUsername(self) -> str:
|
def add_to_chat(self, chat_id: str) -> None:
|
||||||
return self.username
|
self.chats.append(chat_id)
|
||||||
|
|
||||||
def getChats(self) -> Iterable[str]:
|
def remove_from_chat(self, chat_id: str) -> None:
|
||||||
return self.chats
|
if chat_id in self.chats:
|
||||||
|
self.chats.remove(chat_id)
|
||||||
|
|
||||||
def isInChat(self, chatId: str) -> bool:
|
def to_mongo_document(self) -> dict:
|
||||||
return chatId in self.getChats()
|
|
||||||
|
|
||||||
def addToChat(self, chatId: str) -> None:
|
|
||||||
self.chats.append(chatId)
|
|
||||||
|
|
||||||
def removeFromChat(self, chatId: str) -> None:
|
|
||||||
if chatId in self.getChats():
|
|
||||||
self.chats.remove(chatId)
|
|
||||||
|
|
||||||
def toMongoDocument(self) -> dict:
|
|
||||||
return {
|
return {
|
||||||
self.usernameIndex: self.getUsername(),
|
self.username_index: self.username,
|
||||||
self.chatsIndex: self.getChats()
|
self.chats_index: self.chats
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fromMongoDocument(mongoDocument: dict) -> User:
|
def from_mongo_document(mongo_document: dict) -> User:
|
||||||
return User(
|
return User(
|
||||||
mongoDocument[User.idIndex],
|
mongo_document[User.id_index],
|
||||||
mongoDocument[User.usernameIndex],
|
mongo_document[User.username_index],
|
||||||
mongoDocument[User.chatsIndex]
|
mongo_document[User.chats_index]
|
||||||
)
|
)
|
||||||
|
@ -8,17 +8,14 @@ from handler.vo.updateData import UpdateData
|
|||||||
|
|
||||||
|
|
||||||
class AbstractHandler:
|
class AbstractHandler:
|
||||||
def __init__(self) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def getBotHandler(self) -> Handler: raise Exception('getBotHandler method is not implemented')
|
def get_bot_handler(self) -> Handler: raise Exception('get_bot_handler method is not implemented')
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def handle(self, update: Update, context: CallbackContext) -> None: raise Exception('handle method is not implemented')
|
def handle(self, update: Update, context: CallbackContext) -> None: raise Exception('handle method is not implemented')
|
||||||
|
|
||||||
def getUpdateData(self, update: Update) -> UpdateData:
|
def get_update_data(self, update: Update) -> UpdateData:
|
||||||
return UpdateData.createFromUpdate(update)
|
return UpdateData.create_from_update(update)
|
||||||
|
|
||||||
def reply(self, update: Update, message: str) -> None:
|
def reply(self, update: Update, message: str) -> None:
|
||||||
update.effective_message.reply_markdown_v2(text=message)
|
update.effective_message.reply_markdown_v2(text=message)
|
||||||
|
@ -9,30 +9,30 @@ from handler.abstractHandler import AbstractHandler
|
|||||||
|
|
||||||
|
|
||||||
class InHandler(AbstractHandler):
|
class InHandler(AbstractHandler):
|
||||||
botHandler: CommandHandler
|
bot_handler: CommandHandler
|
||||||
userRepository: UserRepository
|
user_repository: UserRepository
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.botHandler = CommandHandler('in', self.handle)
|
self.bot_handler = CommandHandler('in', self.handle)
|
||||||
self.userRepository = UserRepository()
|
self.user_repository = UserRepository()
|
||||||
|
|
||||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||||
updateData = self.getUpdateData(update)
|
update_data = self.get_update_data(update)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user = self.userRepository.getById(updateData.getUserId())
|
user = self.user_repository.get_by_id(update_data.user_id)
|
||||||
|
|
||||||
if user.isInChat(updateData.getChatId()):
|
if user.is_in_chat(update_data.chat_id):
|
||||||
self.reply(update, opted_in_failed)
|
self.reply(update, opted_in_failed)
|
||||||
return
|
return
|
||||||
|
|
||||||
user.addToChat(updateData.getChatId())
|
user.add_to_chat(update_data.chat_id)
|
||||||
self.userRepository.save(user)
|
self.user_repository.save(user)
|
||||||
|
|
||||||
except NotFoundException:
|
except NotFoundException:
|
||||||
self.userRepository.saveByUpdateData(updateData)
|
self.user_repository.save_by_update_data(update_data)
|
||||||
|
|
||||||
self.reply(update, opted_in)
|
self.reply(update, opted_in)
|
||||||
|
|
||||||
def getBotHandler(self) -> CommandHandler:
|
def get_bot_handler(self) -> CommandHandler:
|
||||||
return self.botHandler
|
return self.bot_handler
|
||||||
|
@ -11,37 +11,37 @@ from handler.abstractHandler import AbstractHandler
|
|||||||
|
|
||||||
|
|
||||||
class MentionHandler(AbstractHandler):
|
class MentionHandler(AbstractHandler):
|
||||||
botHandler: CommandHandler
|
bot_handler: CommandHandler
|
||||||
userRepository: UserRepository
|
user_repository: UserRepository
|
||||||
silent: str = 'silent'
|
silent: str = 'silent'
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.botHandler = CommandHandler('everyone', self.handle)
|
self.bot_handler = CommandHandler('everyone', self.handle)
|
||||||
self.userRepository = UserRepository()
|
self.user_repository = UserRepository()
|
||||||
|
|
||||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||||
updateData = self.getUpdateData(update)
|
updateData = self.get_update_data(update)
|
||||||
users = self.userRepository.getAllForChat(updateData.getChatId())
|
users = self.user_repository.get_all_for_chat(updateData.chat_id)
|
||||||
|
|
||||||
if users:
|
if users:
|
||||||
self.reply(update, self.buildMentionMessage(users, self.isSilent(context)))
|
self.reply(update, self.build_mention_message(users, self.isSilent(context)))
|
||||||
return
|
return
|
||||||
|
|
||||||
self.reply(update, mention_failed)
|
self.reply(update, mention_failed)
|
||||||
|
|
||||||
def getBotHandler(self) -> CommandHandler:
|
def get_bot_handler(self) -> CommandHandler:
|
||||||
return self.botHandler
|
return self.bot_handler
|
||||||
|
|
||||||
def buildMentionMessage(self, users: Iterable[User], silent: bool = False) -> str:
|
def build_mention_message(self, users: Iterable[User], silent: bool = False) -> str:
|
||||||
result = ''
|
result = ''
|
||||||
|
|
||||||
for user in users:
|
for user in users:
|
||||||
if not silent:
|
if not silent:
|
||||||
result += f'*[{user.getUsername()}](tg://user?id={user.getUserId()})* '
|
result += f'*[{user.username}](tg://user?id={user.user_id})* '
|
||||||
else:
|
else:
|
||||||
result += f'*{user.getUsername()}\({user.getUserId()}\)*\n'
|
result += f'*{user.username}\({user.user_id}\)*\n'
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def isSilent(self, context: CallbackContext) -> bool:
|
def isSilent(self, context: CallbackContext) -> bool:
|
||||||
return context.args and context.args[0] == self.silent
|
return self.silent in context.args
|
@ -9,28 +9,29 @@ from handler.abstractHandler import AbstractHandler
|
|||||||
|
|
||||||
|
|
||||||
class OutHandler(AbstractHandler):
|
class OutHandler(AbstractHandler):
|
||||||
botHandler: CommandHandler
|
bot_handler: CommandHandler
|
||||||
userRepository: UserRepository
|
user_repository: UserRepository
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.botHandler = CommandHandler('out', self.handle)
|
self.bot_handler = CommandHandler('out', self.handle)
|
||||||
self.userRepository = UserRepository()
|
self.user_repository = UserRepository()
|
||||||
|
|
||||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||||
updateData = self.getUpdateData(update)
|
updateData = self.get_update_data(update)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user = self.userRepository.getById(updateData.getUserId())
|
user = self.user_repository.get_by_id(updateData.user_id)
|
||||||
if not user.isInChat(updateData.getChatId()):
|
|
||||||
|
if not user.is_in_chat(updateData.chat_id):
|
||||||
raise NotFoundException()
|
raise NotFoundException()
|
||||||
except NotFoundException:
|
except NotFoundException:
|
||||||
self.reply(update, opted_off_failed)
|
self.reply(update, opted_off_failed)
|
||||||
return
|
return
|
||||||
|
|
||||||
user.removeFromChat(updateData.getChatId())
|
user.remove_from_chat(updateData.chat_id)
|
||||||
self.userRepository.save(user)
|
self.user_repository.save(user)
|
||||||
|
|
||||||
self.reply(update, opted_off)
|
self.reply(update, opted_off)
|
||||||
|
|
||||||
def getBotHandler(self) -> CommandHandler:
|
def get_bot_handler(self) -> CommandHandler:
|
||||||
return self.botHandler
|
return self.bot_handler
|
||||||
|
@ -1,35 +1,24 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import names
|
import names
|
||||||
from telegram.update import Update
|
from telegram.update import Update
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class UpdateData():
|
class UpdateData():
|
||||||
userId: str
|
user_id: str
|
||||||
chatId: str
|
chat_id: str
|
||||||
username: str
|
username: str
|
||||||
|
|
||||||
def __init__(self, userId: str, chatId: str, username: str) -> None:
|
|
||||||
self.userId = userId
|
|
||||||
self.chatId = chatId
|
|
||||||
self.username = username
|
|
||||||
|
|
||||||
def getUserId(self) -> str:
|
|
||||||
return self.userId
|
|
||||||
|
|
||||||
def getChatId(self) -> str:
|
|
||||||
return self.chatId
|
|
||||||
|
|
||||||
def getUsername(self) -> str:
|
|
||||||
return self.username
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def createFromUpdate(update: Update) -> UpdateData:
|
def create_from_update(update: Update) -> UpdateData:
|
||||||
userId = str(update.effective_user.id)
|
user_id = str(update.effective_user.id)
|
||||||
chatId = str(update.effective_chat.id)
|
chat_id = str(update.effective_chat.id)
|
||||||
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:
|
||||||
username = names.get_first_name()
|
username = names.get_first_name()
|
||||||
|
|
||||||
return UpdateData(userId, chatId, username)
|
return UpdateData(user_id, chat_id, username)
|
||||||
|
@ -12,11 +12,11 @@ class UserRepository():
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
|
||||||
def getById(self, id: str) -> User:
|
def get_by_id(self, id: str) -> User:
|
||||||
user = self.client.findOne(
|
user = self.client.find_one(
|
||||||
User.collection,
|
User.collection,
|
||||||
{
|
{
|
||||||
User.idIndex: id
|
User.id_index: id
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,41 +24,41 @@ class UserRepository():
|
|||||||
raise NotFoundException(f'Could not find user with "{id}" id')
|
raise NotFoundException(f'Could not find user with "{id}" id')
|
||||||
|
|
||||||
return User(
|
return User(
|
||||||
user[User.idIndex],
|
user[User.id_index],
|
||||||
user[User.usernameIndex],
|
user[User.username_index],
|
||||||
user[User.chatsIndex]
|
user[User.chats_index]
|
||||||
)
|
)
|
||||||
|
|
||||||
def save(self, user: User) -> None:
|
def save(self, user: User) -> None:
|
||||||
self.client.updateOne(
|
self.client.update_one(
|
||||||
User.collection,
|
User.collection,
|
||||||
{ User.idIndex: user.getUserId() },
|
{ User.id_index: user.user_id },
|
||||||
user.toMongoDocument()
|
user.to_mongo_document()
|
||||||
)
|
)
|
||||||
|
|
||||||
def saveByUpdateData(self, data: UpdateData) -> None:
|
def save_by_update_data(self, data: UpdateData) -> None:
|
||||||
self.client.insertOne(
|
self.client.insert_one(
|
||||||
User.collection,
|
User.collection,
|
||||||
{
|
{
|
||||||
User.idIndex: data.getUserId(),
|
User.id_index: data.user_id,
|
||||||
User.usernameIndex: data.getUsername(),
|
User.username_index: data.username,
|
||||||
User.chatsIndex: [data.getChatId()]
|
User.chats_index: [data.chat_id]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def getAllForChat(self, chatId: str) -> Iterable[User]:
|
def get_all_for_chat(self, chat_id: str) -> Iterable[User]:
|
||||||
result = []
|
result = []
|
||||||
users = self.client.findMany(
|
users = self.client.find_many(
|
||||||
User.collection,
|
User.collection,
|
||||||
{
|
{
|
||||||
User.chatsIndex: {
|
User.chats_index: {
|
||||||
"$in" : [chatId]
|
"$in" : [chat_id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
for record in users:
|
for record in users:
|
||||||
result.append(User.fromMongoDocument(record))
|
result.append(User.from_mongo_document(record))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user