jellyfin-server/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs
2015-01-23 23:50:45 -05:00

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)
};
}
}
}