mirror of
https://github.com/pacnpal/Pac-cogs.git
synced 2025-12-19 18:31:05 -05:00
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:
43
README.md
43
README.md
@@ -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.
|
||||
|
||||
## 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
|
||||
|
||||
To install the cogs in this repository, follow these steps:
|
||||
|
||||
1. Ensure you have [Red](https://github.com/Cog-Creators/Red-DiscordBot) set up.
|
||||
2. Add this repository to your Red instance:
|
||||
|
||||
```bash
|
||||
[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:
|
||||
|
||||
@@ -59,6 +59,27 @@ Replace `[p]` with your bot's prefix.
|
||||
[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
|
||||
|
||||
@@ -13,6 +13,7 @@ A powerful video archiving cog that automatically downloads and reposts videos f
|
||||
- Default maximum file size: 8MB
|
||||
- Default video format: MP4
|
||||
- Default video quality: High
|
||||
- Support for MP4, WebM, and MKV formats
|
||||
|
||||
- **Video Archive Database**
|
||||
- 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)
|
||||
- Automatic database management and cleanup
|
||||
- Persistent video history tracking
|
||||
- URL-based video lookup
|
||||
|
||||
- **Modular Queue System**
|
||||
- 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
|
||||
- Default concurrent downloads: 2 (configurable 1-5)
|
||||
- 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
|
||||
- Enhanced error recovery
|
||||
|
||||
- **Progress Tracking**
|
||||
- Real-time download progress monitoring
|
||||
@@ -40,18 +43,21 @@ A powerful video archiving cog that automatically downloads and reposts videos f
|
||||
- Memory usage monitoring
|
||||
- Success rate calculations
|
||||
- Automatic cleanup of temporary files
|
||||
- Enhanced logging capabilities
|
||||
|
||||
- **Channel Management**
|
||||
- Flexible channel monitoring (specific channels or all)
|
||||
- Separate archive, notification, and log channels
|
||||
- Customizable message templates
|
||||
- Configurable message duration (default: 30 seconds)
|
||||
- Configurable message duration (0-168 hours)
|
||||
- Enhanced error logging
|
||||
|
||||
- **Access Control**
|
||||
- Role-based permissions
|
||||
- Site-specific enabling/disabling
|
||||
- Admin-only configuration commands
|
||||
- Per-guild settings
|
||||
- Enhanced permission checks
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -72,16 +78,21 @@ All commands support both prefix and slash command syntax:
|
||||
|
||||
### Core Video Archiver Commands (va_)
|
||||
- **`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_maxsize <1-100>`**: Set maximum file size (in MB)
|
||||
- **`va_concurrent <1-5>`**: Set number of concurrent downloads
|
||||
- **`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_update`**: Update yt-dlp to latest version
|
||||
- **`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 enable`**: Enable 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 addchannel <channel>`**: Add a channel to monitor
|
||||
- **`archiver removechannel <channel>`**: Remove a channel from monitoring
|
||||
|
||||
### 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 queue`**: Show current queue status
|
||||
|
||||
### Queue Management Commands (vaq_)
|
||||
- **`vaq_status`**: Show current queue status with basic metrics
|
||||
@@ -120,18 +127,19 @@ All commands support both prefix and slash command syntax:
|
||||
|
||||
```python
|
||||
{
|
||||
"enabled": False, # Video archiving disabled by default
|
||||
"enabled": True, # Video archiving enabled by default
|
||||
"archive_channel": None, # Must be set before use
|
||||
"log_channel": None, # Optional error logging channel
|
||||
"enabled_channels": [], # Channels to monitor
|
||||
"video_format": "mp4", # Default video format
|
||||
"video_quality": "high", # Default video quality
|
||||
"max_file_size": 8, # Maximum file size in MB
|
||||
"message_duration": 30, # Message duration in seconds
|
||||
"enabled_channels": [], # Empty list means all channels
|
||||
"allowed_roles": [], # Empty list means all roles
|
||||
"video_format": "mp4", # Default video format
|
||||
"video_quality": "high", # Default video quality
|
||||
"max_file_size": 8, # Maximum file size in MB
|
||||
"message_duration": 30, # Message duration in hours
|
||||
"message_template": "{author} archived a video from {channel}",
|
||||
"concurrent_downloads": 2, # Number of concurrent downloads
|
||||
"enabled_sites": None, # None means all sites enabled
|
||||
"use_database": False # Database tracking disabled by default
|
||||
"concurrent_downloads": 2, # Number of concurrent downloads
|
||||
"enabled_sites": None, # None means all sites enabled
|
||||
"use_database": False # Database tracking disabled by default
|
||||
}
|
||||
```
|
||||
|
||||
@@ -167,6 +175,7 @@ The cog supports all sites compatible with yt-dlp. Use `vas_list` to see availab
|
||||
- Maximum history age: 24 hours
|
||||
- Unload timeout: 30 seconds
|
||||
- Cleanup timeout: 15 seconds
|
||||
- Queue state persistence across restarts
|
||||
|
||||
## 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
|
||||
- Automatic recovery procedures
|
||||
- Force cleanup on timeout
|
||||
- Enhanced error reporting
|
||||
|
||||
## Support
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ class ConfigManager:
|
||||
"""Manages guild configurations for VideoArchiver"""
|
||||
|
||||
default_guild = {
|
||||
"enabled": False, # Added the enabled setting
|
||||
"archive_channel": None,
|
||||
"notification_channel": None,
|
||||
"log_channel": None,
|
||||
@@ -87,7 +88,7 @@ class ConfigManager:
|
||||
elif setting in ["message_template"] and not isinstance(value, str):
|
||||
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")
|
||||
|
||||
except Exception as e:
|
||||
@@ -275,6 +276,11 @@ class ConfigManager:
|
||||
allowed_roles.append(role.name)
|
||||
|
||||
# Add fields with proper formatting
|
||||
embed.add_field(
|
||||
name="Enabled",
|
||||
value=str(settings["enabled"]),
|
||||
inline=False
|
||||
)
|
||||
embed.add_field(
|
||||
name="Archive Channel",
|
||||
value=archive_channel.mention if archive_channel else "Not set",
|
||||
|
||||
@@ -51,10 +51,11 @@ class VideoArchiver(GroupCog):
|
||||
"""Archive videos from Discord channels"""
|
||||
|
||||
default_guild_settings = {
|
||||
"enabled": False,
|
||||
"enabled": True, # Changed to True to enable by default
|
||||
"archive_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_quality": "high",
|
||||
"max_file_size": 8, # MB
|
||||
@@ -303,6 +304,126 @@ class VideoArchiver(GroupCog):
|
||||
logger.error(f"Error removing enabled channel: {e}")
|
||||
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:
|
||||
"""Handle command errors"""
|
||||
error_msg = None
|
||||
|
||||
@@ -30,15 +30,28 @@ class MessageHandler:
|
||||
logger.warning(f"No settings found for guild {message.guild.id}")
|
||||
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
|
||||
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", [])
|
||||
if enabled_channels and message.channel.id not in enabled_channels:
|
||||
logger.debug(f"Channel {message.channel.id} not in enabled channels: {enabled_channels}")
|
||||
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
|
||||
urls = await self._extract_urls(message, settings)
|
||||
if not urls:
|
||||
@@ -68,6 +81,7 @@ class MessageHandler:
|
||||
for word in message.content.split():
|
||||
logger.debug(f"Checking word: {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):
|
||||
logger.debug(f"Found matching URL: {word}")
|
||||
urls.append(word)
|
||||
|
||||
Reference in New Issue
Block a user