This commit is contained in:
cool.gitter.not.me.again.duh
2025-05-31 16:09:29 -06:00
parent 089cb3dc5a
commit 42411b7ffa
5 changed files with 292 additions and 694 deletions

43
.github/workflows/publish-to-pypi.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Publish Python Package to PyPI
on:
release:
types: [published]
jobs:
build-and-publish:
name: Build and publish Python package to PyPI
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.x"
- name: Install pypa/build
run: >-
python -m
pip install
build
--user
- name: Build a binary wheel and a source tarball
run: >-
python -m
build
--sdist
--wheel
--outdir dist/
.
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
# You may want to publish to a test PyPI repository first
# repository_url: https://test.pypi.org/legacy/
# package_name: deezspot-spotizerr # Ensure this matches your package name if needed explicitly

917
README.md
View File

@@ -1,712 +1,265 @@
# DeezSpot
DeezSpot is a Python library that enables downloading songs, albums, playlists, and podcasts from both Deezer and Spotify. This fork includes tweaks for use with the [spotizerr](https://github.com/Xoconoch/spotizerr) project.
## Description
DeezSpot is a Python library designed for downloading music and episodes from Deezer and Spotify. It allows users to fetch tracks, albums, playlists, and podcast episodes, with support for various audio qualities and tagging.
## Features
- Download tracks, albums, playlists, and podcasts from both Deezer and Spotify
- Search for music by name or download directly using links
- Support for different audio quality options
- Download an artist's discography
- Smart link detection to identify and process different types of content
- Tag downloaded files with correct metadata
- Customizable file and directory naming formats
- **Download from Deezer and Spotify:** Supports downloading content from both major streaming platforms.
- **Content Types:**
* Tracks
* Albums
* Playlists
* Podcast Episodes
- **Audio Quality:** Choose from multiple audio quality options (e.g., MP3\_320, FLAC for Deezer; NORMAL, HIGH, VERY\_HIGH for Spotify).
- **Audio Conversion:** Option to convert downloaded audio to different formats (e.g., mp3, flac, opus, m4a).
- **Metadata Tagging:** Automatically tags downloaded files with relevant metadata (title, artist, album, cover art, etc.).
- **Spotify to Deezer Link Conversion:** Convert Spotify track and album links to their Deezer equivalents to facilitate downloading via Deezer.
- **Login Management:** Securely handles login credentials for Deezer (ARL cookie or email/password) and Spotify (client ID/secret, credentials file).
- **Progress Reporting:** Provides callbacks for real-time progress updates during downloads.
- **Customizable Output:** Flexible options for naming and organizing downloaded files and directories.
- **Resilient Downloads:** Includes retry mechanisms for handling network issues.
- **M3U Playlist Generation:** Automatically creates M3U playlist files for downloaded playlists.
- **ZIP Archiving:** Option to create ZIP archives of downloaded albums and playlists.
## Installation
### From PyPI (recommended)
(Provide instructions on how to install the library, e.g., using pip)
```bash
pip install git+https://github.com/Xoconoch/deezspot-fork-again.git
pip install deezspot-spotizerr
```
*(Note: Adjust the package name if it's different on PyPI)*
Or, if installing from a local source:
```bash
pip install .
```
### From Source
## Usage
```bash
git clone https://github.com/Xoconoch/deezspot-fork-again.git
cd deezspot-fork-again
pip install -e .
### Initialization
**For Deezer:**
```python
from deezspot import DeeLogin
# Using ARL cookie (recommended)
deezer_downloader = DeeLogin(arl="YOUR_DEEZER_ARL_COOKIE")
# Or using email and password (less secure, might be deprecated by Deezer)
# deezer_downloader = DeeLogin(email="your_email", password="your_password")
```
**For Spotify:**
```python
from deezspot.spotloader import SpoLogin # Corrected import path
# You need Spotify API credentials (client_id, client_secret)
# and a credentials.json file for librespot.
spotify_downloader = SpoLogin(
credentials_path="path/to/your/credentials.json",
spotify_client_id="YOUR_SPOTIFY_CLIENT_ID",
spotify_client_secret="YOUR_SPOTIFY_CLIENT_SECRET"
)
```
### Downloading Content
**Deezer Examples:**
```python
# Download a track from Deezer
track_link_dee = "https://www.deezer.com/track/TRACK_ID"
downloaded_track = deezer_downloader.download_trackdee(
link_track=track_link_dee,
output_dir="./music_downloads",
quality_download="FLAC", # or "MP3_320"
convert_to="mp3-320" # Optional: convert to mp3 at 320kbps
)
print(f"Downloaded Deezer track: {downloaded_track.song_path}")
# Download an album from Deezer
album_link_dee = "https://www.deezer.com/album/ALBUM_ID"
downloaded_album = deezer_downloader.download_albumdee(
link_album=album_link_dee,
output_dir="./music_downloads",
make_zip=True
)
print(f"Downloaded Deezer album: {downloaded_album.album_name}")
if downloaded_album.zip_path:
print(f"Album ZIP created at: {downloaded_album.zip_path}")
# Download a playlist from Deezer
playlist_link_dee = "https://www.deezer.com/playlist/PLAYLIST_ID"
downloaded_playlist = deezer_downloader.download_playlistdee(
link_playlist=playlist_link_dee,
output_dir="./music_downloads"
)
print(f"Downloaded Deezer playlist: {len(downloaded_playlist.tracks)} tracks")
# Download an episode from Deezer
episode_link_dee = "https://www.deezer.com/episode/EPISODE_ID"
downloaded_episode = deezer_downloader.download_episode(
link_episode=episode_link_dee,
output_dir="./podcast_downloads"
)
print(f"Downloaded Deezer episode: {downloaded_episode.episode_path}")
```
**Spotify Examples:**
```python
# Download a track from Spotify
track_link_spo = "https://open.spotify.com/track/TRACK_ID"
downloaded_track_spo = spotify_downloader.download_track(
link_track=track_link_spo,
output_dir="./music_downloads_spotify",
quality_download="VERY_HIGH", # or "HIGH", "NORMAL"
convert_to="flac" # Optional: convert to FLAC
)
print(f"Downloaded Spotify track: {downloaded_track_spo.song_path}")
# Download an album from Spotify
album_link_spo = "https://open.spotify.com/album/ALBUM_ID"
downloaded_album_spo = spotify_downloader.download_album(
link_album=album_link_spo,
output_dir="./music_downloads_spotify",
make_zip=True
)
print(f"Downloaded Spotify album: {downloaded_album_spo.album_name}")
# Download a playlist from Spotify
playlist_link_spo = "https://open.spotify.com/playlist/PLAYLIST_ID"
downloaded_playlist_spo = spotify_downloader.download_playlist(
link_playlist=playlist_link_spo,
output_dir="./music_downloads_spotify"
)
print(f"Downloaded Spotify playlist: {len(downloaded_playlist_spo.tracks)} tracks")
# Download an episode from Spotify
episode_link_spo = "https://open.spotify.com/episode/EPISODE_ID"
downloaded_episode_spo = spotify_downloader.download_episode(
link_episode=episode_link_spo,
output_dir="./podcast_downloads_spotify"
)
print(f"Downloaded Spotify episode: {downloaded_episode_spo.episode_path}")
```
**Smart Downloader (Deezer only for now):**
The smart downloader automatically detects the content type (track, album, playlist) from the URL.
```python
smart_link_dee = "https://www.deezer.com/album/ALBUM_ID_OR_TRACK_ID_OR_PLAYLIST_ID"
smart_download_result = deezer_downloader.download_smart(
link=smart_link_dee,
output_dir="./smart_downloads"
)
print(f"Smart download type: {smart_download_result.type}")
if smart_download_result.type == "track":
print(f"Downloaded track: {smart_download_result.track.song_path}")
elif smart_download_result.type == "album":
print(f"Downloaded album: {smart_download_result.album.album_name}")
# ... and so on for playlist
```
### Customizing Output Paths
You can customize the directory structure and track filenames using `custom_dir_format` and `custom_track_format` parameters available in most download methods. These parameters accept strings with placeholders that will be replaced with metadata.
**Available placeholders:**
* `%artist%`
* `%albumartist%`
* `%album%`
* `%title%`
* `%tracknumber%` (can be padded with `pad_tracks=True/False`)
* `%discnumber%`
* `%year%`
* `%genre%`
* `%isrc%`
* `%upc%` (for albums)
* `%quality%` (e.g., "FLAC", "320")
* `%explicit%` (e.g. "Explicit" or empty string)
* `%showname%` (for episodes)
* `%episodetitle%` (for episodes)
* `%podcastgenre%` (for episodes)
**Example:**
```python
# For Deezer
deezer_downloader.download_trackdee(
link_track="some_track_link",
output_dir="./custom_music",
custom_dir_format="%artist%/%album% (%year%)",
custom_track_format="%tracknumber%. %title% [%quality%]",
pad_tracks=True # Results in "01. Song Title [FLAC]"
)
# For Spotify
spotify_downloader.download_track(
link_track="some_spotify_track_link",
output_dir="./custom_music_spotify",
custom_dir_format="%artist% - %album%",
custom_track_format="%title% - %artist%",
pad_tracks=False
)
```
### Progress Reporting
You can provide a callback function during initialization to receive progress updates.
```python
def my_progress_callback(progress_data):
# progress_data is a dictionary with information about the download progress
# Example keys: "type", "status", "song", "artist", "progress", "total_tracks", "current_track", "parent", etc.
print(f"Progress: {progress_data}")
# For Deezer
# deezer_downloader = DeeLogin(arl="YOUR_ARL", progress_callback=my_progress_callback)
# For Spotify
# spotify_downloader = SpoLogin(
# credentials_path="path/to/credentials.json",
# spotify_client_id="YOUR_ID",
# spotify_client_secret="YOUR_SECRET",
# progress_callback=my_progress_callback
# )
```
## Configuration
### Deezer Authentication
DeezSpot supports two methods of authentication for Deezer:
1. Using ARL token:
```python
from deezspot.deezloader import DeeLogin
# Authenticate with ARL
downloader = DeeLogin(arl="your_arl_token")
```
2. Using email and password:
```python
from deezspot.deezloader import DeeLogin
# Authenticate with email and password
downloader = DeeLogin(email="your_email", password="your_password")
```
### Spotify Authentication
For Spotify, you'll need a credentials file:
```python
from deezspot.spotloader import SpoLogin
# Authenticate with credentials file
downloader = SpoLogin(credentials_path="/path/to/credentials.json")
```
To create a credentials file, use a tool like [librespot-java](https://github.com/librespot-org/librespot-java) to generate it.
## Usage
### Downloading from Deezer
```python
from deezspot.deezloader import DeeLogin
# Initialize with your credentials
downloader = DeeLogin(arl="your_arl_token")
# Download a track
track = downloader.download_trackdee(
"https://www.deezer.com/track/123456789",
output_dir="./downloads",
quality_download="FLAC" # Options: MP3_320, FLAC, MP3_128
)
# Download an album
album = downloader.download_albumdee(
"https://www.deezer.com/album/123456789",
output_dir="./downloads",
quality_download="MP3_320",
make_zip=True # Create a zip archive of the album
)
# Download a playlist
playlist = downloader.download_playlistdee(
"https://www.deezer.com/playlist/123456789",
output_dir="./downloads",
quality_download="MP3_320"
)
# Download an artist's top tracks
tracks = downloader.download_artisttopdee(
"https://www.deezer.com/artist/123456789",
output_dir="./downloads"
)
# Search and download by name
track = downloader.download_name(
artist="Artist Name",
song="Song Title",
output_dir="./downloads"
)
```
### Downloading from Spotify
```python
from deezspot.spotloader import SpoLogin
import logging
from deezspot import set_log_level, enable_file_logging
# Configure logging
set_log_level(logging.INFO)
enable_file_logging("spotify_downloads.log")
# Custom progress callback
def spotify_progress_callback(progress_data):
status = progress_data.get("status")
if status == "real_time":
song = progress_data.get("song", "Unknown")
percentage = progress_data.get("percentage", 0) * 100
print(f"Downloading '{song}': {percentage:.1f}%")
elif status == "downloading":
print(f"Starting download: {progress_data.get('song', 'Unknown')}")
elif status == "done":
print(f"Completed: {progress_data.get('song', 'Unknown')}")
# Initialize Spotify client with progress callback
spotify = SpoLogin(
credentials_path="credentials.json",
spotify_client_id="your_client_id",
spotify_client_secret="your_client_secret",
progress_callback=spotify_progress_callback
)
# Or use silent mode for background operations
spotify_silent = SpoLogin(
credentials_path="credentials.json",
spotify_client_id="your_client_id",
spotify_client_secret="your_client_secret",
silent=True
)
# Download a track
spotify.download_track(
"https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT",
output_dir="downloads",
quality_download="HIGH",
real_time_dl=True
)
# Download an album
album = spotify.download_album(
"https://open.spotify.com/album/123456789",
output_dir="./downloads",
quality_download="HIGH",
make_zip=True # Create a zip archive of the album
)
# Download a playlist
playlist = spotify.download_playlist(
"https://open.spotify.com/playlist/123456789",
output_dir="./downloads"
)
# Download a podcast episode
episode = spotify.download_episode(
"https://open.spotify.com/episode/123456789",
output_dir="./downloads"
)
# Download an artist's discography
spotify.download_artist(
"https://open.spotify.com/artist/123456789",
album_type="album,single", # Options: album, single, compilation, appears_on
limit=50, # Number of albums to retrieve
output_dir="./downloads"
)
```
### Smart Download
Both the Deezer and Spotify interfaces provide a "smart" download function that automatically detects the type of content from the link:
```python
# For Deezer
result = downloader.download_smart("https://www.deezer.com/track/123456789")
# For Spotify
result = downloader.download_smart("https://open.spotify.com/album/123456789")
```
### Converting Spotify links to Deezer
DeezSpot can also convert Spotify links to Deezer for downloading with higher quality:
```python
# Convert and download a Spotify track using Deezer
track = downloader.download_trackspo("https://open.spotify.com/track/123456789")
# Convert and download a Spotify album using Deezer
album = downloader.download_albumspo("https://open.spotify.com/album/123456789")
# Convert and download a Spotify playlist using Deezer
playlist = downloader.download_playlistspo("https://open.spotify.com/playlist/123456789")
```
## Available Quality Options
### Deezer
- `MP3_320`: 320 kbps MP3
- `FLAC`: Lossless audio
- `MP3_128`: 128 kbps MP3
- **ARL Cookie:** The primary method for Deezer authentication. You can obtain this from your browser's developer tools when logged into Deezer.
- **Email/Password:** Can be used but is less secure and may have limitations.
### Spotify
- `VERY_HIGH`: 320 kbps OGG
- `HIGH`: 160 kbps OGG
- `NORMAL`: 96 kbps OGG
- **Spotify API Credentials:** You'll need a Client ID and Client Secret from the Spotify Developer Dashboard.
- **`credentials.json`:** This file is used by the underlying `librespot` library for session management. The `SpoLogin` class requires the path to this file. If it doesn't exist, `librespot` might attempt to create it or guide you through an authentication flow (behavior depends on `librespot`).
## Common Parameters
## Logging
Most download methods accept these common parameters:
- `output_dir`: Output directory for downloaded files (default: "Songs/")
- `quality_download`: Quality of audio files (see options above)
- `recursive_quality`: Try another quality if the selected one is not available (default: True)
- `recursive_download`: Try another API if the current one fails (default: True)
- `not_interface`: Hide download progress (default: False)
- `make_zip`: Create a zip archive for albums/playlists (default: False)
- `method_save`: How to save the downloads (default: varies by function)
- `custom_dir_format`: Custom directory naming format
- `custom_track_format`: Custom track naming format
## Custom Naming Formats
You can customize the output directory and file naming patterns:
The library uses Python's standard `logging` module. You can configure the logging level and output:
```python
# Example of custom directory format
result = downloader.download_albumdee(
"https://www.deezer.com/album/123456789",
custom_dir_format="{artist}/{album} [{year}]"
)
# Example of custom track format
result = downloader.download_trackdee(
"https://www.deezer.com/track/123456789",
custom_track_format="{tracknumber} - {title}"
)
```
## License
This project is licensed under the GNU Affero General Public License v3.0 - see the [LICENSE](LICENSE) file for details.
## Credits
This project is a fork of the [original deezspot library](https://github.com/jakiepari/deezspot).
# Deezspot Logging System
This document explains the enhanced logging system implemented in the Deezspot library, making it more suitable for production environments, Celery integrations, and other enterprise applications.
## Overview
The logging system in Deezspot provides:
- Standardized, structured log messages
- Multiple logging levels for different verbosity needs
- File logging capabilities for persistent logs
- Console output for interactive use
- JSON-formatted progress updates
- Custom progress callbacks for integration with other systems
- Silent mode for background operation
## Basic Configuration
### Setting Log Level
```python
from deezspot import set_log_level
import logging
from deezspot import set_log_level, enable_file_logging, disable_logging
# Available log levels:
# - logging.DEBUG (most verbose)
# - logging.INFO (default)
# - logging.WARNING
# - logging.ERROR
# - logging.CRITICAL (least verbose)
# Set logging level (e.g., INFO, DEBUG, WARNING)
set_log_level(logging.DEBUG)
set_log_level(logging.INFO) # Default level shows important information
set_log_level(logging.DEBUG) # For detailed debugging information
set_log_level(logging.WARNING) # For warnings and errors only
# Enable logging to a file
# enable_file_logging("deezspot.log", level=logging.INFO)
# Disable all logging
# disable_logging()
```
### Enabling File Logging
```python
from deezspot import enable_file_logging
# Enable logging to a file (in addition to console)
enable_file_logging("/path/to/logs/deezspot.log")
# With custom log level
enable_file_logging("/path/to/logs/deezspot.log", level=logging.DEBUG)
```
### Disabling Logging
```python
from deezspot import disable_logging
# Completely disable logging (except critical errors)
disable_logging()
```
## Progress Reporting
The library uses a structured JSON format for progress reporting, making it easy to integrate with other systems.
### Progress JSON Structure
For tracks:
```json
{
"status": "downloading|progress|done|skipped|retrying",
"type": "track",
"album": "Album Name",
"song": "Song Title",
"artist": "Artist Name"
}
```
For real-time downloads:
```json
{
"status": "real_time",
"song": "Song Title",
"artist": "Artist Name",
"time_elapsed": 1500,
"percentage": 0.75
}
```
For albums:
```json
{
"status": "initializing|progress|done",
"type": "album",
"album": "Album Name",
"artist": "Artist Name",
"track": "Current Track Title",
"current_track": "3/12"
}
```
For playlists:
```json
{
"status": "initializing|progress|done",
"type": "playlist",
"name": "Playlist Name",
"track": "Current Track Title",
"current_track": "5/25",
"total_tracks": 25
}
```
## Custom Progress Callbacks
For integration with other systems (like Celery), you can provide a custom progress callback function when initializing the library.
### Example with Custom Callback
```python
from deezspot.deezloader import DeeLogin
def my_progress_callback(progress_data):
"""
Custom callback function to handle progress updates
Args:
progress_data: Dictionary containing progress information
"""
status = progress_data.get("status")
track_title = progress_data.get("song", "")
if status == "downloading":
print(f"Starting download: {track_title}")
elif status == "progress":
current = progress_data.get("current_track", "")
print(f"Progress: {current} - {track_title}")
elif status == "done":
print(f"Completed: {track_title}")
elif status == "real_time":
percentage = progress_data.get("percentage", 0) * 100
print(f"Downloading: {track_title} - {percentage:.1f}%")
# Initialize with custom callback
deezer = DeeLogin(
arl="your_arl_token",
progress_callback=my_progress_callback
)
```
### Silent Mode
If you want to disable progress reporting completely (for background operations), use silent mode:
```python
deezer = DeeLogin(
arl="your_arl_token",
silent=True
)
```
## Spotify Integration
For Spotify downloads, the same logging principles apply. Here's an example using the Spotify client:
```python
from deezspot.spotloader import SpoLogin
import logging
from deezspot import set_log_level, enable_file_logging
# Configure logging
set_log_level(logging.INFO)
enable_file_logging("spotify_downloads.log")
# Custom progress callback
def spotify_progress_callback(progress_data):
status = progress_data.get("status")
if status == "real_time":
song = progress_data.get("song", "Unknown")
percentage = progress_data.get("percentage", 0) * 100
print(f"Downloading '{song}': {percentage:.1f}%")
elif status == "downloading":
print(f"Starting download: {progress_data.get('song', 'Unknown')}")
elif status == "done":
print(f"Completed: {progress_data.get('song', 'Unknown')}")
# Initialize Spotify client with progress callback
spotify = SpoLogin(
credentials_path="credentials.json",
spotify_client_id="your_client_id",
spotify_client_secret="your_client_secret",
progress_callback=spotify_progress_callback
)
# Or use silent mode for background operations
spotify_silent = SpoLogin(
credentials_path="credentials.json",
spotify_client_id="your_client_id",
spotify_client_secret="your_client_secret",
silent=True
)
# Download a track
spotify.download_track(
"https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT",
output_dir="downloads",
quality_download="HIGH",
real_time_dl=True
)
```
## Celery Integration Example
Here's how to integrate the logging system with Celery for task progress reporting:
```python
from celery import Celery
from deezspot.deezloader import DeeLogin
import logging
from deezspot import enable_file_logging
# Configure Celery
app = Celery('tasks', broker='pyamqp://guest@localhost//')
# Configure logging
enable_file_logging("/path/to/logs/deezspot.log", level=logging.INFO)
@app.task(bind=True)
def download_music(self, link, output_dir):
# Create a progress callback that updates the Celery task state
def update_progress(progress_data):
status = progress_data.get("status")
if status == "downloading":
self.update_state(
state="DOWNLOADING",
meta={
"track": progress_data.get("song", ""),
"progress": 0
}
)
elif status == "progress":
current, total = progress_data.get("current_track", "1/1").split("/")
progress = int(current) / int(total)
self.update_state(
state="PROGRESS",
meta={
"track": progress_data.get("track", ""),
"progress": progress
}
)
elif status == "real_time":
self.update_state(
state="PROGRESS",
meta={
"track": progress_data.get("song", ""),
"progress": progress_data.get("percentage", 0)
}
)
elif status == "done":
self.update_state(
state="COMPLETED",
meta={
"track": progress_data.get("song", ""),
"progress": 1.0
}
)
# Initialize the client with the progress callback
deezer = DeeLogin(
arl="your_arl_token",
progress_callback=update_progress
)
# Download the content
result = deezer.download_smart(
link=link,
output_dir=output_dir,
quality_download="MP3_320"
)
return {"status": "completed", "output": result.track.song_path}
```
## Direct Logger Access
For advanced use cases, you can directly access and use the logger:
```python
from deezspot.libutils.logging_utils import logger
# Use the logger directly
logger.debug("Detailed debugging information")
logger.info("General information")
logger.warning("Warning message")
logger.error("Error message")
logger.critical("Critical error message")
# Log structured data
import json
logger.info(json.dumps({
"custom_event": "download_started",
"metadata": {
"source": "spotify",
"track_id": "1234567890"
}
}))
```
## Log Format
The default log format is:
```
%(asctime)s - %(name)s - %(levelname)s - %(message)s
```
Example:
```
2023-10-15 12:34:56,789 - deezspot - INFO - {"status": "downloading", "type": "track", "album": "Album Name", "song": "Song Title", "artist": "Artist Name"}
```
## Console vs File Logging
- By default, the library is configured to log at WARNING level to the console only
- You can enable file logging in addition to console logging
- File and console logging can have different log levels
## Using the Logger in Your Code
If you're extending the library or integrating it deeply into your application, you can use the logger directly:
```python
from deezspot.libutils.logging_utils import logger, ProgressReporter
# Create a custom progress reporter
my_reporter = ProgressReporter(
callback=my_callback_function,
silent=False,
log_level=logging.INFO
)
# Report progress
my_reporter.report({
"status": "custom_status",
"message": "Custom progress message",
"progress": 0.5
})
# Log directly
logger.info("Processing started")
```
## Test Script Example
Here's a complete example script that tests the Spotify functionality with logging enabled:
```python
#!/usr/bin/env python3
import os
import logging
from deezspot import set_log_level, enable_file_logging
from deezspot.spotloader import SpoLogin
def main():
# Configure logging
set_log_level(logging.INFO) # Set to logging.DEBUG for more detailed output
enable_file_logging("deezspot.log")
# Spotify API credentials
SPOTIFY_CLIENT_ID = "your_client_id"
SPOTIFY_CLIENT_SECRET = "your_client_secret"
# Path to your Spotify credentials file (from librespot)
CREDENTIALS_PATH = "credentials.json"
# Output directory for downloads
OUTPUT_DIR = "downloads"
os.makedirs(OUTPUT_DIR, exist_ok=True)
try:
# Initialize the Spotify client
spotify = SpoLogin(
credentials_path=CREDENTIALS_PATH,
spotify_client_id=SPOTIFY_CLIENT_ID,
spotify_client_secret=SPOTIFY_CLIENT_SECRET
)
# Test track download
print("\nTesting track download...")
track_url = "https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT"
spotify.download_track(
track_url,
output_dir=OUTPUT_DIR,
quality_download="HIGH",
real_time_dl=True,
custom_dir_format="{artist}/{album}",
custom_track_format="{tracknum} - {title}"
)
except Exception as e:
print(f"Error: {str(e)}")
logging.error(f"Test failed: {str(e)}", exc_info=True)
if __name__ == "__main__":
main()
```
This logging system provides flexibility for both simple scripts and complex production applications, making it easier to monitor and integrate Deezspot in any environment.
## Callback Functionality
Both the Deezer and Spotify components of the deezspot library now support progress callbacks, allowing you to integrate download progress into your applications. This feature enables:
1. **Real-time Progress Tracking**: Monitor download progress for tracks, albums, playlists, and episodes
2. **Custom UI Integration**: Update your application's UI with download status
3. **Background Processing**: Run downloads silently in background tasks
4. **Task Management**: Integrate with task systems like Celery for distributed processing
### Common Callback Events
The progress callback function receives a dictionary with the following common fields:
- `status`: The current status of the operation (`initializing`, `downloading`, `progress`, `done`, `skipped`, `retrying`, `real_time`)
- `type`: The type of content (`track`, `album`, `playlist`, `episode`)
- Additional fields depending on the status and content type
### Usage in Both Components
Both the Deezer and Spotify components use the same callback system:
```python
# For Deezer
deezer = DeeLogin(
arl="your_arl_token",
progress_callback=my_callback_function,
silent=False # Set to True to disable progress reporting
)
# For Spotify
spotify = SpoLogin(
credentials_path="credentials.json",
spotify_client_id="your_client_id",
spotify_client_secret="your_client_secret",
progress_callback=my_callback_function,
silent=False # Set to True to disable progress reporting
)
```
The standardized callback system ensures that your application can handle progress updates consistently regardless of whether the content is being downloaded from Deezer or Spotify.

View File

@@ -11,7 +11,7 @@ from deezspot.libutils.logging_utils import configure_logger, logger
from deezspot.deezloader import DeeLogin
from deezspot.models import Track, Album, Playlist, Smart, Episode
__version__ = "1.0.1"
__version__ = "1.2.0"
# Configure default logging (silent by default)
configure_logger(level=logging.WARNING, to_console=False)

View File

@@ -3,7 +3,7 @@ requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "deezspot"
name = "deezspot-spotizerr"
version = "1.1"
description = "Downloads songs, albums or playlists from deezer and spotify (clone from deezloader)"
readme = "README.md"
@@ -22,13 +22,13 @@ dependencies = [
"fastapi",
"uvicorn[standard]",
"spotipy-anon",
"librespot"
"librespot-spotizerr"
]
[project.urls]
Homepage = "https://github.com/jakiepari/deezspot"
Repository = "https://github.com/jakiepari/deezspot.git"
Documentation = "https://github.com/jakiepari/deezspot/blob/main/README.md"
Homepage = "https://github.com/Xoconoch/deezspot-spotizerr"
Repository = "https://github.com/Xoconoch/deezspot-spotizerr.git"
Documentation = "https://github.com/Xoconoch/deezspot-spotizerr/blob/main/README.md"
[tool.setuptools]
packages = [

View File

@@ -5,9 +5,9 @@ readmed = README.read()
README.close()
setup(
name = "deezspot",
version = "1.1",
description = "Downloads songs, albums or playlists from deezer and spotify (clone from https://pypi.org/project/deezloader/)",
name = "deezspot-spotizerr",
version = "1.2.0",
description = "Spotizerr's implementation of deezspot",
long_description = readmed,
long_description_content_type = "text/markdown",
license = "GNU Affero General Public License v3",
@@ -18,8 +18,10 @@ setup(
packages = [
"deezspot",
"deezspot/models", "deezspot/spotloader",
"deezspot/deezloader", "deezspot/libutils"
"deezspot.models",
"deezspot.spotloader",
"deezspot.deezloader",
"deezspot.libutils"
],
install_requires = [
@@ -27,6 +29,6 @@ setup(
"spotipy", "tqdm", "fastapi",
"uvicorn[standard]",
"spotipy-anon",
"librespot"
"librespot-spotizerr"
],
)