624 lines
15 KiB
Markdown
624 lines
15 KiB
Markdown
# Pomice Advanced Features Guide
|
|
|
|
## 🎉 Overview
|
|
|
|
This guide covers the advanced features added to Pomice to enhance your music bot capabilities. These features include track history, queue statistics, playlist management, and advanced track utilities.
|
|
|
|
### What's New
|
|
|
|
- **Track History**: Keep track of previously played songs with navigation and search
|
|
- **Queue Statistics**: Detailed analytics about queue contents (duration, requesters, etc.)
|
|
- **Playlist Manager**: Export/import playlists to JSON and M3U formats
|
|
- **Track Utilities**: Advanced filtering, searching, and sorting capabilities
|
|
|
|
All features are **fully backward compatible** and **optional** - use what you need!
|
|
|
|
---
|
|
|
|
## 📚 Table of Contents
|
|
|
|
1. [Track History](#-track-history)
|
|
2. [Queue Statistics](#-queue-statistics)
|
|
3. [Playlist Manager](#-playlist-manager)
|
|
4. [Track Utilities](#-track-utilities)
|
|
5. [Complete Examples](#-complete-examples)
|
|
6. [Quick Reference](#-quick-reference)
|
|
|
|
---
|
|
|
|
## 🕐 Track History
|
|
|
|
Keep track of previously played songs with navigation and search capabilities.
|
|
|
|
### Features
|
|
- Configurable maximum history size
|
|
- Navigation (previous/next)
|
|
- Search through history
|
|
- Filter by requester
|
|
- Get unique tracks (remove duplicates)
|
|
|
|
### Basic Usage
|
|
|
|
```python
|
|
import pomice
|
|
|
|
# Create a history tracker
|
|
history = pomice.TrackHistory(max_size=100)
|
|
|
|
# Add tracks as they play
|
|
history.add(track)
|
|
|
|
# Get last 10 played tracks
|
|
recent = history.get_last(10)
|
|
|
|
# Search history
|
|
results = history.search("Imagine Dragons")
|
|
|
|
# Get tracks by specific user
|
|
user_tracks = history.get_by_requester(user_id=123456789)
|
|
|
|
# Navigate through history
|
|
previous_track = history.get_previous()
|
|
next_track = history.get_next()
|
|
|
|
# Get all unique tracks (removes duplicates)
|
|
unique = history.get_unique_tracks()
|
|
|
|
# Clear history
|
|
history.clear()
|
|
```
|
|
|
|
### Properties
|
|
- `is_empty` - Check if history is empty
|
|
- `current` - Get current track in navigation
|
|
|
|
### Use Cases
|
|
- "What was that song that just played?"
|
|
- "Show me the last 10 songs"
|
|
- "Play the previous track"
|
|
- "Show all songs requested by User X"
|
|
|
|
---
|
|
|
|
## 📊 Queue Statistics
|
|
|
|
Get detailed analytics about your queue contents.
|
|
|
|
### Features
|
|
- Total and average duration
|
|
- Longest/shortest tracks
|
|
- Requester statistics
|
|
- Author distribution
|
|
- Duration breakdown
|
|
- Stream detection
|
|
- Playlist distribution
|
|
|
|
### Basic Usage
|
|
|
|
```python
|
|
import pomice
|
|
|
|
# Create stats for a queue
|
|
stats = pomice.QueueStats(player.queue)
|
|
|
|
# Get total duration
|
|
total_ms = stats.total_duration
|
|
formatted = stats.format_duration(total_ms) # "1:23:45"
|
|
|
|
# Get average duration
|
|
avg_ms = stats.average_duration
|
|
|
|
# Find longest and shortest tracks
|
|
longest = stats.longest_track
|
|
shortest = stats.shortest_track
|
|
|
|
# Get requester statistics
|
|
requester_stats = stats.get_requester_stats()
|
|
# Returns: {user_id: {'count': 5, 'total_duration': 900000, 'tracks': [...]}}
|
|
|
|
# Get top requesters
|
|
top_requesters = stats.get_top_requesters(limit=5)
|
|
# Returns: [(requester, count), ...]
|
|
|
|
# Get author distribution
|
|
authors = stats.get_author_distribution()
|
|
# Returns: {'Artist Name': track_count, ...}
|
|
|
|
# Get top authors
|
|
top_authors = stats.get_top_authors(limit=10)
|
|
# Returns: [('Artist Name', count), ...]
|
|
|
|
# Get duration breakdown
|
|
breakdown = stats.get_duration_breakdown()
|
|
# Returns: {'short': 10, 'medium': 25, 'long': 5, 'very_long': 2}
|
|
|
|
# Get stream count
|
|
streams = stats.get_stream_count()
|
|
|
|
# Get comprehensive summary
|
|
summary = stats.get_summary()
|
|
```
|
|
|
|
### Summary Dictionary
|
|
```python
|
|
{
|
|
'total_tracks': 42,
|
|
'total_duration': 7200000, # milliseconds
|
|
'total_duration_formatted': '2:00:00',
|
|
'average_duration': 171428.57,
|
|
'average_duration_formatted': '2:51',
|
|
'longest_track': Track(...),
|
|
'shortest_track': Track(...),
|
|
'stream_count': 3,
|
|
'unique_authors': 15,
|
|
'unique_requesters': 5,
|
|
'duration_breakdown': {...},
|
|
'loop_mode': LoopMode.QUEUE,
|
|
'is_looping': True
|
|
}
|
|
```
|
|
|
|
### Use Cases
|
|
- "How long is the queue?"
|
|
- "Who added the most songs?"
|
|
- "What's the longest track?"
|
|
- "Show me queue statistics"
|
|
|
|
---
|
|
|
|
## 💾 Playlist Manager
|
|
|
|
Export and import playlists to/from JSON and M3U formats.
|
|
|
|
### Features
|
|
- Export queue to JSON
|
|
- Import playlists from JSON
|
|
- Export to M3U format
|
|
- Merge multiple playlists
|
|
- Remove duplicates
|
|
- Playlist metadata
|
|
|
|
### Export Queue
|
|
```python
|
|
import pomice
|
|
|
|
# Export current queue
|
|
pomice.PlaylistManager.export_queue(
|
|
player.queue,
|
|
filepath='playlists/my_playlist.json',
|
|
name='My Awesome Playlist',
|
|
description='Best songs ever',
|
|
include_metadata=True # Include requester info
|
|
)
|
|
```
|
|
|
|
### Import Playlist
|
|
```python
|
|
# Import playlist data
|
|
data = pomice.PlaylistManager.import_playlist('playlists/my_playlist.json')
|
|
|
|
# Get just the URIs
|
|
uris = pomice.PlaylistManager.get_track_uris('playlists/my_playlist.json')
|
|
|
|
# Load tracks into queue
|
|
for uri in uris:
|
|
results = await player.get_tracks(query=uri)
|
|
if results:
|
|
await player.queue.put(results[0])
|
|
```
|
|
|
|
### Export Track List
|
|
```python
|
|
# Export a list of tracks (not from queue)
|
|
tracks = [track1, track2, track3]
|
|
pomice.PlaylistManager.export_track_list(
|
|
tracks,
|
|
filepath='playlists/favorites.json',
|
|
name='Favorites',
|
|
description='My favorite tracks'
|
|
)
|
|
```
|
|
|
|
### Merge Playlists
|
|
```python
|
|
# Merge multiple playlists into one
|
|
pomice.PlaylistManager.merge_playlists(
|
|
filepaths=['playlist1.json', 'playlist2.json', 'playlist3.json'],
|
|
output_path='merged_playlist.json',
|
|
name='Mega Playlist',
|
|
remove_duplicates=True # Remove duplicate tracks
|
|
)
|
|
```
|
|
|
|
### Export to M3U
|
|
```python
|
|
# Export to M3U format (compatible with many players)
|
|
tracks = list(player.queue)
|
|
pomice.PlaylistManager.export_to_m3u(
|
|
tracks,
|
|
filepath='playlists/my_playlist.m3u',
|
|
name='My Playlist'
|
|
)
|
|
```
|
|
|
|
### Get Playlist Info
|
|
```python
|
|
# Get metadata without loading all tracks
|
|
info = pomice.PlaylistManager.get_playlist_info('playlists/my_playlist.json')
|
|
# Returns: {'name': '...', 'track_count': 42, 'total_duration': 7200000, ...}
|
|
```
|
|
|
|
### JSON Format
|
|
```json
|
|
{
|
|
"name": "My Playlist",
|
|
"description": "Best songs",
|
|
"created_at": "2024-01-15T12:30:00",
|
|
"track_count": 10,
|
|
"total_duration": 1800000,
|
|
"version": "1.0",
|
|
"tracks": [
|
|
{
|
|
"title": "Song Title",
|
|
"author": "Artist Name",
|
|
"uri": "https://...",
|
|
"identifier": "abc123",
|
|
"length": 180000,
|
|
"thumbnail": "https://...",
|
|
"isrc": "USRC12345678",
|
|
"requester_id": 123456789,
|
|
"requester_name": "User#1234"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Use Cases
|
|
- "Save this queue for later"
|
|
- "Load my favorite playlist"
|
|
- "Merge all my playlists"
|
|
- "Export to M3U for my media player"
|
|
|
|
---
|
|
|
|
## 🔧 Track Utilities
|
|
|
|
Advanced filtering, searching, and sorting utilities for tracks.
|
|
|
|
### TrackFilter
|
|
|
|
Filter tracks by various criteria.
|
|
|
|
```python
|
|
import pomice
|
|
|
|
tracks = list(player.queue)
|
|
|
|
# Filter by duration (milliseconds)
|
|
short_tracks = pomice.TrackFilter.by_duration(
|
|
tracks,
|
|
min_duration=60000, # 1 minute
|
|
max_duration=300000 # 5 minutes
|
|
)
|
|
|
|
# Filter by author
|
|
artist_tracks = pomice.TrackFilter.by_author(
|
|
tracks,
|
|
author='Imagine Dragons',
|
|
exact=False # Case-insensitive contains
|
|
)
|
|
|
|
# Filter by title
|
|
title_tracks = pomice.TrackFilter.by_title(
|
|
tracks,
|
|
title='Thunder',
|
|
exact=True # Exact match
|
|
)
|
|
|
|
# Filter by requester
|
|
user_tracks = pomice.TrackFilter.by_requester(tracks, requester_id=123456789)
|
|
|
|
# Filter by playlist
|
|
playlist_tracks = pomice.TrackFilter.by_playlist(tracks, playlist_name='Rock Hits')
|
|
|
|
# Get only streams
|
|
streams = pomice.TrackFilter.streams_only(tracks)
|
|
|
|
# Get only non-streams
|
|
non_streams = pomice.TrackFilter.non_streams_only(tracks)
|
|
|
|
# Custom filter with lambda
|
|
long_tracks = pomice.TrackFilter.custom(
|
|
tracks,
|
|
predicate=lambda t: t.length > 600000 # > 10 minutes
|
|
)
|
|
```
|
|
|
|
### SearchHelper
|
|
|
|
Search, sort, and organize tracks.
|
|
|
|
```python
|
|
import pomice
|
|
|
|
tracks = list(player.queue)
|
|
|
|
# Search tracks
|
|
results = pomice.SearchHelper.search_tracks(
|
|
tracks,
|
|
query='imagine',
|
|
search_title=True,
|
|
search_author=True,
|
|
case_sensitive=False
|
|
)
|
|
|
|
# Sort by duration
|
|
sorted_tracks = pomice.SearchHelper.sort_by_duration(
|
|
tracks,
|
|
reverse=True # Longest first
|
|
)
|
|
|
|
# Sort by title (alphabetically)
|
|
sorted_tracks = pomice.SearchHelper.sort_by_title(tracks)
|
|
|
|
# Sort by author
|
|
sorted_tracks = pomice.SearchHelper.sort_by_author(tracks)
|
|
|
|
# Remove duplicates
|
|
unique_tracks = pomice.SearchHelper.remove_duplicates(
|
|
tracks,
|
|
by_uri=True, # Remove by URI
|
|
by_title_author=False # Or by title+author combo
|
|
)
|
|
|
|
# Group by author
|
|
grouped = pomice.SearchHelper.group_by_author(tracks)
|
|
# Returns: {'Artist Name': [track1, track2, ...], ...}
|
|
|
|
# Group by playlist
|
|
grouped = pomice.SearchHelper.group_by_playlist(tracks)
|
|
|
|
# Get random tracks
|
|
random_tracks = pomice.SearchHelper.get_random_tracks(tracks, count=5)
|
|
```
|
|
|
|
### Use Cases
|
|
- "Show me all songs by Artist X"
|
|
- "Find tracks between 3-5 minutes"
|
|
- "Sort queue by duration"
|
|
- "Remove duplicate songs"
|
|
- "Play 5 random tracks"
|
|
|
|
---
|
|
|
|
## 🎯 Complete Examples
|
|
|
|
### Example 1: Basic Music Bot with History
|
|
|
|
```python
|
|
import pomice
|
|
from discord.ext import commands
|
|
|
|
class Music(commands.Cog):
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
self.history = pomice.TrackHistory(max_size=100)
|
|
|
|
@commands.Cog.listener()
|
|
async def on_pomice_track_end(self, player, track, _):
|
|
# Add to history when track ends
|
|
self.history.add(track)
|
|
|
|
@commands.command()
|
|
async def history(self, ctx, limit: int = 10):
|
|
"""Show recently played tracks."""
|
|
recent = self.history.get_last(limit)
|
|
|
|
tracks_list = '\n'.join(
|
|
f"{i}. {track.title} by {track.author}"
|
|
for i, track in enumerate(recent, 1)
|
|
)
|
|
|
|
await ctx.send(f"**Recently Played:**\n{tracks_list}")
|
|
```
|
|
|
|
### Example 2: Queue Statistics Command
|
|
|
|
```python
|
|
@commands.command()
|
|
async def stats(self, ctx):
|
|
"""Show queue statistics."""
|
|
player = ctx.voice_client
|
|
stats = pomice.QueueStats(player.queue)
|
|
summary = stats.get_summary()
|
|
|
|
embed = discord.Embed(title='📊 Queue Statistics', color=discord.Color.green())
|
|
|
|
embed.add_field(name='Total Tracks', value=summary['total_tracks'], inline=True)
|
|
embed.add_field(name='Total Duration', value=summary['total_duration_formatted'], inline=True)
|
|
embed.add_field(name='Average Duration', value=summary['average_duration_formatted'], inline=True)
|
|
|
|
if summary['longest_track']:
|
|
embed.add_field(
|
|
name='Longest Track',
|
|
value=f"{summary['longest_track'].title} ({stats.format_duration(summary['longest_track'].length)})",
|
|
inline=False
|
|
)
|
|
|
|
# Top requesters
|
|
top_requesters = stats.get_top_requesters(3)
|
|
if top_requesters:
|
|
requesters_text = '\n'.join(
|
|
f'{i}. {req.display_name}: {count} tracks'
|
|
for i, (req, count) in enumerate(top_requesters, 1)
|
|
)
|
|
embed.add_field(name='Top Requesters', value=requesters_text, inline=False)
|
|
|
|
await ctx.send(embed=embed)
|
|
```
|
|
|
|
### Example 3: Export/Import Playlists
|
|
|
|
```python
|
|
@commands.command()
|
|
async def export(self, ctx, filename: str = 'playlist.json'):
|
|
"""Export current queue to a file."""
|
|
player = ctx.voice_client
|
|
|
|
pomice.PlaylistManager.export_queue(
|
|
player.queue,
|
|
f'playlists/{filename}',
|
|
name=f"{ctx.guild.name}'s Playlist",
|
|
description=f'Exported from {ctx.guild.name}'
|
|
)
|
|
await ctx.send(f'✅ Queue exported to `playlists/{filename}`')
|
|
|
|
@commands.command()
|
|
async def import_playlist(self, ctx, filename: str):
|
|
"""Import a playlist from a file."""
|
|
player = ctx.voice_client
|
|
|
|
data = pomice.PlaylistManager.import_playlist(f'playlists/{filename}')
|
|
uris = [track['uri'] for track in data['tracks'] if track.get('uri')]
|
|
|
|
added = 0
|
|
for uri in uris:
|
|
results = await player.get_tracks(query=uri, ctx=ctx)
|
|
if results:
|
|
await player.queue.put(results[0])
|
|
added += 1
|
|
|
|
await ctx.send(f'✅ Imported {added} tracks from `{data["name"]}`')
|
|
```
|
|
|
|
### Example 4: Filter and Sort Queue
|
|
|
|
```python
|
|
@commands.command()
|
|
async def filter_short(self, ctx):
|
|
"""Show tracks shorter than 3 minutes."""
|
|
player = ctx.voice_client
|
|
tracks = list(player.queue)
|
|
|
|
short_tracks = pomice.TrackFilter.by_duration(
|
|
tracks,
|
|
max_duration=180000 # 3 minutes in ms
|
|
)
|
|
|
|
await ctx.send(f'Found {len(short_tracks)} tracks under 3 minutes!')
|
|
|
|
@commands.command()
|
|
async def sort_queue(self, ctx, sort_by: str = 'duration'):
|
|
"""Sort the queue by duration, title, or author."""
|
|
player = ctx.voice_client
|
|
queue_tracks = list(player.queue)
|
|
|
|
if sort_by == 'duration':
|
|
sorted_tracks = pomice.SearchHelper.sort_by_duration(queue_tracks)
|
|
elif sort_by == 'title':
|
|
sorted_tracks = pomice.SearchHelper.sort_by_title(queue_tracks)
|
|
elif sort_by == 'author':
|
|
sorted_tracks = pomice.SearchHelper.sort_by_author(queue_tracks)
|
|
else:
|
|
return await ctx.send('Valid options: duration, title, author')
|
|
|
|
# Clear and refill queue
|
|
player.queue._queue.clear()
|
|
for track in sorted_tracks:
|
|
await player.queue.put(track)
|
|
|
|
await ctx.send(f'✅ Queue sorted by {sort_by}')
|
|
```
|
|
|
|
---
|
|
|
|
## 📖 Quick Reference
|
|
|
|
### Track History
|
|
```python
|
|
history = pomice.TrackHistory(max_size=100)
|
|
history.add(track)
|
|
recent = history.get_last(10)
|
|
results = history.search("query")
|
|
previous = history.get_previous()
|
|
unique = history.get_unique_tracks()
|
|
```
|
|
|
|
### Queue Statistics
|
|
```python
|
|
stats = pomice.QueueStats(queue)
|
|
total = stats.total_duration
|
|
formatted = stats.format_duration(total)
|
|
top_users = stats.get_top_requesters(5)
|
|
summary = stats.get_summary()
|
|
```
|
|
|
|
### Playlist Manager
|
|
```python
|
|
# Export
|
|
pomice.PlaylistManager.export_queue(queue, 'playlist.json')
|
|
|
|
# Import
|
|
data = pomice.PlaylistManager.import_playlist('playlist.json')
|
|
|
|
# Merge
|
|
pomice.PlaylistManager.merge_playlists(['p1.json', 'p2.json'], 'merged.json')
|
|
|
|
# M3U
|
|
pomice.PlaylistManager.export_to_m3u(tracks, 'playlist.m3u')
|
|
```
|
|
|
|
### Track Utilities
|
|
```python
|
|
# Filter
|
|
short = pomice.TrackFilter.by_duration(tracks, max_duration=180000)
|
|
artist = pomice.TrackFilter.by_author(tracks, "Artist Name")
|
|
|
|
# Search & Sort
|
|
results = pomice.SearchHelper.search_tracks(tracks, "query")
|
|
sorted_tracks = pomice.SearchHelper.sort_by_duration(tracks)
|
|
unique = pomice.SearchHelper.remove_duplicates(tracks)
|
|
random = pomice.SearchHelper.get_random_tracks(tracks, 5)
|
|
```
|
|
|
|
---
|
|
|
|
## 📝 Notes
|
|
|
|
- All duration values are in **milliseconds**
|
|
- History should be maintained per-guild
|
|
- Exported playlists are in JSON format by default
|
|
- M3U export is compatible with most media players
|
|
- All utilities work with standard Pomice Track objects
|
|
|
|
---
|
|
|
|
## 🚀 Getting Started
|
|
|
|
1. **Import the features you need**:
|
|
```python
|
|
import pomice
|
|
```
|
|
|
|
2. **Use them in your commands**:
|
|
```python
|
|
history = pomice.TrackHistory()
|
|
stats = pomice.QueueStats(player.queue)
|
|
```
|
|
|
|
3. **Check the examples** in `examples/advanced_features.py` for a complete bot
|
|
|
|
4. **Experiment** and customize to fit your needs!
|
|
|
|
---
|
|
|
|
## 🎓 Additional Resources
|
|
|
|
- **Full Example Bot**: See `examples/advanced_features.py`
|
|
- **Main Documentation**: See the main Pomice README
|
|
- **Discord Support**: Join the Pomice Discord server
|
|
|
|
---
|
|
|
|
**Happy coding! 🎵**
|