< Summary - Jellyfin

Information
Class: Jellyfin.Server.Migrations.Routines.FixAudioData
Assembly: jellyfin
File(s): /srv/git/jellyfin/Jellyfin.Server/Migrations/Routines/FixAudioData.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 29
Coverable lines: 29
Total lines: 77
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 6
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
Perform()0%4260%

File(s)

/srv/git/jellyfin/Jellyfin.Server/Migrations/Routines/FixAudioData.cs

#LineLine coverage
 1using System;
 2using System.Globalization;
 3using System.IO;
 4using System.Linq;
 5using System.Threading;
 6using Jellyfin.Data.Enums;
 7using MediaBrowser.Controller;
 8using MediaBrowser.Controller.Entities;
 9using MediaBrowser.Controller.Entities.Audio;
 10using MediaBrowser.Controller.Persistence;
 11using MediaBrowser.Model.Entities;
 12using Microsoft.Extensions.Logging;
 13
 14namespace Jellyfin.Server.Migrations.Routines
 15{
 16    /// <summary>
 17    /// Fixes the data column of audio types to be deserializable.
 18    /// </summary>
 19#pragma warning disable CS0618 // Type or member is obsolete
 20    [JellyfinMigration("2025-04-20T18:00:00", nameof(FixAudioData), "CF6FABC2-9FBE-4933-84A5-FFE52EF22A58")]
 21    [JellyfinMigrationBackup(LegacyLibraryDb = true)]
 22    internal class FixAudioData : IMigrationRoutine
 23#pragma warning restore CS0618 // Type or member is obsolete
 24    {
 25        private readonly ILogger<FixAudioData> _logger;
 26        private readonly IServerApplicationPaths _applicationPaths;
 27        private readonly IItemRepository _itemRepository;
 28
 29        public FixAudioData(
 30            IServerApplicationPaths applicationPaths,
 31            ILoggerFactory loggerFactory,
 32            IItemRepository itemRepository)
 33        {
 034            _applicationPaths = applicationPaths;
 035            _itemRepository = itemRepository;
 036            _logger = loggerFactory.CreateLogger<FixAudioData>();
 037        }
 38
 39        /// <inheritdoc/>
 40        public void Perform()
 41        {
 042            _logger.LogInformation("Backfilling audio lyrics data to database.");
 043            var startIndex = 0;
 044            var records = _itemRepository.GetCount(new InternalItemsQuery
 045            {
 046                IncludeItemTypes = [BaseItemKind.Audio],
 047            });
 48
 049            while (startIndex < records)
 50            {
 051                var results = _itemRepository.GetItemList(new InternalItemsQuery
 052                {
 053                    IncludeItemTypes = [BaseItemKind.Audio],
 054                    StartIndex = startIndex,
 055                    Limit = 5000,
 056                    SkipDeserialization = true
 057                })
 058                .Cast<Audio>()
 059                .ToList();
 60
 061                foreach (var audio in results)
 62                {
 063                    var lyricMediaStreams = audio.GetMediaStreams().Where(s => s.Type == MediaStreamType.Lyric).Select(s
 064                    if (lyricMediaStreams.Count > 0)
 65                    {
 066                        audio.HasLyrics = true;
 067                        audio.LyricFiles = lyricMediaStreams;
 68                    }
 69                }
 70
 071                _itemRepository.SaveItems(results, CancellationToken.None);
 072                startIndex += results.Count;
 073                _logger.LogInformation("Backfilled data for {UpdatedRecords} of {TotalRecords} audio records", startInde
 74            }
 075        }
 76    }
 77}