2
0

AppThemeManager.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using MediaBrowser.Common.Extensions;
  2. using MediaBrowser.Common.IO;
  3. using MediaBrowser.Controller;
  4. using MediaBrowser.Controller.Themes;
  5. using MediaBrowser.Model.Logging;
  6. using MediaBrowser.Model.Serialization;
  7. using MediaBrowser.Model.Themes;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.IO;
  11. using System.Linq;
  12. namespace MediaBrowser.Server.Implementations.Themes
  13. {
  14. public class AppThemeManager : IAppThemeManager
  15. {
  16. private readonly IServerApplicationPaths _appPaths;
  17. private readonly IFileSystem _fileSystem;
  18. private readonly IJsonSerializer _json;
  19. private readonly ILogger _logger;
  20. private readonly string[] _supportedImageExtensions = { ".png", ".jpg", ".jpeg" };
  21. public AppThemeManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer json, ILogger logger)
  22. {
  23. _appPaths = appPaths;
  24. _fileSystem = fileSystem;
  25. _json = json;
  26. _logger = logger;
  27. }
  28. private string ThemePath
  29. {
  30. get
  31. {
  32. return Path.Combine(_appPaths.ProgramDataPath, "appthemes");
  33. }
  34. }
  35. private string GetThemesPath(string applicationName)
  36. {
  37. if (string.IsNullOrWhiteSpace(applicationName))
  38. {
  39. throw new ArgumentNullException("applicationName");
  40. }
  41. // Force everything lowercase for consistency and maximum compatibility with case-sensitive file systems
  42. var name = _fileSystem.GetValidFilename(applicationName.ToLower());
  43. return Path.Combine(ThemePath, name);
  44. }
  45. private string GetThemePath(string applicationName, string name)
  46. {
  47. if (string.IsNullOrWhiteSpace(name))
  48. {
  49. throw new ArgumentNullException("name");
  50. }
  51. // Force everything lowercase for consistency and maximum compatibility with case-sensitive file systems
  52. name = _fileSystem.GetValidFilename(name.ToLower());
  53. return Path.Combine(GetThemesPath(applicationName), name);
  54. }
  55. private string GetImagesPath(string applicationName, string themeName)
  56. {
  57. return Path.Combine(GetThemePath(applicationName, themeName), "images");
  58. }
  59. public IEnumerable<AppThemeInfo> GetThemes(string applicationName)
  60. {
  61. var path = GetThemesPath(applicationName);
  62. try
  63. {
  64. return Directory
  65. .EnumerateFiles(path, "*", SearchOption.AllDirectories)
  66. .Where(i => string.Equals(Path.GetExtension(i), ".json", StringComparison.OrdinalIgnoreCase))
  67. .Select(i =>
  68. {
  69. try
  70. {
  71. return _json.DeserializeFromFile<AppThemeInfo>(i);
  72. }
  73. catch (Exception ex)
  74. {
  75. _logger.ErrorException("Error deserializing {0}", ex, i);
  76. return null;
  77. }
  78. }).Where(i => i != null);
  79. }
  80. catch (DirectoryNotFoundException)
  81. {
  82. return new List<AppThemeInfo>();
  83. }
  84. }
  85. public AppTheme GetTheme(string applicationName, string name)
  86. {
  87. var themePath = GetThemePath(applicationName, name);
  88. var file = Path.Combine(themePath, "theme.json");
  89. var imagesPath = GetImagesPath(applicationName, name);
  90. var theme = _json.DeserializeFromFile<AppTheme>(file);
  91. theme.Images = new DirectoryInfo(imagesPath)
  92. .EnumerateFiles("*", SearchOption.TopDirectoryOnly)
  93. .Where(i => _supportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase))
  94. .Select(GetThemeImage)
  95. .ToList();
  96. return theme;
  97. }
  98. private ThemeImage GetThemeImage(FileInfo file)
  99. {
  100. var dateModified = _fileSystem.GetLastWriteTimeUtc(file);
  101. var cacheTag = (file.FullName + dateModified.Ticks).GetMD5().ToString("N");
  102. return new ThemeImage
  103. {
  104. CacheTag = cacheTag,
  105. Name = file.Name
  106. };
  107. }
  108. public void SaveTheme(AppTheme theme)
  109. {
  110. var themePath = GetThemePath(theme.AppName, theme.Name);
  111. var file = Path.Combine(themePath, "theme.json");
  112. Directory.CreateDirectory(themePath);
  113. // Clone it so that we don't serialize all the images - they're always dynamic
  114. var clone = new AppTheme
  115. {
  116. AppName = theme.AppName,
  117. Name = theme.Name,
  118. Options = theme.Options,
  119. Images = null
  120. };
  121. _json.SerializeToFile(clone, file);
  122. }
  123. public InternalThemeImage GetImageImageInfo(string applicationName, string themeName, string imageName)
  124. {
  125. var imagesPath = GetImagesPath(applicationName, themeName);
  126. var file = new DirectoryInfo(imagesPath).EnumerateFiles("*", SearchOption.TopDirectoryOnly)
  127. .First(i => string.Equals(i.Name, imageName, StringComparison.OrdinalIgnoreCase));
  128. var themeImage = GetThemeImage(file);
  129. return new InternalThemeImage
  130. {
  131. CacheTag = themeImage.CacheTag,
  132. Name = themeImage.Name,
  133. Path = file.FullName,
  134. DateModified = _fileSystem.GetLastWriteTimeUtc(file)
  135. };
  136. }
  137. }
  138. }