mirror of
https://github.com/pacnpal/Pac-cogs.git
synced 2025-12-20 02:41:06 -05:00
fixed imports again
This commit is contained in:
@@ -5,7 +5,7 @@ import asyncio
|
|||||||
import logging
|
import logging
|
||||||
import importlib
|
import importlib
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from redbot.core.bot import Red # type: ignore
|
from redbot.core.bot import Red # type: ignore
|
||||||
|
|
||||||
# Force reload of all modules
|
# Force reload of all modules
|
||||||
modules_to_reload = [
|
modules_to_reload = [
|
||||||
@@ -91,34 +91,34 @@ try:
|
|||||||
)
|
)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
from videoarchiver import utils
|
# from videoarchiver import utils
|
||||||
from videoarchiver import processor
|
# from videoarchiver import processor
|
||||||
from videoarchiver import queue
|
# from videoarchiver import queue
|
||||||
from videoarchiver import ffmpeg
|
# from videoarchiver import ffmpeg
|
||||||
from videoarchiver import database
|
# from videoarchiver import database
|
||||||
from videoarchiver import config
|
# from videoarchiver import config
|
||||||
from videoarchiver import core
|
# from videoarchiver import core
|
||||||
# from videoarchiver.core.base import VideoArchiver
|
# from videoarchiver.core.base import VideoArchiver
|
||||||
# from videoarchiver.core.initialization import initialize_cog, init_callback
|
# from videoarchiver.core.initialization import initialize_cog, init_callback
|
||||||
# from videoarchiver.core.cleanup import cleanup_resources
|
# from videoarchiver.core.cleanup import cleanup_resources
|
||||||
# from videoarchiver.utils.exceptions import (
|
# from videoarchiver.utils.exceptions import (
|
||||||
VideoArchiverError,
|
# VideoArchiverError,
|
||||||
CommandError,
|
# CommandError,
|
||||||
EventError,
|
# EventError,
|
||||||
CogError,
|
# CogError,
|
||||||
ErrorContext,
|
# ErrorContext,
|
||||||
ErrorSeverity,
|
# ErrorSeverity,
|
||||||
ProcessingError,
|
# ProcessingError,
|
||||||
)
|
# )
|
||||||
|
|
||||||
# Reload all modules
|
# Reload all modules
|
||||||
importlib.reload(utils)
|
importlib.reload(utils)
|
||||||
importlib.reload(processor)
|
importlib.reload(processor)
|
||||||
importlib.reload(queue)
|
importlib.reload(queue)
|
||||||
importlib.reload(ffmpeg)
|
importlib.reload(ffmpeg)
|
||||||
importlib.reload(database)
|
importlib.reload(database)
|
||||||
importlib.reload(config)
|
importlib.reload(config)
|
||||||
importlib.reload(core)
|
importlib.reload(core)
|
||||||
|
|
||||||
# Import all submodules
|
# Import all submodules
|
||||||
from .database import *
|
from .database import *
|
||||||
|
|||||||
@@ -1,49 +1,50 @@
|
|||||||
"""Configuration management module"""
|
"""Configuration management module"""
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
ConfigurationError,
|
ConfigurationError,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
PermissionError,
|
PermissionError,
|
||||||
LoadError,
|
LoadError,
|
||||||
SaveError,
|
SaveError,
|
||||||
MigrationError,
|
MigrationError,
|
||||||
SchemaError,
|
SchemaError,
|
||||||
DiscordAPIError,
|
DiscordAPIError,
|
||||||
)
|
)
|
||||||
from .channel_manager import ChannelManager
|
from .channel_manager import ChannelManager
|
||||||
from .role_manager import RoleManager
|
from .role_manager import RoleManager
|
||||||
from .settings_formatter import SettingsFormatter
|
from .settings_formatter import SettingsFormatter
|
||||||
from .validation_manager import ValidationManager
|
from .validation_manager import ValidationManager
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.config.exceptions import (
|
# Fall back to absolute imports if relative imports fail
|
||||||
ConfigurationError,
|
# from videoarchiver.config.exceptions import (
|
||||||
ValidationError,
|
# ConfigurationError,
|
||||||
PermissionError,
|
# ValidationError,
|
||||||
LoadError,
|
# PermissionError,
|
||||||
SaveError,
|
# LoadError,
|
||||||
MigrationError,
|
# SaveError,
|
||||||
SchemaError,
|
# MigrationError,
|
||||||
DiscordAPIError,
|
# SchemaError,
|
||||||
)
|
# DiscordAPIError,
|
||||||
# from videoarchiver.config.channel_manager import ChannelManager
|
# )
|
||||||
# from videoarchiver.config.role_manager import RoleManager
|
# from videoarchiver.config.channel_manager import ChannelManager
|
||||||
# from videoarchiver.config.settings_formatter import SettingsFormatter
|
# from videoarchiver.config.role_manager import RoleManager
|
||||||
# from videoarchiver.config.validation_manager import ValidationManager
|
# from videoarchiver.config.settings_formatter import SettingsFormatter
|
||||||
|
# from videoarchiver.config.validation_manager import ValidationManager
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'ConfigurationError',
|
"ConfigurationError",
|
||||||
'ValidationError',
|
"ValidationError",
|
||||||
'PermissionError',
|
"PermissionError",
|
||||||
'LoadError',
|
"LoadError",
|
||||||
'SaveError',
|
"SaveError",
|
||||||
'MigrationError',
|
"MigrationError",
|
||||||
'SchemaError',
|
"SchemaError",
|
||||||
'DiscordAPIError',
|
"DiscordAPIError",
|
||||||
'ChannelManager',
|
"ChannelManager",
|
||||||
'RoleManager',
|
"RoleManager",
|
||||||
'SettingsFormatter',
|
"SettingsFormatter",
|
||||||
'ValidationManager',
|
"ValidationManager",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,20 +2,21 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, List, Optional, Tuple
|
from typing import Dict, List, Optional, Tuple
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
ConfigurationError as ConfigError,
|
ConfigurationError as ConfigError,
|
||||||
DiscordAPIError,
|
DiscordAPIError,
|
||||||
)
|
)
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.config.exceptions import (
|
# Fall back to absolute imports if relative imports fail
|
||||||
ConfigurationError as ConfigError,
|
# from videoarchiver.config.exceptions import (
|
||||||
DiscordAPIError,
|
# ConfigurationError as ConfigError,
|
||||||
)
|
# DiscordAPIError,
|
||||||
|
# )
|
||||||
|
|
||||||
logger = logging.getLogger("ChannelManager")
|
logger = logging.getLogger("ChannelManager")
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, List, Set, Tuple, Optional, Any
|
from typing import Dict, List, Set, Tuple, Optional, Any
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import ConfigurationError as ConfigError
|
from .exceptions import ConfigurationError as ConfigError
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.config.exceptions import ConfigurationError as ConfigError
|
# Fall back to absolute imports if relative imports fail
|
||||||
|
# from videoarchiver.config.exceptions import ConfigurationError as ConfigError
|
||||||
|
|
||||||
logger = logging.getLogger("RoleManager")
|
logger = logging.getLogger("RoleManager")
|
||||||
|
|
||||||
@@ -21,8 +22,7 @@ class RoleManager:
|
|||||||
self.config_manager = config_manager
|
self.config_manager = config_manager
|
||||||
|
|
||||||
async def check_user_roles(
|
async def check_user_roles(
|
||||||
self,
|
self, member: discord.Member
|
||||||
member: discord.Member
|
|
||||||
) -> Tuple[bool, Optional[str]]:
|
) -> Tuple[bool, Optional[str]]:
|
||||||
"""Check if user has permission based on allowed roles
|
"""Check if user has permission based on allowed roles
|
||||||
|
|
||||||
@@ -37,8 +37,7 @@ class RoleManager:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
allowed_roles = await self.config_manager.get_setting(
|
allowed_roles = await self.config_manager.get_setting(
|
||||||
member.guild.id,
|
member.guild.id, "allowed_roles"
|
||||||
"allowed_roles"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# If no roles are set, allow all users
|
# If no roles are set, allow all users
|
||||||
@@ -53,21 +52,16 @@ class RoleManager:
|
|||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
# Get role names for error message
|
# Get role names for error message
|
||||||
missing_roles = await self._get_role_names(
|
missing_roles = await self._get_role_names(member.guild, allowed_role_set)
|
||||||
member.guild,
|
|
||||||
allowed_role_set
|
|
||||||
)
|
|
||||||
return False, f"Missing required roles: {', '.join(missing_roles)}"
|
return False, f"Missing required roles: {', '.join(missing_roles)}"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to check roles for user {member.id} in guild {member.guild.id}: {e}")
|
logger.error(
|
||||||
|
f"Failed to check roles for user {member.id} in guild {member.guild.id}: {e}"
|
||||||
|
)
|
||||||
raise ConfigError(f"Failed to check user roles: {str(e)}")
|
raise ConfigError(f"Failed to check user roles: {str(e)}")
|
||||||
|
|
||||||
async def add_allowed_role(
|
async def add_allowed_role(self, guild_id: int, role_id: int) -> None:
|
||||||
self,
|
|
||||||
guild_id: int,
|
|
||||||
role_id: int
|
|
||||||
) -> None:
|
|
||||||
"""Add a role to allowed roles
|
"""Add a role to allowed roles
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -78,20 +72,12 @@ class RoleManager:
|
|||||||
ConfigError: If role cannot be added
|
ConfigError: If role cannot be added
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
await self.config_manager.add_to_list(
|
await self.config_manager.add_to_list(guild_id, "allowed_roles", role_id)
|
||||||
guild_id,
|
|
||||||
"allowed_roles",
|
|
||||||
role_id
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to add allowed role {role_id}: {e}")
|
logger.error(f"Failed to add allowed role {role_id}: {e}")
|
||||||
raise ConfigError(f"Failed to add allowed role: {str(e)}")
|
raise ConfigError(f"Failed to add allowed role: {str(e)}")
|
||||||
|
|
||||||
async def remove_allowed_role(
|
async def remove_allowed_role(self, guild_id: int, role_id: int) -> None:
|
||||||
self,
|
|
||||||
guild_id: int,
|
|
||||||
role_id: int
|
|
||||||
) -> None:
|
|
||||||
"""Remove a role from allowed roles
|
"""Remove a role from allowed roles
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -103,18 +89,13 @@ class RoleManager:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
await self.config_manager.remove_from_list(
|
await self.config_manager.remove_from_list(
|
||||||
guild_id,
|
guild_id, "allowed_roles", role_id
|
||||||
"allowed_roles",
|
|
||||||
role_id
|
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to remove allowed role {role_id}: {e}")
|
logger.error(f"Failed to remove allowed role {role_id}: {e}")
|
||||||
raise ConfigError(f"Failed to remove allowed role: {str(e)}")
|
raise ConfigError(f"Failed to remove allowed role: {str(e)}")
|
||||||
|
|
||||||
async def get_allowed_roles(
|
async def get_allowed_roles(self, guild: discord.Guild) -> List[discord.Role]:
|
||||||
self,
|
|
||||||
guild: discord.Guild
|
|
||||||
) -> List[discord.Role]:
|
|
||||||
"""Get all allowed roles for a guild
|
"""Get all allowed roles for a guild
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -152,9 +133,7 @@ class RoleManager:
|
|||||||
raise ConfigError(f"Failed to get allowed roles: {str(e)}")
|
raise ConfigError(f"Failed to get allowed roles: {str(e)}")
|
||||||
|
|
||||||
async def verify_role_hierarchy(
|
async def verify_role_hierarchy(
|
||||||
self,
|
self, guild: discord.Guild, role: discord.Role
|
||||||
guild: discord.Guild,
|
|
||||||
role: discord.Role
|
|
||||||
) -> Tuple[bool, Optional[str]]:
|
) -> Tuple[bool, Optional[str]]:
|
||||||
"""Verify bot's role hierarchy position for managing a role
|
"""Verify bot's role hierarchy position for managing a role
|
||||||
|
|
||||||
@@ -170,7 +149,10 @@ class RoleManager:
|
|||||||
bot_top_role = bot_member.top_role
|
bot_top_role = bot_member.top_role
|
||||||
|
|
||||||
if role >= bot_top_role:
|
if role >= bot_top_role:
|
||||||
return False, f"Role {role.name} is higher than or equal to bot's highest role"
|
return (
|
||||||
|
False,
|
||||||
|
f"Role {role.name} is higher than or equal to bot's highest role",
|
||||||
|
)
|
||||||
|
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
@@ -179,9 +161,7 @@ class RoleManager:
|
|||||||
return False, "Failed to check role hierarchy"
|
return False, "Failed to check role hierarchy"
|
||||||
|
|
||||||
async def _get_role_names(
|
async def _get_role_names(
|
||||||
self,
|
self, guild: discord.Guild, role_ids: Set[int]
|
||||||
guild: discord.Guild,
|
|
||||||
role_ids: Set[int]
|
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
"""Get role names from role IDs
|
"""Get role names from role IDs
|
||||||
|
|
||||||
@@ -199,11 +179,7 @@ class RoleManager:
|
|||||||
role_names.append(role.name)
|
role_names.append(role.name)
|
||||||
return role_names
|
return role_names
|
||||||
|
|
||||||
async def _remove_invalid_roles(
|
async def _remove_invalid_roles(self, guild_id: int, role_ids: List[int]) -> None:
|
||||||
self,
|
|
||||||
guild_id: int,
|
|
||||||
role_ids: List[int]
|
|
||||||
) -> None:
|
|
||||||
"""Remove invalid roles from allowed roles
|
"""Remove invalid roles from allowed roles
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -216,10 +192,7 @@ class RoleManager:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error removing invalid roles: {e}")
|
logger.error(f"Error removing invalid roles: {e}")
|
||||||
|
|
||||||
async def get_role_info(
|
async def get_role_info(self, guild: discord.Guild) -> Dict[str, Any]:
|
||||||
self,
|
|
||||||
guild: discord.Guild
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Get role configuration information
|
"""Get role configuration information
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -233,16 +206,16 @@ class RoleManager:
|
|||||||
bot_member = guild.me
|
bot_member = guild.me
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'allowed_roles': allowed_roles,
|
"allowed_roles": allowed_roles,
|
||||||
'bot_top_role': bot_member.top_role,
|
"bot_top_role": bot_member.top_role,
|
||||||
'bot_permissions': bot_member.guild_permissions,
|
"bot_permissions": bot_member.guild_permissions,
|
||||||
'role_count': len(allowed_roles)
|
"role_count": len(allowed_roles),
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting role info: {e}")
|
logger.error(f"Error getting role info: {e}")
|
||||||
return {
|
return {
|
||||||
'allowed_roles': [],
|
"allowed_roles": [],
|
||||||
'bot_top_role': None,
|
"bot_top_role": None,
|
||||||
'bot_permissions': None,
|
"bot_permissions": None,
|
||||||
'role_count': 0
|
"role_count": 0,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,15 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Dict, Any, List
|
from typing import Dict, Any, List
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import ConfigurationError as ConfigError
|
from .exceptions import ConfigurationError as ConfigError
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.config.exceptions import ConfigurationError as ConfigError
|
# Fall back to absolute imports if relative imports fail
|
||||||
|
# from videoarchiver.config.exceptions import ConfigurationError as ConfigError
|
||||||
|
|
||||||
logger = logging.getLogger("SettingsFormatter")
|
logger = logging.getLogger("SettingsFormatter")
|
||||||
|
|
||||||
@@ -22,9 +23,7 @@ class SettingsFormatter:
|
|||||||
self.embed_color = discord.Color.blue()
|
self.embed_color = discord.Color.blue()
|
||||||
|
|
||||||
async def format_settings_embed(
|
async def format_settings_embed(
|
||||||
self,
|
self, guild: discord.Guild, settings: Dict[str, Any]
|
||||||
guild: discord.Guild,
|
|
||||||
settings: Dict[str, Any]
|
|
||||||
) -> discord.Embed:
|
) -> discord.Embed:
|
||||||
"""Format guild settings into a Discord embed
|
"""Format guild settings into a Discord embed
|
||||||
|
|
||||||
@@ -42,7 +41,7 @@ class SettingsFormatter:
|
|||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title="Video Archiver Settings",
|
title="Video Archiver Settings",
|
||||||
color=self.embed_color,
|
color=self.embed_color,
|
||||||
timestamp=datetime.utcnow()
|
timestamp=datetime.utcnow(),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add sections
|
# Add sections
|
||||||
@@ -61,27 +60,23 @@ class SettingsFormatter:
|
|||||||
raise ConfigError(f"Failed to format settings: {str(e)}")
|
raise ConfigError(f"Failed to format settings: {str(e)}")
|
||||||
|
|
||||||
async def _add_core_settings(
|
async def _add_core_settings(
|
||||||
self,
|
self, embed: discord.Embed, guild: discord.Guild, settings: Dict[str, Any]
|
||||||
embed: discord.Embed,
|
|
||||||
guild: discord.Guild,
|
|
||||||
settings: Dict[str, Any]
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add core settings to embed"""
|
"""Add core settings to embed"""
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Core Settings",
|
name="Core Settings",
|
||||||
value="\n".join([
|
value="\n".join(
|
||||||
f"**Enabled:** {settings['enabled']}",
|
[
|
||||||
f"**Database Enabled:** {settings['use_database']}",
|
f"**Enabled:** {settings['enabled']}",
|
||||||
f"**Update Check Disabled:** {settings['disable_update_check']}"
|
f"**Database Enabled:** {settings['use_database']}",
|
||||||
]),
|
f"**Update Check Disabled:** {settings['disable_update_check']}",
|
||||||
inline=False
|
]
|
||||||
|
),
|
||||||
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _add_channel_settings(
|
async def _add_channel_settings(
|
||||||
self,
|
self, embed: discord.Embed, guild: discord.Guild, settings: Dict[str, Any]
|
||||||
embed: discord.Embed,
|
|
||||||
guild: discord.Guild,
|
|
||||||
settings: Dict[str, Any]
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add channel settings to embed"""
|
"""Add channel settings to embed"""
|
||||||
# Get channels with error handling
|
# Get channels with error handling
|
||||||
@@ -89,20 +84,19 @@ class SettingsFormatter:
|
|||||||
|
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Channel Settings",
|
name="Channel Settings",
|
||||||
value="\n".join([
|
value="\n".join(
|
||||||
f"**Archive Channel:** {channels['archive']}",
|
[
|
||||||
f"**Notification Channel:** {channels['notification']}",
|
f"**Archive Channel:** {channels['archive']}",
|
||||||
f"**Log Channel:** {channels['log']}",
|
f"**Notification Channel:** {channels['notification']}",
|
||||||
f"**Monitored Channels:**\n{channels['monitored']}"
|
f"**Log Channel:** {channels['log']}",
|
||||||
]),
|
f"**Monitored Channels:**\n{channels['monitored']}",
|
||||||
inline=False
|
]
|
||||||
|
),
|
||||||
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _add_permission_settings(
|
async def _add_permission_settings(
|
||||||
self,
|
self, embed: discord.Embed, guild: discord.Guild, settings: Dict[str, Any]
|
||||||
embed: discord.Embed,
|
|
||||||
guild: discord.Guild,
|
|
||||||
settings: Dict[str, Any]
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add permission settings to embed"""
|
"""Add permission settings to embed"""
|
||||||
allowed_roles = await self._get_role_names(guild, settings["allowed_roles"])
|
allowed_roles = await self._get_role_names(guild, settings["allowed_roles"])
|
||||||
@@ -110,62 +104,54 @@ class SettingsFormatter:
|
|||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Permission Settings",
|
name="Permission Settings",
|
||||||
value=f"**Allowed Roles:**\n{allowed_roles}",
|
value=f"**Allowed Roles:**\n{allowed_roles}",
|
||||||
inline=False
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _add_video_settings(
|
async def _add_video_settings(
|
||||||
self,
|
self, embed: discord.Embed, settings: Dict[str, Any]
|
||||||
embed: discord.Embed,
|
|
||||||
settings: Dict[str, Any]
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add video settings to embed"""
|
"""Add video settings to embed"""
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Video Settings",
|
name="Video Settings",
|
||||||
value="\n".join([
|
value="\n".join(
|
||||||
f"**Format:** {settings['video_format']}",
|
[
|
||||||
f"**Max Quality:** {settings['video_quality']}p",
|
f"**Format:** {settings['video_format']}",
|
||||||
f"**Max File Size:** {settings['max_file_size']}MB"
|
f"**Max Quality:** {settings['video_quality']}p",
|
||||||
]),
|
f"**Max File Size:** {settings['max_file_size']}MB",
|
||||||
inline=False
|
]
|
||||||
|
),
|
||||||
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _add_operation_settings(
|
async def _add_operation_settings(
|
||||||
self,
|
self, embed: discord.Embed, settings: Dict[str, Any]
|
||||||
embed: discord.Embed,
|
|
||||||
settings: Dict[str, Any]
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add operation settings to embed"""
|
"""Add operation settings to embed"""
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Operation Settings",
|
name="Operation Settings",
|
||||||
value="\n".join([
|
value="\n".join(
|
||||||
f"**Delete After Repost:** {settings['delete_after_repost']}",
|
[
|
||||||
f"**Message Duration:** {settings['message_duration']} hours",
|
f"**Delete After Repost:** {settings['delete_after_repost']}",
|
||||||
f"**Concurrent Downloads:** {settings['concurrent_downloads']}",
|
f"**Message Duration:** {settings['message_duration']} hours",
|
||||||
f"**Max Retries:** {settings['max_retries']}",
|
f"**Concurrent Downloads:** {settings['concurrent_downloads']}",
|
||||||
f"**Retry Delay:** {settings['retry_delay']}s"
|
f"**Max Retries:** {settings['max_retries']}",
|
||||||
]),
|
f"**Retry Delay:** {settings['retry_delay']}s",
|
||||||
inline=False
|
]
|
||||||
|
),
|
||||||
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _add_site_settings(
|
async def _add_site_settings(
|
||||||
self,
|
self, embed: discord.Embed, settings: Dict[str, Any]
|
||||||
embed: discord.Embed,
|
|
||||||
settings: Dict[str, Any]
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add site settings to embed"""
|
"""Add site settings to embed"""
|
||||||
enabled_sites = settings["enabled_sites"]
|
enabled_sites = settings["enabled_sites"]
|
||||||
sites_text = ", ".join(enabled_sites) if enabled_sites else "All sites"
|
sites_text = ", ".join(enabled_sites) if enabled_sites else "All sites"
|
||||||
|
|
||||||
embed.add_field(
|
embed.add_field(name="Enabled Sites", value=sites_text, inline=False)
|
||||||
name="Enabled Sites",
|
|
||||||
value=sites_text,
|
|
||||||
inline=False
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _get_channel_mentions(
|
async def _get_channel_mentions(
|
||||||
self,
|
self, guild: discord.Guild, settings: Dict[str, Any]
|
||||||
guild: discord.Guild,
|
|
||||||
settings: Dict[str, Any]
|
|
||||||
) -> Dict[str, str]:
|
) -> Dict[str, str]:
|
||||||
"""Get channel mentions with error handling"""
|
"""Get channel mentions with error handling"""
|
||||||
try:
|
try:
|
||||||
@@ -183,9 +169,17 @@ class SettingsFormatter:
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"archive": archive_channel.mention if archive_channel else "Not set",
|
"archive": archive_channel.mention if archive_channel else "Not set",
|
||||||
"notification": notification_channel.mention if notification_channel else "Same as archive",
|
"notification": (
|
||||||
|
notification_channel.mention
|
||||||
|
if notification_channel
|
||||||
|
else "Same as archive"
|
||||||
|
),
|
||||||
"log": log_channel.mention if log_channel else "Not set",
|
"log": log_channel.mention if log_channel else "Not set",
|
||||||
"monitored": "\n".join(monitored_channels) if monitored_channels else "All channels"
|
"monitored": (
|
||||||
|
"\n".join(monitored_channels)
|
||||||
|
if monitored_channels
|
||||||
|
else "All channels"
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -194,14 +188,10 @@ class SettingsFormatter:
|
|||||||
"archive": "Error",
|
"archive": "Error",
|
||||||
"notification": "Error",
|
"notification": "Error",
|
||||||
"log": "Error",
|
"log": "Error",
|
||||||
"monitored": "Error getting channels"
|
"monitored": "Error getting channels",
|
||||||
}
|
}
|
||||||
|
|
||||||
async def _get_role_names(
|
async def _get_role_names(self, guild: discord.Guild, role_ids: List[int]) -> str:
|
||||||
self,
|
|
||||||
guild: discord.Guild,
|
|
||||||
role_ids: List[int]
|
|
||||||
) -> str:
|
|
||||||
"""Get role names with error handling"""
|
"""Get role names with error handling"""
|
||||||
try:
|
try:
|
||||||
role_names = []
|
role_names = []
|
||||||
@@ -210,7 +200,9 @@ class SettingsFormatter:
|
|||||||
if role:
|
if role:
|
||||||
role_names.append(role.name)
|
role_names.append(role.name)
|
||||||
|
|
||||||
return ", ".join(role_names) if role_names else "All roles (no restrictions)"
|
return (
|
||||||
|
", ".join(role_names) if role_names else "All roles (no restrictions)"
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting role names: {e}")
|
logger.error(f"Error getting role names: {e}")
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict, List, Union
|
from typing import Any, Dict, List, Union
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import ConfigurationError as ConfigError
|
from .exceptions import ConfigurationError as ConfigError
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.config.exceptions import ConfigurationError as ConfigError
|
# Fall back to absolute imports if relative imports fail
|
||||||
|
# from videoarchiver.config.exceptions import ConfigurationError as ConfigError
|
||||||
|
|
||||||
logger = logging.getLogger("ConfigValidation")
|
logger = logging.getLogger("ConfigValidation")
|
||||||
|
|
||||||
@@ -72,7 +73,9 @@ class ValidationManager:
|
|||||||
|
|
||||||
def _validate_concurrent_downloads(self, value: int) -> None:
|
def _validate_concurrent_downloads(self, value: int) -> None:
|
||||||
"""Validate concurrent downloads setting"""
|
"""Validate concurrent downloads setting"""
|
||||||
if not isinstance(value, int) or not (1 <= value <= self.MAX_CONCURRENT_DOWNLOADS):
|
if not isinstance(value, int) or not (
|
||||||
|
1 <= value <= self.MAX_CONCURRENT_DOWNLOADS
|
||||||
|
):
|
||||||
raise ConfigError(
|
raise ConfigError(
|
||||||
f"Concurrent downloads must be between 1 and {self.MAX_CONCURRENT_DOWNLOADS}"
|
f"Concurrent downloads must be between 1 and {self.MAX_CONCURRENT_DOWNLOADS}"
|
||||||
)
|
)
|
||||||
@@ -87,9 +90,7 @@ class ValidationManager:
|
|||||||
def _validate_max_retries(self, value: int) -> None:
|
def _validate_max_retries(self, value: int) -> None:
|
||||||
"""Validate max retries setting"""
|
"""Validate max retries setting"""
|
||||||
if not isinstance(value, int) or not (0 <= value <= self.MAX_RETRIES):
|
if not isinstance(value, int) or not (0 <= value <= self.MAX_RETRIES):
|
||||||
raise ConfigError(
|
raise ConfigError(f"Max retries must be between 0 and {self.MAX_RETRIES}")
|
||||||
f"Max retries must be between 0 and {self.MAX_RETRIES}"
|
|
||||||
)
|
|
||||||
|
|
||||||
def _validate_retry_delay(self, value: int) -> None:
|
def _validate_retry_delay(self, value: int) -> None:
|
||||||
"""Validate retry delay setting"""
|
"""Validate retry delay setting"""
|
||||||
@@ -124,7 +125,12 @@ class ValidationManager:
|
|||||||
if setting.endswith("_channel") and value is not None:
|
if setting.endswith("_channel") and value is not None:
|
||||||
if not isinstance(value, int):
|
if not isinstance(value, int):
|
||||||
raise ConfigError(f"{setting} must be a channel ID (int) or None")
|
raise ConfigError(f"{setting} must be a channel ID (int) or None")
|
||||||
elif setting in ["enabled", "delete_after_repost", "disable_update_check", "use_database"]:
|
elif setting in [
|
||||||
|
"enabled",
|
||||||
|
"delete_after_repost",
|
||||||
|
"disable_update_check",
|
||||||
|
"use_database",
|
||||||
|
]:
|
||||||
self._validate_boolean(value)
|
self._validate_boolean(value)
|
||||||
elif setting in ["monitored_channels", "allowed_roles", "enabled_sites"]:
|
elif setting in ["monitored_channels", "allowed_roles", "enabled_sites"]:
|
||||||
self._validate_list(value)
|
self._validate_list(value)
|
||||||
|
|||||||
@@ -3,23 +3,24 @@
|
|||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import Dict, Any, Optional, List, Union
|
from typing import Dict, Any, Optional, List, Union
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
from redbot.core import Config # type: ignore
|
from redbot.core import Config # type: ignore
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .config.validation_manager import ValidationManager
|
from .config.validation_manager import ValidationManager
|
||||||
from .config.settings_formatter import SettingsFormatter
|
from .config.settings_formatter import SettingsFormatter
|
||||||
from .config.channel_manager import ChannelManager
|
from .config.channel_manager import ChannelManager
|
||||||
from .config.role_manager import RoleManager
|
from .config.role_manager import RoleManager
|
||||||
from .utils.exceptions import ConfigurationError as ConfigError
|
from .utils.exceptions import ConfigurationError as ConfigError
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.config.validation_manager import ValidationManager
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.config.settings_formatter import SettingsFormatter
|
# from videoarchiver.config.validation_manager import ValidationManager
|
||||||
# from videoarchiver.config.channel_manager import ChannelManager
|
# from videoarchiver.config.settings_formatter import SettingsFormatter
|
||||||
# from videoarchiver.config.role_manager import RoleManager
|
# from videoarchiver.config.channel_manager import ChannelManager
|
||||||
# from videoarchiver.utils.exceptions import ConfigurationError as ConfigError
|
# from videoarchiver.config.role_manager import RoleManager
|
||||||
|
# from videoarchiver.utils.exceptions import ConfigurationError as ConfigError
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
@@ -80,12 +81,7 @@ class ConfigManager:
|
|||||||
logger.error(f"Failed to get guild settings for {guild_id}: {e}")
|
logger.error(f"Failed to get guild settings for {guild_id}: {e}")
|
||||||
raise ConfigError(f"Failed to get guild settings: {str(e)}")
|
raise ConfigError(f"Failed to get guild settings: {str(e)}")
|
||||||
|
|
||||||
async def update_setting(
|
async def update_setting(self, guild_id: int, setting: str, value: Any) -> None:
|
||||||
self,
|
|
||||||
guild_id: int,
|
|
||||||
setting: str,
|
|
||||||
value: Any
|
|
||||||
) -> None:
|
|
||||||
"""Update a specific setting for a guild"""
|
"""Update a specific setting for a guild"""
|
||||||
try:
|
try:
|
||||||
if setting not in self.default_guild:
|
if setting not in self.default_guild:
|
||||||
@@ -98,14 +94,12 @@ class ConfigManager:
|
|||||||
await self.config.guild_from_id(guild_id).set_raw(setting, value=value)
|
await self.config.guild_from_id(guild_id).set_raw(setting, value=value)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to update setting {setting} for guild {guild_id}: {e}")
|
logger.error(
|
||||||
|
f"Failed to update setting {setting} for guild {guild_id}: {e}"
|
||||||
|
)
|
||||||
raise ConfigError(f"Failed to update setting: {str(e)}")
|
raise ConfigError(f"Failed to update setting: {str(e)}")
|
||||||
|
|
||||||
async def get_setting(
|
async def get_setting(self, guild_id: int, setting: str) -> Any:
|
||||||
self,
|
|
||||||
guild_id: int,
|
|
||||||
setting: str
|
|
||||||
) -> Any:
|
|
||||||
"""Get a specific setting for a guild"""
|
"""Get a specific setting for a guild"""
|
||||||
try:
|
try:
|
||||||
if setting not in self.default_guild:
|
if setting not in self.default_guild:
|
||||||
@@ -118,11 +112,7 @@ class ConfigManager:
|
|||||||
logger.error(f"Failed to get setting {setting} for guild {guild_id}: {e}")
|
logger.error(f"Failed to get setting {setting} for guild {guild_id}: {e}")
|
||||||
raise ConfigError(f"Failed to get setting: {str(e)}")
|
raise ConfigError(f"Failed to get setting: {str(e)}")
|
||||||
|
|
||||||
async def toggle_setting(
|
async def toggle_setting(self, guild_id: int, setting: str) -> bool:
|
||||||
self,
|
|
||||||
guild_id: int,
|
|
||||||
setting: str
|
|
||||||
) -> bool:
|
|
||||||
"""Toggle a boolean setting for a guild"""
|
"""Toggle a boolean setting for a guild"""
|
||||||
try:
|
try:
|
||||||
if setting not in self.default_guild:
|
if setting not in self.default_guild:
|
||||||
@@ -137,22 +127,21 @@ class ConfigManager:
|
|||||||
return not current
|
return not current
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to toggle setting {setting} for guild {guild_id}: {e}")
|
logger.error(
|
||||||
|
f"Failed to toggle setting {setting} for guild {guild_id}: {e}"
|
||||||
|
)
|
||||||
raise ConfigError(f"Failed to toggle setting: {str(e)}")
|
raise ConfigError(f"Failed to toggle setting: {str(e)}")
|
||||||
|
|
||||||
async def add_to_list(
|
async def add_to_list(self, guild_id: int, setting: str, value: Any) -> None:
|
||||||
self,
|
|
||||||
guild_id: int,
|
|
||||||
setting: str,
|
|
||||||
value: Any
|
|
||||||
) -> None:
|
|
||||||
"""Add a value to a list setting"""
|
"""Add a value to a list setting"""
|
||||||
try:
|
try:
|
||||||
if setting not in self.default_guild:
|
if setting not in self.default_guild:
|
||||||
raise ConfigError(f"Invalid setting: {setting}")
|
raise ConfigError(f"Invalid setting: {setting}")
|
||||||
|
|
||||||
async with await self._get_guild_lock(guild_id):
|
async with await self._get_guild_lock(guild_id):
|
||||||
async with self.config.guild_from_id(guild_id).get_attr(setting)() as items:
|
async with self.config.guild_from_id(guild_id).get_attr(
|
||||||
|
setting
|
||||||
|
)() as items:
|
||||||
if not isinstance(items, list):
|
if not isinstance(items, list):
|
||||||
raise ConfigError(f"Setting {setting} is not a list")
|
raise ConfigError(f"Setting {setting} is not a list")
|
||||||
if value not in items:
|
if value not in items:
|
||||||
@@ -162,26 +151,25 @@ class ConfigManager:
|
|||||||
logger.error(f"Failed to add to list {setting} for guild {guild_id}: {e}")
|
logger.error(f"Failed to add to list {setting} for guild {guild_id}: {e}")
|
||||||
raise ConfigError(f"Failed to add to list: {str(e)}")
|
raise ConfigError(f"Failed to add to list: {str(e)}")
|
||||||
|
|
||||||
async def remove_from_list(
|
async def remove_from_list(self, guild_id: int, setting: str, value: Any) -> None:
|
||||||
self,
|
|
||||||
guild_id: int,
|
|
||||||
setting: str,
|
|
||||||
value: Any
|
|
||||||
) -> None:
|
|
||||||
"""Remove a value from a list setting"""
|
"""Remove a value from a list setting"""
|
||||||
try:
|
try:
|
||||||
if setting not in self.default_guild:
|
if setting not in self.default_guild:
|
||||||
raise ConfigError(f"Invalid setting: {setting}")
|
raise ConfigError(f"Invalid setting: {setting}")
|
||||||
|
|
||||||
async with await self._get_guild_lock(guild_id):
|
async with await self._get_guild_lock(guild_id):
|
||||||
async with self.config.guild_from_id(guild_id).get_attr(setting)() as items:
|
async with self.config.guild_from_id(guild_id).get_attr(
|
||||||
|
setting
|
||||||
|
)() as items:
|
||||||
if not isinstance(items, list):
|
if not isinstance(items, list):
|
||||||
raise ConfigError(f"Setting {setting} is not a list")
|
raise ConfigError(f"Setting {setting} is not a list")
|
||||||
if value in items:
|
if value in items:
|
||||||
items.remove(value)
|
items.remove(value)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to remove from list {setting} for guild {guild_id}: {e}")
|
logger.error(
|
||||||
|
f"Failed to remove from list {setting} for guild {guild_id}: {e}"
|
||||||
|
)
|
||||||
raise ConfigError(f"Failed to remove from list: {str(e)}")
|
raise ConfigError(f"Failed to remove from list: {str(e)}")
|
||||||
|
|
||||||
async def format_settings_embed(self, guild: discord.Guild) -> discord.Embed:
|
async def format_settings_embed(self, guild: discord.Guild) -> discord.Embed:
|
||||||
@@ -194,11 +182,15 @@ class ConfigManager:
|
|||||||
raise ConfigError(f"Failed to format settings: {str(e)}")
|
raise ConfigError(f"Failed to format settings: {str(e)}")
|
||||||
|
|
||||||
# Channel management delegated to channel_manager
|
# Channel management delegated to channel_manager
|
||||||
async def get_channel(self, guild: discord.Guild, channel_type: str) -> Optional[discord.TextChannel]:
|
async def get_channel(
|
||||||
|
self, guild: discord.Guild, channel_type: str
|
||||||
|
) -> Optional[discord.TextChannel]:
|
||||||
"""Get a channel by type"""
|
"""Get a channel by type"""
|
||||||
return await self.channel_manager.get_channel(guild, channel_type)
|
return await self.channel_manager.get_channel(guild, channel_type)
|
||||||
|
|
||||||
async def get_monitored_channels(self, guild: discord.Guild) -> List[discord.TextChannel]:
|
async def get_monitored_channels(
|
||||||
|
self, guild: discord.Guild
|
||||||
|
) -> List[discord.TextChannel]:
|
||||||
"""Get all monitored channels for a guild"""
|
"""Get all monitored channels for a guild"""
|
||||||
return await self.channel_manager.get_monitored_channels(guild)
|
return await self.channel_manager.get_monitored_channels(guild)
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
"""Core module for VideoArchiver cog"""
|
"""Core module for VideoArchiver cog"""
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .base import VideoArchiver
|
from .base import VideoArchiver
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.core.base import VideoArchiver
|
# Fall back to absolute imports if relative imports fail
|
||||||
|
# from videoarchiver.core.base import VideoArchiver
|
||||||
|
|
||||||
__all__ = ["VideoArchiver"]
|
__all__ = ["VideoArchiver"]
|
||||||
|
|||||||
@@ -12,40 +12,41 @@ import discord # type: ignore
|
|||||||
from redbot.core.bot import Red # type: ignore
|
from redbot.core.bot import Red # type: ignore
|
||||||
from redbot.core.commands import GroupCog, Context # type: ignore
|
from redbot.core.commands import GroupCog, Context # type: ignore
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .settings import Settings
|
from .settings import Settings
|
||||||
from .lifecycle import LifecycleManager, LifecycleState
|
from .lifecycle import LifecycleManager, LifecycleState
|
||||||
from .component_manager import ComponentManager, ComponentState
|
from .component_manager import ComponentManager, ComponentState
|
||||||
from .error_handler import error_manager, handle_command_error
|
from .error_handler import error_manager, handle_command_error
|
||||||
from .response_handler import ResponseManager
|
from .response_handler import ResponseManager
|
||||||
from .commands.archiver_commands import setup_archiver_commands
|
from .commands.archiver_commands import setup_archiver_commands
|
||||||
from .commands.database_commands import setup_database_commands
|
from .commands.database_commands import setup_database_commands
|
||||||
from .commands.settings_commands import setup_settings_commands
|
from .commands.settings_commands import setup_settings_commands
|
||||||
from .events import setup_events, EventManager
|
from .events import setup_events, EventManager
|
||||||
from ..processor.core import VideoProcessor
|
from ..processor.core import VideoProcessor
|
||||||
from ..queue.manager import EnhancedVideoQueueManager
|
from ..queue.manager import EnhancedVideoQueueManager
|
||||||
from ..ffmpeg.ffmpeg_manager import FFmpegManager
|
from ..ffmpeg.ffmpeg_manager import FFmpegManager
|
||||||
from ..database.video_archive_db import VideoArchiveDB
|
from ..database.video_archive_db import VideoArchiveDB
|
||||||
from ..config_manager import ConfigManager
|
from ..config_manager import ConfigManager
|
||||||
from ..utils.exceptions import CogError, ErrorContext, ErrorSeverity
|
from ..utils.exceptions import CogError, ErrorContext, ErrorSeverity
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.core.settings import Settings
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.core.lifecycle import LifecycleManager, LifecycleState
|
# from videoarchiver.core.settings import Settings
|
||||||
# from videoarchiver.core.component_manager import ComponentManager, ComponentState
|
# from videoarchiver.core.lifecycle import LifecycleManager, LifecycleState
|
||||||
# from videoarchiver.core.error_handler import error_manager, handle_command_error
|
# from videoarchiver.core.component_manager import ComponentManager, ComponentState
|
||||||
# from videoarchiver.core.response_handler import ResponseManager
|
# from videoarchiver.core.error_handler import error_manager, handle_command_error
|
||||||
# from videoarchiver.core.commands.archiver_commands import setup_archiver_commands
|
# from videoarchiver.core.response_handler import ResponseManager
|
||||||
# from videoarchiver.core.commands.database_commands import setup_database_commands
|
# from videoarchiver.core.commands.archiver_commands import setup_archiver_commands
|
||||||
# from videoarchiver.core.commands.settings_commands import setup_settings_commands
|
# from videoarchiver.core.commands.database_commands import setup_database_commands
|
||||||
# from videoarchiver.core.events import setup_events, EventManager
|
# from videoarchiver.core.commands.settings_commands import setup_settings_commands
|
||||||
# from videoarchiver.processor.core import VideoProcessor
|
# from videoarchiver.core.events import setup_events, EventManager
|
||||||
# from videoarchiver.queue.manager import EnhancedVideoQueueManager
|
# from videoarchiver.processor.core import VideoProcessor
|
||||||
# from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager
|
# from videoarchiver.queue.manager import EnhancedVideoQueueManager
|
||||||
# from videoarchiver.database.video_archive_db import VideoArchiveDB
|
# from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager
|
||||||
# from videoarchiver.config_manager import ConfigManager
|
# from videoarchiver.database.video_archive_db import VideoArchiveDB
|
||||||
# from videoarchiver.utils.exceptions import CogError, ErrorContext, ErrorSeverity
|
# from videoarchiver.config_manager import ConfigManager
|
||||||
|
# from videoarchiver.utils.exceptions import CogError, ErrorContext, ErrorSeverity
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
|
|||||||
@@ -8,19 +8,19 @@ from enum import Enum, auto
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Dict, Any, Optional, TypedDict, ClassVar
|
from typing import TYPE_CHECKING, Dict, Any, Optional, TypedDict, ClassVar
|
||||||
|
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.file_ops import cleanup_downloads
|
from ..utils.file_ops import cleanup_downloads
|
||||||
from ..utils.exceptions import CleanupError, ErrorContext, ErrorSeverity
|
from ..utils.exceptions import CleanupError, ErrorContext, ErrorSeverity
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.utils.file_ops import cleanup_downloads
|
# from videoarchiver.utils.file_ops import cleanup_downloads
|
||||||
# from videoarchiver.utils.exceptions import CleanupError, ErrorContext, ErrorSeverity
|
# from videoarchiver.utils.exceptions import CleanupError, ErrorContext, ErrorSeverity
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
try:
|
#try:
|
||||||
from .base import VideoArchiver
|
from .base import VideoArchiver
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# from videoarchiver.core.base import VideoArchiver
|
# from videoarchiver.core.base import VideoArchiver
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
try:
|
# try:
|
||||||
from .base import VideoArchiver
|
from .base import VideoArchiver
|
||||||
except ImportError:
|
# except ImportError:
|
||||||
# from videoarchiver.core.base import VideoArchiver
|
# from videoarchiver.core.base import VideoArchiver
|
||||||
|
|
||||||
def setup_commands(cog: "VideoArchiver") -> None:
|
def setup_commands(cog: "VideoArchiver") -> None:
|
||||||
|
|||||||
@@ -20,22 +20,23 @@ from datetime import datetime
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.exceptions import ComponentError, ErrorContext, ErrorSeverity
|
from ..utils.exceptions import ComponentError, ErrorContext, ErrorSeverity
|
||||||
from ..utils.path_manager import PathManager
|
from ..utils.path_manager import PathManager
|
||||||
from ..config_manager import ConfigManager
|
from ..config_manager import ConfigManager
|
||||||
from ..processor.core import VideoProcessor
|
from ..processor.core import VideoProcessor
|
||||||
from ..queue.manager import EnhancedVideoQueueManager
|
from ..queue.manager import EnhancedVideoQueueManager
|
||||||
from ..ffmpeg.ffmpeg_manager import FFmpegManager
|
from ..ffmpeg.ffmpeg_manager import FFmpegManager
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.utils.exceptions import ComponentError, ErrorContext, ErrorSeverity
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.utils.path_manager import PathManager
|
# from videoarchiver.utils.exceptions import ComponentError, ErrorContext, ErrorSeverity
|
||||||
# from videoarchiver.config_manager import ConfigManager
|
# from videoarchiver.utils.path_manager import PathManager
|
||||||
# from videoarchiver.processor.core import VideoProcessor
|
# from videoarchiver.config_manager import ConfigManager
|
||||||
# from videoarchiver.queue.manager import EnhancedVideoQueueManager
|
# from videoarchiver.processor.core import VideoProcessor
|
||||||
# from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager
|
# from videoarchiver.queue.manager import EnhancedVideoQueueManager
|
||||||
|
# from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
|
|||||||
@@ -14,49 +14,49 @@ from redbot.core.commands import ( # type: ignore
|
|||||||
CommandError
|
CommandError
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.exceptions import (
|
from ..utils.exceptions import (
|
||||||
VideoArchiverError,
|
VideoArchiverError,
|
||||||
ErrorSeverity,
|
ErrorSeverity,
|
||||||
ErrorContext,
|
ErrorContext,
|
||||||
ProcessorError,
|
ProcessorError,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
DisplayError,
|
DisplayError,
|
||||||
URLExtractionError,
|
URLExtractionError,
|
||||||
MessageHandlerError,
|
MessageHandlerError,
|
||||||
QueueHandlerError,
|
QueueHandlerError,
|
||||||
QueueProcessorError,
|
QueueProcessorError,
|
||||||
FFmpegError,
|
FFmpegError,
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
HealthCheckError,
|
HealthCheckError,
|
||||||
TrackingError,
|
TrackingError,
|
||||||
NetworkError,
|
NetworkError,
|
||||||
ResourceExhaustedError,
|
ResourceExhaustedError,
|
||||||
ConfigurationError
|
ConfigurationError
|
||||||
)
|
)
|
||||||
from ..core.response_handler import response_manager
|
from ..core.response_handler import response_manager
|
||||||
except ImportError:
|
# except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# # Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.utils.exceptions import (
|
# # from videoarchiver.utils.exceptions import (
|
||||||
VideoArchiverError,
|
# VideoArchiverError,
|
||||||
ErrorSeverity,
|
# ErrorSeverity,
|
||||||
ErrorContext,
|
# ErrorContext,
|
||||||
ProcessorError,
|
# ProcessorError,
|
||||||
ValidationError,
|
# ValidationError,
|
||||||
DisplayError,
|
# DisplayError,
|
||||||
URLExtractionError,
|
# URLExtractionError,
|
||||||
MessageHandlerError,
|
# MessageHandlerError,
|
||||||
QueueHandlerError,
|
# QueueHandlerError,
|
||||||
QueueProcessorError,
|
# QueueProcessorError,
|
||||||
FFmpegError,
|
# FFmpegError,
|
||||||
DatabaseError,
|
# DatabaseError,
|
||||||
HealthCheckError,
|
# HealthCheckError,
|
||||||
TrackingError,
|
# TrackingError,
|
||||||
NetworkError,
|
# NetworkError,
|
||||||
ResourceExhaustedError,
|
# ResourceExhaustedError,
|
||||||
ConfigurationError
|
# ConfigurationError
|
||||||
)
|
# )
|
||||||
# from videoarchiver.core.response_handler import response_manager
|
# from videoarchiver.core.response_handler import response_manager
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ from typing import TYPE_CHECKING, Dict, Any, Optional, TypedDict, ClassVar, List
|
|||||||
|
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
|
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..processor.constants import REACTIONS
|
from ..processor.constants import REACTIONS
|
||||||
from ..processor.reactions import handle_archived_reaction
|
from ..processor.reactions import handle_archived_reaction
|
||||||
from .guild import initialize_guild_components, cleanup_guild_components
|
from .guild import initialize_guild_components, cleanup_guild_components
|
||||||
from .error_handler import ErrorManager
|
from .error_handler import ErrorManager
|
||||||
from .response_handler import response_manager
|
from .response_handler import response_manager
|
||||||
from ..utils.exceptions import EventError, ErrorContext, ErrorSeverity
|
from ..utils.exceptions import EventError, ErrorContext, ErrorSeverity
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.processor.constants import REACTIONS
|
# from videoarchiver.processor.constants import REACTIONS
|
||||||
# from videoarchiver.processor.reactions import handle_archived_reaction
|
# from videoarchiver.processor.reactions import handle_archived_reaction
|
||||||
@@ -27,9 +27,9 @@ except ImportError:
|
|||||||
# from videoarchiver.utils.exceptions import EventError, ErrorContext, ErrorSeverity
|
# from videoarchiver.utils.exceptions import EventError, ErrorContext, ErrorSeverity
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
try:
|
#try:
|
||||||
from .base import VideoArchiver
|
from .base import VideoArchiver
|
||||||
except ImportError:
|
# except ImportError:
|
||||||
# from videoarchiver.core.base import VideoArchiver
|
# from videoarchiver.core.base import VideoArchiver
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|||||||
@@ -4,24 +4,25 @@ import logging
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Dict, Any, Optional
|
from typing import TYPE_CHECKING, Dict, Any, Optional
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.download_core import DownloadCore
|
from ..utils.download_core import DownloadCore
|
||||||
from ..utils.message_manager import MessageManager
|
from ..utils.message_manager import MessageManager
|
||||||
from ..utils.file_ops import cleanup_downloads
|
from ..utils.file_ops import cleanup_downloads
|
||||||
from ..utils.exceptions import VideoArchiverError as ProcessingError
|
from ..utils.exceptions import VideoArchiverError as ProcessingError
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.utils.download_core import DownloadCore
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.utils.message_manager import MessageManager
|
# from videoarchiver.utils.download_core import DownloadCore
|
||||||
# from videoarchiver.utils.file_ops import cleanup_downloads
|
# from videoarchiver.utils.message_manager import MessageManager
|
||||||
# from videoarchiver.utils.exceptions import VideoArchiverError as ProcessingError
|
# from videoarchiver.utils.file_ops import cleanup_downloads
|
||||||
|
# from videoarchiver.utils.exceptions import VideoArchiverError as ProcessingError
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
try:
|
# try:
|
||||||
from .base import VideoArchiver
|
from .base import VideoArchiver
|
||||||
except ImportError:
|
# except ImportError:
|
||||||
# from videoarchiver.core.base import VideoArchiver
|
# from videoarchiver.core.base import VideoArchiver
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
|
|||||||
@@ -4,20 +4,21 @@ from typing import TYPE_CHECKING, Optional, Dict, Any
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.exceptions import ComponentError, ErrorContext, ErrorSeverity
|
from ..utils.exceptions import ComponentError, ErrorContext, ErrorSeverity
|
||||||
from .lifecycle import LifecycleState
|
from .lifecycle import LifecycleState
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.utils.exceptions import ComponentError, ErrorContext, ErrorSeverity
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.core.lifecycle import LifecycleState
|
# from videoarchiver.utils.exceptions import ComponentError, ErrorContext, ErrorSeverity
|
||||||
|
# from videoarchiver.core.lifecycle import LifecycleState
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
try:
|
# try:
|
||||||
from .base import VideoArchiver
|
from .base import VideoArchiver
|
||||||
except ImportError:
|
# except ImportError:
|
||||||
# from videoarchiver.core.base import VideoArchiver
|
# from videoarchiver.core.base import VideoArchiver
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
@@ -48,8 +49,8 @@ async def initialize_cog(cog: "VideoArchiver") -> None:
|
|||||||
"Initialization",
|
"Initialization",
|
||||||
"initialize_cog",
|
"initialize_cog",
|
||||||
{"state": cog.lifecycle_manager.state_tracker.state.name},
|
{"state": cog.lifecycle_manager.state_tracker.state.name},
|
||||||
ErrorSeverity.HIGH
|
ErrorSeverity.HIGH,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -103,8 +104,8 @@ def get_init_status(cog: "VideoArchiver") -> Dict[str, Any]:
|
|||||||
"update_checker",
|
"update_checker",
|
||||||
"ffmpeg_mgr",
|
"ffmpeg_mgr",
|
||||||
"components",
|
"components",
|
||||||
"db"
|
"db",
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
"history": cog.lifecycle_manager.state_tracker.get_state_history()
|
"history": cog.lifecycle_manager.state_tracker.get_state_history(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,26 +7,26 @@ from typing import Optional, Dict, Any, Set, List, Callable, TypedDict, ClassVar
|
|||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .cleanup import cleanup_resources, force_cleanup_resources
|
from .cleanup import cleanup_resources, force_cleanup_resources
|
||||||
from ..utils.exceptions import (
|
from ..utils.exceptions import (
|
||||||
VideoArchiverError,
|
VideoArchiverError,
|
||||||
ErrorContext,
|
ErrorContext,
|
||||||
ErrorSeverity,
|
ErrorSeverity,
|
||||||
ComponentError,
|
ComponentError,
|
||||||
CleanupError,
|
CleanupError,
|
||||||
)
|
)
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.core.cleanup import cleanup_resources, force_cleanup_resources
|
# from videoarchiver.core.cleanup import cleanup_resources, force_cleanup_resources
|
||||||
# from videoarchiver.utils.exceptions import (
|
# from videoarchiver.utils.exceptions import (
|
||||||
VideoArchiverError,
|
# VideoArchiverError,
|
||||||
ErrorContext,
|
# ErrorContext,
|
||||||
ErrorSeverity,
|
# ErrorSeverity,
|
||||||
ComponentError,
|
# ComponentError,
|
||||||
CleanupError,
|
# CleanupError,
|
||||||
)
|
# )
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ from datetime import datetime
|
|||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
from redbot.core.commands import Context # type: ignore
|
from redbot.core.commands import Context # type: ignore
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.exceptions import ErrorSeverity
|
from ..utils.exceptions import ErrorSeverity
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.utils.exceptions import ErrorSeverity
|
# Fall back to absolute imports if relative imports fail
|
||||||
|
# from videoarchiver.utils.exceptions import ErrorSeverity
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
|
|||||||
@@ -4,29 +4,35 @@ from typing import Dict, Any, List, Optional, Union, TypedDict, ClassVar
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.exceptions import ConfigurationError, ErrorContext, ErrorSeverity
|
from ..utils.exceptions import ConfigurationError, ErrorContext, ErrorSeverity
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.utils.exceptions import ConfigurationError, ErrorContext, ErrorSeverity
|
# Fall back to absolute imports if relative imports fail
|
||||||
|
# from videoarchiver.utils.exceptions import ConfigurationError, ErrorContext, ErrorSeverity
|
||||||
|
|
||||||
|
|
||||||
class VideoFormat(Enum):
|
class VideoFormat(Enum):
|
||||||
"""Supported video formats"""
|
"""Supported video formats"""
|
||||||
|
|
||||||
MP4 = "mp4"
|
MP4 = "mp4"
|
||||||
WEBM = "webm"
|
WEBM = "webm"
|
||||||
MKV = "mkv"
|
MKV = "mkv"
|
||||||
|
|
||||||
|
|
||||||
class VideoQuality(Enum):
|
class VideoQuality(Enum):
|
||||||
"""Video quality presets"""
|
"""Video quality presets"""
|
||||||
LOW = "low" # 480p
|
|
||||||
|
LOW = "low" # 480p
|
||||||
MEDIUM = "medium" # 720p
|
MEDIUM = "medium" # 720p
|
||||||
HIGH = "high" # 1080p
|
HIGH = "high" # 1080p
|
||||||
ULTRA = "ultra" # 4K
|
ULTRA = "ultra" # 4K
|
||||||
|
|
||||||
|
|
||||||
class SettingCategory(Enum):
|
class SettingCategory(Enum):
|
||||||
"""Setting categories"""
|
"""Setting categories"""
|
||||||
|
|
||||||
GENERAL = auto()
|
GENERAL = auto()
|
||||||
CHANNELS = auto()
|
CHANNELS = auto()
|
||||||
PERMISSIONS = auto()
|
PERMISSIONS = auto()
|
||||||
@@ -35,15 +41,19 @@ class SettingCategory(Enum):
|
|||||||
PERFORMANCE = auto()
|
PERFORMANCE = auto()
|
||||||
FEATURES = auto()
|
FEATURES = auto()
|
||||||
|
|
||||||
|
|
||||||
class ValidationResult(TypedDict):
|
class ValidationResult(TypedDict):
|
||||||
"""Type definition for validation result"""
|
"""Type definition for validation result"""
|
||||||
|
|
||||||
valid: bool
|
valid: bool
|
||||||
error: Optional[str]
|
error: Optional[str]
|
||||||
details: Dict[str, Any]
|
details: Dict[str, Any]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class SettingDefinition:
|
class SettingDefinition:
|
||||||
"""Defines a setting's properties"""
|
"""Defines a setting's properties"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
category: SettingCategory
|
category: SettingCategory
|
||||||
default_value: Any
|
default_value: Any
|
||||||
@@ -66,8 +76,8 @@ class SettingDefinition:
|
|||||||
"Settings",
|
"Settings",
|
||||||
"definition_validation",
|
"definition_validation",
|
||||||
{"setting": self.name},
|
{"setting": self.name},
|
||||||
ErrorSeverity.HIGH
|
ErrorSeverity.HIGH,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.min_value is not None and self.max_value is not None:
|
if self.min_value is not None and self.max_value is not None:
|
||||||
@@ -78,10 +88,11 @@ class SettingDefinition:
|
|||||||
"Settings",
|
"Settings",
|
||||||
"definition_validation",
|
"definition_validation",
|
||||||
{"setting": self.name},
|
{"setting": self.name},
|
||||||
ErrorSeverity.HIGH
|
ErrorSeverity.HIGH,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Settings:
|
class Settings:
|
||||||
"""Manages VideoArchiver settings"""
|
"""Manages VideoArchiver settings"""
|
||||||
|
|
||||||
@@ -92,7 +103,7 @@ class Settings:
|
|||||||
category=SettingCategory.GENERAL,
|
category=SettingCategory.GENERAL,
|
||||||
default_value=False,
|
default_value=False,
|
||||||
description="Whether the archiver is enabled for this guild",
|
description="Whether the archiver is enabled for this guild",
|
||||||
data_type=bool
|
data_type=bool,
|
||||||
),
|
),
|
||||||
"archive_channel": SettingDefinition(
|
"archive_channel": SettingDefinition(
|
||||||
name="archive_channel",
|
name="archive_channel",
|
||||||
@@ -101,7 +112,7 @@ class Settings:
|
|||||||
description="Channel where archived videos are posted",
|
description="Channel where archived videos are posted",
|
||||||
data_type=int,
|
data_type=int,
|
||||||
required=False,
|
required=False,
|
||||||
error_message="Archive channel must be a valid channel ID"
|
error_message="Archive channel must be a valid channel ID",
|
||||||
),
|
),
|
||||||
"log_channel": SettingDefinition(
|
"log_channel": SettingDefinition(
|
||||||
name="log_channel",
|
name="log_channel",
|
||||||
@@ -110,7 +121,7 @@ class Settings:
|
|||||||
description="Channel for logging archiver actions",
|
description="Channel for logging archiver actions",
|
||||||
data_type=int,
|
data_type=int,
|
||||||
required=False,
|
required=False,
|
||||||
error_message="Log channel must be a valid channel ID"
|
error_message="Log channel must be a valid channel ID",
|
||||||
),
|
),
|
||||||
"enabled_channels": SettingDefinition(
|
"enabled_channels": SettingDefinition(
|
||||||
name="enabled_channels",
|
name="enabled_channels",
|
||||||
@@ -118,7 +129,7 @@ class Settings:
|
|||||||
default_value=[],
|
default_value=[],
|
||||||
description="Channels to monitor (empty means all channels)",
|
description="Channels to monitor (empty means all channels)",
|
||||||
data_type=list,
|
data_type=list,
|
||||||
error_message="Enabled channels must be a list of valid channel IDs"
|
error_message="Enabled channels must be a list of valid channel IDs",
|
||||||
),
|
),
|
||||||
"allowed_roles": SettingDefinition(
|
"allowed_roles": SettingDefinition(
|
||||||
name="allowed_roles",
|
name="allowed_roles",
|
||||||
@@ -126,7 +137,7 @@ class Settings:
|
|||||||
default_value=[],
|
default_value=[],
|
||||||
description="Roles allowed to use archiver (empty means all roles)",
|
description="Roles allowed to use archiver (empty means all roles)",
|
||||||
data_type=list,
|
data_type=list,
|
||||||
error_message="Allowed roles must be a list of valid role IDs"
|
error_message="Allowed roles must be a list of valid role IDs",
|
||||||
),
|
),
|
||||||
"video_format": SettingDefinition(
|
"video_format": SettingDefinition(
|
||||||
name="video_format",
|
name="video_format",
|
||||||
@@ -135,7 +146,7 @@ class Settings:
|
|||||||
description="Format for archived videos",
|
description="Format for archived videos",
|
||||||
data_type=str,
|
data_type=str,
|
||||||
choices=[format.value for format in VideoFormat],
|
choices=[format.value for format in VideoFormat],
|
||||||
error_message=f"Video format must be one of: {', '.join(f.value for f in VideoFormat)}"
|
error_message=f"Video format must be one of: {', '.join(f.value for f in VideoFormat)}",
|
||||||
),
|
),
|
||||||
"video_quality": SettingDefinition(
|
"video_quality": SettingDefinition(
|
||||||
name="video_quality",
|
name="video_quality",
|
||||||
@@ -144,7 +155,7 @@ class Settings:
|
|||||||
description="Quality preset for archived videos",
|
description="Quality preset for archived videos",
|
||||||
data_type=str,
|
data_type=str,
|
||||||
choices=[quality.value for quality in VideoQuality],
|
choices=[quality.value for quality in VideoQuality],
|
||||||
error_message=f"Video quality must be one of: {', '.join(q.value for q in VideoQuality)}"
|
error_message=f"Video quality must be one of: {', '.join(q.value for q in VideoQuality)}",
|
||||||
),
|
),
|
||||||
"max_file_size": SettingDefinition(
|
"max_file_size": SettingDefinition(
|
||||||
name="max_file_size",
|
name="max_file_size",
|
||||||
@@ -154,7 +165,7 @@ class Settings:
|
|||||||
data_type=int,
|
data_type=int,
|
||||||
min_value=1,
|
min_value=1,
|
||||||
max_value=100,
|
max_value=100,
|
||||||
error_message="Max file size must be between 1 and 100 MB"
|
error_message="Max file size must be between 1 and 100 MB",
|
||||||
),
|
),
|
||||||
"message_duration": SettingDefinition(
|
"message_duration": SettingDefinition(
|
||||||
name="message_duration",
|
name="message_duration",
|
||||||
@@ -164,7 +175,7 @@ class Settings:
|
|||||||
data_type=int,
|
data_type=int,
|
||||||
min_value=5,
|
min_value=5,
|
||||||
max_value=300,
|
max_value=300,
|
||||||
error_message="Message duration must be between 5 and 300 seconds"
|
error_message="Message duration must be between 5 and 300 seconds",
|
||||||
),
|
),
|
||||||
"message_template": SettingDefinition(
|
"message_template": SettingDefinition(
|
||||||
name="message_template",
|
name="message_template",
|
||||||
@@ -172,7 +183,7 @@ class Settings:
|
|||||||
default_value="{author} archived a video from {channel}",
|
default_value="{author} archived a video from {channel}",
|
||||||
description="Template for archive messages",
|
description="Template for archive messages",
|
||||||
data_type=str,
|
data_type=str,
|
||||||
error_message="Message template must contain {author} and {channel} placeholders"
|
error_message="Message template must contain {author} and {channel} placeholders",
|
||||||
),
|
),
|
||||||
"concurrent_downloads": SettingDefinition(
|
"concurrent_downloads": SettingDefinition(
|
||||||
name="concurrent_downloads",
|
name="concurrent_downloads",
|
||||||
@@ -182,7 +193,7 @@ class Settings:
|
|||||||
data_type=int,
|
data_type=int,
|
||||||
min_value=1,
|
min_value=1,
|
||||||
max_value=5,
|
max_value=5,
|
||||||
error_message="Concurrent downloads must be between 1 and 5"
|
error_message="Concurrent downloads must be between 1 and 5",
|
||||||
),
|
),
|
||||||
"enabled_sites": SettingDefinition(
|
"enabled_sites": SettingDefinition(
|
||||||
name="enabled_sites",
|
name="enabled_sites",
|
||||||
@@ -191,14 +202,14 @@ class Settings:
|
|||||||
description="Sites to enable archiving for (None means all sites)",
|
description="Sites to enable archiving for (None means all sites)",
|
||||||
data_type=list,
|
data_type=list,
|
||||||
required=False,
|
required=False,
|
||||||
error_message="Enabled sites must be a list of valid site identifiers"
|
error_message="Enabled sites must be a list of valid site identifiers",
|
||||||
),
|
),
|
||||||
"use_database": SettingDefinition(
|
"use_database": SettingDefinition(
|
||||||
name="use_database",
|
name="use_database",
|
||||||
category=SettingCategory.FEATURES,
|
category=SettingCategory.FEATURES,
|
||||||
default_value=False,
|
default_value=False,
|
||||||
description="Enable database tracking of archived videos",
|
description="Enable database tracking of archived videos",
|
||||||
data_type=bool
|
data_type=bool,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +227,9 @@ class Settings:
|
|||||||
return cls.SETTINGS.get(setting)
|
return cls.SETTINGS.get(setting)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_settings_by_category(cls, category: SettingCategory) -> Dict[str, SettingDefinition]:
|
def get_settings_by_category(
|
||||||
|
cls, category: SettingCategory
|
||||||
|
) -> Dict[str, SettingDefinition]:
|
||||||
"""
|
"""
|
||||||
Get all settings in a category.
|
Get all settings in a category.
|
||||||
|
|
||||||
@@ -252,18 +265,15 @@ class Settings:
|
|||||||
raise ConfigurationError(
|
raise ConfigurationError(
|
||||||
f"Unknown setting: {setting}",
|
f"Unknown setting: {setting}",
|
||||||
context=ErrorContext(
|
context=ErrorContext(
|
||||||
"Settings",
|
"Settings", "validation", {"setting": setting}, ErrorSeverity.HIGH
|
||||||
"validation",
|
),
|
||||||
{"setting": setting},
|
|
||||||
ErrorSeverity.HIGH
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
details = {
|
details = {
|
||||||
"setting": setting,
|
"setting": setting,
|
||||||
"value": value,
|
"value": value,
|
||||||
"type": type(value).__name__,
|
"type": type(value).__name__,
|
||||||
"expected_type": definition.data_type.__name__
|
"expected_type": definition.data_type.__name__,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check type
|
# Check type
|
||||||
@@ -271,15 +281,13 @@ class Settings:
|
|||||||
return ValidationResult(
|
return ValidationResult(
|
||||||
valid=False,
|
valid=False,
|
||||||
error=f"Invalid type: expected {definition.data_type.__name__}, got {type(value).__name__}",
|
error=f"Invalid type: expected {definition.data_type.__name__}, got {type(value).__name__}",
|
||||||
details=details
|
details=details,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check required
|
# Check required
|
||||||
if definition.required and value is None:
|
if definition.required and value is None:
|
||||||
return ValidationResult(
|
return ValidationResult(
|
||||||
valid=False,
|
valid=False, error="Required setting cannot be None", details=details
|
||||||
error="Required setting cannot be None",
|
|
||||||
details=details
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check choices
|
# Check choices
|
||||||
@@ -287,7 +295,7 @@ class Settings:
|
|||||||
return ValidationResult(
|
return ValidationResult(
|
||||||
valid=False,
|
valid=False,
|
||||||
error=f"Value must be one of: {', '.join(map(str, definition.choices))}",
|
error=f"Value must be one of: {', '.join(map(str, definition.choices))}",
|
||||||
details=details
|
details=details,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check numeric bounds
|
# Check numeric bounds
|
||||||
@@ -296,13 +304,13 @@ class Settings:
|
|||||||
return ValidationResult(
|
return ValidationResult(
|
||||||
valid=False,
|
valid=False,
|
||||||
error=f"Value must be at least {definition.min_value}",
|
error=f"Value must be at least {definition.min_value}",
|
||||||
details=details
|
details=details,
|
||||||
)
|
)
|
||||||
if definition.max_value is not None and value > definition.max_value:
|
if definition.max_value is not None and value > definition.max_value:
|
||||||
return ValidationResult(
|
return ValidationResult(
|
||||||
valid=False,
|
valid=False,
|
||||||
error=f"Value must be at most {definition.max_value}",
|
error=f"Value must be at most {definition.max_value}",
|
||||||
details=details
|
details=details,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Custom validation
|
# Custom validation
|
||||||
@@ -313,20 +321,12 @@ class Settings:
|
|||||||
return ValidationResult(
|
return ValidationResult(
|
||||||
valid=False,
|
valid=False,
|
||||||
error=definition.error_message or "Validation failed",
|
error=definition.error_message or "Validation failed",
|
||||||
details=details
|
details=details,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return ValidationResult(
|
return ValidationResult(valid=False, error=str(e), details=details)
|
||||||
valid=False,
|
|
||||||
error=str(e),
|
|
||||||
details=details
|
|
||||||
)
|
|
||||||
|
|
||||||
return ValidationResult(
|
return ValidationResult(valid=True, error=None, details=details)
|
||||||
valid=True,
|
|
||||||
error=None,
|
|
||||||
details=details
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def default_guild_settings(self) -> Dict[str, Any]:
|
def default_guild_settings(self) -> Dict[str, Any]:
|
||||||
@@ -337,8 +337,7 @@ class Settings:
|
|||||||
Dictionary of default settings
|
Dictionary of default settings
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
name: definition.default_value
|
name: definition.default_value for name, definition in self.SETTINGS.items()
|
||||||
for name, definition in self.SETTINGS.items()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -362,7 +361,7 @@ class Settings:
|
|||||||
f"Description: {definition.description}",
|
f"Description: {definition.description}",
|
||||||
f"Type: {definition.data_type.__name__}",
|
f"Type: {definition.data_type.__name__}",
|
||||||
f"Required: {definition.required}",
|
f"Required: {definition.required}",
|
||||||
f"Default: {definition.default_value}"
|
f"Default: {definition.default_value}",
|
||||||
]
|
]
|
||||||
|
|
||||||
if definition.choices:
|
if definition.choices:
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
"""Database management package for video archiving"""
|
"""Database management package for video archiving"""
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .connection_manager import DatabaseConnectionManager
|
from .connection_manager import DatabaseConnectionManager
|
||||||
from .query_manager import DatabaseQueryManager
|
from .query_manager import DatabaseQueryManager
|
||||||
from .schema_manager import DatabaseSchemaManager
|
from .schema_manager import DatabaseSchemaManager
|
||||||
from .video_archive_db import VideoArchiveDB
|
from .video_archive_db import VideoArchiveDB
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.database.connection_manager import DatabaseConnectionManager
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.database.query_manager import DatabaseQueryManager
|
# from videoarchiver.database.connection_manager import DatabaseConnectionManager
|
||||||
# from videoarchiver.database.schema_manager import DatabaseSchemaManager
|
# from videoarchiver.database.query_manager import DatabaseQueryManager
|
||||||
# from videoarchiver.database.video_archive_db import VideoArchiveDB
|
# from videoarchiver.database.schema_manager import DatabaseSchemaManager
|
||||||
|
# from videoarchiver.database.video_archive_db import VideoArchiveDB
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'DatabaseConnectionManager',
|
"DatabaseConnectionManager",
|
||||||
'DatabaseQueryManager',
|
"DatabaseQueryManager",
|
||||||
'DatabaseSchemaManager',
|
"DatabaseSchemaManager",
|
||||||
'VideoArchiveDB'
|
"VideoArchiveDB",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ import threading
|
|||||||
from queue import Queue, Empty
|
from queue import Queue, Empty
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.exceptions import DatabaseError, ErrorContext, ErrorSeverity
|
from ..utils.exceptions import DatabaseError, ErrorContext, ErrorSeverity
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.utils.exceptions import DatabaseError, ErrorContext, ErrorSeverity
|
# from videoarchiver.utils.exceptions import DatabaseError, ErrorContext, ErrorSeverity
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ from typing import List, Dict, Any, Optional, TypedDict, ClassVar, Union
|
|||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.exceptions import DatabaseError, ErrorContext, ErrorSeverity
|
from ..utils.exceptions import DatabaseError, ErrorContext, ErrorSeverity
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.utils.exceptions import DatabaseError, ErrorContext, ErrorSeverity
|
# from videoarchiver.utils.exceptions import DatabaseError, ErrorContext, ErrorSeverity
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,17 @@ import logging
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, Dict, Any, List
|
from typing import Optional, Dict, Any, List
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .schema_manager import DatabaseSchemaManager
|
from .schema_manager import DatabaseSchemaManager
|
||||||
from .query_manager import DatabaseQueryManager
|
from .query_manager import DatabaseQueryManager
|
||||||
from .connection_manager import DatabaseConnectionManager
|
from .connection_manager import DatabaseConnectionManager
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.database.schema_manager import DatabaseSchemaManager
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.database.query_manager import DatabaseQueryManager
|
# from videoarchiver.database.schema_manager import DatabaseSchemaManager
|
||||||
# from videoarchiver.database.connection_manager import DatabaseConnectionManager
|
# from videoarchiver.database.query_manager import DatabaseQueryManager
|
||||||
|
# from videoarchiver.database.connection_manager import DatabaseConnectionManager
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiverDB")
|
logger = logging.getLogger("VideoArchiverDB")
|
||||||
|
|
||||||
|
|||||||
@@ -18,33 +18,33 @@ logging.basicConfig(
|
|||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
# Import components after logging is configured
|
# Import components after logging is configured
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .ffmpeg_manager import FFmpegManager
|
from .ffmpeg_manager import FFmpegManager
|
||||||
from .video_analyzer import VideoAnalyzer
|
from .video_analyzer import VideoAnalyzer
|
||||||
from .gpu_detector import GPUDetector
|
from .gpu_detector import GPUDetector
|
||||||
from .encoder_params import EncoderParams
|
from .encoder_params import EncoderParams
|
||||||
from .ffmpeg_downloader import FFmpegDownloader
|
from .ffmpeg_downloader import FFmpegDownloader
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
FFmpegError,
|
FFmpegError,
|
||||||
DownloadError,
|
DownloadError,
|
||||||
VerificationError,
|
VerificationError,
|
||||||
EncodingError,
|
EncodingError,
|
||||||
AnalysisError,
|
AnalysisError,
|
||||||
GPUError,
|
GPUError,
|
||||||
HardwareAccelerationError,
|
HardwareAccelerationError,
|
||||||
FFmpegNotFoundError,
|
FFmpegNotFoundError,
|
||||||
FFprobeError,
|
FFprobeError,
|
||||||
CompressionError,
|
CompressionError,
|
||||||
FormatError,
|
FormatError,
|
||||||
PermissionError,
|
PermissionError,
|
||||||
TimeoutError,
|
TimeoutError,
|
||||||
ResourceError,
|
ResourceError,
|
||||||
QualityError,
|
QualityError,
|
||||||
AudioError,
|
AudioError,
|
||||||
BitrateError,
|
BitrateError,
|
||||||
)
|
)
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager
|
# from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager
|
||||||
# from videoarchiver.ffmpeg.video_analyzer import VideoAnalyzer
|
# from videoarchiver.ffmpeg.video_analyzer import VideoAnalyzer
|
||||||
@@ -52,24 +52,24 @@ except ImportError:
|
|||||||
# from videoarchiver.ffmpeg.encoder_params import EncoderParams
|
# from videoarchiver.ffmpeg.encoder_params import EncoderParams
|
||||||
# from videoarchiver.ffmpeg.ffmpeg_downloader import FFmpegDownloader
|
# from videoarchiver.ffmpeg.ffmpeg_downloader import FFmpegDownloader
|
||||||
# from videoarchiver.ffmpeg.exceptions import (
|
# from videoarchiver.ffmpeg.exceptions import (
|
||||||
FFmpegError,
|
# FFmpegError,
|
||||||
DownloadError,
|
# DownloadError,
|
||||||
VerificationError,
|
# VerificationError,
|
||||||
EncodingError,
|
# EncodingError,
|
||||||
AnalysisError,
|
# AnalysisError,
|
||||||
GPUError,
|
# GPUError,
|
||||||
HardwareAccelerationError,
|
# HardwareAccelerationError,
|
||||||
FFmpegNotFoundError,
|
# FFmpegNotFoundError,
|
||||||
FFprobeError,
|
# FFprobeError,
|
||||||
CompressionError,
|
# CompressionError,
|
||||||
FormatError,
|
# FormatError,
|
||||||
PermissionError,
|
# PermissionError,
|
||||||
TimeoutError,
|
# TimeoutError,
|
||||||
ResourceError,
|
# ResourceError,
|
||||||
QualityError,
|
# QualityError,
|
||||||
AudioError,
|
# AudioError,
|
||||||
BitrateError,
|
# BitrateError,
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
class FFmpeg:
|
class FFmpeg:
|
||||||
|
|||||||
@@ -5,26 +5,26 @@ import os
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
FFmpegError,
|
FFmpegError,
|
||||||
DownloadError,
|
DownloadError,
|
||||||
VerificationError,
|
VerificationError,
|
||||||
PermissionError,
|
PermissionError,
|
||||||
FFmpegNotFoundError
|
FFmpegNotFoundError
|
||||||
)
|
)
|
||||||
from .ffmpeg_downloader import FFmpegDownloader
|
from .ffmpeg_downloader import FFmpegDownloader
|
||||||
from .verification_manager import VerificationManager
|
from .verification_manager import VerificationManager
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.ffmpeg.exceptions import (
|
# from videoarchiver.ffmpeg.exceptions import (
|
||||||
FFmpegError,
|
# FFmpegError,
|
||||||
DownloadError,
|
# DownloadError,
|
||||||
VerificationError,
|
# VerificationError,
|
||||||
PermissionError,
|
# PermissionError,
|
||||||
FFmpegNotFoundError
|
# FFmpegNotFoundError
|
||||||
)
|
# )
|
||||||
# from videoarchiver.ffmpeg.ffmpeg_downloader import FFmpegDownloader
|
# from videoarchiver.ffmpeg.ffmpeg_downloader import FFmpegDownloader
|
||||||
# from videoarchiver.ffmpeg.verification_manager import VerificationManager
|
# from videoarchiver.ffmpeg.verification_manager import VerificationManager
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import os
|
|||||||
import logging
|
import logging
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
|
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import CompressionError, QualityError, BitrateError
|
from .exceptions import CompressionError, QualityError, BitrateError
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.ffmpeg.exceptions import CompressionError, QualityError, BitrateError
|
# from videoarchiver.ffmpeg.exceptions import CompressionError, QualityError, BitrateError
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ from typing import Optional, Dict, List
|
|||||||
import time
|
import time
|
||||||
import lzma
|
import lzma
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import DownloadError
|
from .exceptions import DownloadError
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.ffmpeg.exceptions import DownloadError
|
# Fall back to absolute imports if relative imports fail
|
||||||
|
# from videoarchiver.ffmpeg.exceptions import DownloadError
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
@@ -249,14 +250,16 @@ class FFmpegDownloader:
|
|||||||
binary_files = [
|
binary_files = [
|
||||||
f
|
f
|
||||||
for f in zip_ref.namelist()
|
for f in zip_ref.namelist()
|
||||||
if f.endswith(f"/bin/{binary_name}") or f.endswith(f"\\bin\\{binary_name}")
|
if f.endswith(f"/bin/{binary_name}")
|
||||||
|
or f.endswith(f"\\bin\\{binary_name}")
|
||||||
]
|
]
|
||||||
if not binary_files:
|
if not binary_files:
|
||||||
# Fallback to old structure
|
# Fallback to old structure
|
||||||
binary_files = [
|
binary_files = [
|
||||||
f
|
f
|
||||||
for f in zip_ref.namelist()
|
for f in zip_ref.namelist()
|
||||||
if f.endswith(f"/{binary_name}") or f.endswith(f"\\{binary_name}")
|
if f.endswith(f"/{binary_name}")
|
||||||
|
or f.endswith(f"\\{binary_name}")
|
||||||
]
|
]
|
||||||
if not binary_files:
|
if not binary_files:
|
||||||
raise DownloadError(f"{binary_name} not found in archive")
|
raise DownloadError(f"{binary_name} not found in archive")
|
||||||
@@ -271,10 +274,10 @@ class FFmpegDownloader:
|
|||||||
"""Extract from tar archive (Linux/macOS)"""
|
"""Extract from tar archive (Linux/macOS)"""
|
||||||
try:
|
try:
|
||||||
# First decompress the .xz file in chunks to prevent blocking
|
# First decompress the .xz file in chunks to prevent blocking
|
||||||
decompressed_path = archive_path.with_suffix('')
|
decompressed_path = archive_path.with_suffix("")
|
||||||
chunk_size = 1024 * 1024 # 1MB chunks
|
chunk_size = 1024 * 1024 # 1MB chunks
|
||||||
with lzma.open(archive_path, 'rb') as compressed:
|
with lzma.open(archive_path, "rb") as compressed:
|
||||||
with open(decompressed_path, 'wb') as decompressed:
|
with open(decompressed_path, "wb") as decompressed:
|
||||||
while True:
|
while True:
|
||||||
chunk = compressed.read(chunk_size)
|
chunk = compressed.read(chunk_size)
|
||||||
if not chunk:
|
if not chunk:
|
||||||
@@ -289,12 +292,16 @@ class FFmpegDownloader:
|
|||||||
for binary_name in binary_names:
|
for binary_name in binary_names:
|
||||||
# BtbN's builds have binaries in bin directory
|
# BtbN's builds have binaries in bin directory
|
||||||
binary_files = [
|
binary_files = [
|
||||||
f for f in tar_ref.getnames() if f.endswith(f"/bin/{binary_name}")
|
f
|
||||||
|
for f in tar_ref.getnames()
|
||||||
|
if f.endswith(f"/bin/{binary_name}")
|
||||||
]
|
]
|
||||||
if not binary_files:
|
if not binary_files:
|
||||||
# Fallback to old structure
|
# Fallback to old structure
|
||||||
binary_files = [
|
binary_files = [
|
||||||
f for f in tar_ref.getnames() if f.endswith(f"/{binary_name}")
|
f
|
||||||
|
for f in tar_ref.getnames()
|
||||||
|
if f.endswith(f"/{binary_name}")
|
||||||
]
|
]
|
||||||
if not binary_files:
|
if not binary_files:
|
||||||
raise DownloadError(f"{binary_name} not found in archive")
|
raise DownloadError(f"{binary_name} not found in archive")
|
||||||
@@ -306,7 +313,9 @@ class FFmpegDownloader:
|
|||||||
target_path = self.base_dir / binary_name
|
target_path = self.base_dir / binary_name
|
||||||
|
|
||||||
# Copy file in chunks
|
# Copy file in chunks
|
||||||
with open(extracted_path, 'rb') as src, open(target_path, 'wb') as dst:
|
with open(extracted_path, "rb") as src, open(
|
||||||
|
target_path, "wb"
|
||||||
|
) as dst:
|
||||||
while True:
|
while True:
|
||||||
chunk = src.read(chunk_size)
|
chunk = src.read(chunk_size)
|
||||||
if not chunk:
|
if not chunk:
|
||||||
@@ -350,7 +359,7 @@ class FFmpegDownloader:
|
|||||||
timeout=5,
|
timeout=5,
|
||||||
text=True,
|
text=True,
|
||||||
check=False, # Don't raise on non-zero return code
|
check=False, # Don't raise on non-zero return code
|
||||||
env={"PATH": os.environ.get("PATH", "")} # Ensure PATH is set
|
env={"PATH": os.environ.get("PATH", "")}, # Ensure PATH is set
|
||||||
)
|
)
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
logger.error("FFmpeg verification timed out")
|
logger.error("FFmpeg verification timed out")
|
||||||
@@ -368,7 +377,7 @@ class FFmpegDownloader:
|
|||||||
timeout=5,
|
timeout=5,
|
||||||
text=True,
|
text=True,
|
||||||
check=False, # Don't raise on non-zero return code
|
check=False, # Don't raise on non-zero return code
|
||||||
env={"PATH": os.environ.get("PATH", "")} # Ensure PATH is set
|
env={"PATH": os.environ.get("PATH", "")}, # Ensure PATH is set
|
||||||
)
|
)
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
logger.error("FFprobe verification timed out")
|
logger.error("FFprobe verification timed out")
|
||||||
|
|||||||
@@ -6,32 +6,29 @@ import multiprocessing
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Any, Optional
|
from typing import Dict, Any, Optional
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import (
|
from .exceptions import FFmpegError, AnalysisError, FFmpegNotFoundError
|
||||||
FFmpegError,
|
from .gpu_detector import GPUDetector
|
||||||
AnalysisError,
|
from .video_analyzer import VideoAnalyzer
|
||||||
FFmpegNotFoundError
|
from .encoder_params import EncoderParams
|
||||||
)
|
from .process_manager import ProcessManager
|
||||||
from .gpu_detector import GPUDetector
|
from .verification_manager import VerificationManager
|
||||||
from .video_analyzer import VideoAnalyzer
|
from .binary_manager import BinaryManager
|
||||||
from .encoder_params import EncoderParams
|
|
||||||
from .process_manager import ProcessManager
|
# except ImportError:
|
||||||
from .verification_manager import VerificationManager
|
# Fall back to absolute imports if relative imports fail
|
||||||
from .binary_manager import BinaryManager
|
# from videoarchiver.ffmpeg.exceptions import (
|
||||||
except ImportError:
|
# FFmpegError,
|
||||||
# Fall back to absolute imports if relative imports fail
|
# AnalysisError,
|
||||||
# from videoarchiver.ffmpeg.exceptions import (
|
# FFmpegNotFoundError
|
||||||
FFmpegError,
|
# )
|
||||||
AnalysisError,
|
# from videoarchiver.ffmpeg.gpu_detector import GPUDetector
|
||||||
FFmpegNotFoundError
|
# from videoarchiver.ffmpeg.video_analyzer import VideoAnalyzer
|
||||||
)
|
# from videoarchiver.ffmpeg.encoder_params import EncoderParams
|
||||||
# from videoarchiver.ffmpeg.gpu_detector import GPUDetector
|
# from videoarchiver.ffmpeg.process_manager import ProcessManager
|
||||||
# from videoarchiver.ffmpeg.video_analyzer import VideoAnalyzer
|
# from videoarchiver.ffmpeg.verification_manager import VerificationManager
|
||||||
# from videoarchiver.ffmpeg.encoder_params import EncoderParams
|
# from videoarchiver.ffmpeg.binary_manager import BinaryManager
|
||||||
# from videoarchiver.ffmpeg.process_manager import ProcessManager
|
|
||||||
# from videoarchiver.ffmpeg.verification_manager import VerificationManager
|
|
||||||
# from videoarchiver.ffmpeg.binary_manager import BinaryManager
|
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
@@ -53,7 +50,7 @@ class FFmpegManager:
|
|||||||
base_dir=self.base_dir,
|
base_dir=self.base_dir,
|
||||||
system=platform.system(),
|
system=platform.system(),
|
||||||
machine=platform.machine(),
|
machine=platform.machine(),
|
||||||
verification_manager=self.verification_manager
|
verification_manager=self.verification_manager,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Initialize components
|
# Initialize components
|
||||||
@@ -87,7 +84,9 @@ class FFmpegManager:
|
|||||||
raise
|
raise
|
||||||
raise AnalysisError(f"Failed to analyze video: {e}")
|
raise AnalysisError(f"Failed to analyze video: {e}")
|
||||||
|
|
||||||
def get_compression_params(self, input_path: str, target_size_mb: int) -> Dict[str, str]:
|
def get_compression_params(
|
||||||
|
self, input_path: str, target_size_mb: int
|
||||||
|
) -> Dict[str, str]:
|
||||||
"""Get optimal compression parameters for the given input file"""
|
"""Get optimal compression parameters for the given input file"""
|
||||||
try:
|
try:
|
||||||
# Analyze video first
|
# Analyze video first
|
||||||
@@ -113,7 +112,7 @@ class FFmpegManager:
|
|||||||
"preset": "medium",
|
"preset": "medium",
|
||||||
"crf": "23",
|
"crf": "23",
|
||||||
"c:a": "aac",
|
"c:a": "aac",
|
||||||
"b:a": "128k"
|
"b:a": "128k",
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_ffmpeg_path(self) -> str:
|
def get_ffmpeg_path(self) -> str:
|
||||||
|
|||||||
@@ -6,22 +6,23 @@ import subprocess
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
TimeoutError,
|
TimeoutError,
|
||||||
VerificationError,
|
VerificationError,
|
||||||
EncodingError,
|
EncodingError,
|
||||||
handle_ffmpeg_error
|
handle_ffmpeg_error,
|
||||||
)
|
)
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.ffmpeg.exceptions import (
|
# Fall back to absolute imports if relative imports fail
|
||||||
TimeoutError,
|
# from videoarchiver.ffmpeg.exceptions import (
|
||||||
VerificationError,
|
# TimeoutError,
|
||||||
EncodingError,
|
# VerificationError,
|
||||||
handle_ffmpeg_error
|
# EncodingError,
|
||||||
)
|
# handle_ffmpeg_error
|
||||||
|
# )
|
||||||
|
|
||||||
logger = logging.getLogger("FFmpegVerification")
|
logger = logging.getLogger("FFmpegVerification")
|
||||||
|
|
||||||
@@ -33,10 +34,7 @@ class VerificationManager:
|
|||||||
self.process_manager = process_manager
|
self.process_manager = process_manager
|
||||||
|
|
||||||
def verify_ffmpeg(
|
def verify_ffmpeg(
|
||||||
self,
|
self, ffmpeg_path: Path, ffprobe_path: Path, gpu_info: Dict[str, bool]
|
||||||
ffmpeg_path: Path,
|
|
||||||
ffprobe_path: Path,
|
|
||||||
gpu_info: Dict[str, bool]
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Verify FFmpeg functionality with comprehensive checks
|
"""Verify FFmpeg functionality with comprehensive checks
|
||||||
|
|
||||||
@@ -72,8 +70,7 @@ class VerificationManager:
|
|||||||
"""Verify FFmpeg version"""
|
"""Verify FFmpeg version"""
|
||||||
try:
|
try:
|
||||||
result = self._execute_command(
|
result = self._execute_command(
|
||||||
[str(ffmpeg_path), "-version"],
|
[str(ffmpeg_path), "-version"], "FFmpeg version check"
|
||||||
"FFmpeg version check"
|
|
||||||
)
|
)
|
||||||
logger.info(f"FFmpeg version: {result.stdout.split()[2]}")
|
logger.info(f"FFmpeg version: {result.stdout.split()[2]}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -83,23 +80,20 @@ class VerificationManager:
|
|||||||
"""Verify FFprobe version"""
|
"""Verify FFprobe version"""
|
||||||
try:
|
try:
|
||||||
result = self._execute_command(
|
result = self._execute_command(
|
||||||
[str(ffprobe_path), "-version"],
|
[str(ffprobe_path), "-version"], "FFprobe version check"
|
||||||
"FFprobe version check"
|
|
||||||
)
|
)
|
||||||
logger.info(f"FFprobe version: {result.stdout.split()[2]}")
|
logger.info(f"FFprobe version: {result.stdout.split()[2]}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise VerificationError(f"FFprobe version check failed: {e}")
|
raise VerificationError(f"FFprobe version check failed: {e}")
|
||||||
|
|
||||||
def _verify_ffmpeg_capabilities(
|
def _verify_ffmpeg_capabilities(
|
||||||
self,
|
self, ffmpeg_path: Path, gpu_info: Dict[str, bool]
|
||||||
ffmpeg_path: Path,
|
|
||||||
gpu_info: Dict[str, bool]
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Verify FFmpeg capabilities and encoders"""
|
"""Verify FFmpeg capabilities and encoders"""
|
||||||
try:
|
try:
|
||||||
result = self._execute_command(
|
result = self._execute_command(
|
||||||
[str(ffmpeg_path), "-hide_banner", "-encoders"],
|
[str(ffmpeg_path), "-hide_banner", "-encoders"],
|
||||||
"FFmpeg capabilities check"
|
"FFmpeg capabilities check",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Verify required encoders
|
# Verify required encoders
|
||||||
@@ -107,7 +101,8 @@ class VerificationManager:
|
|||||||
available_encoders = result.stdout.lower()
|
available_encoders = result.stdout.lower()
|
||||||
|
|
||||||
missing_encoders = [
|
missing_encoders = [
|
||||||
encoder for encoder in required_encoders
|
encoder
|
||||||
|
for encoder in required_encoders
|
||||||
if encoder not in available_encoders
|
if encoder not in available_encoders
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -122,17 +117,12 @@ class VerificationManager:
|
|||||||
raise VerificationError(f"FFmpeg capabilities check failed: {e}")
|
raise VerificationError(f"FFmpeg capabilities check failed: {e}")
|
||||||
|
|
||||||
def _execute_command(
|
def _execute_command(
|
||||||
self,
|
self, command: List[str], operation: str, timeout: int = 10
|
||||||
command: List[str],
|
|
||||||
operation: str,
|
|
||||||
timeout: int = 10
|
|
||||||
) -> subprocess.CompletedProcess:
|
) -> subprocess.CompletedProcess:
|
||||||
"""Execute a command with proper error handling"""
|
"""Execute a command with proper error handling"""
|
||||||
try:
|
try:
|
||||||
result = self.process_manager.execute_command(
|
result = self.process_manager.execute_command(
|
||||||
command,
|
command, timeout=timeout, check=False
|
||||||
timeout=timeout,
|
|
||||||
check=False
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
|
|||||||
@@ -8,10 +8,17 @@ from typing import Any, ClassVar, Dict, List, Optional, Tuple, TYPE_CHECKING
|
|||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
from discord.ext import commands # type: ignore
|
from discord.ext import commands # type: ignore
|
||||||
|
|
||||||
# from videoarchiver.core.types import ComponentState, ProcessorState, ComponentStatus, IComponent, IConfigManager, IQueueManager
|
from ..core.types import (
|
||||||
# from videoarchiver.processor.constants import REACTIONS
|
ComponentState,
|
||||||
# from videoarchiver.utils.progress_tracker import ProgressTracker
|
ProcessorState,
|
||||||
# from videoarchiver.utils.exceptions import ProcessorError
|
ComponentStatus,
|
||||||
|
IComponent,
|
||||||
|
IConfigManager,
|
||||||
|
IQueueManager,
|
||||||
|
)
|
||||||
|
from .constants import REACTIONS
|
||||||
|
from ..utils.progress_tracker import ProgressTracker
|
||||||
|
from ..utils.exceptions import ProcessorError
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
@@ -45,11 +52,13 @@ class OperationTracker:
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""End tracking an operation"""
|
"""End tracking an operation"""
|
||||||
if op_id in self.operations:
|
if op_id in self.operations:
|
||||||
self.operations[op_id].update({
|
self.operations[op_id].update(
|
||||||
"end_time": datetime.utcnow(),
|
{
|
||||||
"status": "success" if success else "error",
|
"end_time": datetime.utcnow(),
|
||||||
"error": error,
|
"status": "success" if success else "error",
|
||||||
})
|
"error": error,
|
||||||
|
}
|
||||||
|
)
|
||||||
# Move to history
|
# Move to history
|
||||||
self.operation_history.append(self.operations.pop(op_id))
|
self.operation_history.append(self.operations.pop(op_id))
|
||||||
# Update counts
|
# Update counts
|
||||||
@@ -60,7 +69,7 @@ class OperationTracker:
|
|||||||
|
|
||||||
# Cleanup old history if needed
|
# Cleanup old history if needed
|
||||||
if len(self.operation_history) > self.MAX_HISTORY:
|
if len(self.operation_history) > self.MAX_HISTORY:
|
||||||
self.operation_history = self.operation_history[-self.MAX_HISTORY:]
|
self.operation_history = self.operation_history[-self.MAX_HISTORY :]
|
||||||
|
|
||||||
def get_active_operations(self) -> Dict[str, Dict[str, Any]]:
|
def get_active_operations(self) -> Dict[str, Dict[str, Any]]:
|
||||||
"""Get currently active operations"""
|
"""Get currently active operations"""
|
||||||
@@ -114,11 +123,13 @@ class HealthMonitor:
|
|||||||
self.last_check = datetime.utcnow()
|
self.last_check = datetime.utcnow()
|
||||||
|
|
||||||
# Check component health
|
# Check component health
|
||||||
self.health_status.update({
|
self.health_status.update(
|
||||||
"queue_handler": self.processor.queue_handler.is_healthy(),
|
{
|
||||||
"message_handler": self.processor.message_handler.is_healthy(),
|
"queue_handler": self.processor.queue_handler.is_healthy(),
|
||||||
"progress_tracker": self.progress_tracker.is_healthy(),
|
"message_handler": self.processor.message_handler.is_healthy(),
|
||||||
})
|
"progress_tracker": self.progress_tracker.is_healthy(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# Check operation health
|
# Check operation health
|
||||||
op_stats = self.processor.operation_tracker.get_operation_stats()
|
op_stats = self.processor.operation_tracker.get_operation_stats()
|
||||||
@@ -168,8 +179,12 @@ class VideoProcessor(IComponent):
|
|||||||
from .cleanup_manager import CleanupManager, CleanupStrategy
|
from .cleanup_manager import CleanupManager, CleanupStrategy
|
||||||
|
|
||||||
# Initialize handlers
|
# Initialize handlers
|
||||||
self.queue_handler: "QueueHandler" = QueueHandler(bot, config_manager, components)
|
self.queue_handler: "QueueHandler" = QueueHandler(
|
||||||
self.message_handler: "MessageHandler" = MessageHandler(bot, config_manager, queue_manager)
|
bot, config_manager, components
|
||||||
|
)
|
||||||
|
self.message_handler: "MessageHandler" = MessageHandler(
|
||||||
|
bot, config_manager, queue_manager
|
||||||
|
)
|
||||||
self.cleanup_manager: "CleanupManager" = CleanupManager(
|
self.cleanup_manager: "CleanupManager" = CleanupManager(
|
||||||
self.queue_handler, ffmpeg_mgr, CleanupStrategy.NORMAL
|
self.queue_handler, ffmpeg_mgr, CleanupStrategy.NORMAL
|
||||||
)
|
)
|
||||||
@@ -243,9 +258,7 @@ class VideoProcessor(IComponent):
|
|||||||
|
|
||||||
async def cleanup(self) -> None:
|
async def cleanup(self) -> None:
|
||||||
"""Clean up resources and stop processing"""
|
"""Clean up resources and stop processing"""
|
||||||
op_id = self.operation_tracker.start_operation(
|
op_id = self.operation_tracker.start_operation("cleanup", {"type": "normal"})
|
||||||
"cleanup", {"type": "normal"}
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._state = ProcessorState.SHUTDOWN
|
self._state = ProcessorState.SHUTDOWN
|
||||||
@@ -260,9 +273,7 @@ class VideoProcessor(IComponent):
|
|||||||
|
|
||||||
async def force_cleanup(self) -> None:
|
async def force_cleanup(self) -> None:
|
||||||
"""Force cleanup of resources"""
|
"""Force cleanup of resources"""
|
||||||
op_id = self.operation_tracker.start_operation(
|
op_id = self.operation_tracker.start_operation("cleanup", {"type": "force"})
|
||||||
"cleanup", {"type": "force"}
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._state = ProcessorState.SHUTDOWN
|
self._state = ProcessorState.SHUTDOWN
|
||||||
@@ -321,5 +332,5 @@ class VideoProcessor(IComponent):
|
|||||||
"operations": self.operation_tracker.get_operation_stats(),
|
"operations": self.operation_tracker.get_operation_stats(),
|
||||||
"active_operations": self.operation_tracker.get_active_operations(),
|
"active_operations": self.operation_tracker.get_active_operations(),
|
||||||
"health_status": self.health_monitor.health_status,
|
"health_status": self.health_monitor.health_status,
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,33 +4,45 @@ import asyncio
|
|||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from enum import auto, Enum
|
from enum import auto, Enum
|
||||||
from typing import Any, ClassVar, Dict, List, Optional, Set, Tuple, TypedDict, TYPE_CHECKING
|
from typing import (
|
||||||
|
Any,
|
||||||
|
ClassVar,
|
||||||
|
Dict,
|
||||||
|
List,
|
||||||
|
Optional,
|
||||||
|
Set,
|
||||||
|
Tuple,
|
||||||
|
TypedDict,
|
||||||
|
TYPE_CHECKING,
|
||||||
|
)
|
||||||
|
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
from discord.ext import commands # type: ignore
|
from discord.ext import commands # type: ignore
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..config_manager import ConfigManager
|
from ..config_manager import ConfigManager
|
||||||
from .constants import REACTIONS
|
from .constants import REACTIONS
|
||||||
from .message_validator import MessageValidator, ValidationError
|
from .message_validator import MessageValidator, ValidationError
|
||||||
from .url_extractor import URLExtractor, URLMetadata
|
from .url_extractor import URLExtractor, URLMetadata
|
||||||
from ..queue.types import QueuePriority
|
from ..queue.types import QueuePriority
|
||||||
from ..utils.exceptions import MessageHandlerError
|
from ..utils.exceptions import MessageHandlerError
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.config_manager import ConfigManager
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.processor.constants import REACTIONS
|
# from videoarchiver.config_manager import ConfigManager
|
||||||
# from videoarchiver.processor.message_validator import MessageValidator, ValidationError
|
# from videoarchiver.processor.constants import REACTIONS
|
||||||
# from videoarchiver.processor.url_extractor import URLExtractor, URLMetadata
|
# from videoarchiver.processor.message_validator import MessageValidator, ValidationError
|
||||||
# from videoarchiver.queue.types import QueuePriority
|
# from videoarchiver.processor.url_extractor import URLExtractor, URLMetadata
|
||||||
# from videoarchiver.utils.exceptions import MessageHandlerError
|
# from videoarchiver.queue.types import QueuePriority
|
||||||
|
# from videoarchiver.utils.exceptions import MessageHandlerError
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
try:
|
# try:
|
||||||
from ..queue.manager import EnhancedVideoQueueManager
|
from ..queue.manager import EnhancedVideoQueueManager
|
||||||
except ImportError:
|
|
||||||
# from videoarchiver.queue.manager import EnhancedVideoQueueManager
|
# except ImportError:
|
||||||
|
# from videoarchiver.queue.manager import EnhancedVideoQueueManager
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
@@ -337,7 +349,7 @@ class MessageHandler:
|
|||||||
channel_id=message.channel.id,
|
channel_id=message.channel.id,
|
||||||
guild_id=message.guild.id,
|
guild_id=message.guild.id,
|
||||||
author_id=message.author.id,
|
author_id=message.author.id,
|
||||||
priority=QueuePriority.NORMAL.value
|
priority=QueuePriority.NORMAL.value,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MessageHandlerError(f"Queue processing failed: {str(e)}")
|
raise MessageHandlerError(f"Queue processing failed: {str(e)}")
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ from typing import Dict, Optional, Tuple, List, Any, Callable, Set, TypedDict, C
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
|
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.exceptions import ValidationError
|
from ..utils.exceptions import ValidationError
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.utils.exceptions import ValidationError
|
# from videoarchiver.utils.exceptions import ValidationError
|
||||||
|
|
||||||
|
|||||||
@@ -8,27 +8,28 @@ from typing import Optional, Dict, Any, List, Tuple, Set, TypedDict, ClassVar, C
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .. import utils
|
from .. import utils
|
||||||
from ..database.video_archive_db import VideoArchiveDB
|
from ..database.video_archive_db import VideoArchiveDB
|
||||||
from ..utils.download_manager import DownloadManager
|
from ..utils.download_manager import DownloadManager
|
||||||
from ..utils.message_manager import MessageManager
|
from ..utils.message_manager import MessageManager
|
||||||
from ..utils.exceptions import QueueHandlerError
|
from ..utils.exceptions import QueueHandlerError
|
||||||
from ..queue.models import QueueItem
|
from ..queue.models import QueueItem
|
||||||
from ..config_manager import ConfigManager
|
from ..config_manager import ConfigManager
|
||||||
from . import progress_tracker # Import from processor package
|
from . import progress_tracker # Import from processor package
|
||||||
from .constants import REACTIONS
|
from .constants import REACTIONS
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.database.video_archive_db import VideoArchiveDB
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.utils.download_manager import DownloadManager
|
# from videoarchiver.database.video_archive_db import VideoArchiveDB
|
||||||
# from videoarchiver.utils.message_manager import MessageManager
|
# from videoarchiver.utils.download_manager import DownloadManager
|
||||||
# from videoarchiver.utils.exceptions import QueueHandlerError
|
# from videoarchiver.utils.message_manager import MessageManager
|
||||||
# from videoarchiver.queue.models import QueueItem
|
# from videoarchiver.utils.exceptions import QueueHandlerError
|
||||||
# from videoarchiver.config_manager import ConfigManager
|
# from videoarchiver.queue.models import QueueItem
|
||||||
# from videoarchiver.processor import progress_tracker # Import from processor package
|
# from videoarchiver.config_manager import ConfigManager
|
||||||
# from videoarchiver.processor.constants import REACTIONS
|
# from videoarchiver.processor import progress_tracker # Import from processor package
|
||||||
|
# from videoarchiver.processor.constants import REACTIONS
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import asyncio
|
|||||||
from typing import List, Optional, Dict, Any, Set, ClassVar
|
from typing import List, Optional, Dict, Any, Set, ClassVar
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
try:
|
#try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..queue.types import QueuePriority, QueueMetrics, ProcessingMetrics
|
from ..queue.types import QueuePriority, QueueMetrics, ProcessingMetrics
|
||||||
from ..queue.models import QueueItem
|
from ..queue.models import QueueItem
|
||||||
except ImportError:
|
#except ImportError:
|
||||||
# Fall back to absolute imports if relative imports fail
|
# Fall back to absolute imports if relative imports fail
|
||||||
# from videoarchiver.queue.types import QueuePriority, QueueMetrics, ProcessingMetrics
|
# from videoarchiver.queue.types import QueuePriority, QueueMetrics, ProcessingMetrics
|
||||||
# from videoarchiver.queue.models import QueueItem
|
# from videoarchiver.queue.models import QueueItem
|
||||||
|
|||||||
@@ -7,24 +7,25 @@ from typing import List, Optional
|
|||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..processor.constants import (
|
from ..processor.constants import (
|
||||||
REACTIONS,
|
REACTIONS,
|
||||||
ReactionType,
|
ReactionType,
|
||||||
get_reaction,
|
get_reaction,
|
||||||
get_progress_emoji,
|
get_progress_emoji,
|
||||||
)
|
)
|
||||||
from ..database.video_archive_db import VideoArchiveDB
|
from ..database.video_archive_db import VideoArchiveDB
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.processor.constants import (
|
# Fall back to absolute imports if relative imports fail
|
||||||
REACTIONS,
|
# from videoarchiver.processor.constants import (
|
||||||
ReactionType,
|
# REACTIONS,
|
||||||
get_reaction,
|
# ReactionType,
|
||||||
get_progress_emoji,
|
# get_reaction,
|
||||||
)
|
# get_progress_emoji,
|
||||||
# from videoarchiver.database.video_archive_db import VideoArchiveDB
|
# )
|
||||||
|
# from videoarchiver.database.video_archive_db import VideoArchiveDB
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,13 @@ from typing import (
|
|||||||
)
|
)
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from ..utils.exceptions import DisplayError
|
from ..utils.exceptions import DisplayError
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.utils.exceptions import DisplayError
|
# Fall back to absolute imports if relative imports fail
|
||||||
|
# from videoarchiver.utils.exceptions import DisplayError
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from importlib.metadata import version as get_package_version
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from packaging import version
|
from packaging import version
|
||||||
import discord # type: ignore
|
import discord # type: ignore
|
||||||
from typing import Optional, Tuple, Dict, Any
|
from typing import Optional, Tuple, Dict, Any
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
@@ -16,12 +16,13 @@ import tempfile
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
# Try relative imports first
|
# Try relative imports first
|
||||||
from .utils.exceptions import UpdateError
|
from .utils.exceptions import UpdateError
|
||||||
except ImportError:
|
|
||||||
# Fall back to absolute imports if relative imports fail
|
# except ImportError:
|
||||||
# from videoarchiver.utils.exceptions import UpdateError
|
# Fall back to absolute imports if relative imports fail
|
||||||
|
# from videoarchiver.utils.exceptions import UpdateError
|
||||||
|
|
||||||
logger = logging.getLogger("VideoArchiver")
|
logger = logging.getLogger("VideoArchiver")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user