Add changeable roles

This commit is contained in:
AlberLC
2022-07-29 07:15:58 +02:00
parent b58d7c2e56
commit 9fe9fe5757
3 changed files with 90 additions and 17 deletions

View File

@@ -17,7 +17,7 @@ import plotly.graph_objects
import pymongo
from flanaapis import InstagramLoginError, MediaNotFoundError, Place, PlaceNotFoundError, WeatherEmoji, instagram, tiktok, twitter
from flanautils import Media, MediaType, NotFoundError, OrderedSet, Source, TimeUnits, TraceMetadata, return_if_first_empty
from multibot import Action, BadRoleError, BotAction, ButtonsGroup, MultiBot, SendError, User, admin, bot_mentioned, constants as multibot_constants, group, ignore_self_message, inline, reply
from multibot import Action, BadRoleError, BotAction, ButtonsGroup, MultiBot, Role, SendError, User, admin, bot_mentioned, constants as multibot_constants, group, ignore_self_message, inline, reply
from flanabot import constants
from flanabot.models import Chat, Message, Punishment, WeatherChart
@@ -102,8 +102,16 @@ class FlanaBot(MultiBot, ABC):
self.register(self._on_punish, (multibot_constants.KEYWORDS['deactivate'], constants.KEYWORDS['unpunish']))
self.register(self._on_punish, (multibot_constants.KEYWORDS['deactivate'], multibot_constants.KEYWORDS['permission']))
self.register(self._on_recover_message, multibot_constants.KEYWORDS['reset'])
self.register(self._on_recover_message, (multibot_constants.KEYWORDS['reset'], multibot_constants.KEYWORDS['message']))
self.register(self._on_roles, multibot_constants.KEYWORDS['permission'])
self.register(self._on_roles, multibot_constants.KEYWORDS['role'])
self.register(self._on_roles, (multibot_constants.KEYWORDS['permission'], multibot_constants.KEYWORDS['role']))
self.register(self._on_roles, (multibot_constants.KEYWORDS['change'], multibot_constants.KEYWORDS['permission']))
self.register(self._on_roles, (multibot_constants.KEYWORDS['activate'], multibot_constants.KEYWORDS['role']))
self.register(self._on_roles, (multibot_constants.KEYWORDS['deactivate'], multibot_constants.KEYWORDS['role']))
self.register(self._on_scraping, constants.KEYWORDS['scraping'])
self.register(self._on_scraping_config_activate, (multibot_constants.KEYWORDS['activate'], constants.KEYWORDS['scraping']))
@@ -148,6 +156,7 @@ class FlanaBot(MultiBot, ABC):
self.register_button(self._on_config_button_press, ButtonsGroup.CONFIG)
self.register_button(self._on_poll_button_press, ButtonsGroup.POLL)
self.register_button(self._on_roles_button_press, ButtonsGroup.ROLES)
self.register_button(self._on_weather_button_press, ButtonsGroup.WEATHER)
async def _change_config(self, config_name: str, message: Message, value: bool = None):
@@ -159,6 +168,9 @@ class FlanaBot(MultiBot, ABC):
await self.send(f"He {'activado ✔' if value else 'desactivado ❌'} {config_name}.", message)
async def _changeable_roles(self, group_: int | str | Chat | Message) -> list[Role]:
pass
@admin(False)
@group
async def _check_message_flood(self, message: Message):
@@ -192,6 +204,9 @@ class FlanaBot(MultiBot, ABC):
else:
await self.send(f'Castigado durante {TimeUnits(seconds=punishment_seconds).to_words()}.', message)
def _distribute_buttons(self, texts: Sequence[str]) -> list[list[str]]:
pass
@staticmethod
def _get_options(text: str, discarded_words: Iterable = ()) -> list[str]:
options = (option for option in text.split() if not flanautils.cartesian_product_string_matching(option.lower(), discarded_words, min_ratio=multibot_constants.PARSE_CALLBACKS_MIN_RATIO_DEFAULT))
@@ -266,6 +281,20 @@ class FlanaBot(MultiBot, ABC):
async def _punish(self, user: int | str | User, group_: int | str | Chat | Message, message: Message = None):
pass
async def _role_state_options(self, group_: int | str | Chat | Message, activated_user_role_names: list[str]) -> list[str]:
options = []
for role in await self._changeable_roles(group_):
if role.name == '@everyone':
continue
if role.name in activated_user_role_names:
options.append(f'{role.name}')
else:
options.append(f'{role.name}')
options.reverse()
return options
async def _search_and_send_medias(self, message: Message, send_song_info=False) -> list[Message]:
sended_media_messages = []
@@ -326,26 +355,26 @@ class FlanaBot(MultiBot, ABC):
'entre', 'between'
}
if final_options := self._get_options(message.text, discarded_words):
for i in range(1, len(final_options) - 1):
if options := self._get_options(message.text, discarded_words):
for i in range(1, len(options) - 1):
try:
n1 = flanautils.cast_number(final_options[i - 1])
n1 = flanautils.cast_number(options[i - 1])
except ValueError:
try:
n1 = flanautils.words_to_numbers(final_options[i - 1], ignore_no_numbers=False)
n1 = flanautils.words_to_numbers(options[i - 1], ignore_no_numbers=False)
except KeyError:
continue
try:
n2 = flanautils.cast_number(final_options[i + 1])
n2 = flanautils.cast_number(options[i + 1])
except ValueError:
try:
n2 = flanautils.words_to_numbers(final_options[i + 1], ignore_no_numbers=False)
n2 = flanautils.words_to_numbers(options[i + 1], ignore_no_numbers=False)
except KeyError:
continue
if final_options[i] in ('al', 'el', 'to'):
if options[i] in ('al', 'el', 'to'):
await self.send(random.randint(math.ceil(n1), math.floor(n2)), message)
return
await self.send(random.choice(final_options), message)
await self.send(random.choice(options), message)
else:
await self.send(random.choice(('¿Que elija el qué?', '¿Y las opciones?', '?', '🤔')), message)
@@ -486,9 +515,6 @@ class FlanaBot(MultiBot, ABC):
if not await self._on_scraping(message, delete_original=False):
await self._on_recover_message(message)
def _distribute_poll_buttons(self, texts: Sequence[str]) -> list[list[str]]:
pass
async def _on_poll(self, message: Message):
if message.chat.is_group and not self.is_bot_mentioned(message):
return
@@ -497,7 +523,13 @@ class FlanaBot(MultiBot, ABC):
discarded_words = {*constants.KEYWORDS['poll'], self.name.lower(), f'<@{self.id}>'}
if final_options := [f'{option[0].upper()}{option[1:]}' for option in self._get_options(message.text, discarded_words)]:
await self.send('Encuesta en curso...', self._distribute_poll_buttons(final_options), message, buttons_key=ButtonsGroup.POLL, contents={'poll': {'is_active': True, 'votes': {option: [] for option in final_options}}})
await self.send(
'Encuesta en curso...',
self._distribute_buttons(final_options),
message,
buttons_key=ButtonsGroup.POLL,
contents={'poll': {'is_active': True, 'votes': {option: [] for option in final_options}}}
)
else:
await self.send(random.choice(('¿Y las opciones?', '?', '🤔')), message)
@@ -535,7 +567,7 @@ class FlanaBot(MultiBot, ABC):
else:
buttons = list(message.contents['poll']['votes'].keys())
await self.edit(self._distribute_poll_buttons(buttons), message)
await self.edit(self._distribute_buttons(buttons), message)
@bot_mentioned
@group
@@ -570,6 +602,39 @@ class FlanaBot(MultiBot, ABC):
for deleted_message in deleted_messages:
await self.send(deleted_message.text, message)
async def _on_roles(self, message: Message):
# noinspection PyTypeChecker
user_role_names = [discord_role.name for discord_role in message.author.original_object.roles]
await self.delete_message(message)
await self.send(
f'<b>Roles de {message.author.name}:</b>',
self._distribute_buttons(await self._role_state_options(message, user_role_names)),
message,
buttons_key=ButtonsGroup.ROLES,
contents={'user_id': message.author.id}
)
async def _on_roles_button_press(self, message: Message):
await self.accept_button_event(message)
if message.buttons_info.presser_user.id != message.contents['user_id']:
return
role = await self.find_role(message.buttons_info.pressed_text[1:].strip(), message)
user_role_names = [discord_role.name for discord_role in message.buttons_info.presser_user.original_object.roles]
if role.name in user_role_names:
await self.remove_role(message.buttons_info.presser_user, message, role)
message.buttons_info.presser_user.roles.remove(role)
user_role_names.remove(role.name)
else:
await self.add_role(message.buttons_info.presser_user, message, role)
message.buttons_info.presser_user.roles.append(role)
user_role_names.append(role.name)
await self.edit(self._distribute_buttons(await self._role_state_options(message, user_role_names)), message)
message.buttons_info.presser_user.save()
async def _on_scraping(self, message: Message, delete_original: bool = None) -> OrderedSet[Media]:
sended_media_messages = OrderedSet()
if message.replied_message:

