diff options
| author | Shadowghost <Shadowghost@users.noreply.github.com> | 2024-06-01 18:40:57 -0400 |
|---|---|---|
| committer | Joshua M. Boniface <joshua@boniface.me> | 2024-06-01 18:40:57 -0400 |
| commit | 407dc9272c0db664dc3802046be62da3cd58ed3e (patch) | |
| tree | d7545f182163942e4ddc8d3bcbb066da4e08a3f7 /Jellyfin.Server | |
| parent | 5d4880c4974a8399d178147fcc4e78e1aed191e9 (diff) | |
Backport pull request #11762 from jellyfin/release-10.9.z
Mark Audio as RequiresDeserialization and backfill data
Original-merge: e2c909f50f34cc06fcd39a02407d1f5b7bb37a1e
Merged-by: joshuaboniface <joshua@boniface.me>
Backported-by: Joshua M. Boniface <joshua@boniface.me>
Diffstat (limited to 'Jellyfin.Server')
| -rw-r--r-- | Jellyfin.Server/Migrations/MigrationRunner.cs | 3 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/FixAudioData.cs | 104 |
2 files changed, 106 insertions, 1 deletions
diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs index 44aa43044..81fecc9a1 100644 --- a/Jellyfin.Server/Migrations/MigrationRunner.cs +++ b/Jellyfin.Server/Migrations/MigrationRunner.cs @@ -44,7 +44,8 @@ namespace Jellyfin.Server.Migrations typeof(Routines.FixPlaylistOwner), typeof(Routines.MigrateRatingLevels), typeof(Routines.AddDefaultCastReceivers), - typeof(Routines.UpdateDefaultPluginRepository) + typeof(Routines.UpdateDefaultPluginRepository), + typeof(Routines.FixAudioData), }; /// <summary> diff --git a/Jellyfin.Server/Migrations/Routines/FixAudioData.cs b/Jellyfin.Server/Migrations/Routines/FixAudioData.cs new file mode 100644 index 000000000..74f7e9c3e --- /dev/null +++ b/Jellyfin.Server/Migrations/Routines/FixAudioData.cs @@ -0,0 +1,104 @@ +using System; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Threading; +using Jellyfin.Data.Enums; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Entities; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Server.Migrations.Routines +{ + /// <summary> + /// Fixes the data column of audio types to be deserializable. + /// </summary> + internal class FixAudioData : IMigrationRoutine + { + private const string DbFilename = "library.db"; + private readonly ILogger<FixAudioData> _logger; + private readonly IServerApplicationPaths _applicationPaths; + private readonly IItemRepository _itemRepository; + + public FixAudioData( + IServerApplicationPaths applicationPaths, + ILoggerFactory loggerFactory, + IItemRepository itemRepository) + { + _applicationPaths = applicationPaths; + _itemRepository = itemRepository; + _logger = loggerFactory.CreateLogger<FixAudioData>(); + } + + /// <inheritdoc/> + public Guid Id => Guid.Parse("{CF6FABC2-9FBE-4933-84A5-FFE52EF22A58}"); + + /// <inheritdoc/> + public string Name => "FixAudioData"; + + /// <inheritdoc/> + public bool PerformOnNewInstall => false; + + /// <inheritdoc/> + public void Perform() + { + var dbPath = Path.Combine(_applicationPaths.DataPath, DbFilename); + + // Back up the database before modifying any entries + for (int i = 1; ; i++) + { + var bakPath = string.Format(CultureInfo.InvariantCulture, "{0}.bak{1}", dbPath, i); + if (!File.Exists(bakPath)) + { + try + { + File.Copy(dbPath, bakPath); + _logger.LogInformation("Library database backed up to {BackupPath}", bakPath); + break; + } + catch (Exception ex) + { + _logger.LogError(ex, "Cannot make a backup of {Library} at path {BackupPath}", DbFilename, bakPath); + throw; + } + } + } + + _logger.LogInformation("Backfilling audio lyrics data to database."); + var startIndex = 0; + var records = _itemRepository.GetCount(new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Audio], + }); + + while (startIndex < records) + { + var results = _itemRepository.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Audio], + StartIndex = startIndex, + Limit = 100, + SkipDeserialization = true + }) + .Cast<Audio>() + .ToList(); + + foreach (var audio in results) + { + var lyricMediaStreams = audio.GetMediaStreams().Where(s => s.Type == MediaStreamType.Lyric).Select(s => s.Path).ToList(); + if (lyricMediaStreams.Count > 0) + { + audio.HasLyrics = true; + audio.LyricFiles = lyricMediaStreams; + } + } + + _itemRepository.SaveItems(results, CancellationToken.None); + startIndex += 100; + } + } + } +} |
