Improved steam offer #188

This commit is contained in:
Sven Heidemann 2023-10-11 21:22:10 +02:00
parent d448ad7707
commit 90fce5a79a
7 changed files with 57 additions and 72 deletions

View File

@ -8,6 +8,7 @@ from cpl_discord.service import DiscordBotServiceABC, DiscordBotService
from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSettings from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSettings
from bot_api.api_thread import ApiThread 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_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.service.data_integrity_service import DataIntegrityService from bot_core.service.data_integrity_service import DataIntegrityService
@ -29,6 +30,8 @@ class Application(DiscordBotApplicationABC):
# cpl-translation # cpl-translation
self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC) self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC)
self._t: TranslatePipe = services.get_service(TranslatePipe) self._t: TranslatePipe = services.get_service(TranslatePipe)
# internal stuff
self._tasks = services.get_services(list[TaskABC])
self._feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings) self._feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings)
@ -55,6 +58,9 @@ class Application(DiscordBotApplicationABC):
return return
self._logger.info(__name__, f"Try to start {DiscordBotService.__name__}") 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.start_async()
await self._bot.stop_async() await self._bot.stop_async()
except Exception as e: except Exception as e:

View File

@ -3,7 +3,7 @@ from abc import ABC, abstractmethod
from discord.ext import commands from discord.ext import commands
class SpecialOfferWatcherABC(commands.Cog): class TaskABC(commands.Cog):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
commands.Cog.__init__(self) commands.Cog.__init__(self)

View File

@ -1 +0,0 @@
# imports

View File

@ -1 +0,0 @@
# imports

View File

@ -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()

View File

@ -1,13 +1,11 @@
from cpl_core.configuration import ConfigurationABC from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceCollectionABC from cpl_core.dependency_injection import ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironmentABC 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 cpl_discord.service.discord_collection_abc import DiscordCollectionABC
from bot_core.abc.module_abc import ModuleABC 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 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 from modules.special_offers.steam_offer_watcher import SteamOfferWatcher
@ -19,7 +17,6 @@ class SteamSpecialOffersModule(ModuleABC):
pass pass
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
services.add_singleton(SpecialOfferWatcherABC, SteamOfferWatcher) services.add_singleton(TaskABC, SteamOfferWatcher)
# commands # commands
# events # events
self._dc.add_event(DiscordEventTypesEnum.on_ready.value, SpecialOfferOnReadyEvent)

View File

@ -1,5 +1,5 @@
import asyncio
from datetime import datetime from datetime import datetime
from typing import Optional
import bs4 import bs4
import discord import discord
@ -11,6 +11,7 @@ from cpl_query.extension import List
from cpl_translation import TranslatePipe from cpl_translation import TranslatePipe
from discord.ext import tasks 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_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.logging.task_logger import TaskLogger 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.abc.steam_special_offer_repository_abc import SteamSpecialOfferRepositoryABC
from bot_data.model.server_config import ServerConfig from bot_data.model.server_config import ServerConfig
from bot_data.model.steam_special_offer import SteamSpecialOffer 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__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
@ -32,7 +32,7 @@ class SteamOfferWatcher(SpecialOfferWatcherABC):
message_service: MessageService, message_service: MessageService,
t: TranslatePipe, t: TranslatePipe,
): ):
SpecialOfferWatcherABC.__init__(self) TaskABC.__init__(self)
self._config = config self._config = config
self._logger = logger self._logger = logger
@ -46,6 +46,8 @@ class SteamOfferWatcher(SpecialOfferWatcherABC):
self._urls = {} self._urls = {}
self._image_urls = {} self._image_urls = {}
self.watch.start()
def start(self): def start(self):
self.watch.start() self.watch.start()
@ -107,8 +109,8 @@ class SteamOfferWatcher(SpecialOfferWatcherABC):
def _get_new_game_offers(self) -> List[SteamSpecialOffer]: def _get_new_game_offers(self) -> List[SteamSpecialOffer]:
new_offers = List(SteamSpecialOffer) new_offers = List(SteamSpecialOffer)
sale_count = self._get_max_count() + 100 # sale_count = self._get_max_count() + 100
sale_count = 300 sale_count = 1500 # only look at first 1500
self._logger.debug(__name__, f"Get special offers from 0 to {sale_count}") self._logger.debug(__name__, f"Get special offers from 0 to {sale_count}")
for i in range(0, sale_count, 100): for i in range(0, sale_count, 100):
new_offers.extend(self._get_games_from_page(i, 100)) new_offers.extend(self._get_games_from_page(i, 100))
@ -117,7 +119,7 @@ class SteamOfferWatcher(SpecialOfferWatcherABC):
return new_offers 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( embed = discord.Embed(
title=offer.name, title=offer.name,
url=self._urls[offer.name], url=self._urls[offer.name],
@ -140,9 +142,14 @@ class SteamOfferWatcher(SpecialOfferWatcherABC):
) )
embed.set_image(url=self._image_urls[offer.name]) 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 self._is_new = self._offers.get_steam_special_offers().count() == 0
new_offers = self._get_new_game_offers() new_offers = self._get_new_game_offers()
new_offers_names = new_offers.select(lambda x: x.name).to_list() new_offers_names = new_offers.select(lambda x: x.name).to_list()
@ -171,40 +178,42 @@ class SteamOfferWatcher(SpecialOfferWatcherABC):
offers_for_notifications.add(offer) offers_for_notifications.add(offer)
self._logger.trace(__name__, "Finished watching") self._logger.trace(__name__, "Finished watching")
# if self._is_new: return offers_for_notifications
# return
@tasks.loop(minutes=60)
async def watch(self):
self._logger.info(__name__, "Watching steam special offers")
try:
offers_for_notifications = self._watch()
self._logger.debug(__name__, f"Sending offer notifications for {offers_for_notifications.count()} offers") 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: for guild in self._bot.guilds:
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}") settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}")
if ( if (
not FeatureFlagsSettings.get_flag_from_dict( not FeatureFlagsSettings.get_flag_from_dict(
settings.feature_flags, FeatureFlagsEnum.steam_special_offers settings.feature_flags, FeatureFlagsEnum.steam_special_offers
) )
and settings.game_offer_notification_chat_id is None or settings.game_offer_notification_chat_id is None
): ):
continue continue
embeds = []
for offer in offers_for_notifications: for offer in offers_for_notifications:
embed = self._build_embed_for_offer(offer) self._bot.loop.create_task(
if embed is None: self._send_embed_for_offer(offer, settings.game_offer_notification_chat_id)
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,
# )
@tasks.loop(minutes=60)
async def watch(self):
self._logger.info(__name__, "Watching steam special offers")
try:
pass
# await self._watch()
except Exception as e: except Exception as e:
self._logger.error(__name__, f"Steam offer watcher failed", 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()