mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-10-31 10:37:22 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			169 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using MediaBrowser.Common.Extensions;
 | |
| using MediaBrowser.Common.IO;
 | |
| using MediaBrowser.Controller;
 | |
| using MediaBrowser.Controller.Themes;
 | |
| using MediaBrowser.Model.Logging;
 | |
| using MediaBrowser.Model.Serialization;
 | |
| using MediaBrowser.Model.Themes;
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.IO;
 | |
| using System.Linq;
 | |
| 
 | |
| namespace MediaBrowser.Server.Implementations.Themes
 | |
| {
 | |
|     public class AppThemeManager : IAppThemeManager
 | |
|     {
 | |
|         private readonly IServerApplicationPaths _appPaths;
 | |
|         private readonly IFileSystem _fileSystem;
 | |
|         private readonly IJsonSerializer _json;
 | |
|         private readonly ILogger _logger;
 | |
| 
 | |
|         private readonly string[] _supportedImageExtensions = { ".png", ".jpg", ".jpeg" };
 | |
| 
 | |
|         public AppThemeManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer json, ILogger logger)
 | |
|         {
 | |
|             _appPaths = appPaths;
 | |
|             _fileSystem = fileSystem;
 | |
|             _json = json;
 | |
|             _logger = logger;
 | |
|         }
 | |
| 
 | |
|         private string ThemePath
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return Path.Combine(_appPaths.ProgramDataPath, "appthemes");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private string GetThemesPath(string applicationName)
 | |
|         {
 | |
|             if (string.IsNullOrWhiteSpace(applicationName))
 | |
|             {
 | |
|                 throw new ArgumentNullException("applicationName");
 | |
|             }
 | |
| 
 | |
|             // Force everything lowercase for consistency and maximum compatibility with case-sensitive file systems
 | |
|             var name = _fileSystem.GetValidFilename(applicationName.ToLower());
 | |
| 
 | |
|             return Path.Combine(ThemePath, name);
 | |
|         }
 | |
| 
 | |
|         private string GetThemePath(string applicationName, string name)
 | |
|         {
 | |
|             if (string.IsNullOrWhiteSpace(name))
 | |
|             {
 | |
|                 throw new ArgumentNullException("name");
 | |
|             }
 | |
|             
 | |
|             // Force everything lowercase for consistency and maximum compatibility with case-sensitive file systems
 | |
|             name = _fileSystem.GetValidFilename(name.ToLower());
 | |
| 
 | |
|             return Path.Combine(GetThemesPath(applicationName), name);
 | |
|         }
 | |
| 
 | |
|         private string GetImagesPath(string applicationName, string themeName)
 | |
|         {
 | |
|             return Path.Combine(GetThemePath(applicationName, themeName), "images");
 | |
|         }
 | |
| 
 | |
|         public IEnumerable<AppThemeInfo> GetThemes(string applicationName)
 | |
|         {
 | |
|             var path = GetThemesPath(applicationName);
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 return Directory
 | |
|                     .EnumerateFiles(path, "*", SearchOption.AllDirectories)
 | |
|                     .Where(i => string.Equals(Path.GetExtension(i), ".json", StringComparison.OrdinalIgnoreCase))
 | |
|                     .Select(i =>
 | |
|                     {
 | |
|                         try
 | |
|                         {
 | |
|                             return _json.DeserializeFromFile<AppThemeInfo>(i);
 | |
|                         }
 | |
|                         catch (Exception ex)
 | |
|                         {
 | |
|                             _logger.ErrorException("Error deserializing {0}", ex, i);
 | |
|                             return null;
 | |
|                         }
 | |
| 
 | |
|                     }).Where(i => i != null);
 | |
|             }
 | |
|             catch (DirectoryNotFoundException)
 | |
|             {
 | |
|                 return new List<AppThemeInfo>();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public AppTheme GetTheme(string applicationName, string name)
 | |
|         {
 | |
|             var themePath = GetThemePath(applicationName, name);
 | |
|             var file = Path.Combine(themePath, "theme.json");
 | |
| 
 | |
|             var imagesPath = GetImagesPath(applicationName, name);
 | |
| 
 | |
|             var theme = _json.DeserializeFromFile<AppTheme>(file);
 | |
| 
 | |
|             theme.Images = new DirectoryInfo(imagesPath)
 | |
|                 .EnumerateFiles("*", SearchOption.TopDirectoryOnly)
 | |
|                 .Where(i => _supportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase))
 | |
|                 .Select(GetThemeImage)
 | |
|                 .ToList();
 | |
| 
 | |
|             return theme;
 | |
|         }
 | |
| 
 | |
|         private ThemeImage GetThemeImage(FileInfo file)
 | |
|         {
 | |
|             var dateModified = _fileSystem.GetLastWriteTimeUtc(file);
 | |
| 
 | |
|             var cacheTag = (file.FullName + dateModified.Ticks).GetMD5().ToString("N");
 | |
| 
 | |
|             return new ThemeImage
 | |
|             {
 | |
|                 CacheTag = cacheTag,
 | |
|                 Name = file.Name
 | |
|             };
 | |
|         }
 | |
| 
 | |
|         public void SaveTheme(AppTheme theme)
 | |
|         {
 | |
|             var themePath = GetThemePath(theme.AppName, theme.Name);
 | |
|             var file = Path.Combine(themePath, "theme.json");
 | |
| 
 | |
|             Directory.CreateDirectory(themePath);
 | |
| 
 | |
|             // Clone it so that we don't serialize all the images - they're always dynamic
 | |
|             var clone = new AppTheme
 | |
|             {
 | |
|                 AppName = theme.AppName,
 | |
|                 Name = theme.Name,
 | |
|                 Options = theme.Options,
 | |
|                 Images = null
 | |
|             };
 | |
| 
 | |
|             _json.SerializeToFile(clone, file);
 | |
|         }
 | |
| 
 | |
|         public InternalThemeImage GetImageImageInfo(string applicationName, string themeName, string imageName)
 | |
|         {
 | |
|             var imagesPath = GetImagesPath(applicationName, themeName);
 | |
| 
 | |
|             var file = new DirectoryInfo(imagesPath).EnumerateFiles("*", SearchOption.TopDirectoryOnly)
 | |
|                 .First(i => string.Equals(i.Name, imageName, StringComparison.OrdinalIgnoreCase));
 | |
| 
 | |
|             var themeImage = GetThemeImage(file);
 | |
| 
 | |
|             return new InternalThemeImage
 | |
|             {
 | |
|                 CacheTag = themeImage.CacheTag,
 | |
|                 Name = themeImage.Name,
 | |
|                 Path = file.FullName,
 | |
|                 DateModified = _fileSystem.GetLastWriteTimeUtc(file)
 | |
|             };
 | |
|         }
 | |
|     }
 | |
| }
 |