Files
Pac-cogs/videoarchiver/processor/reactions.py

186 lines
6.3 KiB
Python

"""Reaction handling for VideoProcessor"""
import logging
import asyncio
import re
from typing import List, Optional
import discord
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)