Go back to cookies :(

This commit is contained in:
2024-08-16 06:37:54 +02:00
parent 324f255a8e
commit 3ff3fe157a
14 changed files with 478 additions and 563 deletions

View File

@ -3,20 +3,40 @@ import os
from typing import TYPE_CHECKING
from discord_webhook import DiscordWebhook
from django.db.models.manager import BaseManager
from django.db.models.signals import post_save
from django.dispatch import receiver
from core.discord import generate_game_message, generate_owner_message
from core.models import DropCampaign, Game, GameSubscription, Owner, OwnerSubscription, User
from core.discord import convert_time_to_discord_timestamp
from core.models import DropCampaign, Game, Owner, User, Webhook
if TYPE_CHECKING:
import requests
from django.db.models.manager import BaseManager
logger: logging.Logger = logging.getLogger(__name__)
def generate_message(game: Game, drop: DropCampaign) -> str:
"""Generate a message for a game.
Args:
game (Game): The game to generate a message for.
drop (DropCampaign): The drop campaign to generate a message for.
Returns:
str: The message.
"""
# TODO(TheLovinator): Add a twitch link to a stream that has drops enabled. # noqa: TD003
game_name: str = game.name or "Unknown game"
description: str = drop.description or "No description available."
start_at: str = convert_time_to_discord_timestamp(drop.starts_at)
end_at: str = convert_time_to_discord_timestamp(drop.ends_at)
msg: str = f"**{game_name}**\n\n{description}\n\nStarts: {start_at}\nEnds: {end_at}"
logger.debug(msg)
return msg
@receiver(signal=post_save, sender=User)
def handle_user_signed_up(sender: User, instance: User, created: bool, **kwargs) -> None: # noqa: ANN003, ARG001, FBT001
"""Send a message to Discord when a user signs up.
@ -48,9 +68,8 @@ def handle_user_signed_up(sender: User, instance: User, created: bool, **kwargs)
logger.debug(response)
@receiver(signal=post_save, sender=DropCampaign)
def notify_users_of_new_drop(sender: DropCampaign, instance: DropCampaign, created: bool, **kwargs) -> None: # noqa: ANN003, ARG001, FBT001
"""Notify users of a new drop campaign.
"""Send message to all webhooks subscribed to new drops.
Args:
sender (DropCampaign): The model we are sending the signal from.
@ -64,37 +83,81 @@ def notify_users_of_new_drop(sender: DropCampaign, instance: DropCampaign, creat
game: Game | None = instance.game
if not game:
logger.error("No game found. %s", instance)
return
if game.owner: # type: ignore # noqa: PGH003
handle_owner_drops(instance, game)
else:
logger.error("No owner found. %s", instance)
if game := instance.game:
handle_game_drops(instance, game)
else:
logger.error("No game found. %s", instance)
def handle_game_drops(instance: DropCampaign, game: Game) -> None:
"""Send message to all webhooks subscribed to new drops for this game.
Args:
instance (DropCampaign): The drop campaign that was created.
game (Game): The game that the drop campaign is for.
"""
webhooks: list[Webhook] = game.subscribed_new_games.all() # type: ignore # noqa: PGH003
for hook in webhooks:
# Don't spam the same drop campaign.
if hook in hook.seen_drops.all():
logger.error("Already seen drop campaign '%s'.", instance.name)
continue
# Set the webhook as seen so we don't spam it.
hook.seen_drops.add(instance)
# Send the webhook.
webhook_url: str = hook.get_webhook_url()
if not webhook_url:
logger.error("No webhook URL provided.")
continue
webhook = DiscordWebhook(
url=webhook_url,
content=generate_message(game, instance),
username=f"{game.name} Twitch drops",
rate_limit_retry=True,
)
response: requests.Response = webhook.execute()
logger.debug(response)
def handle_owner_drops(instance: DropCampaign, game: Game) -> None:
"""Send message to all webhooks subscribed to new drops for this owner/organization.
Args:
instance (DropCampaign): The drop campaign that was created.
game (Game): The game that the drop campaign is for.
"""
owner: Owner = game.owner # type: ignore # noqa: PGH003
webhooks: list[Webhook] = owner.subscribed_new_games.all() # type: ignore # noqa: PGH003
for hook in webhooks:
# Don't spam the same drop campaign.
if hook in hook.seen_drops.all():
logger.error("Already seen drop campaign '%s'.", instance.name)
continue
# Notify users subscribed to the game
game_subs: BaseManager[GameSubscription] = GameSubscription.objects.filter(game=game)
for sub in game_subs:
if not sub.webhook.url:
# Set the webhook as seen so we don't spam it.
hook.seen_drops.add(instance)
# Send the webhook.
webhook_url: str = hook.get_webhook_url()
if not webhook_url:
logger.error("No webhook URL provided.")
return
continue
webhook = DiscordWebhook(
url=sub.webhook.url,
content=generate_game_message(instance=instance, game=game, sub=sub),
username=f"{game.name} drop.",
rate_limit_retry=True,
)
response: requests.Response = webhook.execute()
logger.debug(response)
# Notify users subscribed to the owner
owner_subs: BaseManager[OwnerSubscription] = OwnerSubscription.objects.filter(owner=owner)
for sub in owner_subs:
if not sub.webhook.url:
logger.error("No webhook URL provided.")
return
webhook = DiscordWebhook(
url=sub.webhook.url,
content=generate_owner_message(instance=instance, owner=owner, sub=sub),
username=f"{owner.name} drop.",
url=webhook_url,
content=generate_message(game, instance),
username=f"{game.name} Twitch drops",
rate_limit_retry=True,
)
response: requests.Response = webhook.execute()