mirror of
https://github.com/pacnpal/Pac-cogs.git
synced 2025-12-20 02:41:06 -05:00
videoarchiver/config/role_manager.py videoarchiver/database/connection_manager.py videoarchiver/database/schema_manager.py videoarchiver/queue/cleaners/tracking_cleaner.py videoarchiver/exceptions.py videoarchiver/processor.py videoarchiver/commands.py videoarchiver/update_checker.py videoarchiver/utils/path_manager.py videoarchiver/utils/file_ops.py videoarchiver/processor/message_validator.py videoarchiver/utils/download_manager.py
214 lines
7.1 KiB
Python
214 lines
7.1 KiB
Python
"""Module for managing Discord channel configurations"""
|
|
|
|
import logging
|
|
from typing import Dict, List, Optional, Tuple
|
|
import discord
|
|
|
|
from videoarchiver.config.exceptions import (
|
|
ConfigurationError as ConfigError,
|
|
DiscordAPIError,
|
|
)
|
|
|
|
logger = logging.getLogger("ChannelManager")
|
|
|
|
|
|
class ChannelManager:
|
|
"""Manages Discord channel configurations"""
|
|
|
|
def __init__(self, config_manager):
|
|
self.config_manager = config_manager
|
|
|
|
async def get_channel(
|
|
self, guild: discord.Guild, channel_type: str
|
|
) -> Optional[discord.TextChannel]:
|
|
"""Get a channel by type
|
|
|
|
Args:
|
|
guild: Discord guild
|
|
channel_type: Type of channel (archive, notification, log)
|
|
|
|
Returns:
|
|
Optional[discord.TextChannel]: Channel if found and valid
|
|
|
|
Raises:
|
|
ConfigError: If channel type is invalid
|
|
DiscordAPIError: If channel exists but is invalid type
|
|
"""
|
|
try:
|
|
if channel_type not in ["archive", "notification", "log"]:
|
|
raise ConfigError(f"Invalid channel type: {channel_type}")
|
|
|
|
settings = await self.config_manager.get_guild_settings(guild.id)
|
|
channel_id = settings.get(f"{channel_type}_channel")
|
|
|
|
if channel_id is None:
|
|
return None
|
|
|
|
channel = guild.get_channel(channel_id)
|
|
if channel is None:
|
|
logger.warning(f"Channel {channel_id} not found in guild {guild.id}")
|
|
return None
|
|
|
|
return None
|
|
|
|
if not isinstance(channel, discord.TextChannel):
|
|
raise DiscordAPIError(f"Channel {channel_id} is not a text channel")
|
|
|
|
return channel
|
|
|
|
except Exception as e:
|
|
logger.error(
|
|
f"Failed to get {channel_type} channel for guild {guild.id}: {e}"
|
|
)
|
|
raise ConfigError(f"Failed to get channel: {str(e)}")
|
|
|
|
async def get_monitored_channels(
|
|
self, guild: discord.Guild
|
|
) -> List[discord.TextChannel]:
|
|
"""Get all monitored channels for a guild
|
|
|
|
Args:
|
|
guild: Discord guild
|
|
|
|
Returns:
|
|
List[discord.TextChannel]: List of monitored channels
|
|
|
|
Raises:
|
|
ConfigError: If channel retrieval fails
|
|
"""
|
|
try:
|
|
settings = await self.config_manager.get_guild_settings(guild.id)
|
|
monitored_channel_ids = settings["monitored_channels"]
|
|
|
|
# If no channels are set to be monitored, return all text channels
|
|
if not monitored_channel_ids:
|
|
return [
|
|
channel
|
|
for channel in guild.channels
|
|
if isinstance(channel, discord.TextChannel)
|
|
]
|
|
|
|
# Otherwise, return only the specified channels
|
|
channels: List[discord.TextChannel] = []
|
|
invalid_channels: List[int] = []
|
|
|
|
for channel_id in monitored_channel_ids:
|
|
channel = guild.get_channel(channel_id)
|
|
if channel and isinstance(channel, discord.TextChannel):
|
|
channels.append(channel)
|
|
else:
|
|
invalid_channels.append(channel_id)
|
|
logger.warning(
|
|
f"Invalid monitored channel {channel_id} in guild {guild.id}"
|
|
)
|
|
|
|
# Clean up invalid channels if found
|
|
if invalid_channels:
|
|
await self._remove_invalid_channels(guild.id, invalid_channels)
|
|
|
|
return channels
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to get monitored channels for guild {guild.id}: {e}")
|
|
raise ConfigError(f"Failed to get monitored channels: {str(e)}")
|
|
|
|
async def verify_channel_permissions(
|
|
self, channel: discord.TextChannel, required_permissions: List[str]
|
|
) -> Tuple[bool, List[str]]:
|
|
"""Verify bot has required permissions in a channel
|
|
|
|
Args:
|
|
channel: Channel to check
|
|
required_permissions: List of required permission names
|
|
|
|
Returns:
|
|
Tuple[bool, List[str]]: (Has all permissions, List of missing permissions)
|
|
"""
|
|
try:
|
|
bot_member = channel.guild.me
|
|
channel_perms = channel.permissions_for(bot_member)
|
|
|
|
missing_perms = [
|
|
perm
|
|
for perm in required_permissions
|
|
if not getattr(channel_perms, perm, False)
|
|
]
|
|
|
|
return not bool(missing_perms), missing_perms
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error checking channel permissions: {e}")
|
|
return False, ["Failed to check permissions"]
|
|
|
|
async def add_monitored_channel(self, guild_id: int, channel_id: int) -> None:
|
|
"""Add a channel to monitored channels
|
|
|
|
Args:
|
|
guild_id: Guild ID
|
|
channel_id: Channel ID to add
|
|
|
|
Raises:
|
|
ConfigError: If channel cannot be added
|
|
"""
|
|
try:
|
|
await self.config_manager.add_to_list(
|
|
guild_id, "monitored_channels", channel_id
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Failed to add monitored channel {channel_id}: {e}")
|
|
raise ConfigError(f"Failed to add monitored channel: {str(e)}")
|
|
|
|
async def remove_monitored_channel(self, guild_id: int, channel_id: int) -> None:
|
|
"""Remove a channel from monitored channels
|
|
|
|
Args:
|
|
guild_id: Guild ID
|
|
channel_id: Channel ID to remove
|
|
|
|
Raises:
|
|
ConfigError: If channel cannot be removed
|
|
"""
|
|
try:
|
|
await self.config_manager.remove_from_list(
|
|
guild_id, "monitored_channels", channel_id
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Failed to remove monitored channel {channel_id}: {e}")
|
|
raise ConfigError(f"Failed to remove monitored channel: {str(e)}")
|
|
|
|
async def _remove_invalid_channels(
|
|
self, guild_id: int, channel_ids: List[int]
|
|
) -> None:
|
|
"""Remove invalid channels from monitored channels
|
|
|
|
Args:
|
|
guild_id: Guild ID
|
|
channel_ids: List of invalid channel IDs to remove
|
|
"""
|
|
try:
|
|
for channel_id in channel_ids:
|
|
await self.remove_monitored_channel(guild_id, channel_id)
|
|
except Exception as e:
|
|
logger.error(f"Error removing invalid channels: {e}")
|
|
|
|
async def get_channel_info(
|
|
self, guild: discord.Guild
|
|
) -> Dict[str, Optional[discord.TextChannel]]:
|
|
"""Get all configured channels for a guild
|
|
|
|
Args:
|
|
guild: Discord guild
|
|
|
|
Returns:
|
|
Dict[str, Optional[discord.TextChannel]]: Dictionary of channel types to channels
|
|
"""
|
|
try:
|
|
return {
|
|
"archive": await self.get_channel(guild, "archive"),
|
|
"notification": await self.get_channel(guild, "notification"),
|
|
"log": await self.get_channel(guild, "log"),
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"Error getting channel info: {e}")
|
|
return {"archive": None, "notification": None, "log": None}
|