Files
pgsql-jellyfin/MediaBrowser.Providers/Lyric/LyricScheduledTask.cs
T
wjones af1152b001 Refactor: standardize namespace and using directive style
Refactored all C# test files to use explicit namespace declarations and moved all using directives inside the namespace block for consistency. Updated assembly info and cache files to reflect the new build. Adjusted MvcTestingAppManifest.json to use fully qualified assembly names. No functional changes; all updates are related to code style, organization, and project metadata.
2026-02-20 16:26:53 -05:00

176 lines
6.7 KiB
C#

// <copyright file="LyricScheduledTask.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace MediaBrowser.Providers.Lyric;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Lyrics;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Lyrics;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
/// <summary>
/// Task to download lyrics.
/// </summary>
public class LyricScheduledTask : IScheduledTask
{
private const int QueryPageLimit = 100;
private static readonly BaseItemKind[] _itemKinds = [BaseItemKind.Audio];
private static readonly MediaType[] _mediaTypes = [MediaType.Audio];
private static readonly SourceType[] _sourceTypes = [SourceType.Library];
private static readonly DtoOptions _dtoOptions = new(false);
private readonly ILibraryManager _libraryManager;
private readonly ILyricManager _lyricManager;
private readonly ILogger<LyricScheduledTask> _logger;
private readonly ILocalizationManager _localizationManager;
/// <summary>
/// Initializes a new instance of the <see cref="LyricScheduledTask"/> class.
/// </summary>
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
/// <param name="lyricManager">Instance of the <see cref="ILyricManager"/> interface.</param>
/// <param name="logger">Instance of the <see cref="ILogger{DownloaderScheduledTask}"/> interface.</param>
/// <param name="localizationManager">Instance of the <see cref="ILocalizationManager"/> interface.</param>
public LyricScheduledTask(
ILibraryManager libraryManager,
ILyricManager lyricManager,
ILogger<LyricScheduledTask> logger,
ILocalizationManager localizationManager)
{
_libraryManager = libraryManager;
_lyricManager = lyricManager;
_logger = logger;
_localizationManager = localizationManager;
}
/// <inheritdoc />
public string Name => _localizationManager.GetLocalizedString("TaskDownloadMissingLyrics");
/// <inheritdoc />
public string Key => "DownloadLyrics";
/// <inheritdoc />
public string Description => _localizationManager.GetLocalizedString("TaskDownloadMissingLyricsDescription");
/// <inheritdoc />
public string Category => _localizationManager.GetLocalizedString("TasksLibraryCategory");
/// <inheritdoc />
public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
{
var totalCount = _libraryManager.GetCount(new InternalItemsQuery
{
Recursive = true,
IsVirtualItem = false,
IncludeItemTypes = _itemKinds,
DtoOptions = _dtoOptions,
MediaTypes = _mediaTypes,
SourceTypes = _sourceTypes
});
var completed = 0;
foreach (var library in _libraryManager.RootFolder.Children.ToList())
{
var libraryOptions = _libraryManager.GetLibraryOptions(library);
var itemQuery = new InternalItemsQuery
{
Recursive = true,
IsVirtualItem = false,
IncludeItemTypes = _itemKinds,
DtoOptions = _dtoOptions,
MediaTypes = _mediaTypes,
SourceTypes = _sourceTypes,
Limit = QueryPageLimit,
Parent = library
};
int previousCount;
var startIndex = 0;
do
{
itemQuery.StartIndex = startIndex;
var audioItems = _libraryManager.GetItemList(itemQuery);
foreach (var audioItem in audioItems.OfType<Audio>())
{
cancellationToken.ThrowIfCancellationRequested();
try
{
if (audioItem.GetMediaStreams().All(s => s.Type != MediaStreamType.Lyric))
{
_logger.LogDebug("Searching for lyrics for {Path}", audioItem.Path);
var lyricResults = await _lyricManager.SearchLyricsAsync(
new LyricSearchRequest
{
MediaPath = audioItem.Path,
SongName = audioItem.Name,
AlbumName = audioItem.Album,
AlbumArtistsNames = audioItem.AlbumArtists,
ArtistNames = audioItem.Artists,
Duration = audioItem.RunTimeTicks,
IsAutomated = true,
DisabledLyricFetchers = libraryOptions.DisabledLyricFetchers,
LyricFetcherOrder = libraryOptions.LyricFetcherOrder
},
cancellationToken)
.ConfigureAwait(false);
if (lyricResults.Count != 0)
{
_logger.LogDebug("Saving lyrics for {Path}", audioItem.Path);
await _lyricManager.DownloadLyricsAsync(
audioItem,
libraryOptions,
lyricResults[0].Id,
cancellationToken)
.ConfigureAwait(false);
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error downloading lyrics for {Path}", audioItem.Path);
}
completed++;
progress.Report(100d * completed / totalCount);
}
startIndex += QueryPageLimit;
previousCount = audioItems.Count;
} while (previousCount > 0);
}
progress.Report(100);
}
/// <inheritdoc />
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
return
[
new TaskTriggerInfo
{
Type = TaskTriggerInfoType.IntervalTrigger,
IntervalTicks = TimeSpan.FromHours(24).Ticks
}
];
}
}