From dcafa63d746aa4aabe6fe70aebfb51084c9783b9 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 11 Oct 2023 21:22:10 +0200 Subject: [PATCH] Improved steam offer #188 --- kdb-bot/src/bot/application.py | 6 ++ .../abc/task_abc.py} | 2 +- .../modules/special_offers/base/__init__.py | 1 - .../modules/special_offers/events/__init__.py | 1 - .../events/special_offer_on_ready_event.py | 25 ------ .../special_offers/special_offers_module.py | 7 +- .../special_offers/steam_offer_watcher.py | 87 ++++++++++--------- 7 files changed, 57 insertions(+), 72 deletions(-) rename kdb-bot/src/{modules/special_offers/base/special_offer_watcher_abc.py => bot_core/abc/task_abc.py} (82%) delete mode 100644 kdb-bot/src/modules/special_offers/base/__init__.py delete mode 100644 kdb-bot/src/modules/special_offers/events/__init__.py delete mode 100644 kdb-bot/src/modules/special_offers/events/special_offer_on_ready_event.py diff --git a/kdb-bot/src/bot/application.py b/kdb-bot/src/bot/application.py index 13d46815..257d57ff 100644 --- a/kdb-bot/src/bot/application.py +++ b/kdb-bot/src/bot/application.py @@ -8,6 +8,7 @@ from cpl_discord.service import DiscordBotServiceABC, DiscordBotService from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSettings from bot_api.api_thread import ApiThread +from bot_core.abc.task_abc import TaskABC from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.service.data_integrity_service import DataIntegrityService @@ -29,6 +30,8 @@ class Application(DiscordBotApplicationABC): # cpl-translation self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC) self._t: TranslatePipe = services.get_service(TranslatePipe) + # internal stuff + self._tasks = services.get_services(list[TaskABC]) self._feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings) @@ -55,6 +58,9 @@ class Application(DiscordBotApplicationABC): return self._logger.info(__name__, f"Try to start {DiscordBotService.__name__}") + for task in self._tasks: + await self._bot.add_cog(task) + await self._bot.start_async() await self._bot.stop_async() except Exception as e: diff --git a/kdb-bot/src/modules/special_offers/base/special_offer_watcher_abc.py b/kdb-bot/src/bot_core/abc/task_abc.py similarity index 82% rename from kdb-bot/src/modules/special_offers/base/special_offer_watcher_abc.py rename to kdb-bot/src/bot_core/abc/task_abc.py index fd4fe99d..093f0893 100644 --- a/kdb-bot/src/modules/special_offers/base/special_offer_watcher_abc.py +++ b/kdb-bot/src/bot_core/abc/task_abc.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from discord.ext import commands -class SpecialOfferWatcherABC(commands.Cog): +class TaskABC(commands.Cog): @abstractmethod def __init__(self): commands.Cog.__init__(self) diff --git a/kdb-bot/src/modules/special_offers/base/__init__.py b/kdb-bot/src/modules/special_offers/base/__init__.py deleted file mode 100644 index 425ab6c1..00000000 --- a/kdb-bot/src/modules/special_offers/base/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# imports diff --git a/kdb-bot/src/modules/special_offers/events/__init__.py b/kdb-bot/src/modules/special_offers/events/__init__.py deleted file mode 100644 index 425ab6c1..00000000 --- a/kdb-bot/src/modules/special_offers/events/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# imports diff --git a/kdb-bot/src/modules/special_offers/events/special_offer_on_ready_event.py b/kdb-bot/src/modules/special_offers/events/special_offer_on_ready_event.py deleted file mode 100644 index b594cf7b..00000000 --- a/kdb-bot/src/modules/special_offers/events/special_offer_on_ready_event.py +++ /dev/null @@ -1,25 +0,0 @@ -from cpl_core.logging import LoggerABC -from cpl_discord.events import OnReadyABC -from cpl_discord.service import DiscordBotServiceABC - -from bot_core.logging.task_logger import TaskLogger -from modules.special_offers.base.special_offer_watcher_abc import SpecialOfferWatcherABC - - -class SpecialOfferOnReadyEvent(OnReadyABC): - def __init__( - self, - logger: TaskLogger, - bot: DiscordBotServiceABC, - watchers: list[SpecialOfferWatcherABC], - ): - OnReadyABC.__init__(self) - - self._logger = logger - self._bot = bot - self._watchers = watchers - - async def on_ready(self): - for watcher in self._watchers: - self._logger.info(__name__, f"Starting watcher {type(watcher).__name__}") - watcher.start() diff --git a/kdb-bot/src/modules/special_offers/special_offers_module.py b/kdb-bot/src/modules/special_offers/special_offers_module.py index 72adf21b..e64108b5 100644 --- a/kdb-bot/src/modules/special_offers/special_offers_module.py +++ b/kdb-bot/src/modules/special_offers/special_offers_module.py @@ -1,13 +1,11 @@ from cpl_core.configuration import ConfigurationABC from cpl_core.dependency_injection import ServiceCollectionABC from cpl_core.environment import ApplicationEnvironmentABC -from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum from cpl_discord.service.discord_collection_abc import DiscordCollectionABC from bot_core.abc.module_abc import ModuleABC +from bot_core.abc.task_abc import TaskABC from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum -from modules.special_offers.base.special_offer_watcher_abc import SpecialOfferWatcherABC -from modules.special_offers.events.special_offer_on_ready_event import SpecialOfferOnReadyEvent from modules.special_offers.steam_offer_watcher import SteamOfferWatcher @@ -19,7 +17,6 @@ class SteamSpecialOffersModule(ModuleABC): pass def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): - services.add_singleton(SpecialOfferWatcherABC, SteamOfferWatcher) + services.add_singleton(TaskABC, SteamOfferWatcher) # commands # events - self._dc.add_event(DiscordEventTypesEnum.on_ready.value, SpecialOfferOnReadyEvent) diff --git a/kdb-bot/src/modules/special_offers/steam_offer_watcher.py b/kdb-bot/src/modules/special_offers/steam_offer_watcher.py index 36d54e72..7830d43e 100644 --- a/kdb-bot/src/modules/special_offers/steam_offer_watcher.py +++ b/kdb-bot/src/modules/special_offers/steam_offer_watcher.py @@ -1,5 +1,5 @@ +import asyncio from datetime import datetime -from typing import Optional import bs4 import discord @@ -11,6 +11,7 @@ from cpl_query.extension import List from cpl_translation import TranslatePipe from discord.ext import tasks +from bot_core.abc.task_abc import TaskABC from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.logging.task_logger import TaskLogger @@ -18,10 +19,9 @@ from bot_core.service.message_service import MessageService from bot_data.abc.steam_special_offer_repository_abc import SteamSpecialOfferRepositoryABC from bot_data.model.server_config import ServerConfig from bot_data.model.steam_special_offer import SteamSpecialOffer -from modules.special_offers.base.special_offer_watcher_abc import SpecialOfferWatcherABC -class SteamOfferWatcher(SpecialOfferWatcherABC): +class SteamOfferWatcher(TaskABC): def __init__( self, config: ConfigurationABC, @@ -32,7 +32,7 @@ class SteamOfferWatcher(SpecialOfferWatcherABC): message_service: MessageService, t: TranslatePipe, ): - SpecialOfferWatcherABC.__init__(self) + TaskABC.__init__(self) self._config = config self._logger = logger @@ -46,6 +46,8 @@ class SteamOfferWatcher(SpecialOfferWatcherABC): self._urls = {} self._image_urls = {} + self.watch.start() + def start(self): self.watch.start() @@ -107,8 +109,8 @@ class SteamOfferWatcher(SpecialOfferWatcherABC): def _get_new_game_offers(self) -> List[SteamSpecialOffer]: new_offers = List(SteamSpecialOffer) - sale_count = self._get_max_count() + 100 - sale_count = 300 + # sale_count = self._get_max_count() + 100 + sale_count = 1500 # only look at first 1500 self._logger.debug(__name__, f"Get special offers from 0 to {sale_count}") for i in range(0, sale_count, 100): new_offers.extend(self._get_games_from_page(i, 100)) @@ -117,7 +119,7 @@ class SteamOfferWatcher(SpecialOfferWatcherABC): return new_offers - def _build_embed_for_offer(self, offer: SteamSpecialOffer) -> discord.Embed: + async def _send_embed_for_offer(self, offer: SteamSpecialOffer, channel_id: int) -> discord.Embed: embed = discord.Embed( title=offer.name, url=self._urls[offer.name], @@ -140,9 +142,14 @@ class SteamOfferWatcher(SpecialOfferWatcherABC): ) embed.set_image(url=self._image_urls[offer.name]) - return embed - async def _watch(self): + await self._message_service.send_channel_message( + self._bot.get_channel(channel_id), + embed, + is_persistent=True, + ) + + def _watch(self) -> List[SteamSpecialOffer]: self._is_new = self._offers.get_steam_special_offers().count() == 0 new_offers = self._get_new_game_offers() new_offers_names = new_offers.select(lambda x: x.name).to_list() @@ -171,40 +178,42 @@ class SteamOfferWatcher(SpecialOfferWatcherABC): offers_for_notifications.add(offer) self._logger.trace(__name__, "Finished watching") - # if self._is_new: - # return - - self._logger.debug(__name__, f"Sending offer notifications for {offers_for_notifications.count()} offers") - for guild in self._bot.guilds: - settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}") - if ( - not FeatureFlagsSettings.get_flag_from_dict( - settings.feature_flags, FeatureFlagsEnum.steam_special_offers - ) - and settings.game_offer_notification_chat_id is None - ): - continue - - embeds = [] - - for offer in offers_for_notifications: - embed = self._build_embed_for_offer(offer) - if embed is None: - continue - embeds.append(embed) - - print(embeds) - # await self._message_service.send_channel_message( - # self._bot.get_channel(settings.game_offer_notification_chat_id), - # embeds, - # is_persistent=True, - # ) + return offers_for_notifications @tasks.loop(minutes=60) async def watch(self): self._logger.info(__name__, "Watching steam special offers") try: - pass - # await self._watch() + offers_for_notifications = self._watch() + self._logger.debug(__name__, f"Sending offer notifications for {offers_for_notifications.count()} offers") + if self._is_new: + return + for guild in self._bot.guilds: + settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}") + if ( + not FeatureFlagsSettings.get_flag_from_dict( + settings.feature_flags, FeatureFlagsEnum.steam_special_offers + ) + or settings.game_offer_notification_chat_id is None + ): + continue + + for offer in offers_for_notifications: + self._bot.loop.create_task( + self._send_embed_for_offer(offer, settings.game_offer_notification_chat_id) + ) except Exception as e: self._logger.error(__name__, f"Steam offer watcher failed", e) + + @watch.before_loop + async def before_printer(self): + self._logger.debug(__name__, f"Waiting before checking steam special offers") + await self._bot.wait_until_ready() + + async def wait(): + is_ready = self._config.get_configuration("IS_READY") + if is_ready != "true": + await asyncio.sleep(1) + await wait() + + await wait()