Files
Pac-cogs/videoarchiver/processor/reactions.py
2024-11-17 19:47:18 +00:00

189 lines
6.3 KiB
Python

"""Reaction handling for VideoProcessor"""
import logging
import asyncio
import re
from typing import List, Optional
import discord # type: ignore
from urllib.parse import urlparse
from ..processor.constants import (
REACTIONS,
ReactionType,
get_reaction,
get_progress_emoji,
)
from ..database.video_archive_db import VideoArchiveDB
logger = logging.getLogger("VideoArchiver")
async def handle_archived_reaction(
message: discord.Message, user: discord.User, db: VideoArchiveDB
) -> None:
"""
Handle reaction to archived video message.
Args:
message: The Discord message that was reacted to
user: The user who added the reaction
db: Database instance for checking archived videos
"""
try:
# Check if the reaction is from a user (not the bot) and is the archived reaction
if user.bot or str(message.reactions[0].emoji) != get_reaction(
ReactionType.ARCHIVED
):
return
# Extract URLs from the message using regex
url_pattern = re.compile(r'https?://[^\s<>"]+|www\.[^\s<>"]+')
urls = url_pattern.findall(message.content) if message.content else []
# Check each URL in the database
for url in urls:
# Ensure URL has proper scheme
if url.startswith("www."):
url = "http://" + url
# Validate URL
try:
result = urlparse(url)
if not all([result.scheme, result.netloc]):
continue
except Exception:
continue
result = db.get_archived_video(url)
if result:
discord_url = result[0]
await message.reply(
f"This video was already archived. You can find it here: {discord_url}"
)
return
except Exception as e:
logger.error(f"Error handling archived reaction: {e}", exc_info=True)
async def update_queue_position_reaction(
message: discord.Message, position: int, bot_user: discord.ClientUser
) -> None:
"""
Update queue position reaction.
Args:
message: The Discord message to update reactions on
position: Queue position (0-based index)
bot_user: The bot's user instance for managing reactions
"""
try:
numbers = get_reaction(ReactionType.NUMBERS)
if not isinstance(numbers, list):
logger.error("Numbers reaction is not a list")
return
# Remove old reactions
for reaction in numbers:
try:
await message.remove_reaction(reaction, bot_user)
except discord.HTTPException as e:
logger.warning(f"Failed to remove number reaction: {e}")
except Exception as e:
logger.error(f"Unexpected error removing number reaction: {e}")
# Add new reaction if position is valid
if 0 <= position < len(numbers):
try:
await message.add_reaction(numbers[position])
logger.info(
f"Updated queue position reaction to {position + 1} for message {message.id}"
)
except discord.HTTPException as e:
logger.error(f"Failed to add queue position reaction: {e}")
except Exception as e:
logger.error(f"Failed to update queue position reaction: {e}", exc_info=True)
async def update_progress_reaction(
message: discord.Message, progress: float, bot_user: discord.ClientUser
) -> None:
"""
Update progress reaction based on FFmpeg progress.
Args:
message: The Discord message to update reactions on
progress: Progress value between 0 and 100
bot_user: The bot's user instance for managing reactions
"""
if not message:
return
try:
progress_emojis = get_reaction(ReactionType.PROGRESS)
if not isinstance(progress_emojis, list):
logger.error("Progress reaction is not a list")
return
# Remove old reactions
for reaction in progress_emojis:
try:
await message.remove_reaction(reaction, bot_user)
except discord.HTTPException as e:
logger.warning(f"Failed to remove progress reaction: {e}")
except Exception as e:
logger.error(f"Unexpected error removing progress reaction: {e}")
# Add new reaction based on progress
try:
normalized_progress = progress / 100 # Convert to 0-1 range
emoji = get_progress_emoji(normalized_progress, progress_emojis)
await message.add_reaction(emoji)
except Exception as e:
logger.error(f"Failed to add progress reaction: {e}")
except Exception as e:
logger.error(f"Failed to update progress reaction: {e}", exc_info=True)
async def update_download_progress_reaction(
message: discord.Message, progress: float, bot_user: discord.ClientUser
) -> None:
"""
Update download progress reaction.
Args:
message: The Discord message to update reactions on
progress: Progress value between 0 and 100
bot_user: The bot's user instance for managing reactions
"""
if not message:
return
try:
download_emojis = get_reaction(ReactionType.DOWNLOAD)
if not isinstance(download_emojis, list):
logger.error("Download reaction is not a list")
return
# Remove old reactions
for reaction in download_emojis:
try:
await message.remove_reaction(reaction, bot_user)
except discord.HTTPException as e:
logger.warning(f"Failed to remove download reaction: {e}")
except Exception as e:
logger.error(f"Unexpected error removing download reaction: {e}")
# Add new reaction based on progress
try:
normalized_progress = progress / 100 # Convert to 0-1 range
emoji = get_progress_emoji(normalized_progress, download_emojis)
await message.add_reaction(emoji)
except Exception as e:
logger.error(f"Failed to add download reaction: {e}")
except Exception as e:
logger.error(f"Failed to update download progress reaction: {e}", exc_info=True)