DiscoveryLastFM
Discovers and download via torrent new music. Based on Last.fm listening history and automatically queues downloads via Lidarr or Headphones API
Install / Use
/learn @MrRobotoGit/DiscoveryLastFMREADME
DiscoveryLastFM
🎵 Modern music discovery tool that integrates Last.fm, MusicBrainz, and both Headphones & Lidarr to automatically discover and queue new albums based on your listening history.
🚀 What's New in v2.1.1
Bug Fixes & Improvements
- Robust Retry Logic: Added retry mechanism (3 attempts) for all API calls
- Connection Error Handling: Gracefully handles ConnectionResetError, Timeout, and ConnectionError
- Exponential Backoff: Implements exponential backoff strategy for failed attempts
- Rate Limiting: Improved HTTP 429 rate limit handling
- Enhanced Stability: Fixes fatal crashes from intermittent connection issues
- Better Logging: Enhanced error logging for connection troubleshooting
Previous v2.1.0 Features
- Dual Service Support: Choose between Headphones or Lidarr
- Modular Architecture: Clean service layer for easy extensibility
- Auto Update System: Built-in auto-update from GitHub releases
🎵 Features
Core Discovery Engine
- Smart Discovery: Analyzes your Last.fm listening history to find similar artists
- Quality Filtering: Only queues studio albums, excluding compilations, live albums, EPs, etc.
- Duplicate Prevention: Maintains persistent cache to avoid adding albums multiple times
- Comprehensive Logging: Detailed logging both to console and file
Service Integration
- Dual Service Support: Seamlessly works with both Headphones and Lidarr
- Easy Service Switching: Change between services with a single configuration parameter
- Quality Profiles: Advanced quality and metadata profile management (Lidarr)
- Folder Management: Automatic root folder and library organization
Technical Excellence
- Robust API Handling: Built-in retry mechanisms with exponential backoff
- Rate Limiting: Respects API rate limits for all services
- Modular Architecture: Clean, extensible service layer design
- Configuration Validation: Startup validation ensures proper setup
🛠️ How It Works
- Fetch Recent Artists: Retrieves artists you've listened to recently on Last.fm
- Find Similar Artists: Discovers similar artists using Last.fm's recommendation engine
- Add to Music Service: Automatically adds both original and similar artists to your chosen service (Headphones/Lidarr)
- Queue Top Albums: Fetches and queues the most popular studio albums from each artist
- Smart Filtering: Uses MusicBrainz metadata to filter out non-studio releases
- Cache Management: Maintains cache to optimize performance and avoid duplicates
- Service Integration: Seamlessly works with your chosen music management service
😊 User Reviews
"I for one am happy to wake up on my Sunday to this new music discovery tool."
— Shark7809
"Wow! That sounds amazing! For a newbie like me, who is just starting out in the Plexamp world."
— Hisxela
"This is something I've been looking for actually."
— AlteRedditor
"I'm excited to try this. I've already pulled in a few recommendations and can't wait to let the script keep running to see what else it uncovers."
— mush0uth2
"This is incredible! I'm in the middle of setting things up and was wandering if such thing existed, you made my day!!"
— williewaller
📋 Prerequisites
Required
- Python 3.8+: Modern Python installation
- Last.fm Account: Free account with API key (Get API Key)
- MusicBrainz Access: Public API (no registration required)
Music Service (Choose One)
- Option A: Headphones installation with API access
- Option B: Lidarr installation with API access
🐳 Quick Start with Docker
The easiest way to run DiscoveryLastFM is using Docker!
Automated Setup Script
# Clone the repository
git clone https://github.com/MrRobotoGit/DiscoveryLastFM-Docker.git
cd DiscoveryLastFM-Docker
# Run the automated setup
./scripts/setup-docker.sh
🔗 Complete Docker Guide & Examples
🛠️ Manual Installation
For advanced users who prefer running without Docker:
-
Clone the repository:
git clone https://github.com/MrRobotoGit/DiscoveryLastFM.git cd DiscoveryLastFM -
Install dependencies:
# Recommended for Debian/Ubuntu/Raspberry Pi sudo apt update && sudo apt install python3-requests python3-packaging # Alternative for other systems pip install requests packaging -
Configure the script: Copy the example configuration and edit with your credentials:
cp config.example.py config.pyEdit
config.pywith your actual values:For Headphones users:
MUSIC_SERVICE = "headphones" LASTFM_USERNAME = "your_lastfm_username" LASTFM_API_KEY = "your_lastfm_api_key" HP_API_KEY = "your_headphones_api_key" HP_ENDPOINT = "http://your-headphones-server:port"For Lidarr users:
MUSIC_SERVICE = "lidarr" LASTFM_USERNAME = "your_lastfm_username" LASTFM_API_KEY = "your_lastfm_api_key" LIDARR_API_KEY = "your_lidarr_api_key" LIDARR_ENDPOINT = "http://your-lidarr-server:port" LIDARR_ROOT_FOLDER = "/music" LIDARR_QUALITY_PROFILE_ID = 2 # 2=Lossless (recommended) LIDARR_METADATA_PROFILE_ID = 1 # 1=Standard
⚙️ Configuration
Service Selection
Choose your music management service with the MUSIC_SERVICE parameter:
MUSIC_SERVICE = "headphones" # or "lidarr"
Discovery Parameters
The script offers several configurable parameters:
| Parameter | Default | Description |
|-----------|---------|-------------|
| MUSIC_SERVICE | "headphones" | Music service: "headphones" or "lidarr" |
| RECENT_MONTHS | 3 | Months of listening history to analyze |
| MIN_PLAYS | 20 | Minimum plays required to consider an artist |
| SIMILAR_MATCH_MIN | 0.46 | Minimum similarity score for artist matching |
| MAX_SIMILAR_PER_ART | 20 | Maximum similar artists to process per artist |
| MAX_POP_ALBUMS | 5 | Maximum popular albums to queue per artist |
| CACHE_TTL_HOURS | 24 | Cache time-to-live in hours |
Lidarr-Specific Configuration
| Parameter | Default | Description |
|-----------|---------|-------------|
| LIDARR_QUALITY_PROFILE_ID | 2 | Quality profile (1=Any, 2=Lossless, 3=Standard) |
| LIDARR_METADATA_PROFILE_ID | 1 | Metadata profile (1=Standard, 2=None) |
| LIDARR_MONITOR_MODE | "all" | Monitor mode: "all", "future", "missing", etc. |
| LIDARR_SEARCH_ON_ADD | True | Auto-search when adding artists/albums |
🏃 Usage
Manual Execution
python3 DiscoveryLastFM.py
Automated Execution (Cron)
Set up a daily cron job for automated discovery:
# Run daily at 3:00 AM
0 3 * * * python3 /path/to/DiscoveryLastFM/DiscoveryLastFM.py >> /path/to/DiscoveryLastFM/log/discover.log 2>&1
🔄 Auto-Update System
DiscoveryLastFM includes a built-in auto-update system to keep your installation current.
CLI Commands
# Check for updates and install
python3 DiscoveryLastFM.py --update
# Show current version
python3 DiscoveryLastFM.py --version
# Show update status
python3 DiscoveryLastFM.py --update-status
# List available backups
python3 DiscoveryLastFM.py --list-backups
Configuration
Add to your config.py to enable automatic update checking:
AUTO_UPDATE_ENABLED = True # Enable automatic update checking
UPDATE_CHECK_INTERVAL_HOURS = 24 # Check frequency in hours
BACKUP_RETENTION_DAYS = 7 # Backup retention period
The auto-update system includes automatic backup creation, safe installation with verification, and automatic rollback if issues are detected. Your configuration files and cache are always preserved during updates.
📊 Sample Output
2025-06-22 03:00:01 INFO Analizzo 15 artisti...
2025-06-22 03:00:05 INFO Processo artista: Radiohead (a74b1b7f-71a5-4011-9441-d0b5e4122711)
2025-06-22 03:00:10 INFO Trovati 5 album per Thom Yorke
2025-06-22 03:00:15 INFO Aggiungo album f47ac10b-58cc-4372-a567-0e02b2c3d479
2025-06-22 03:05:30 INFO Sync completata in 5.5 minuti. Statistiche:
2025-06-22 03:05:30 INFO - Album aggiunti con successo: 42
2025-06-22 03:05:30 INFO - Errori riscontrati: 3
2025-06-22 03:05:30 INFO - Album skippati: 18
2025-06-22 03:05:30 INFO - Artisti processati: 85
📁 Project Structure
DiscoveryLastFM/
├── DiscoveryLastFM.py # Main script
├── config.example.py # Example configuration file
├── config.py # Your configuration (not in git)
├── services/ # Service layer (v2.0)
│ ├── __init__.py # Module initialization
│ ├── base.py # Abstract base classes
│ ├── exceptions.py #
