7 Commits

Author SHA1 Message Date
AlberLC
1e8a33c0c4 Improve button registration 2022-06-08 22:05:02 +02:00
AlberLC
daef039ce5 Change _manage_exceptions context arg 2022-06-06 04:22:26 +02:00
AlberLC
7ad4c4052e Remove twitch bot at main 2022-06-06 02:31:16 +02:00
AlberLC
641dc72738 Update requirements.txt 2022-06-04 03:33:59 +02:00
AlberLC
cafa7ce1c5 Fix recover original message 2022-06-04 02:58:32 +02:00
AlberLC
c9a46b2b07 Fix roles mentions in weather 2022-06-01 03:16:45 +02:00
AlberLC
92ee0e405d Fix env variable names 2022-05-31 23:08:36 +02:00
11 changed files with 79 additions and 90 deletions

View File

@@ -1,3 +1,5 @@
__all__ = ['FlanaBot']
import asyncio
import datetime
import random
@@ -10,12 +12,13 @@ import flanaapis.geolocation.functions
import flanaapis.weather.functions
import flanautils
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, MultiBot, SendError, User, admin, bot_mentioned, constants as multibot_constants, group, ignore_self_message, inline, reply
from flanabot import constants
from flanabot.models import ButtonsMessageType, Chat, Message, Punishment, WeatherChart
from flanabot.models import Chat, Message, Punishment, WeatherChart
# ----------------------------------------------------------------------------------------------------- #
@@ -128,7 +131,8 @@ class FlanaBot(MultiBot, ABC):
self.register(self._on_weather_chart_config_show, (constants.KEYWORDS['weather_chart'], multibot_constants.KEYWORDS['config']))
self.register(self._on_weather_chart_config_show, (multibot_constants.KEYWORDS['show'], constants.KEYWORDS['weather_chart'], multibot_constants.KEYWORDS['config']))
self.register_button(self._on_button_press)
self.register_button(self._on_config_button_press, list(Chat.DEFAULT_CONFIG.keys()))
self.register_button(self._on_weather_button_press, WeatherEmoji.values)
async def _change_config(self, config_name: str, message: Message, value: bool = None):
if value is None:
@@ -184,10 +188,11 @@ class FlanaBot(MultiBot, ABC):
config = message.chat.config
buttons_texts = [f"{'' if v else ''} {k}" for k, v in config.items()]
# noinspection PyTypeChecker
return flanautils.chunks(buttons_texts, 3)
@return_if_first_empty(exclude_self_types='FlanaBot', globals_=globals())
async def _manage_exceptions(self, exceptions: BaseException | Iterable[BaseException], message: Message):
async def _manage_exceptions(self, exceptions: BaseException | Iterable[BaseException], context: Chat | Message):
if not isinstance(exceptions, Iterable):
exceptions = (exceptions,)
@@ -195,15 +200,15 @@ class FlanaBot(MultiBot, ABC):
try:
raise exception
except BadRoleError as e:
await self.send_error(f'Rol no encontrado en {e}', message)
await self.send_error(f'Rol no encontrado en {e}', context)
except InstagramLoginError as e:
await self.send_error(f'No me puedo loguear en Instagram {random.choice(multibot_constants.SAD_EMOJIS)} 👉 {e}', message)
await self.send_error(f'No me puedo loguear en Instagram {random.choice(multibot_constants.SAD_EMOJIS)} 👉 {e}', context)
except MediaNotFoundError as e:
await self.send_error(f'No he podido sacar nada de {e.source} {random.choice(multibot_constants.SAD_EMOJIS)}', message)
await self.send_error(f'No he podido sacar nada de {e.source} {random.choice(multibot_constants.SAD_EMOJIS)}', context)
except PlaceNotFoundError as e:
await self.send_error(f'No he podido encontrar "{e}" {random.choice(multibot_constants.SAD_EMOJIS)}', message)
await self.send_error(f'No he podido encontrar "{e}" {random.choice(multibot_constants.SAD_EMOJIS)}', context)
except Exception as e:
await super()._manage_exceptions(e, message)
await super()._manage_exceptions(e, context)
@staticmethod
def _medias_sended_info(medias: Iterable[Media]) -> str:
@@ -292,59 +297,23 @@ class FlanaBot(MultiBot, ABC):
# ---------------------------------------------- #
# HANDLERS #
# ---------------------------------------------- #
async def _on_button_press(self, message: Message):
await self._accept_button_event(message)
match message.button_pressed_text:
case WeatherEmoji.ZOOM_IN.value:
buttons_message_type = ButtonsMessageType.WEATHER
message.weather_chart.zoom_in()
case WeatherEmoji.ZOOM_OUT.value:
buttons_message_type = ButtonsMessageType.WEATHER
message.weather_chart.zoom_out()
case WeatherEmoji.LEFT.value:
buttons_message_type = ButtonsMessageType.WEATHER
message.weather_chart.move_left()
case WeatherEmoji.RIGHT.value:
buttons_message_type = ButtonsMessageType.WEATHER
message.weather_chart.move_right()
case WeatherEmoji.PRECIPITATION_VOLUME.value:
buttons_message_type = ButtonsMessageType.WEATHER
message.weather_chart.trace_metadatas['rain_volume'].show = not message.weather_chart.trace_metadatas['rain_volume'].show
message.weather_chart.trace_metadatas['snow_volume'].show = not message.weather_chart.trace_metadatas['snow_volume'].show
case emoji if emoji in WeatherEmoji.values:
buttons_message_type = ButtonsMessageType.WEATHER
trace_metadata_name = WeatherEmoji(emoji).name.lower()
message.weather_chart.trace_metadatas[trace_metadata_name].show = not message.weather_chart.trace_metadatas[trace_metadata_name].show
case _ if message.button_pressed_user.is_admin and 'auto_' in (config := message.button_pressed_text.split()[1]):
buttons_message_type = ButtonsMessageType.CONFIG
message.chat.config[config] = not message.chat.config[config]
message.save()
await self.edit('<b>Estos son los ajustes del grupo:</b>\n\n', self._get_config_buttons(message), message)
case _:
return
if buttons_message_type is ButtonsMessageType.WEATHER:
message.weather_chart.apply_zoom()
message.weather_chart.draw()
message.save()
image_bytes = message.weather_chart.to_image()
await self.edit(Media(image_bytes, MediaType.IMAGE), message)
async def _on_bye(self, message: Message):
if not message.chat.is_group or self.is_bot_mentioned(message):
await self.send_bye(message)
async def _on_config_button_press(self, message: Message):
await self._accept_button_event(message)
if not message.button_pressed_user.is_admin or 'auto_' not in (config := message.button_pressed_text.split()[1]):
return
message.chat.config[config] = not message.chat.config[config]
message.save()
await self.edit('<b>Estos son los ajustes del grupo:</b>\n\n', self._get_config_buttons(message), message)
@group
@bot_mentioned
async def _on_config_list_show(self, message: Message):
# config_info = pprint.pformat(message.chat.config)
# config_info = flanautils.translate(config_info, {'{': None, '}': None, ',': None, 'True': '', "'": None, 'False': '❌'})
# config_info = config_info.splitlines()
# config_info = '\n'.join(config_info_.strip() for config_info_ in config_info)
# await self.send(f'<b>Estos son los ajustes del grupo:</b>\n\n<code>{config_info}</code>', message)
await self.send('<b>Estos son los ajustes del grupo:</b>\n\n', self._get_config_buttons(message), message)
async def _on_covid_chart(self, message: Message): # todo2
@@ -460,14 +429,18 @@ class FlanaBot(MultiBot, ABC):
@inline(False)
async def _on_recover_message(self, message: Message):
if message.replied_message:
message_deleted_bot_action = BotAction.find_one({'action': bytes(Action.MESSAGE_DELETED), 'chat': message.chat.object_id, 'affected_objects': message.replied_message.object_id})
message_deleted_bot_action = BotAction.find_one({'action': Action.MESSAGE_DELETED.value, 'chat': message.chat.object_id, 'affected_objects': message.replied_message.object_id})
elif self.is_bot_mentioned(message):
message_deleted_bot_action = BotAction.find_one({'action': bytes(Action.MESSAGE_DELETED), 'chat': message.chat.object_id, 'date': {'$gt': datetime.datetime.now(datetime.timezone.utc) - constants.RECOVERY_DELETED_MESSAGE_BEFORE}})
message_deleted_bot_action = BotAction.find_one({
'action': Action.MESSAGE_DELETED.value,
'chat': message.chat.object_id,
'date': {'$gt': datetime.datetime.now(datetime.timezone.utc) - constants.RECOVERY_DELETED_MESSAGE_BEFORE}
}, sort_keys=(('date', pymongo.DESCENDING),))
else:
return
if not message_deleted_bot_action:
await self.send_error(random.choice(constants.RECOVER_PHRASES), message)
await self.send_error('No hay nada que recuperar.', message)
return
affected_object_ids = [affected_message_object_id for affected_message_object_id in message_deleted_bot_action.affected_objects]
@@ -475,8 +448,6 @@ class FlanaBot(MultiBot, ABC):
for deleted_message in deleted_messages:
await self.send(deleted_message.text, message)
message_deleted_bot_action.delete()
async def _on_scraping(self, message: Message, delete_original: bool = None) -> OrderedSet[Media]:
sended_media_messages = await self._search_and_send_medias(message.replied_message) if message.replied_message else OrderedSet()
sended_media_messages += await self._search_and_send_medias(message)
@@ -548,6 +519,34 @@ class FlanaBot(MultiBot, ABC):
for user in await self._find_users_to_punish(message):
await self.unpunish(user, message, message)
async def _on_weather_button_press(self, message: Message):
await self._accept_button_event(message)
match message.button_pressed_text:
case WeatherEmoji.ZOOM_IN.value:
message.weather_chart.zoom_in()
case WeatherEmoji.ZOOM_OUT.value:
message.weather_chart.zoom_out()
case WeatherEmoji.LEFT.value:
message.weather_chart.move_left()
case WeatherEmoji.RIGHT.value:
message.weather_chart.move_right()
case WeatherEmoji.PRECIPITATION_VOLUME.value:
message.weather_chart.trace_metadatas['rain_volume'].show = not message.weather_chart.trace_metadatas['rain_volume'].show
message.weather_chart.trace_metadatas['snow_volume'].show = not message.weather_chart.trace_metadatas['snow_volume'].show
case emoji if emoji in WeatherEmoji.values:
trace_metadata_name = WeatherEmoji(emoji).name.lower()
message.weather_chart.trace_metadatas[trace_metadata_name].show = not message.weather_chart.trace_metadatas[trace_metadata_name].show
case _:
return
message.weather_chart.apply_zoom()
message.weather_chart.draw()
message.save()
image_bytes = message.weather_chart.to_image()
await self.edit(Media(image_bytes, MediaType.IMAGE), message)
async def _on_weather_chart(self, message: Message):
bot_state_message: Message | None = None
if message.is_inline:
@@ -568,8 +567,9 @@ class FlanaBot(MultiBot, ABC):
possible_mentioned_ids.append(user.name.split('#')[0].lower())
possible_mentioned_ids.append(f'@{user.id}')
for role in await self.get_group_roles(message):
possible_mentioned_ids.append(f'@{role.id}')
if roles := await self.get_roles(message):
for role in roles:
possible_mentioned_ids.append(f'@{role.id}')
original_text_words = flanautils.remove_accents(message.text.lower())
original_text_words = original_text_words.replace(',', ' ').replace(';', ' ').replace('-', ' -')
@@ -757,10 +757,7 @@ class FlanaBot(MultiBot, ABC):
message.song_infos.add(media.song_info)
message.save()
try:
bot_message = await self.send(media, message)
except SendError as e:
await self._manage_exceptions(e, message)
if not (bot_message := await self.send(media, message)):
fails += 1
else:
sended_media_messages.append(bot_message)

