diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs index 866262d22f..abfdcd77d5 100644 --- a/Jellyfin.Server/Migrations/MigrationRunner.cs +++ b/Jellyfin.Server/Migrations/MigrationRunner.cs @@ -22,8 +22,7 @@ namespace Jellyfin.Server.Migrations private static readonly Type[] _preStartupMigrationTypes = { typeof(PreStartupRoutines.CreateNetworkConfiguration), - typeof(PreStartupRoutines.MigrateMusicBrainzTimeout), - typeof(PreStartupRoutines.MigrateRatingLevels) + typeof(PreStartupRoutines.MigrateMusicBrainzTimeout) }; /// @@ -41,7 +40,8 @@ namespace Jellyfin.Server.Migrations typeof(Routines.MigrateDisplayPreferencesDb), typeof(Routines.RemoveDownloadImagesInAdvance), typeof(Routines.MigrateAuthenticationDb), - typeof(Routines.FixPlaylistOwner) + typeof(Routines.FixPlaylistOwner), + typeof(Routines.MigrateRatingLevels) }; /// diff --git a/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateRatingLevels.cs b/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateRatingLevels.cs deleted file mode 100644 index 465bbd7fe1..0000000000 --- a/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateRatingLevels.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Globalization; -using System.IO; - -using Emby.Server.Implementations; -using MediaBrowser.Controller; -using Microsoft.Extensions.Logging; -using SQLitePCL.pretty; - -namespace Jellyfin.Server.Migrations.PreStartupRoutines -{ - /// - /// Migrate rating levels to new rating level system. - /// - internal class MigrateRatingLevels : IMigrationRoutine - { - private const string DbFilename = "library.db"; - private readonly ILogger _logger; - private readonly IServerApplicationPaths _applicationPaths; - - public MigrateRatingLevels(ServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory) - { - _applicationPaths = applicationPaths; - _logger = loggerFactory.CreateLogger(); - } - - /// - public Guid Id => Guid.Parse("{67445D54-B895-4B24-9F4C-35CE0690EA07}"); - - /// - public string Name => "MigrateRatingLevels"; - - /// - public bool PerformOnNewInstall => false; - - /// - public void Perform() - { - var dataPath = _applicationPaths.DataPath; - var dbPath = Path.Combine(dataPath, DbFilename); - using (var connection = SQLite3.Open( - dbPath, - ConnectionFlags.ReadWrite, - null)) - { - // Back up the database before deleting 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; - } - } - } - - // Migrate parental rating levels to new schema - _logger.LogInformation("Migrating parental rating levels."); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = NULL WHERE OfficialRating = 'NR'"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = NULL WHERE InheritedParentalRatingValue = ''"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = NULL WHERE InheritedParentalRatingValue = 0"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 1000 WHERE InheritedParentalRatingValue = 100"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 1000 WHERE InheritedParentalRatingValue = 15"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 18 WHERE InheritedParentalRatingValue = 10"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 18 WHERE InheritedParentalRatingValue = 9"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 16 WHERE InheritedParentalRatingValue = 8"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 12 WHERE InheritedParentalRatingValue = 7"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 12 WHERE InheritedParentalRatingValue = 6"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 12 WHERE InheritedParentalRatingValue = 5"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 7 WHERE InheritedParentalRatingValue = 4"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 6 WHERE InheritedParentalRatingValue = 3"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 6 WHERE InheritedParentalRatingValue = 2"); - connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = 0 WHERE InheritedParentalRatingValue = 1"); - } - } - } -} diff --git a/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs b/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs new file mode 100644 index 0000000000..9dee520a50 --- /dev/null +++ b/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs @@ -0,0 +1,103 @@ +using System; +using System.Globalization; +using System.IO; + +using Emby.Server.Implementations.Data; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Globalization; +using Microsoft.Extensions.Logging; +using SQLitePCL.pretty; + +namespace Jellyfin.Server.Migrations.Routines +{ + /// + /// Migrate rating levels to new rating level system. + /// + internal class MigrateRatingLevels : IMigrationRoutine + { + private const string DbFilename = "library.db"; + private readonly ILogger _logger; + private readonly IServerApplicationPaths _applicationPaths; + private readonly ILocalizationManager _localizationManager; + private readonly IItemRepository _repository; + + public MigrateRatingLevels( + IServerApplicationPaths applicationPaths, + ILoggerFactory loggerFactory, + ILocalizationManager localizationManager, + IItemRepository repository) + { + _applicationPaths = applicationPaths; + _localizationManager = localizationManager; + _repository = repository; + _logger = loggerFactory.CreateLogger(); + } + + /// + public Guid Id => Guid.Parse("{67445D54-B895-4B24-9F4C-35CE0690EA07}"); + + /// + public string Name => "MigrateRatingLevels"; + + /// + public bool PerformOnNewInstall => false; + + /// + 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; + } + } + } + + // Migrate parental rating strings to new levels + _logger.LogInformation("Recalculating parental rating levels based on rating string."); + using (var connection = SQLite3.Open( + dbPath, + ConnectionFlags.ReadWrite, + null)) + { + var queryResult = connection.Query("SELECT DISTINCT OfficialRating FROM TypedBaseItems"); + foreach (var entry in queryResult) + { + var ratingString = entry[0].ToString(); + if (string.IsNullOrEmpty(ratingString)) + { + connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = NULL WHERE OfficialRating IS NULL OR OfficialRating='';"); + } + else + { + var ratingValue = _localizationManager.GetRatingLevel(ratingString).ToString(); + if (string.IsNullOrEmpty(ratingValue)) + { + ratingValue = "NULL"; + } + + var statement = connection.PrepareStatement("UPDATE TypedBaseItems SET InheritedParentalRatingValue = @Value WHERE OfficialRating = @Rating;"); + statement.TryBind("@Value", ratingValue); + statement.TryBind("@Rating", ratingString); + statement.ExecuteQuery(); + } + } + } + } + } +}