refactor: reuse Jellyfin settings for Spotify feature

- Remove duplicate JellyfinUrl and ApiKey from SpotifyImportSettings
- Use existing JELLYFIN_URL and JELLYFIN_API_KEY settings
- Simplify configuration - no duplicate settings needed
- Update documentation and .env.example
This commit is contained in:
2026-01-31 16:52:26 -05:00
parent 0ee1883ccb
commit 2b078453b2
6 changed files with 28 additions and 44 deletions

View File

@@ -100,19 +100,11 @@ CACHE_DURATION_HOURS=1
# REQUIRES: Jellyfin Spotify Import Plugin (https://github.com/Viperinius/jellyfin-plugin-spotify-import)
# This feature injects virtual Spotify playlists (Release Radar, Discover Weekly) into Jellyfin
# with tracks auto-matched from external providers (SquidWTF, Deezer, Qobuz)
# Uses JELLYFIN_URL and JELLYFIN_API_KEY for API access
# Enable Spotify playlist injection (optional, default: false)
SPOTIFY_IMPORT_ENABLED=false
# Jellyfin server URL (required if SPOTIFY_IMPORT_ENABLED=true)
# Should match your JELLYFIN_URL unless using a different URL for plugin access
SPOTIFY_IMPORT_JELLYFIN_URL=http://localhost:8096
# Jellyfin API key (REQUIRED if SPOTIFY_IMPORT_ENABLED=true)
# Get from Jellyfin Dashboard > API Keys > Create new key
# This is used to fetch missing tracks files from the Spotify Import plugin
SPOTIFY_IMPORT_API_KEY=
# Sync schedule: When does the Spotify Import plugin run?
# Set these to match your plugin's sync schedule in Jellyfin
# Example: If plugin runs daily at 4:15 PM, set HOUR=16 and MINUTE=15

View File