View File

@@ -1,3 +1,5 @@
__all__ = ['FlanaDiscBot']
import asyncio
import os
@@ -29,7 +31,7 @@ HOT_CHANNEL_ID = 493530483045564417
# ---------------------------------------------------------------------------------------------------- #
class FlanaDiscBot(DiscordBot, FlanaBot):
def __init__(self):
super().__init__(os.environ['DISCORD_BOT_TOKEN2'])
super().__init__(os.environ['DISCORD_BOT_TOKEN'])
self.heating = False
self.heat_level = 0

View File

@@ -1,5 +1,7 @@
from __future__ import annotations # todo0 remove in 3.11
__all__ = ['whitelisted_event', 'FlanaTeleBot']
import functools
import os
from typing import Callable
@@ -36,7 +38,7 @@ class FlanaTeleBot(TelegramBot, FlanaBot):
super().__init__(
api_id=os.environ['TELEGRAM_API_ID'],
api_hash=os.environ['TELEGRAM_API_HASH'],
bot_session=os.environ['TELEGRAM_BOT_SESSION2'],
bot_session=os.environ['TELEGRAM_BOT_SESSION'],
user_session=os.environ['TELEGRAM_USER_SESSION']
)
self.whitelist_ids = []

View File

@@ -71,14 +71,5 @@ KEYWORDS = {
'wetter')
}
RECOVER_PHRASES = (
'No hay nada que recuperar.',
'Ya lo he recuperado y enviado, así que callate ya.',
'Ya lo he recuperado y enviado, así que mejor estás antento antes de dar por culo.',
'Ya lo he recuperado y enviado, no lo voy a hacer dos veces.',
'Ya lo he recuperado y enviado. A ver si leemos más y jodemos menos.',
'Ya lo he reenviado.'
)
SCRAPING_PHRASES = ('Analizando...', 'Buscando...', 'Hackeando internet... 👀', 'Rebuscando en la web...',
'Robando cosas...', 'Scrapeando...', 'Scraping...')

