Updated default settings (video archiving enabled by default)

New database functionality and commands
Additional video format support (MKV)
Message duration now in hours (0-168)
Enhanced error handling and logging
Queue persistence and management improvements
Hardware acceleration updates
More detailed command descriptions
Improved performance & limitations documentation
This commit is contained in:
pacnpal
2024-11-16 01:22:37 +00:00
parent 01a9067368
commit 609aecdc4e
5 changed files with 205 additions and 33 deletions

View File

@@ -2,24 +2,24 @@
Welcome to **Pac-cogs**, a collection of custom cogs for [Red](https://github.com/Cog-Creators/Red-DiscordBot). These cogs are designed to add extra functionality to your Red bot instance on Discord. Welcome to **Pac-cogs**, a collection of custom cogs for [Red](https://github.com/Cog-Creators/Red-DiscordBot). These cogs are designed to add extra functionality to your Red bot instance on Discord.
## Cogs Overview
| Cog Name | Description |
|------------|--------------------------------------------------|
| **Birthday** | Assigns a special birthday role to users and sends a celebratory message with random cake or pie emojis. Features include: automatic role removal at midnight in configurable timezone, custom announcement channels, role-based command permissions, random cake/pie emoji generation, task persistence across bot restarts, context menu support (right-click user to assign role), birthday role removal task checking, and no hierarchy requirements for role assignment. Perfect for automated birthday celebrations! |
| **Overseerr** | Allows interaction with [Overseerr](https://overseerr.dev/) directly from Discord. Users can search for movies or TV shows, request them, and have admins approve requests. Features include: media availability checking, request status tracking, admin role configuration, direct integration with Overseerr's API, and full slash command support. Requires a running Overseerr instance and API key. |
| **VideoArchiver** | A powerful video archiving cog that automatically downloads and reposts videos from monitored channels. Features hardware-accelerated compression (NVIDIA, AMD, Intel, ARM), multi-video processing, modular queue system with priority processing and state persistence, role-based permissions, automatic file cleanup, and support for multiple video platforms via yt-dlp. The enhanced queue system provides metrics tracking, health monitoring, and efficient resource management while maintaining quality. New features include: video archive database for tracking and retrieving archived videos, detailed queue monitoring with real-time progress tracking, and comprehensive error handling with automatic recovery. |
## Installation ## Installation
To install the cogs in this repository, follow these steps: To install the cogs in this repository, follow these steps:
1. Ensure you have [Red](https://github.com/Cog-Creators/Red-DiscordBot) set up. 1. Ensure you have [Red](https://github.com/Cog-Creators/Red-DiscordBot) set up.
2. Add this repository to your Red instance: 2. Add this repository to your Red instance:
```bash ```bash
[p]repo add Pac-cogs https://github.com/pacnpal/Pac-cogs [p]repo add Pac-cogs https://github.com/pacnpal/Pac-cogs
``` ```
3. Install the desired cog:
```bash
[p]cog install Pac-cogs videoarchiver
```
4. Load the installed cog:
```bash
[p]load videoarchiver
```
3. Install the desired cog: 3. Install the desired cog:
@@ -59,6 +59,27 @@ Replace `[p]` with your bot's prefix.
[p]overseerr apikey <your-api-key> [p]overseerr apikey <your-api-key>
``` ```
- **VideoArchiver**: The cog requires FFmpeg for video processing. The cog will attempt to download and manage FFmpeg automatically if it's not found on your system. The required Python packages (yt-dlp, ffmpeg-python, requests) will be installed automatically during cog installation. Features a modular queue system with priority processing, performance metrics, health monitoring, and automatic cleanup. The queue system maintains state across bot restarts and provides efficient resource management. - **VideoArchiver**: The cog requires FFmpeg for video processing. The cog will attempt to download and manage FFmpeg automatically if it's not found on your system. The required Python packages (yt-dlp, ffmpeg-python, requests) will be installed automatically during cog installation.
For more details on setting up and managing Red, visit the [Red documentation](https://docs.discord.red). ## VideoArchiver Commands and Features
The VideoArchiver cog now comes with enhanced features and a comprehensive set of slash commands for easy management.
### Default Behavior
- Video archiving is enabled by default for new servers
- All channels are monitored by default (can be restricted using commands)
- All users can trigger archiving by default (can be restricted using commands)
- All video sites are supported by default (can be restricted using commands)
### Core Commands
- `/archiver settings` - View all current settings
- `/archiver enable`, `/archiver disable` - Toggle video archiving
- `/archiver queue` - View the current processing queue
### Channel Management
- `/archiver setchannel` - Set the archive channel
- `/archiver setlog` - Set the log channel
- `/archiver addchannel` - Add a channel to monitor
- `/archiver removechannel` - Remove a channel from monitoring
### Video Settings

View File

@@ -13,6 +13,7 @@ A powerful video archiving cog that automatically downloads and reposts videos f
- Default maximum file size: 8MB - Default maximum file size: 8MB
- Default video format: MP4 - Default video format: MP4
- Default video quality: High - Default video quality: High
- Support for MP4, WebM, and MKV formats
- **Video Archive Database** - **Video Archive Database**
- Track and store archived video information - Track and store archived video information
@@ -21,6 +22,7 @@ A powerful video archiving cog that automatically downloads and reposts videos f
- Optional database functionality (disabled by default) - Optional database functionality (disabled by default)
- Automatic database management and cleanup - Automatic database management and cleanup
- Persistent video history tracking - Persistent video history tracking
- URL-based video lookup
- **Modular Queue System** - **Modular Queue System**
- Priority-based processing with state persistence - Priority-based processing with state persistence
@@ -29,8 +31,9 @@ A powerful video archiving cog that automatically downloads and reposts videos f
- Automatic cleanup and memory optimization - Automatic cleanup and memory optimization
- Default concurrent downloads: 2 (configurable 1-5) - Default concurrent downloads: 2 (configurable 1-5)
- Maximum queue size: 1000 items - Maximum queue size: 1000 items
- Automatic retry on failures (3 attempts) - Automatic retry on failures (3 attempts with 5-second delay)
- Queue state persistence across bot restarts - Queue state persistence across bot restarts
- Enhanced error recovery
- **Progress Tracking** - **Progress Tracking**
- Real-time download progress monitoring - Real-time download progress monitoring
@@ -40,18 +43,21 @@ A powerful video archiving cog that automatically downloads and reposts videos f
- Memory usage monitoring - Memory usage monitoring
- Success rate calculations - Success rate calculations
- Automatic cleanup of temporary files - Automatic cleanup of temporary files
- Enhanced logging capabilities
- **Channel Management** - **Channel Management**
- Flexible channel monitoring (specific channels or all) - Flexible channel monitoring (specific channels or all)
- Separate archive, notification, and log channels - Separate archive, notification, and log channels
- Customizable message templates - Customizable message templates
- Configurable message duration (default: 30 seconds) - Configurable message duration (0-168 hours)
- Enhanced error logging
- **Access Control** - **Access Control**
- Role-based permissions - Role-based permissions
- Site-specific enabling/disabling - Site-specific enabling/disabling
- Admin-only configuration commands - Admin-only configuration commands
- Per-guild settings - Per-guild settings
- Enhanced permission checks
## Installation ## Installation
@@ -72,16 +78,21 @@ All commands support both prefix and slash command syntax:
### Core Video Archiver Commands (va_) ### Core Video Archiver Commands (va_)
- **`va_settings`**: Show current video archiver settings - **`va_settings`**: Show current video archiver settings
- **`va_format <mp4|webm>`**: Set video format - **`va_format <mp4|webm|mkv>`**: Set video format
- **`va_quality <144-4320>`**: Set maximum video quality (in pixels) - **`va_quality <144-4320>`**: Set maximum video quality (in pixels)
- **`va_maxsize <1-100>`**: Set maximum file size (in MB) - **`va_maxsize <1-100>`**: Set maximum file size (in MB)
- **`va_concurrent <1-5>`**: Set number of concurrent downloads - **`va_concurrent <1-5>`**: Set number of concurrent downloads
- **`va_toggledelete`**: Toggle deletion of local files after reposting - **`va_toggledelete`**: Toggle deletion of local files after reposting
- **`va_duration <0-720>`**: Set message duration in hours (0 for permanent) - **`va_duration <0-168>`**: Set message duration in hours (0 for permanent)
- **`va_template <template>`**: Set message template using {author}, {url}, {original_message} - **`va_template <template>`**: Set message template using {author}, {url}, {original_message}
- **`va_update`**: Update yt-dlp to latest version - **`va_update`**: Update yt-dlp to latest version
- **`va_toggleupdates`**: Toggle update notifications - **`va_toggleupdates`**: Toggle update notifications
### Database Management Commands (archivedb_)
- **`archivedb enable`**: Enable the video archive database
- **`archivedb disable`**: Disable the video archive database
- **`checkarchived <url>`**: Check if a video URL has been archived
### Archiver Management Commands (archiver_) ### Archiver Management Commands (archiver_)
- **`archiver enable`**: Enable video archiving in the server - **`archiver enable`**: Enable video archiving in the server
- **`archiver disable`**: Disable video archiving in the server - **`archiver disable`**: Disable video archiving in the server
@@ -89,11 +100,7 @@ All commands support both prefix and slash command syntax:
- **`archiver setlog <channel>`**: Set the log channel - **`archiver setlog <channel>`**: Set the log channel
- **`archiver addchannel <channel>`**: Add a channel to monitor - **`archiver addchannel <channel>`**: Add a channel to monitor
- **`archiver removechannel <channel>`**: Remove a channel from monitoring - **`archiver removechannel <channel>`**: Remove a channel from monitoring
- **`archiver queue`**: Show current queue status
### Database Management Commands (archivedb_)
- **`archivedb enable`**: Enable the video archive database
- **`archivedb disable`**: Disable the video archive database
- **`checkarchived <url>`**: Check if a video URL has been archived
### Queue Management Commands (vaq_) ### Queue Management Commands (vaq_)
- **`vaq_status`**: Show current queue status with basic metrics - **`vaq_status`**: Show current queue status with basic metrics
@@ -120,14 +127,15 @@ All commands support both prefix and slash command syntax:
```python ```python
{ {
"enabled": False, # Video archiving disabled by default "enabled": True, # Video archiving enabled by default
"archive_channel": None, # Must be set before use "archive_channel": None, # Must be set before use
"log_channel": None, # Optional error logging channel "log_channel": None, # Optional error logging channel
"enabled_channels": [], # Channels to monitor "enabled_channels": [], # Empty list means all channels
"allowed_roles": [], # Empty list means all roles
"video_format": "mp4", # Default video format "video_format": "mp4", # Default video format
"video_quality": "high", # Default video quality "video_quality": "high", # Default video quality
"max_file_size": 8, # Maximum file size in MB "max_file_size": 8, # Maximum file size in MB
"message_duration": 30, # Message duration in seconds "message_duration": 30, # Message duration in hours
"message_template": "{author} archived a video from {channel}", "message_template": "{author} archived a video from {channel}",
"concurrent_downloads": 2, # Number of concurrent downloads "concurrent_downloads": 2, # Number of concurrent downloads
"enabled_sites": None, # None means all sites enabled "enabled_sites": None, # None means all sites enabled
@@ -167,6 +175,7 @@ The cog supports all sites compatible with yt-dlp. Use `vas_list` to see availab
- Maximum history age: 24 hours - Maximum history age: 24 hours
- Unload timeout: 30 seconds - Unload timeout: 30 seconds
- Cleanup timeout: 15 seconds - Cleanup timeout: 15 seconds
- Queue state persistence across restarts
## Error Handling ## Error Handling
@@ -178,6 +187,7 @@ The cog supports all sites compatible with yt-dlp. Use `vas_list` to see availab
- Error type tracking and analysis - Error type tracking and analysis
- Automatic recovery procedures - Automatic recovery procedures
- Force cleanup on timeout - Force cleanup on timeout
- Enhanced error reporting
## Support ## Support

View File

@@ -13,6 +13,7 @@ class ConfigManager:
"""Manages guild configurations for VideoArchiver""" """Manages guild configurations for VideoArchiver"""
default_guild = { default_guild = {
"enabled": False, # Added the enabled setting
"archive_channel": None, "archive_channel": None,
"notification_channel": None, "notification_channel": None,
"log_channel": None, "log_channel": None,
@@ -87,7 +88,7 @@ class ConfigManager:
elif setting in ["message_template"] and not isinstance(value, str): elif setting in ["message_template"] and not isinstance(value, str):
raise ConfigError("Message template must be a string") raise ConfigError("Message template must be a string")
elif setting in ["delete_after_repost", "disable_update_check"] and not isinstance(value, bool): elif setting in ["enabled", "delete_after_repost", "disable_update_check"] and not isinstance(value, bool):
raise ConfigError(f"{setting} must be a boolean") raise ConfigError(f"{setting} must be a boolean")
except Exception as e: except Exception as e:
@@ -275,6 +276,11 @@ class ConfigManager:
allowed_roles.append(role.name) allowed_roles.append(role.name)
# Add fields with proper formatting # Add fields with proper formatting
embed.add_field(
name="Enabled",
value=str(settings["enabled"]),
inline=False
)
embed.add_field( embed.add_field(
name="Archive Channel", name="Archive Channel",
value=archive_channel.mention if archive_channel else "Not set", value=archive_channel.mention if archive_channel else "Not set",

View File

@@ -51,10 +51,11 @@ class VideoArchiver(GroupCog):
"""Archive videos from Discord channels""" """Archive videos from Discord channels"""
default_guild_settings = { default_guild_settings = {
"enabled": False, "enabled": True, # Changed to True to enable by default
"archive_channel": None, "archive_channel": None,
"log_channel": None, "log_channel": None,
"enabled_channels": [], "enabled_channels": [], # Empty list means all channels
"allowed_roles": [], # Empty list means all roles
"video_format": "mp4", "video_format": "mp4",
"video_quality": "high", "video_quality": "high",
"max_file_size": 8, # MB "max_file_size": 8, # MB
@@ -303,6 +304,126 @@ class VideoArchiver(GroupCog):
logger.error(f"Error removing enabled channel: {e}") logger.error(f"Error removing enabled channel: {e}")
await ctx.send("An error occurred while removing the channel.") await ctx.send("An error occurred while removing the channel.")
@archiver.command(name="setformat")
@guild_only()
@checks.admin_or_permissions(administrator=True)
@app_commands.describe(format="The video format to use (mp4, webm, or mkv)")
async def set_video_format(self, ctx: Context, format: str):
"""Set the video format for archived videos."""
try:
format = format.lower()
if format not in ["mp4", "webm", "mkv"]:
await ctx.send("Invalid format. Please use mp4, webm, or mkv.")
return
await self.config_manager.update_setting(ctx.guild.id, "video_format", format)
await ctx.send(f"Video format has been set to {format}.")
except Exception as e:
logger.error(f"Error setting video format: {e}")
await ctx.send("An error occurred while setting the video format.")
@archiver.command(name="setquality")
@guild_only()
@checks.admin_or_permissions(administrator=True)
@app_commands.describe(quality="The video quality (144-4320)")
async def set_video_quality(self, ctx: Context, quality: int):
"""Set the video quality for archived videos."""
try:
if not 144 <= quality <= 4320:
await ctx.send("Quality must be between 144 and 4320.")
return
await self.config_manager.update_setting(ctx.guild.id, "video_quality", quality)
await ctx.send(f"Video quality has been set to {quality}p.")
except Exception as e:
logger.error(f"Error setting video quality: {e}")
await ctx.send("An error occurred while setting the video quality.")
@archiver.command(name="setmaxsize")
@guild_only()
@checks.admin_or_permissions(administrator=True)
@app_commands.describe(size="The maximum file size in MB (1-100)")
async def set_max_file_size(self, ctx: Context, size: int):
"""Set the maximum file size for archived videos."""
try:
if not 1 <= size <= 100:
await ctx.send("Size must be between 1 and 100 MB.")
return
await self.config_manager.update_setting(ctx.guild.id, "max_file_size", size)
await ctx.send(f"Maximum file size has been set to {size}MB.")
except Exception as e:
logger.error(f"Error setting max file size: {e}")
await ctx.send("An error occurred while setting the maximum file size.")
@archiver.command(name="setmessageduration")
@guild_only()
@checks.admin_or_permissions(administrator=True)
@app_commands.describe(hours="How long to keep messages in hours (0-168)")
async def set_message_duration(self, ctx: Context, hours: int):
"""Set how long to keep archived messages."""
try:
if not 0 <= hours <= 168:
await ctx.send("Duration must be between 0 and 168 hours (1 week).")
return
await self.config_manager.update_setting(ctx.guild.id, "message_duration", hours)
await ctx.send(f"Message duration has been set to {hours} hours.")
except Exception as e:
logger.error(f"Error setting message duration: {e}")
await ctx.send("An error occurred while setting the message duration.")
@archiver.command(name="settemplate")
@guild_only()
@checks.admin_or_permissions(administrator=True)
@app_commands.describe(template="The message template to use")
async def set_message_template(self, ctx: Context, *, template: str):
"""Set the template for archived messages. Use {author}, {channel}, and {original_message} as placeholders."""
try:
if not any(ph in template for ph in ["{author}", "{channel}", "{original_message}"]):
await ctx.send("Template must include at least one placeholder: {author}, {channel}, or {original_message}")
return
await self.config_manager.update_setting(ctx.guild.id, "message_template", template)
await ctx.send(f"Message template has been set to: {template}")
except Exception as e:
logger.error(f"Error setting message template: {e}")
await ctx.send("An error occurred while setting the message template.")
@archiver.command(name="setconcurrent")
@guild_only()
@checks.admin_or_permissions(administrator=True)
@app_commands.describe(count="Number of concurrent downloads (1-5)")
async def set_concurrent_downloads(self, ctx: Context, count: int):
"""Set the number of concurrent downloads allowed."""
try:
if not 1 <= count <= 5:
await ctx.send("Concurrent downloads must be between 1 and 5.")
return
await self.config_manager.update_setting(ctx.guild.id, "concurrent_downloads", count)
await ctx.send(f"Concurrent downloads has been set to {count}.")
except Exception as e:
logger.error(f"Error setting concurrent downloads: {e}")
await ctx.send("An error occurred while setting concurrent downloads.")
@archiver.command(name="settings")
@guild_only()
async def show_settings(self, ctx: Context):
"""Show current archiver settings."""
try:
embed = await self.config_manager.format_settings_embed(ctx.guild)
await ctx.send(embed=embed)
except Exception as e:
logger.error(f"Error showing settings: {e}")
await ctx.send("An error occurred while showing settings.")
@archiver.command(name="queue")
@guild_only()
async def show_queue(self, ctx: Context):
"""Show the current video processing queue."""
await self.processor.show_queue_details(ctx)
async def cog_command_error(self, ctx: Context, error: Exception) -> None: async def cog_command_error(self, ctx: Context, error: Exception) -> None:
"""Handle command errors""" """Handle command errors"""
error_msg = None error_msg = None

View File

@@ -30,15 +30,28 @@ class MessageHandler:
logger.warning(f"No settings found for guild {message.guild.id}") logger.warning(f"No settings found for guild {message.guild.id}")
return return
# Check if video archiving is enabled for this guild
if not settings.get("enabled", False):
logger.debug(f"Video archiving is disabled for guild {message.guild.id}")
return
# Log settings for debugging # Log settings for debugging
logger.debug(f"Guild {message.guild.id} settings: {settings}") logger.debug(f"Guild {message.guild.id} settings: {settings}")
# Check if channel is enabled # Check if channel is enabled (empty list means all channels)
enabled_channels = settings.get("enabled_channels", []) enabled_channels = settings.get("enabled_channels", [])
if enabled_channels and message.channel.id not in enabled_channels: if enabled_channels and message.channel.id not in enabled_channels:
logger.debug(f"Channel {message.channel.id} not in enabled channels: {enabled_channels}") logger.debug(f"Channel {message.channel.id} not in enabled channels: {enabled_channels}")
return return
# Check if user has allowed role (empty list means all roles)
allowed_roles = settings.get("allowed_roles", [])
if allowed_roles:
user_roles = [role.id for role in message.author.roles]
if not any(role_id in allowed_roles for role_id in user_roles):
logger.debug(f"User {message.author.id} does not have any allowed roles")
return
# Extract URLs from message # Extract URLs from message
urls = await self._extract_urls(message, settings) urls = await self._extract_urls(message, settings)
if not urls: if not urls:
@@ -68,6 +81,7 @@ class MessageHandler:
for word in message.content.split(): for word in message.content.split():
logger.debug(f"Checking word: {word}") logger.debug(f"Checking word: {word}")
if is_video_url_pattern(word): if is_video_url_pattern(word):
# If enabled_sites is empty or None, allow all sites
if not enabled_sites or any(site in word.lower() for site in enabled_sites): if not enabled_sites or any(site in word.lower() for site in enabled_sites):
logger.debug(f"Found matching URL: {word}") logger.debug(f"Found matching URL: {word}")
urls.append(word) urls.append(word)