diff options
20 files changed, 438 insertions, 10 deletions
diff --git a/MediaBrowser.Api/AppThemeService.cs b/MediaBrowser.Api/AppThemeService.cs new file mode 100644 index 000000000..3115fbb36 --- /dev/null +++ b/MediaBrowser.Api/AppThemeService.cs @@ -0,0 +1,102 @@ +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Themes; +using MediaBrowser.Model.Themes; +using ServiceStack; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Api +{ + [Route("/Themes", "GET")] + [Api(Description = "Gets a list of available themes for an app")] + public class GetAppThemes : IReturn<List<AppThemeInfo>> + { + [ApiMember(Name = "ApplicationName", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string ApplicationName { get; set; } + } + + [Route("/Themes/Info", "GET")] + [Api(Description = "Gets an app theme")] + public class GetAppTheme : IReturn<AppTheme> + { + [ApiMember(Name = "ApplicationName", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string ApplicationName { get; set; } + + [ApiMember(Name = "Name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string Name { get; set; } + } + + [Route("/Themes/Images", "GET")] + [Api(Description = "Gets an app theme")] + public class GetAppThemeImage + { + [ApiMember(Name = "ApplicationName", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string ApplicationName { get; set; } + + [ApiMember(Name = "ThemeName", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string ThemeName { get; set; } + + [ApiMember(Name = "Name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string Name { get; set; } + + [ApiMember(Name = "Tag", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string Tag { get; set; } + } + + [Route("/Themes", "POST")] + [Api(Description = "Saves a theme")] + public class SaveTheme : AppTheme, IReturnVoid + { + } + + public class AppThemeService : BaseApiService + { + private readonly IAppThemeManager _themeManager; + private readonly IFileSystem _fileSystem; + + public AppThemeService(IAppThemeManager themeManager, IFileSystem fileSystem) + { + _themeManager = themeManager; + _fileSystem = fileSystem; + } + + public object Get(GetAppThemes request) + { + var result = _themeManager.GetThemes(request.ApplicationName).ToList(); + + return ToOptimizedResult(result); + } + + public object Get(GetAppTheme request) + { + var result = _themeManager.GetTheme(request.ApplicationName, request.Name); + + return ToOptimizedResult(result); + } + + public void Post(SaveTheme request) + { + _themeManager.SaveTheme(request); + } + + public object Get(GetAppThemeImage request) + { + var info = _themeManager.GetImageImageInfo(request.ApplicationName, request.ThemeName, request.Name); + + var cacheGuid = new Guid(info.CacheTag); + + TimeSpan? cacheDuration = null; + + if (!string.IsNullOrEmpty(request.Tag) && cacheGuid == new Guid(request.Tag)) + { + cacheDuration = TimeSpan.FromDays(365); + } + + var contentType = MimeTypes.GetMimeType(info.Path); + + return ToCachedResult(cacheGuid, info.DateModified, cacheDuration, () => _fileSystem.GetFileStream(info.Path, FileMode.Open, FileAccess.Read, FileShare.Read), contentType); + } + } +} diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 6e214f960..ee2a7eafc 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -67,6 +67,7 @@ <Link>Properties\SharedVersion.cs</Link> </Compile> <Compile Include="AlbumsService.cs" /> + <Compile Include="AppThemeService.cs" /> <Compile Include="BaseApiService.cs" /> <Compile Include="ConfigurationService.cs" /> <Compile Include="DefaultTheme\DefaultThemeService.cs" /> diff --git a/MediaBrowser.Common.Implementations/Security/MBRegistration.cs b/MediaBrowser.Common.Implementations/Security/MBRegistration.cs index cbb6bda94..1d64b5ea1 100644 --- a/MediaBrowser.Common.Implementations/Security/MBRegistration.cs +++ b/MediaBrowser.Common.Implementations/Security/MBRegistration.cs @@ -14,11 +14,12 @@ namespace MediaBrowser.Common.Implementations.Security { private static MBLicenseFile _licenseFile; - private const string MBValidateUrl = Constants.Constants.MbAdminUrl+"service/registration/validate"; + private const string MBValidateUrl = Constants.Constants.MbAdminUrl + "service/registration/validate"; private static IApplicationPaths _appPaths; private static INetworkManager _networkManager; private static ILogger _logger; + private static IApplicationHost _applicationHost; private static MBLicenseFile LicenseFile { @@ -37,24 +38,35 @@ namespace MediaBrowser.Common.Implementations.Security set { LicenseFile.LegacyKey = value; LicenseFile.Save(); } } - public static void Init(IApplicationPaths appPaths, INetworkManager networkManager, ILogManager logManager) + public static void Init(IApplicationPaths appPaths, INetworkManager networkManager, ILogManager logManager, IApplicationHost appHost) { // Ugly alert (static init) _appPaths = appPaths; _networkManager = networkManager; _logger = logManager.GetLogger("SecurityManager"); + _applicationHost = appHost; } public static async Task<MBRegistrationRecord> GetRegistrationStatus(IHttpClient httpClient, IJsonSerializer jsonSerializer, string feature, string mb2Equivalent = null, string version = null) { //check the reg file first to alleviate strain on the MB admin server - must actually check in every 30 days tho - var reg = new RegRecord {registered = LicenseFile.LastChecked(feature) > DateTime.UtcNow.AddDays(-30)}; + var reg = new RegRecord { registered = LicenseFile.LastChecked(feature) > DateTime.UtcNow.AddDays(-30) }; if (!reg.registered) { var mac = _networkManager.GetMacAddress(); - var data = new Dictionary<string, string> { { "feature", feature }, { "key", SupporterKey }, { "mac", mac }, { "mb2equiv", mb2Equivalent }, { "legacykey", LegacyKey }, { "ver", version }, { "platform", Environment.OSVersion.VersionString } }; + var data = new Dictionary<string, string> + { + { "feature", feature }, + { "key", SupporterKey }, + { "mac", mac }, + { "mb2equiv", mb2Equivalent }, + { "legacykey", LegacyKey }, + { "ver", version }, + { "platform", Environment.OSVersion.VersionString }, + { "isservice", _applicationHost.IsRunningAsService.ToString().ToLower() } + }; try { @@ -79,7 +91,7 @@ namespace MediaBrowser.Common.Implementations.Security } } - return new MBRegistrationRecord {IsRegistered = reg.registered, ExpirationDate = reg.expDate, RegChecked = true}; + return new MBRegistrationRecord { IsRegistered = reg.registered, ExpirationDate = reg.expDate, RegChecked = true }; } } diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index 3cfdc8053..d0b108c7d 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -74,7 +74,7 @@ namespace MediaBrowser.Common.Implementations.Security _appHost = appHost; _httpClient = httpClient; _jsonSerializer = jsonSerializer; - MBRegistration.Init(_applciationPaths, _networkManager, logManager); + MBRegistration.Init(_applciationPaths, _networkManager, logManager, _appHost); } /// <summary> diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 8784a7187..4a3c82b46 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -256,6 +256,7 @@ namespace MediaBrowser.Controller.Entities.TV if (series != null) { id.SeriesProviderIds = series.ProviderIds; + id.AnimeSeriesIndex = series.AnimeSeriesIndex; } id.IndexNumberEnd = IndexNumberEnd; diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 4fadd8f6e..d371cbb92 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -257,6 +257,7 @@ namespace MediaBrowser.Controller.Entities.TV if (series != null) { id.SeriesProviderIds = series.ProviderIds; + id.AnimeSeriesIndex = series.AnimeSeriesIndex; } return id; diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index be6c92864..ce0ea4458 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -20,6 +20,8 @@ namespace MediaBrowser.Controller.Entities.TV public int SeasonCount { get; set; } + public int? AnimeSeriesIndex { get; set; } + /// <summary> /// Gets or sets the preferred metadata country code. /// </summary> @@ -224,7 +226,11 @@ namespace MediaBrowser.Controller.Entities.TV public SeriesInfo GetLookupInfo() { - return GetItemLookupInfo<SeriesInfo>(); + var info = GetItemLookupInfo<SeriesInfo>(); + + info.AnimeSeriesIndex = AnimeSeriesIndex; + + return info; } public override bool BeforeMetadataRefresh() diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 30174982f..c07693b36 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -239,6 +239,8 @@ <Compile Include="Sorting\IUserBaseItemComparer.cs" /> <Compile Include="Providers\BaseItemXmlParser.cs" /> <Compile Include="Sorting\SortExtensions.cs" /> + <Compile Include="Themes\IAppThemeManager.cs" /> + <Compile Include="Themes\InternalThemeImage.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj"> diff --git a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs index c2409715a..65ee94556 100644 --- a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs +++ b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs @@ -101,6 +101,7 @@ namespace MediaBrowser.Controller.Providers public Dictionary<string, string> SeriesProviderIds { get; set; } public int? IndexNumberEnd { get; set; } + public int? AnimeSeriesIndex { get; set; } public EpisodeInfo() { @@ -117,7 +118,7 @@ namespace MediaBrowser.Controller.Providers public class SeriesInfo : ItemLookupInfo { - + public int? AnimeSeriesIndex { get; set; } } public class PersonLookupInfo : ItemLookupInfo @@ -153,6 +154,7 @@ namespace MediaBrowser.Controller.Providers public class SeasonInfo : ItemLookupInfo { public Dictionary<string, string> SeriesProviderIds { get; set; } + public int? AnimeSeriesIndex { get; set; } public SeasonInfo() { diff --git a/MediaBrowser.Controller/Themes/IAppThemeManager.cs b/MediaBrowser.Controller/Themes/IAppThemeManager.cs new file mode 100644 index 000000000..1a7c2aaab --- /dev/null +++ b/MediaBrowser.Controller/Themes/IAppThemeManager.cs @@ -0,0 +1,38 @@ +using MediaBrowser.Model.Themes; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Themes +{ + public interface IAppThemeManager + { + /// <summary> + /// Gets the themes. + /// </summary> + /// <param name="applicationName">Name of the application.</param> + /// <returns>IEnumerable{AppThemeInfo}.</returns> + IEnumerable<AppThemeInfo> GetThemes(string applicationName); + + /// <summary> + /// Gets the theme. + /// </summary> + /// <param name="applicationName">Name of the application.</param> + /// <param name="name">The name.</param> + /// <returns>AppTheme.</returns> + AppTheme GetTheme(string applicationName, string name); + + /// <summary> + /// Saves the theme. + /// </summary> + /// <param name="theme">The theme.</param> + void SaveTheme(AppTheme theme); + + /// <summary> + /// Gets the image image information. + /// </summary> + /// <param name="applicationName">Name of the application.</param> + /// <param name="themeName">Name of the theme.</param> + /// <param name="imageName">Name of the image.</param> + /// <returns>InternalThemeImage.</returns> + InternalThemeImage GetImageImageInfo(string applicationName, string themeName, string imageName); + } +} diff --git a/MediaBrowser.Controller/Themes/InternalThemeImage.cs b/MediaBrowser.Controller/Themes/InternalThemeImage.cs new file mode 100644 index 000000000..2b676c25b --- /dev/null +++ b/MediaBrowser.Controller/Themes/InternalThemeImage.cs @@ -0,0 +1,31 @@ +using System; + +namespace MediaBrowser.Controller.Themes +{ + public class InternalThemeImage + { + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + + /// <summary> + /// Gets or sets the cache tag. + /// </summary> + /// <value>The cache tag.</value> + public string CacheTag { get; set; } + + /// <summary> + /// Gets or sets the path. + /// </summary> + /// <value>The path.</value> + public string Path { get; set; } + + /// <summary> + /// Gets or sets the date modified. + /// </summary> + /// <value>The date modified.</value> + public DateTime DateModified { get; set; } + } +} diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index e9ac46e50..04296de35 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -452,6 +452,12 @@ <Compile Include="..\MediaBrowser.Model\Tasks\TaskTriggerInfo.cs"> <Link>Tasks\TaskTriggerInfo.cs</Link> </Compile> + <Compile Include="..\MediaBrowser.Model\Themes\AppTheme.cs"> + <Link>Themes\AppTheme.cs</Link> + </Compile> + <Compile Include="..\MediaBrowser.Model\Themes\ThemeImage.cs"> + <Link>Themes\ThemeImage.cs</Link> + </Compile> <Compile Include="..\MediaBrowser.Model\Updates\CheckForUpdateResult.cs"> <Link>Updates\CheckForUpdateResult.cs</Link> </Compile> diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 16e3f2767..56f7fb99d 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -439,6 +439,12 @@ <Compile Include="..\MediaBrowser.Model\Tasks\TaskTriggerInfo.cs"> <Link>Tasks\TaskTriggerInfo.cs</Link> </Compile> + <Compile Include="..\MediaBrowser.Model\Themes\AppTheme.cs"> + <Link>Themes\AppTheme.cs</Link> + </Compile> + <Compile Include="..\MediaBrowser.Model\Themes\ThemeImage.cs"> + <Link>Themes\ThemeImage.cs</Link> + </Compile> <Compile Include="..\MediaBrowser.Model\Updates\CheckForUpdateResult.cs"> <Link>Updates\CheckForUpdateResult.cs</Link> </Compile> diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index d9c7cbffe..10aedb3ba 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -165,6 +165,8 @@ <Compile Include="Session\SessionInfoDto.cs" /> <Compile Include="Session\SystemCommand.cs" /> <Compile Include="Session\UserDataChangeInfo.cs" /> + <Compile Include="Themes\AppTheme.cs" /> + <Compile Include="Themes\ThemeImage.cs" /> <Compile Include="Updates\CheckForUpdateResult.cs" /> <Compile Include="Updates\PackageTargetSystem.cs" /> <Compile Include="Updates\InstallationInfo.cs" /> diff --git a/MediaBrowser.Model/Themes/AppTheme.cs b/MediaBrowser.Model/Themes/AppTheme.cs new file mode 100644 index 000000000..a0532854d --- /dev/null +++ b/MediaBrowser.Model/Themes/AppTheme.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Model.Themes +{ + public class AppTheme + { + public string ApplicationName { get; set; } + + public string Name { get; set; } + + public Dictionary<string, string> Options { get; set; } + + public List<ThemeImage> Images { get; set; } + + public AppTheme() + { + Options = new Dictionary<string, string>(StringComparer.Ordinal); + + Images = new List<ThemeImage>(); + } + } + + public class AppThemeInfo + { + public string ApplicationName { get; set; } + + public string Name { get; set; } + } +} diff --git a/MediaBrowser.Model/Themes/ThemeImage.cs b/MediaBrowser.Model/Themes/ThemeImage.cs new file mode 100644 index 000000000..2fe0820ae --- /dev/null +++ b/MediaBrowser.Model/Themes/ThemeImage.cs @@ -0,0 +1,18 @@ + +namespace MediaBrowser.Model.Themes +{ + public class ThemeImage + { + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + + /// <summary> + /// Gets or sets the cache tag. + /// </summary> + /// <value>The cache tag.</value> + public string CacheTag { get; set; } + } +} diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs index db839a66e..415205cb1 100644 --- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -25,6 +25,7 @@ namespace MediaBrowser.Server.Implementations.Configuration : base(applicationPaths, logManager, xmlSerializer) { UpdateItemsByNamePath(); + UpdateTranscodingTempPath(); } /// <summary> diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 01fd82b19..f0b08b923 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -248,6 +248,7 @@ <Compile Include="Persistence\SqliteUserRepository.cs" /> <Compile Include="Sorting\TrailerCountComparer.cs" /> <Compile Include="Sorting\VideoBitRateComparer.cs" /> + <Compile Include="Themes\AppThemeManager.cs" /> <Compile Include="Udp\UdpMessageReceivedEventArgs.cs" /> <Compile Include="Udp\UdpServer.cs" /> <Compile Include="WebSocket\AlchemyServer.cs" /> diff --git a/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs b/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs new file mode 100644 index 000000000..ca792bcd3 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs @@ -0,0 +1,163 @@ +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.ItemsByNamePath, "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); + } + + 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 theme = _json.DeserializeFromFile<AppTheme>(file); + + theme.Images = new DirectoryInfo(themePath) + .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.ApplicationName, 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 + { + ApplicationName = theme.ApplicationName, + Name = theme.Name, + Options = theme.Options, + Images = null + }; + + _json.SerializeToFile(clone, file); + } + + public InternalThemeImage GetImageImageInfo(string applicationName, string themeName, string imageName) + { + var themePath = GetThemePath(applicationName, themeName); + + var fullPath = Path.Combine(themePath, imageName); + + var file = new DirectoryInfo(themePath).EnumerateFiles("*", SearchOption.TopDirectoryOnly) + .First(i => string.Equals(i.FullName, fullPath, StringComparison.OrdinalIgnoreCase)); + + var themeImage = GetThemeImage(file); + + return new InternalThemeImage + { + CacheTag = themeImage.CacheTag, + Name = themeImage.Name, + Path = file.FullName, + DateModified = _fileSystem.GetLastWriteTimeUtc(file) + }; + } + } +} diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index f199dc048..73f99cda1 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -27,6 +27,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Sorting; +using MediaBrowser.Controller.Themes; using MediaBrowser.Dlna.PlayTo; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; @@ -49,6 +50,7 @@ using MediaBrowser.Server.Implementations.MediaEncoder; using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Implementations.ServerManager; using MediaBrowser.Server.Implementations.Session; +using MediaBrowser.Server.Implementations.Themes; using MediaBrowser.Server.Implementations.WebSocket; using MediaBrowser.ServerApplication.EntryPoints; using MediaBrowser.ServerApplication.FFMpeg; @@ -163,7 +165,7 @@ namespace MediaBrowser.ServerApplication private ILocalizationManager LocalizationManager { get; set; } private IEncodingManager EncodingManager { get; set; } - + /// <summary> /// Gets or sets the user data repository. /// </summary> @@ -438,6 +440,9 @@ namespace MediaBrowser.ServerApplication MediaEncoder); RegisterSingleInstance(EncodingManager); + var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger); + RegisterSingleInstance<IAppThemeManager>(appThemeManager); + LiveTvManager = new LiveTvManager(ServerConfigurationManager, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager); RegisterSingleInstance(LiveTvManager); @@ -747,7 +752,7 @@ namespace MediaBrowser.ServerApplication // Dlna implementations list.Add(typeof(PlayToServerEntryPoint).Assembly); - + list.AddRange(Assemblies.GetAssembliesWithParts()); // Include composable parts in the running assembly |