View File

@@ -7,12 +7,16 @@ from typing import Sequence
import discord
import flanautils
from flanautils import NotFoundError
from multibot import BadRoleError, DiscordBot, User, constants as multibot_constants
from multibot import BadRoleError, DiscordBot, Role, User, constants as multibot_constants
from flanabot import constants
from flanabot.bots.flana_bot import FlanaBot
from flanabot.models import Chat, Message, Punishment
CHANGEABLE_ROLES = {
360868977754505217: [881238165476741161, 991454395663401072],
862823584670285835: [976660580939202610, 984269640752590868],
}
HEAT_NAMES = [
'Canal Congelado',
'Canal Fresquito',
@@ -47,8 +51,12 @@ class FlanaDiscBot(DiscordBot, FlanaBot):
self.client.add_listener(self._on_member_remove, 'on_member_remove')
self.client.add_listener(self._on_voice_state_update, 'on_voice_state_update')
async def _changeable_roles(self, group_: int | str | Chat | Message) -> list[Role]:
group_id = self.get_group_id(group_)
return [role for role in await self.get_group_roles(group_) if role.id in CHANGEABLE_ROLES[group_id]]
# noinspection PyTypeChecker
def _distribute_poll_buttons(self, texts: Sequence[str]) -> list[list[str]]:
def _distribute_buttons(self, texts: Sequence[str]) -> list[list[str]]:
if len(texts) <= multibot_constants.DISCORD_BUTTONS_MAX:
return flanautils.chunks(texts, 1)
else:

View File

@@ -47,7 +47,7 @@ class FlanaTeleBot(TelegramBot, FlanaBot):
# ----------------------------------------------------------- #
# -------------------- PROTECTED METHODS -------------------- #
# ----------------------------------------------------------- #
def _distribute_poll_buttons(self, texts: Sequence[str]) -> list[list[str]]:
def _distribute_buttons(self, texts: Sequence[str]) -> list[list[str]]:
# noinspection PyTypeChecker
return flanautils.chunks(texts, 1)