View File

@@ -5,7 +5,6 @@ import flanautils
os.environ |= flanautils.find_environment_variables('../.env')
import asyncio
from flanabot.bots.flana_disc_bot import FlanaDiscBot
from flanabot.bots.flana_tele_bot import FlanaTeleBot

View File

@@ -1,5 +1,4 @@
from flanabot.models.chat import *
from flanabot.models.enums import *
from flanabot.models.message import *
from flanabot.models.punishment import *
from flanabot.models.weather_chart import *

View File

@@ -1,3 +1,5 @@
__all__ = ['Chat']
from dataclasses import dataclass
from multibot.models import Chat as MultiBotChat

View File

@@ -1,8 +0,0 @@
from enum import auto
from flanautils import FlanaEnum
class ButtonsMessageType(FlanaEnum):
CONFIG = auto()
WEATHER = auto()

View File

@@ -1,5 +1,7 @@
from __future__ import annotations # todo0 remove in 3.11
__all__ = ['Message']
from dataclasses import dataclass, field
from typing import Iterable

View File

@@ -1,3 +1,5 @@
__all__ = ['Direction', 'WeatherChart']
import datetime
from dataclasses import dataclass, field

View File

@@ -1,9 +1,9 @@
aiohttp==3.7.4.post0
aiohttp==3.8.1
aiosignal==1.2.0
anyio==3.5.0
asgiref==3.4.1
async-generator==1.10
async-timeout==3.0.1
async-timeout==4.0.2
attrs==21.4.0
beautifulsoup4==4.10.0
certifi==2021.10.8
@@ -14,7 +14,7 @@ click==8.0.3
colorama==0.4.4
cryptg==0.2.post4
cryptography==36.0.1
discord.py==2.0.0a4269+gb7e25645
discord.py @ git+https://github.com/Rapptz/discord.py@b7e25645dc68bbb828bf1ede711d098c6b183237
fastapi==0.71.0
flanaapis
flanautils
@@ -47,6 +47,7 @@ selenium-stealth==1.0.6
six==1.16.0
sniffio==1.2.0
sortedcontainers==2.4.0
soupsieve==2.3.1
starlette==0.17.1
sympy==1.9
Telethon==1.24.0
@@ -54,7 +55,7 @@ tenacity==8.0.1
TikTokApi==4.1.0
trio==0.19.0
trio-websocket==0.9.2
twitchio==2.1.4
twitchio==2.3.0
typing_extensions==4.0.1
ujson==5.1.0
urllib3==1.26.8