MigrateRatingLevels.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using System;
  2. using System.Globalization;
  3. using System.IO;
  4. using Emby.Server.Implementations.Data;
  5. using MediaBrowser.Controller;
  6. using MediaBrowser.Controller.Persistence;
  7. using MediaBrowser.Model.Globalization;
  8. using Microsoft.Extensions.Logging;
  9. using SQLitePCL.pretty;
  10. namespace Jellyfin.Server.Migrations.Routines
  11. {
  12. /// <summary>
  13. /// Migrate rating levels to new rating level system.
  14. /// </summary>
  15. internal class MigrateRatingLevels : IMigrationRoutine
  16. {
  17. private const string DbFilename = "library.db";
  18. private readonly ILogger<MigrateRatingLevels> _logger;
  19. private readonly IServerApplicationPaths _applicationPaths;
  20. private readonly ILocalizationManager _localizationManager;
  21. private readonly IItemRepository _repository;
  22. public MigrateRatingLevels(
  23. IServerApplicationPaths applicationPaths,
  24. ILoggerFactory loggerFactory,
  25. ILocalizationManager localizationManager,
  26. IItemRepository repository)
  27. {
  28. _applicationPaths = applicationPaths;
  29. _localizationManager = localizationManager;
  30. _repository = repository;
  31. _logger = loggerFactory.CreateLogger<MigrateRatingLevels>();
  32. }
  33. /// <inheritdoc/>
  34. public Guid Id => Guid.Parse("{67445D54-B895-4B24-9F4C-35CE0690EA07}");
  35. /// <inheritdoc/>
  36. public string Name => "MigrateRatingLevels";
  37. /// <inheritdoc/>
  38. public bool PerformOnNewInstall => false;
  39. /// <inheritdoc/>
  40. public void Perform()
  41. {
  42. var dbPath = Path.Combine(_applicationPaths.DataPath, DbFilename);
  43. // Back up the database before modifying any entries
  44. for (int i = 1; ; i++)
  45. {
  46. var bakPath = string.Format(CultureInfo.InvariantCulture, "{0}.bak{1}", dbPath, i);
  47. if (!File.Exists(bakPath))
  48. {
  49. try
  50. {
  51. File.Copy(dbPath, bakPath);
  52. _logger.LogInformation("Library database backed up to {BackupPath}", bakPath);
  53. break;
  54. }
  55. catch (Exception ex)
  56. {
  57. _logger.LogError(ex, "Cannot make a backup of {Library} at path {BackupPath}", DbFilename, bakPath);
  58. throw;
  59. }
  60. }
  61. }
  62. // Migrate parental rating strings to new levels
  63. _logger.LogInformation("Recalculating parental rating levels based on rating string.");
  64. using (var connection = SQLite3.Open(
  65. dbPath,
  66. ConnectionFlags.ReadWrite,
  67. null))
  68. {
  69. var queryResult = connection.Query("SELECT DISTINCT OfficialRating FROM TypedBaseItems");
  70. foreach (var entry in queryResult)
  71. {
  72. var ratingString = entry[0].ToString();
  73. if (string.IsNullOrEmpty(ratingString))
  74. {
  75. connection.Execute("UPDATE TypedBaseItems SET InheritedParentalRatingValue = NULL WHERE OfficialRating IS NULL OR OfficialRating='';");
  76. }
  77. else
  78. {
  79. var ratingValue = _localizationManager.GetRatingLevel(ratingString).ToString();
  80. if (string.IsNullOrEmpty(ratingValue))
  81. {
  82. ratingValue = "NULL";
  83. }
  84. var statement = connection.PrepareStatement("UPDATE TypedBaseItems SET InheritedParentalRatingValue = @Value WHERE OfficialRating = @Rating;");
  85. statement.TryBind("@Value", ratingValue);
  86. statement.TryBind("@Rating", ratingString);
  87. statement.ExecuteQuery();
  88. }
  89. }
  90. }
  91. }
  92. }
  93. }