Improved steam offer #188

This commit is contained in:
Sven Heidemann 2023-10-11 21:22:10 +02:00
parent 3a42b42dbf
commit dcafa63d74
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 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:

View File

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

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.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)

View File

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