|
|
|
@@ -3,10 +3,11 @@ __all__ = ['FlanaBot']
|
|
|
|
import asyncio
|
|
|
|
import asyncio
|
|
|
|
import datetime
|
|
|
|
import datetime
|
|
|
|
import random
|
|
|
|
import random
|
|
|
|
|
|
|
|
import re
|
|
|
|
import time as time_module
|
|
|
|
import time as time_module
|
|
|
|
from abc import ABC
|
|
|
|
from abc import ABC
|
|
|
|
from asyncio import Future
|
|
|
|
from asyncio import Future
|
|
|
|
from typing import Iterable
|
|
|
|
from typing import Iterable, Sequence
|
|
|
|
|
|
|
|
|
|
|
|
import flanaapis.geolocation.functions
|
|
|
|
import flanaapis.geolocation.functions
|
|
|
|
import flanaapis.weather.functions
|
|
|
|
import flanaapis.weather.functions
|
|
|
|
@@ -15,7 +16,7 @@ import plotly.graph_objects
|
|
|
|
import pymongo
|
|
|
|
import pymongo
|
|
|
|
from flanaapis import InstagramLoginError, MediaNotFoundError, Place, PlaceNotFoundError, WeatherEmoji, instagram, tiktok, twitter
|
|
|
|
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 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 multibot import Action, BadRoleError, BotAction, ButtonsGroup, MultiBot, SendError, User, admin, bot_mentioned, constants as multibot_constants, group, ignore_self_message, inline, reply
|
|
|
|
|
|
|
|
|
|
|
|
from flanabot import constants
|
|
|
|
from flanabot import constants
|
|
|
|
from flanabot.models import Chat, Message, Punishment, WeatherChart
|
|
|
|
from flanabot.models import Chat, Message, Punishment, WeatherChart
|
|
|
|
@@ -37,6 +38,10 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_bye, multibot_constants.KEYWORDS['bye'])
|
|
|
|
self.register(self._on_bye, multibot_constants.KEYWORDS['bye'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_choose, constants.KEYWORDS['choose'])
|
|
|
|
|
|
|
|
self.register(self._on_choose, constants.KEYWORDS['random'])
|
|
|
|
|
|
|
|
self.register(self._on_choose, (constants.KEYWORDS['choose'], constants.KEYWORDS['random']))
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_config_list_show, multibot_constants.KEYWORDS['config'])
|
|
|
|
self.register(self._on_config_list_show, multibot_constants.KEYWORDS['config'])
|
|
|
|
self.register(self._on_config_list_show, (multibot_constants.KEYWORDS['show'], multibot_constants.KEYWORDS['config']))
|
|
|
|
self.register(self._on_config_list_show, (multibot_constants.KEYWORDS['show'], multibot_constants.KEYWORDS['config']))
|
|
|
|
|
|
|
|
|
|
|
|
@@ -79,6 +84,8 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
self.register(self._on_delete_original_config_show, (multibot_constants.KEYWORDS['delete'], multibot_constants.KEYWORDS['message'], multibot_constants.KEYWORDS['config']))
|
|
|
|
self.register(self._on_delete_original_config_show, (multibot_constants.KEYWORDS['delete'], multibot_constants.KEYWORDS['message'], multibot_constants.KEYWORDS['config']))
|
|
|
|
self.register(self._on_delete_original_config_show, (multibot_constants.KEYWORDS['show'], multibot_constants.KEYWORDS['delete'], multibot_constants.KEYWORDS['message'], multibot_constants.KEYWORDS['config']))
|
|
|
|
self.register(self._on_delete_original_config_show, (multibot_constants.KEYWORDS['show'], multibot_constants.KEYWORDS['delete'], multibot_constants.KEYWORDS['message'], multibot_constants.KEYWORDS['config']))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_dice, constants.KEYWORDS['dice'])
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_hello, multibot_constants.KEYWORDS['hello'])
|
|
|
|
self.register(self._on_hello, multibot_constants.KEYWORDS['hello'])
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_new_message_default, default=True)
|
|
|
|
self.register(self._on_new_message_default, default=True)
|
|
|
|
@@ -88,6 +95,8 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
self.register(self._on_no_delete_original, (multibot_constants.KEYWORDS['negate'], multibot_constants.KEYWORDS['delete'], multibot_constants.KEYWORDS['message']))
|
|
|
|
self.register(self._on_no_delete_original, (multibot_constants.KEYWORDS['negate'], multibot_constants.KEYWORDS['delete'], multibot_constants.KEYWORDS['message']))
|
|
|
|
self.register(self._on_no_delete_original, (multibot_constants.KEYWORDS['deactivate'], multibot_constants.KEYWORDS['delete'], multibot_constants.KEYWORDS['message']))
|
|
|
|
self.register(self._on_no_delete_original, (multibot_constants.KEYWORDS['deactivate'], multibot_constants.KEYWORDS['delete'], multibot_constants.KEYWORDS['message']))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_poll, constants.KEYWORDS['poll'])
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_punish, constants.KEYWORDS['punish'])
|
|
|
|
self.register(self._on_punish, constants.KEYWORDS['punish'])
|
|
|
|
self.register(self._on_punish, (multibot_constants.KEYWORDS['deactivate'], constants.KEYWORDS['unpunish']))
|
|
|
|
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_punish, (multibot_constants.KEYWORDS['deactivate'], multibot_constants.KEYWORDS['permission']))
|
|
|
|
@@ -111,6 +120,11 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_song_info, constants.KEYWORDS['song_info'])
|
|
|
|
self.register(self._on_song_info, constants.KEYWORDS['song_info'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_stop_poll, multibot_constants.KEYWORDS['deactivate'])
|
|
|
|
|
|
|
|
self.register(self._on_stop_poll, (multibot_constants.KEYWORDS['deactivate'], constants.KEYWORDS['poll']))
|
|
|
|
|
|
|
|
self.register(self._on_stop_poll, multibot_constants.KEYWORDS['stop'])
|
|
|
|
|
|
|
|
self.register(self._on_stop_poll, (multibot_constants.KEYWORDS['stop'], constants.KEYWORDS['poll']))
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_unpunish, constants.KEYWORDS['unpunish'])
|
|
|
|
self.register(self._on_unpunish, constants.KEYWORDS['unpunish'])
|
|
|
|
|
|
|
|
|
|
|
|
self.register(self._on_unpunish, (multibot_constants.KEYWORDS['deactivate'], constants.KEYWORDS['punish']))
|
|
|
|
self.register(self._on_unpunish, (multibot_constants.KEYWORDS['deactivate'], constants.KEYWORDS['punish']))
|
|
|
|
@@ -131,8 +145,9 @@ 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, (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(self._on_weather_chart_config_show, (multibot_constants.KEYWORDS['show'], constants.KEYWORDS['weather_chart'], multibot_constants.KEYWORDS['config']))
|
|
|
|
|
|
|
|
|
|
|
|
self.register_button(self._on_config_button_press, list(Chat.DEFAULT_CONFIG.keys()))
|
|
|
|
self.register_button(self._on_config_button_press, ButtonsGroup.CONFIG)
|
|
|
|
self.register_button(self._on_weather_button_press, WeatherEmoji.values)
|
|
|
|
self.register_button(self._on_poll_button_press, ButtonsGroup.POLL)
|
|
|
|
|
|
|
|
self.register_button(self._on_weather_button_press, ButtonsGroup.WEATHER)
|
|
|
|
|
|
|
|
|
|
|
|
async def _change_config(self, config_name: str, message: Message, value: bool = None):
|
|
|
|
async def _change_config(self, config_name: str, message: Message, value: bool = None):
|
|
|
|
if value is None:
|
|
|
|
if value is None:
|
|
|
|
@@ -174,18 +189,6 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
await self.send(f'Castigado durante {TimeUnits(seconds=punishment_seconds).to_words()}.', message)
|
|
|
|
await self.send(f'Castigado durante {TimeUnits(seconds=punishment_seconds).to_words()}.', message)
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
|
|
|
def _get_config_buttons(config: dict | Chat | Message) -> list[list[str]]:
|
|
|
|
|
|
|
|
match config:
|
|
|
|
|
|
|
|
case Chat() as chat:
|
|
|
|
|
|
|
|
config = chat.config
|
|
|
|
|
|
|
|
case Message() as message:
|
|
|
|
|
|
|
|
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())
|
|
|
|
@return_if_first_empty(exclude_self_types='FlanaBot', globals_=globals())
|
|
|
|
async def _manage_exceptions(self, exceptions: BaseException | Iterable[BaseException], context: Chat | Message):
|
|
|
|
async def _manage_exceptions(self, exceptions: BaseException | Iterable[BaseException], context: Chat | Message):
|
|
|
|
if not isinstance(exceptions, Iterable):
|
|
|
|
if not isinstance(exceptions, Iterable):
|
|
|
|
@@ -266,7 +269,7 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
return_exceptions=True
|
|
|
|
return_exceptions=True
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if not message.is_inline and (self.is_bot_mentioned(message) or not message.chat.is_group):
|
|
|
|
if not message.is_inline and (self.is_bot_mentioned(message) or message.chat.is_private):
|
|
|
|
while not results.done():
|
|
|
|
while not results.done():
|
|
|
|
if constants.SCRAPING_MESSAGE_WAITING_TIME <= time_module.perf_counter() - start_time:
|
|
|
|
if constants.SCRAPING_MESSAGE_WAITING_TIME <= time_module.perf_counter() - start_time:
|
|
|
|
bot_state_message = await self.send(random.choice(constants.SCRAPING_PHRASES), message)
|
|
|
|
bot_state_message = await self.send(random.choice(constants.SCRAPING_PHRASES), message)
|
|
|
|
@@ -293,23 +296,38 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
# HANDLERS #
|
|
|
|
# HANDLERS #
|
|
|
|
# ---------------------------------------------- #
|
|
|
|
# ---------------------------------------------- #
|
|
|
|
async def _on_bye(self, message: Message):
|
|
|
|
async def _on_bye(self, message: Message):
|
|
|
|
if not message.chat.is_group or self.is_bot_mentioned(message):
|
|
|
|
if message.chat.is_private or self.is_bot_mentioned(message):
|
|
|
|
await self.send_bye(message)
|
|
|
|
await self.send_bye(message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def _on_choose(self, message: Message):
|
|
|
|
|
|
|
|
if message.chat.is_group and not self.is_bot_mentioned(message):
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
discarded_words = {*constants.KEYWORDS['choose'], *constants.KEYWORDS['random'], self.name, f'<@{self.id}>'}
|
|
|
|
|
|
|
|
if final_words := [word for word in message.text.split() if not flanautils.cartesian_product_string_matching(word.lower(), discarded_words, min_ratio=multibot_constants.PARSE_CALLBACKS_MIN_RATIO_DEFAULT)]:
|
|
|
|
|
|
|
|
await self.send(random.choice(final_words), message)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
await self.send(random.choice(('¿Que elija el qué?', '¿Y las opciones?', '?', '🤔')), message)
|
|
|
|
|
|
|
|
|
|
|
|
async def _on_config_button_press(self, message: Message):
|
|
|
|
async def _on_config_button_press(self, message: Message):
|
|
|
|
await self._accept_button_event(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]):
|
|
|
|
if message.buttons_info.presser_user.is_admin is False:
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config = message.buttons_info.pressed_text.split()[1]
|
|
|
|
message.chat.config[config] = not message.chat.config[config]
|
|
|
|
message.chat.config[config] = not message.chat.config[config]
|
|
|
|
|
|
|
|
pressed_button = message.buttons_info[message.buttons_info.pressed_text]
|
|
|
|
|
|
|
|
pressed_button.is_checked = not pressed_button.is_checked
|
|
|
|
|
|
|
|
pressed_button.text = f"{'✔' if pressed_button.is_checked else '❌'} {config}"
|
|
|
|
|
|
|
|
|
|
|
|
await self.edit('<b>Estos son los ajustes del grupo:</b>\n\n', self._get_config_buttons(message), message)
|
|
|
|
await self.edit('<b>Estos son los ajustes del grupo:</b>\n\n', message.buttons_info.buttons, message)
|
|
|
|
|
|
|
|
|
|
|
|
@group
|
|
|
|
@group
|
|
|
|
@bot_mentioned
|
|
|
|
@bot_mentioned
|
|
|
|
async def _on_config_list_show(self, message: Message):
|
|
|
|
async def _on_config_list_show(self, message: Message):
|
|
|
|
await self.send('<b>Estos son los ajustes del grupo:</b>\n\n', self._get_config_buttons(message), message)
|
|
|
|
buttons_texts = [(f"{'✔' if v else '❌'} {k}", v) for k, v in message.chat.config.items()]
|
|
|
|
|
|
|
|
await self.send('<b>Estos son los ajustes del grupo:</b>\n\n', flanautils.chunks(buttons_texts, 3), message, buttons_key=ButtonsGroup.CONFIG)
|
|
|
|
|
|
|
|
|
|
|
|
async def _on_covid_chart(self, message: Message): # todo2
|
|
|
|
async def _on_covid_chart(self, message: Message): # todo2
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
@@ -365,8 +383,17 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
async def _on_delete_original_config_show(self, message: Message):
|
|
|
|
async def _on_delete_original_config_show(self, message: Message):
|
|
|
|
await self._show_config('auto_delete_original', message)
|
|
|
|
await self._show_config('auto_delete_original', message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def _on_dice(self, message: Message):
|
|
|
|
|
|
|
|
if message.chat.is_group and not self.is_bot_mentioned(message):
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if top_number := flanautils.sum_numbers_in_text(message.text):
|
|
|
|
|
|
|
|
await self.send(random.randint(1, top_number), message)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
await self.send(random.choice(('¿De cuántas caras?', '¿Y el número?', '?', '🤔')), message)
|
|
|
|
|
|
|
|
|
|
|
|
async def _on_hello(self, message: Message):
|
|
|
|
async def _on_hello(self, message: Message):
|
|
|
|
if not message.chat.is_group or self.is_bot_mentioned(message):
|
|
|
|
if message.chat.is_private or self.is_bot_mentioned(message):
|
|
|
|
await self.send_hello(message)
|
|
|
|
await self.send_hello(message)
|
|
|
|
|
|
|
|
|
|
|
|
async def _on_new_message_default(self, message: Message):
|
|
|
|
async def _on_new_message_default(self, message: Message):
|
|
|
|
@@ -410,6 +437,55 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
if not await self._on_scraping(message, delete_original=False):
|
|
|
|
if not await self._on_scraping(message, delete_original=False):
|
|
|
|
await self._on_recover_message(message)
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
discarded_words = {*constants.KEYWORDS['poll'], self.name.lower(), f'<@{self.id}>'}
|
|
|
|
|
|
|
|
if final_options := [option.title() for option in message.text.split() if not flanautils.cartesian_product_string_matching(option.lower(), discarded_words, min_ratio=multibot_constants.PARSE_CALLBACKS_MIN_RATIO_DEFAULT)]:
|
|
|
|
|
|
|
|
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}}})
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
await self.send(random.choice(('¿Y las opciones?', '?', '🤔')), message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def _on_poll_button_press(self, message: Message):
|
|
|
|
|
|
|
|
await self._accept_button_event(message)
|
|
|
|
|
|
|
|
if not message.contents['poll']['is_active']:
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
option_name = results[0] if (results := re.findall('(.*?) ➜.+', message.buttons_info.pressed_text)) else message.buttons_info.pressed_text
|
|
|
|
|
|
|
|
selected_option_votes = message.contents['poll']['votes'][option_name]
|
|
|
|
|
|
|
|
presser_id = message.buttons_info.presser_user.id
|
|
|
|
|
|
|
|
presser_name = message.buttons_info.presser_user.name.split('#')[0]
|
|
|
|
|
|
|
|
total_votes = sum(len(option_votes) for option_votes in message.contents['poll']['votes'].values())
|
|
|
|
|
|
|
|
if [presser_id, presser_name] in selected_option_votes:
|
|
|
|
|
|
|
|
selected_option_votes.remove([presser_id, presser_name])
|
|
|
|
|
|
|
|
total_votes -= 1
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
for option_votes in message.contents['poll']['votes'].values():
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
option_votes.remove([presser_id, presser_name])
|
|
|
|
|
|
|
|
except ValueError:
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
total_votes -= 1
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
selected_option_votes.append((presser_id, presser_name))
|
|
|
|
|
|
|
|
total_votes += 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if total_votes:
|
|
|
|
|
|
|
|
buttons = []
|
|
|
|
|
|
|
|
for option, option_votes in message.contents['poll']['votes'].items():
|
|
|
|
|
|
|
|
percent = f'{round(len(option_votes) / total_votes * 100)}%'
|
|
|
|
|
|
|
|
names = f"({', '.join(option_vote[1] for option_vote in option_votes)})" if option_votes else ''
|
|
|
|
|
|
|
|
buttons.append(f'{option} ➜ {percent} {names}')
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
buttons = list(message.contents['poll']['votes'].keys())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await self.edit(self._distribute_poll_buttons(buttons), message)
|
|
|
|
|
|
|
|
|
|
|
|
@bot_mentioned
|
|
|
|
@bot_mentioned
|
|
|
|
@group
|
|
|
|
@group
|
|
|
|
@admin(send_negative=True)
|
|
|
|
@admin(send_negative=True)
|
|
|
|
@@ -510,9 +586,48 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
if song_infos:
|
|
|
|
if song_infos:
|
|
|
|
for song_info in song_infos:
|
|
|
|
for song_info in song_infos:
|
|
|
|
await self.send_song_info(song_info, message)
|
|
|
|
await self.send_song_info(song_info, message)
|
|
|
|
elif self.is_bot_mentioned(message) or not message.chat.is_group:
|
|
|
|
elif self.is_bot_mentioned(message) or message.chat.is_private:
|
|
|
|
await self._manage_exceptions(SendError('No hay información musical en ese mensaje.'), message)
|
|
|
|
await self._manage_exceptions(SendError('No hay información musical en ese mensaje.'), message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def _on_stop_poll(self, message: Message):
|
|
|
|
|
|
|
|
if poll_message := message.replied_message:
|
|
|
|
|
|
|
|
if poll_message.contents.get('poll') is None:
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
elif (
|
|
|
|
|
|
|
|
(message.chat.is_private or self.is_bot_mentioned(message))
|
|
|
|
|
|
|
|
and
|
|
|
|
|
|
|
|
flanautils.cartesian_product_string_matching(message.text, constants.KEYWORDS['poll'], min_ratio=multibot_constants.PARSE_CALLBACKS_MIN_RATIO_DEFAULT)
|
|
|
|
|
|
|
|
and
|
|
|
|
|
|
|
|
(poll_message := Message.find_one({'contents.poll.is_active': True}, sort_keys=(('date', pymongo.DESCENDING),)))
|
|
|
|
|
|
|
|
):
|
|
|
|
|
|
|
|
poll_message = await self.get_message(poll_message.chat.id, poll_message.id)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
winners = []
|
|
|
|
|
|
|
|
max_votes = 1
|
|
|
|
|
|
|
|
for option, votes in poll_message.contents['poll']['votes'].items():
|
|
|
|
|
|
|
|
if len(votes) > max_votes:
|
|
|
|
|
|
|
|
winners = [option]
|
|
|
|
|
|
|
|
max_votes = len(votes)
|
|
|
|
|
|
|
|
elif len(votes) == max_votes:
|
|
|
|
|
|
|
|
winners.append(option)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
match winners:
|
|
|
|
|
|
|
|
case [_, _, *_]:
|
|
|
|
|
|
|
|
winners = [f'<b>{winner}</b>' for winner in winners]
|
|
|
|
|
|
|
|
text = f"Encuesta finalizada. Los ganadores son: {flanautils.join_last_separator(winners, ', ', ' y ')}."
|
|
|
|
|
|
|
|
case [winner]:
|
|
|
|
|
|
|
|
text = f'Encuesta finalizada. Ganador: <b>{winner}</b>.'
|
|
|
|
|
|
|
|
case _:
|
|
|
|
|
|
|
|
text = 'Encuesta finalizada.'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
poll_message.contents['poll']['is_active'] = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await self.edit(text, poll_message)
|
|
|
|
|
|
|
|
if not message.replied_message:
|
|
|
|
|
|
|
|
await self.send(text, reply_to=poll_message)
|
|
|
|
|
|
|
|
|
|
|
|
@group
|
|
|
|
@group
|
|
|
|
@bot_mentioned
|
|
|
|
@bot_mentioned
|
|
|
|
@admin(send_negative=True)
|
|
|
|
@admin(send_negative=True)
|
|
|
|
@@ -523,7 +638,7 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
async def _on_weather_button_press(self, message: Message):
|
|
|
|
async def _on_weather_button_press(self, message: Message):
|
|
|
|
await self._accept_button_event(message)
|
|
|
|
await self._accept_button_event(message)
|
|
|
|
|
|
|
|
|
|
|
|
match message.button_pressed_text:
|
|
|
|
match message.buttons_info.pressed_text:
|
|
|
|
case WeatherEmoji.ZOOM_IN.value:
|
|
|
|
case WeatherEmoji.ZOOM_IN.value:
|
|
|
|
message.weather_chart.zoom_in()
|
|
|
|
message.weather_chart.zoom_in()
|
|
|
|
case WeatherEmoji.ZOOM_OUT.value:
|
|
|
|
case WeatherEmoji.ZOOM_OUT.value:
|
|
|
|
@@ -676,6 +791,7 @@ class FlanaBot(MultiBot, ABC):
|
|
|
|
[WeatherEmoji.HUMIDITY.value, WeatherEmoji.PRECIPITATION_PROBABILITY.value, WeatherEmoji.PRECIPITATION_VOLUME.value, WeatherEmoji.PRESSURE.value, WeatherEmoji.WIND_SPEED.value]
|
|
|
|
[WeatherEmoji.HUMIDITY.value, WeatherEmoji.PRECIPITATION_PROBABILITY.value, WeatherEmoji.PRECIPITATION_VOLUME.value, WeatherEmoji.PRESSURE.value, WeatherEmoji.WIND_SPEED.value]
|
|
|
|
],
|
|
|
|
],
|
|
|
|
message,
|
|
|
|
message,
|
|
|
|
|
|
|
|
buttons_key=ButtonsGroup.WEATHER,
|
|
|
|
send_as_file=False
|
|
|
|
send_as_file=False
|
|
|
|
)
|
|
|
|
)
|
|
|
|
await self.send_inline_results(message)
|
|
|
|
await self.send_inline_results(message)
|
|
|
|
|