@@ -295,15 +295,13 @@ Allstarr can inject virtual Spotify playlists (Release Radar, Discover Weekly) i
**Requirements:**
- [Jellyfin Spotify Import Plugin](https://github.com/Viperinius/jellyfin-plugin-spotify-import) installed and configured
- Plugin must run on a daily schedule (e.g., 4:15 PM daily)
- Jellyfin API key with access to plugin endpoints
- Jellyfin URL and API key configured (uses existing JELLYFIN_URL and JELLYFIN_API_KEY settings)
**Configuration:**
| Setting | Description |
|---------|-------------|
| `SpotifyImport:Enabled` | Enable Spotify playlist injection (default: `false`) |
| `SpotifyImport:JellyfinUrl` | Jellyfin server URL for plugin access |
| `SpotifyImport:ApiKey` | **REQUIRED** - Jellyfin API key for accessing missing tracks files |
| `SpotifyImport:SyncStartHour` | Hour when plugin runs (24-hour format, 0-23) |
| `SpotifyImport:SyncStartMinute` | Minute when plugin runs (0-59) |
| `SpotifyImport:SyncWindowHours` | Hours to search for missing tracks files after sync time |
@@ -319,15 +317,13 @@ Allstarr can inject virtual Spotify playlists (Release Radar, Discover Weekly) i
**Environment variables:**
```bash
SPOTIFY_IMPORT_ENABLED=true
SPOTIFY_IMPORT_JELLYFIN_URL=http://localhost:8096
SPOTIFY_IMPORT_API_KEY=your-jellyfin-api-key
SPOTIFY_IMPORT_SYNC_START_HOUR=16
SPOTIFY_IMPORT_SYNC_START_MINUTE=15
SPOTIFY_IMPORT_SYNC_WINDOW_HOURS=2
SPOTIFY_IMPORT_PLAYLISTS=Release Radar,Discover Weekly
```
> **Note**: This feature only works with Jellyfin backend. The plugin must be configured to run on a schedule, and the sync window should cover the plugin's execution time.
> **Note**: This feature uses your existing JELLYFIN_URL and JELLYFIN_API_KEY settings. The plugin must be configured to run on a schedule, and the sync window should cover the plugin's execution time.
### Getting Credentials

View File

@@ -3,6 +3,7 @@ namespace allstarr.Models.Settings;
/// <summary>
/// Configuration for Spotify playlist injection feature.
/// Requires Jellyfin Spotify Import Plugin: https://github.com/Viperinius/jellyfin-plugin-spotify-import
/// Uses JellyfinSettings.Url and JellyfinSettings.ApiKey for API access.
/// </summary>
public class SpotifyImportSettings
{
@@ -11,17 +12,6 @@ public class SpotifyImportSettings
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// Jellyfin server URL (for accessing plugin API)
/// </summary>
public string JellyfinUrl { get; set; } = string.Empty;
/// <summary>
/// Jellyfin API key (REQUIRED for accessing missing tracks files)
/// Get from Jellyfin Dashboard > API Keys
/// </summary>
public string ApiKey { get; set; } = string.Empty;
/// <summary>
/// Hour when Spotify Import plugin runs (24-hour format, 0-23)
/// Example: 16 for 4:00 PM

View File

@@ -8,18 +8,21 @@ namespace allstarr.Services.Spotify;
public class SpotifyMissingTracksFetcher : BackgroundService
{
private readonly IOptions<SpotifyImportSettings> _settings;
private readonly IOptions<SpotifyImportSettings> _spotifySettings;
private readonly IOptions<JellyfinSettings> _jellyfinSettings;
private readonly IHttpClientFactory _httpClientFactory;
private readonly RedisCacheService _cache;
private readonly ILogger<SpotifyMissingTracksFetcher> _logger;
public SpotifyMissingTracksFetcher(
IOptions<SpotifyImportSettings> settings,
IOptions<SpotifyImportSettings> spotifySettings,
IOptions<JellyfinSettings> jellyfinSettings,
IHttpClientFactory httpClientFactory,
RedisCacheService cache,
ILogger<SpotifyMissingTracksFetcher> logger)
{
_settings = settings;
_spotifySettings = spotifySettings;
_jellyfinSettings = jellyfinSettings;
_httpClientFactory = httpClientFactory;
_cache = cache;
_logger = logger;
@@ -27,12 +30,21 @@ public class SpotifyMissingTracksFetcher : BackgroundService
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (!_settings.Value.Enabled)
if (!_spotifySettings.Value.Enabled)
{
_logger.LogInformation("Spotify playlist injection is disabled");
return;
}
var jellyfinUrl = _jellyfinSettings.Value.Url;
var apiKey = _jellyfinSettings.Value.ApiKey;
if (string.IsNullOrEmpty(jellyfinUrl) || string.IsNullOrEmpty(apiKey))
{
_logger.LogWarning("Jellyfin URL or API key not configured, Spotify playlist injection disabled");
return;
}
_logger.LogInformation("Spotify missing tracks fetcher started");
while (!stoppingToken.IsCancellationRequested)
@@ -52,13 +64,9 @@ public class SpotifyMissingTracksFetcher : BackgroundService
private async Task FetchMissingTracksAsync(CancellationToken cancellationToken)
{
var settings = _settings.Value;
if (string.IsNullOrEmpty(settings.ApiKey))
{
_logger.LogWarning("Spotify import API key not configured");
return;
}
var settings = _spotifySettings.Value;
var jellyfinUrl = _jellyfinSettings.Value.Url;
var apiKey = _jellyfinSettings.Value.ApiKey;
var now = DateTime.UtcNow;
var syncStart = now.Date
@@ -88,7 +96,9 @@ public class SpotifyMissingTracksFetcher : BackgroundService
return;
}
var settings = _settings.Value;
var settings = _spotifySettings.Value;
var jellyfinUrl = _jellyfinSettings.Value.Url;
var apiKey = _jellyfinSettings.Value.ApiKey;
var httpClient = _httpClientFactory.CreateClient();
var today = DateTime.UtcNow.Date;
var syncStart = today
@@ -101,8 +111,8 @@ public class SpotifyMissingTracksFetcher : BackgroundService
if (cancellationToken.IsCancellationRequested) break;
var filename = $"{playlist.SpotifyName}_missing_{time:yyyy-MM-dd_HH-mm}.json";
var url = $"{settings.JellyfinUrl}/Viperinius.Plugin.SpotifyImport/MissingTracksFile" +
$"?name={Uri.EscapeDataString(filename)}&api_key={settings.ApiKey}";
var url = $"{jellyfinUrl}/Viperinius.Plugin.SpotifyImport/MissingTracksFile" +
$"?name={Uri.EscapeDataString(filename)}&api_key={apiKey}";
try
{

View File

@@ -7,8 +7,6 @@
},
"SpotifyImport": {
"Enabled": false,
"JellyfinUrl": "http://localhost:8096",
"ApiKey": "",
"SyncStartHour": 16,
"SyncStartMinute": 15,
"SyncWindowHours": 2,

View File

@@ -45,8 +45,6 @@
},
"SpotifyImport": {
"Enabled": false,
"JellyfinUrl": "https://jellyfin.example.com",
"ApiKey": "",
"SyncStartHour": 16,
"SyncStartMinute": 15,
"SyncWindowHours": 2,