diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs index 01466970a..067da3853 100644 --- a/MediaBrowser.Api/EnvironmentService.cs +++ b/MediaBrowser.Api/EnvironmentService.cs @@ -116,12 +116,6 @@ namespace MediaBrowser.Api return ToOptimizedResult(GetNetworkShares(path).OrderBy(i => i.Path).ToList()); } - // Reject invalid input - if (!Path.IsPathRooted(path)) - { - throw new ArgumentException(string.Format("Invalid path: {0}", path)); - } - return ToOptimizedResult(GetFileSystemEntries(request).OrderBy(i => i.Path).ToList()); } diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 27881d12b..633d63514 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -92,7 +92,7 @@ namespace MediaBrowser.Api.Images [ApiMember(Name = "Id", Description = "Channel Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Id { get; set; } } - + /// /// Class UpdateItemImageIndex /// @@ -281,7 +281,7 @@ namespace MediaBrowser.Api.Images [ApiMember(Name = "Id", Description = "Channel Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] public string Id { get; set; } } - + /// /// Class PostUserImage /// @@ -375,7 +375,7 @@ namespace MediaBrowser.Api.Images /// The request stream. public Stream RequestStream { get; set; } } - + /// /// Class ImageService /// @@ -400,7 +400,7 @@ namespace MediaBrowser.Api.Images private readonly IImageProcessor _imageProcessor; private readonly ILiveTvManager _liveTv; - + /// /// Initializes a new instance of the class. /// @@ -438,7 +438,7 @@ namespace MediaBrowser.Api.Images return ToOptimizedResult(result); } - + public object Get(GetItemByNameImageInfos request) { var result = GetItemByNameImageInfos(request); @@ -496,16 +496,20 @@ namespace MediaBrowser.Api.Images index = 0; - foreach (var image in item.ScreenshotImagePaths) + var hasScreenshots = item as IHasScreenshots; + if (hasScreenshots != null) { - var info = GetImageInfo(image, item, index, ImageType.Screenshot); - - if (info != null) + foreach (var image in hasScreenshots.ScreenshotImagePaths) { - list.Add(info); - } + var info = GetImageInfo(image, item, index, ImageType.Screenshot); - index++; + if (info != null) + { + list.Add(info); + } + + index++; + } } var video = item as Video; @@ -667,7 +671,7 @@ namespace MediaBrowser.Api.Images Task.WaitAll(task); } - + /// /// Deletes the specified request. /// @@ -702,7 +706,7 @@ namespace MediaBrowser.Api.Images Task.WaitAll(task); } - + /// /// Deletes the specified request. /// @@ -764,8 +768,9 @@ namespace MediaBrowser.Api.Images if (type == ImageType.Screenshot) { - file1 = item.ScreenshotImagePaths[currentIndex]; - file2 = item.ScreenshotImagePaths[newIndex]; + var hasScreenshots = (IHasScreenshots)item; + file1 = hasScreenshots.ScreenshotImagePaths[currentIndex]; + file2 = hasScreenshots.ScreenshotImagePaths[newIndex]; } else if (type == ImageType.Backdrop) { diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 90fe11129..4483b74f9 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -270,7 +270,12 @@ namespace MediaBrowser.Api item.ParentIndexNumber = request.ParentIndexNumber; item.Overview = request.Overview; item.Genres = request.Genres; - item.Tags = request.Tags; + + var hasTags = item as IHasTags; + if (hasTags != null) + { + hasTags.Tags = request.Tags; + } if (request.Studios != null) { @@ -290,11 +295,17 @@ namespace MediaBrowser.Api item.EndDate = request.EndDate.HasValue ? request.EndDate.Value.ToUniversalTime() : (DateTime?)null; item.PremiereDate = request.PremiereDate.HasValue ? request.PremiereDate.Value.ToUniversalTime() : (DateTime?)null; item.ProductionYear = request.ProductionYear; - item.ProductionLocations = request.ProductionLocations; - item.Language = request.Language; item.OfficialRating = request.OfficialRating; item.CustomRating = request.CustomRating; + SetProductionLocations(item, request); + + var hasLanguage = item as IHasLanguage; + if (hasLanguage != null) + { + hasLanguage.Language = request.Language; + } + var hasAspectRatio = item as IHasAspectRatio; if (hasAspectRatio != null) { @@ -366,5 +377,22 @@ namespace MediaBrowser.Api } } + private void SetProductionLocations(BaseItem item, BaseItemDto request) + { + var hasProductionLocations = item as IHasProductionLocations; + + if (hasProductionLocations != null) + { + hasProductionLocations.ProductionLocations = request.ProductionLocations; + } + + var person = item as Person; + if (person != null) + { + person.PlaceOfBirth = request.ProductionLocations == null + ? null + : request.ProductionLocations.FirstOrDefault(); + } + } } } diff --git a/MediaBrowser.Api/Library/LibraryHelpers.cs b/MediaBrowser.Api/Library/LibraryHelpers.cs index d16250ce9..fb986605c 100644 --- a/MediaBrowser.Api/Library/LibraryHelpers.cs +++ b/MediaBrowser.Api/Library/LibraryHelpers.cs @@ -60,11 +60,6 @@ namespace MediaBrowser.Api.Library /// The path does not exist. public static void AddMediaPath(IFileSystem fileSystem, string virtualFolderName, string path, User user, IServerApplicationPaths appPaths) { - if (!Path.IsPathRooted(path)) - { - throw new ArgumentException("The path is not valid."); - } - if (!Directory.Exists(path)) { throw new DirectoryNotFoundException("The path does not exist."); diff --git a/MediaBrowser.Api/LibraryService.cs b/MediaBrowser.Api/LibraryService.cs index cf62e42ba..51eef225e 100644 --- a/MediaBrowser.Api/LibraryService.cs +++ b/MediaBrowser.Api/LibraryService.cs @@ -588,7 +588,7 @@ namespace MediaBrowser.Api var originalItem = item; - while (item.ThemeSongIds.Count == 0 && request.InheritFromParent && item.Parent != null) + while (GetThemeSongIds(item).Count == 0 && request.InheritFromParent && item.Parent != null) { item = item.Parent; } @@ -598,7 +598,7 @@ namespace MediaBrowser.Api .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) .ToList(); - var themeSongIds = item.ThemeSongIds; + var themeSongIds = GetThemeSongIds(item); if (themeSongIds.Count == 0 && request.InheritFromParent) { @@ -608,11 +608,11 @@ namespace MediaBrowser.Api { var linkedItemWithThemes = album.SoundtrackIds .Select(i => _libraryManager.GetItemById(i)) - .FirstOrDefault(i => i.ThemeSongIds.Count > 0); + .FirstOrDefault(i => GetThemeSongIds(i).Count > 0); if (linkedItemWithThemes != null) { - themeSongIds = linkedItemWithThemes.ThemeSongIds; + themeSongIds = GetThemeSongIds(linkedItemWithThemes); item = linkedItemWithThemes; } } @@ -656,7 +656,7 @@ namespace MediaBrowser.Api var originalItem = item; - while (item.ThemeVideoIds.Count == 0 && request.InheritFromParent && item.Parent != null) + while (GetThemeVideoIds(item).Count == 0 && request.InheritFromParent && item.Parent != null) { item = item.Parent; } @@ -666,7 +666,7 @@ namespace MediaBrowser.Api .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) .ToList(); - var themeVideoIds = item.ThemeVideoIds; + var themeVideoIds = GetThemeVideoIds(item); if (themeVideoIds.Count == 0 && request.InheritFromParent) { @@ -681,11 +681,11 @@ namespace MediaBrowser.Api { var linkedItemWithThemes = album.SoundtrackIds .Select(i => _libraryManager.GetItemById(i)) - .FirstOrDefault(i => i.ThemeVideoIds.Count > 0); + .FirstOrDefault(i => GetThemeVideoIds(i).Count > 0); if (linkedItemWithThemes != null) { - themeVideoIds = linkedItemWithThemes.ThemeVideoIds; + themeVideoIds = GetThemeVideoIds(linkedItemWithThemes); item = linkedItemWithThemes; } } @@ -705,6 +705,30 @@ namespace MediaBrowser.Api }; } + private List GetThemeVideoIds(BaseItem item) + { + var i = item as IHasThemeMedia; + + if (i != null) + { + return i.ThemeVideoIds; + } + + return new List(); + } + + private List GetThemeSongIds(BaseItem item) + { + var i = item as IHasThemeMedia; + + if (i != null) + { + return i.ThemeSongIds; + } + + return new List(); + } + private readonly CultureInfo _usCulture = new CultureInfo("en-US"); public object Get(GetYearIndex request) diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 706117fc2..ffcc4b838 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -38,18 +38,6 @@ Always - - False - ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll - - - False - ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll - - - False - ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll - @@ -60,6 +48,15 @@ ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll + + ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll + + + ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll + + + ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll + diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs index a160ce666..b0de3cf73 100644 --- a/MediaBrowser.Api/SimilarItemsHelper.cs +++ b/MediaBrowser.Api/SimilarItemsHelper.cs @@ -119,6 +119,17 @@ namespace MediaBrowser.Api .Select(i => i.Item1); } + private static IEnumerable GetTags(BaseItem item) + { + var hasTags = item as IHasTags; + if (hasTags != null) + { + return hasTags.Tags; + } + + return new List(); + } + /// /// Gets the similiarity score. /// @@ -138,7 +149,7 @@ namespace MediaBrowser.Api points += item1.Genres.Where(i => item2.Genres.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10); // Find common tags - points += item1.Tags.Where(i => item2.Tags.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10); + points += GetTags(item1).Where(i => GetTags(item2).Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10); // Find common studios points += item1.Studios.Where(i => item2.Studios.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 3); diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 3a7ea5ddd..7cb624af8 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -884,12 +884,36 @@ namespace MediaBrowser.Api.UserLibrary if (request.HasThemeSong.HasValue) { - items = items.Where(i => request.HasThemeSong.Value ? i.ThemeSongIds.Count > 0 : i.ThemeSongIds.Count == 0); + var filterValue = request.HasThemeSong.Value; + + items = items.Where(i => + { + var themeCount = 0; + var iHasThemeMedia = i as IHasThemeMedia; + + if (iHasThemeMedia != null) + { + themeCount = iHasThemeMedia.ThemeSongIds.Count; + } + return filterValue ? themeCount > 0 : themeCount == 0; + }); } if (request.HasThemeVideo.HasValue) { - items = items.Where(i => request.HasThemeVideo.Value ? i.ThemeVideoIds.Count > 0 : i.ThemeVideoIds.Count == 0); + var filterValue = request.HasThemeVideo.Value; + + items = items.Where(i => + { + var themeCount = 0; + var iHasThemeMedia = i as IHasThemeMedia; + + if (iHasThemeMedia != null) + { + themeCount = iHasThemeMedia.ThemeVideoIds.Count; + } + return filterValue ? themeCount > 0 : themeCount == 0; + }); } if (request.MinPlayers.HasValue) @@ -1166,7 +1190,12 @@ namespace MediaBrowser.Api.UserLibrary if (imageType == ImageType.Screenshot) { - return item.ScreenshotImagePaths.Count > 0; + var hasScreenshots = item as IHasScreenshots; + if (hasScreenshots == null) + { + return false; + } + return hasScreenshots.ScreenshotImagePaths.Count > 0; } return item.HasImage(imageType); diff --git a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs index ba68d1f5a..6acaac5c9 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs @@ -280,8 +280,7 @@ namespace MediaBrowser.Common.Implementations // If it's a relative path, e.g. "..\" if (!Path.IsPathRooted(programDataPath)) { - var path = Assembly.GetExecutingAssembly().Location; - path = Path.GetDirectoryName(path); + var path = Path.GetDirectoryName(ApplicationPath); if (string.IsNullOrEmpty(path)) { diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index 214ed106d..19091885d 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -103,21 +103,24 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager private WebRequest GetMonoRequest(HttpRequestOptions options, string method, bool enableHttpCompression) { - var request = WebRequest.Create(options.Url); + var request = (HttpWebRequest)WebRequest.Create(options.Url); if (!string.IsNullOrEmpty(options.AcceptHeader)) { - request.Headers.Add("Accept", options.AcceptHeader); + request.Accept = options.AcceptHeader; } + request.AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None; request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate); request.ConnectionGroupName = GetHostFromUrl(options.Url); + request.KeepAlive = true; request.Method = method; + request.Pipelined = true; request.Timeout = 20000; if (!string.IsNullOrEmpty(options.UserAgent)) { - request.Headers.Add("User-Agent", options.UserAgent); + request.UserAgent = options.UserAgent; } return request; diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 948785575..f990db556 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -37,21 +37,9 @@ Always - - False - ..\packages\NLog.2.1.0\lib\net45\NLog.dll - - - False - ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll - ..\packages\sharpcompress.0.10.1.3\lib\net40\SharpCompress.dll - - False - ..\packages\SimpleInjector.2.3.6\lib\net40-client\SimpleInjector.dll - @@ -59,6 +47,15 @@ + + ..\packages\NLog.2.1.0\lib\net45\NLog.dll + + + ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll + + + ..\packages\SimpleInjector.2.3.6\lib\net40-client\SimpleInjector.dll + diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index a9499dedd..c7b3a6511 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -35,21 +35,18 @@ 4 - - False - ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll - - - False - ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll - - - False - ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll - + + ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll + + + ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll + + + ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll + diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index ea4439c4e..795d22100 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -57,7 +57,7 @@ namespace MediaBrowser.Common.Plugins { get { return typeof(TConfigurationType); } } - + /// /// The _assembly name /// @@ -90,7 +90,8 @@ namespace MediaBrowser.Common.Plugins if (!_uniqueId.HasValue) { - _uniqueId = Marshal.GetTypeLibGuidForAssembly(GetType().Assembly); + var attribute = (GuidAttribute)GetType().Assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0]; + _uniqueId = new Guid(attribute.Value); } return _uniqueId.Value; @@ -282,7 +283,7 @@ namespace MediaBrowser.Common.Plugins { throw new ArgumentNullException("configuration"); } - + Configuration = (TConfigurationType)configuration; SaveConfiguration(); @@ -315,7 +316,7 @@ namespace MediaBrowser.Common.Plugins /// public virtual void OnUninstalling() { - + } /// diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 13b33c637..2a7aa4fea 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -9,7 +9,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// /// Class Audio /// - public class Audio : BaseItem, IHasMediaStreams, IHasAlbumArtist, IHasArtist, IHasMusicGenres + public class Audio : BaseItem, IHasMediaStreams, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLanguage { public Audio() { @@ -17,6 +17,12 @@ namespace MediaBrowser.Controller.Entities.Audio Artists = new List(); } + /// + /// Gets or sets the language. + /// + /// The language. + public string Language { get; set; } + /// /// Gets or sets the media streams. /// diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 09aefdac9..3facccec1 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -9,7 +9,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// /// Class MusicAlbum /// - public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres + public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasTags { public List SoundtrackIds { get; set; } @@ -17,11 +17,18 @@ namespace MediaBrowser.Controller.Entities.Audio { Artists = new List(); SoundtrackIds = new List(); + Tags = new List(); } public string LastFmImageUrl { get; set; } public string LastFmImageSize { get; set; } + /// + /// Gets or sets the tags. + /// + /// The tags. + public List Tags { get; set; } + /// /// Songs will group into us so don't also include us in the index /// diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index d5572b9a5..3be555f49 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -11,13 +11,21 @@ namespace MediaBrowser.Controller.Entities.Audio /// /// Class MusicArtist /// - public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess + public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess, IHasTags, IHasProductionLocations { [IgnoreDataMember] public List UserItemCountList { get; set; } public bool IsAccessedByName { get; set; } + /// + /// Gets or sets the tags. + /// + /// The tags. + public List Tags { get; set; } + + public List ProductionLocations { get; set; } + public override bool IsFolder { get @@ -70,6 +78,8 @@ namespace MediaBrowser.Controller.Entities.Audio public MusicArtist() { UserItemCountList = new List(); + Tags = new List(); + ProductionLocations = new List(); } /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 4f7889f97..2be4c7708 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -29,16 +29,10 @@ namespace MediaBrowser.Controller.Entities Genres = new List(); Studios = new List(); People = new List(); - ScreenshotImagePaths = new List(); BackdropImagePaths = new List(); - ProductionLocations = new List(); Images = new Dictionary(); ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); - Tags = new List(); - ThemeSongIds = new List(); - ThemeVideoIds = new List(); LockedFields = new List(); - Taglines = new List(); ImageSources = new List(); } @@ -84,12 +78,6 @@ namespace MediaBrowser.Controller.Entities /// The id. public Guid Id { get; set; } - /// - /// Gets or sets the taglines. - /// - /// The taglines. - public List Taglines { get; set; } - /// /// Return the id that should be used to key display prefs for this item. /// Default is based on the type for everything except actual generic folders. @@ -509,12 +497,6 @@ namespace MediaBrowser.Controller.Entities /// The backdrop image sources. public List ImageSources { get; set; } - /// - /// Gets or sets the screenshot image paths. - /// - /// The screenshot image paths. - public List ScreenshotImagePaths { get; set; } - /// /// Gets or sets the official rating. /// @@ -533,11 +515,6 @@ namespace MediaBrowser.Controller.Entities /// The custom rating. public string CustomRating { get; set; } - /// - /// Gets or sets the language. - /// - /// The language. - public string Language { get; set; } /// /// Gets or sets the overview. /// @@ -550,12 +527,6 @@ namespace MediaBrowser.Controller.Entities /// The people. public List People { get; set; } - /// - /// Gets or sets the tags. - /// - /// The tags. - public List Tags { get; set; } - /// /// Override this if you need to combine/collapse person information /// @@ -596,12 +567,6 @@ namespace MediaBrowser.Controller.Entities /// The home page URL. public string HomePageUrl { get; set; } - /// - /// Gets or sets the production locations. - /// - /// The production locations. - public List ProductionLocations { get; set; } - /// /// Gets or sets the community rating. /// @@ -644,9 +609,6 @@ namespace MediaBrowser.Controller.Entities /// The parent index number. public int? ParentIndexNumber { get; set; } - public List ThemeSongIds { get; set; } - public List ThemeVideoIds { get; set; } - [IgnoreDataMember] public virtual string OfficialRatingForComparison { @@ -884,9 +846,13 @@ namespace MediaBrowser.Controller.Entities if (LocationType == LocationType.FileSystem && Parent != null) { - themeSongsChanged = await RefreshThemeSongs(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); + var hasThemeMedia = this as IHasThemeMedia; + if (hasThemeMedia != null) + { + themeSongsChanged = await RefreshThemeSongs(hasThemeMedia, cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); - themeVideosChanged = await RefreshThemeVideos(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); + themeVideosChanged = await RefreshThemeVideos(hasThemeMedia, cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); + } var hasTrailers = this as IHasTrailers; if (hasTrailers != null) @@ -928,18 +894,18 @@ namespace MediaBrowser.Controller.Entities return itemsChanged || results.Contains(true); } - private async Task RefreshThemeVideos(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) + private async Task RefreshThemeVideos(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) { var newThemeVideos = LoadThemeVideos().ToList(); var newThemeVideoIds = newThemeVideos.Select(i => i.Id).ToList(); - var themeVideosChanged = !ThemeVideoIds.SequenceEqual(newThemeVideoIds); + var themeVideosChanged = !item.ThemeVideoIds.SequenceEqual(newThemeVideoIds); var tasks = newThemeVideos.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); - ThemeVideoIds = newThemeVideoIds; + item.ThemeVideoIds = newThemeVideoIds; return themeVideosChanged || results.Contains(true); } @@ -947,18 +913,18 @@ namespace MediaBrowser.Controller.Entities /// /// Refreshes the theme songs. /// - private async Task RefreshThemeSongs(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) + private async Task RefreshThemeSongs(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) { var newThemeSongs = LoadThemeSongs().ToList(); var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList(); - var themeSongsChanged = !ThemeSongIds.SequenceEqual(newThemeSongIds); + var themeSongsChanged = !item.ThemeSongIds.SequenceEqual(newThemeSongIds); var tasks = newThemeSongs.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); - ThemeSongIds = newThemeSongIds; + item.ThemeSongIds = newThemeSongIds; return themeSongsChanged || results.Contains(true); } @@ -1229,24 +1195,6 @@ namespace MediaBrowser.Controller.Entities } } - /// - /// Adds the tagline. - /// - /// The tagline. - /// tagline - public void AddTagline(string tagline) - { - if (string.IsNullOrWhiteSpace(tagline)) - { - throw new ArgumentNullException("tagline"); - } - - if (!Taglines.Contains(tagline, StringComparer.OrdinalIgnoreCase)) - { - Taglines.Add(tagline); - } - } - /// /// Adds a studio to the item /// @@ -1265,19 +1213,6 @@ namespace MediaBrowser.Controller.Entities } } - public void AddTag(string name) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException("name"); - } - - if (!Tags.Contains(name, StringComparer.OrdinalIgnoreCase)) - { - Tags.Add(name); - } - } - /// /// Adds a genre to the item /// @@ -1296,24 +1231,6 @@ namespace MediaBrowser.Controller.Entities } } - /// - /// Adds the production location. - /// - /// The location. - /// location - public void AddProductionLocation(string location) - { - if (string.IsNullOrWhiteSpace(location)) - { - throw new ArgumentNullException("location"); - } - - if (!ProductionLocations.Contains(location, StringComparer.OrdinalIgnoreCase)) - { - ProductionLocations.Add(location); - } - } - /// /// Marks the played. /// @@ -1516,9 +1433,10 @@ namespace MediaBrowser.Controller.Entities throw new ArgumentException("Please specify a screenshot image index to delete."); } - var file = ScreenshotImagePaths[index.Value]; + var hasScreenshots = (IHasScreenshots)this; + var file = hasScreenshots.ScreenshotImagePaths[index.Value]; - ScreenshotImagePaths.Remove(file); + hasScreenshots.ScreenshotImagePaths.Remove(file); // Delete the source file DeleteImagePath(file); @@ -1673,15 +1591,17 @@ namespace MediaBrowser.Controller.Entities /// public void ValidateScreenshots() { + var hasScreenshots = (IHasScreenshots)this; + // Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below - var deletedImages = ScreenshotImagePaths + var deletedImages = hasScreenshots.ScreenshotImagePaths .Where(path => !File.Exists(path)) .ToList(); // Now remove them from the dictionary foreach (var path in deletedImages) { - ScreenshotImagePaths.Remove(path); + hasScreenshots.ScreenshotImagePaths.Remove(path); } } @@ -1703,7 +1623,8 @@ namespace MediaBrowser.Controller.Entities if (imageType == ImageType.Screenshot) { - return ScreenshotImagePaths[imageIndex]; + var hasScreenshots = (IHasScreenshots)this; + return hasScreenshots.ScreenshotImagePaths[imageIndex]; } if (imageType == ImageType.Chapter) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index e8b583181..ba2bd85e8 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -21,13 +21,19 @@ namespace MediaBrowser.Controller.Entities /// /// Class Folder /// - public class Folder : BaseItem + public class Folder : BaseItem, IHasThemeMedia { public static IUserManager UserManager { get; set; } + public List ThemeSongIds { get; set; } + public List ThemeVideoIds { get; set; } + public Folder() { LinkedChildren = new List(); + + ThemeSongIds = new List(); + ThemeVideoIds = new List(); } /// @@ -687,7 +693,12 @@ namespace MediaBrowser.Controller.Entities //existing item - check if it has changed if (currentChild.HasChanged(child)) { - EntityResolutionHelper.EnsureDates(FileSystem, currentChild, child.ResolveArgs, false); + var currentChildLocationType = currentChild.LocationType; + if (currentChildLocationType != LocationType.Remote && + currentChildLocationType != LocationType.Virtual) + { + EntityResolutionHelper.EnsureDates(FileSystem, currentChild, child.ResolveArgs, false); + } validChildren.Add(new Tuple(currentChild, true)); } diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index e15b7e4c9..c15a31dd3 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -4,26 +4,51 @@ using System.Collections.Generic; namespace MediaBrowser.Controller.Entities { - public class Game : BaseItem, IHasSoundtracks, IHasTrailers + public class Game : BaseItem, IHasSoundtracks, IHasTrailers, IHasThemeMedia, IHasTags, IHasLanguage, IHasScreenshots { public List SoundtrackIds { get; set; } + public List ThemeSongIds { get; set; } + public List ThemeVideoIds { get; set; } + public Game() { MultiPartGameFiles = new List(); SoundtrackIds = new List(); RemoteTrailers = new List(); LocalTrailerIds = new List(); + ThemeSongIds = new List(); + ThemeVideoIds = new List(); + Tags = new List(); + ScreenshotImagePaths = new List(); } + /// + /// Gets or sets the language. + /// + /// The language. + public string Language { get; set; } + public List LocalTrailerIds { get; set; } - + + /// + /// Gets or sets the screenshot image paths. + /// + /// The screenshot image paths. + public List ScreenshotImagePaths { get; set; } + + /// + /// Gets or sets the tags. + /// + /// The tags. + public List Tags { get; set; } + /// /// Gets or sets the remote trailers. /// /// The remote trailers. public List RemoteTrailers { get; set; } - + /// /// Gets the type of the media. /// diff --git a/MediaBrowser.Controller/Entities/IHasLanguage.cs b/MediaBrowser.Controller/Entities/IHasLanguage.cs new file mode 100644 index 000000000..a1bb80098 --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasLanguage.cs @@ -0,0 +1,15 @@ + +namespace MediaBrowser.Controller.Entities +{ + /// + /// Interface IHasLanguage + /// + public interface IHasLanguage + { + /// + /// Gets or sets the language. + /// + /// The language. + string Language { get; set; } + } +} diff --git a/MediaBrowser.Controller/Entities/IHasProductionLocations.cs b/MediaBrowser.Controller/Entities/IHasProductionLocations.cs new file mode 100644 index 000000000..e4652fa8d --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasProductionLocations.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Controller.Entities +{ + /// + /// Interface IHasProductionLocations + /// + public interface IHasProductionLocations + { + /// + /// Gets or sets the production locations. + /// + /// The production locations. + List ProductionLocations { get; set; } + } + + public static class ProductionLocationExtensions + { + public static void AddProductionLocation(this IHasProductionLocations item, string name) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException("name"); + } + + if (!item.ProductionLocations.Contains(name, StringComparer.OrdinalIgnoreCase)) + { + item.ProductionLocations.Add(name); + } + } + } +} diff --git a/MediaBrowser.Controller/Entities/IHasScreenshots.cs b/MediaBrowser.Controller/Entities/IHasScreenshots.cs new file mode 100644 index 000000000..341d6403f --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasScreenshots.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Entities +{ + /// + /// Interface IHasScreenshots + /// + public interface IHasScreenshots + { + /// + /// Gets or sets the screenshot image paths. + /// + /// The screenshot image paths. + List ScreenshotImagePaths { get; set; } + } +} diff --git a/MediaBrowser.Controller/Entities/IHasTaglines.cs b/MediaBrowser.Controller/Entities/IHasTaglines.cs new file mode 100644 index 000000000..8025d6b44 --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasTaglines.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Controller.Entities +{ + /// + /// Interface IHasTaglines + /// + public interface IHasTaglines + { + /// + /// Gets or sets the taglines. + /// + /// The taglines. + List Taglines { get; set; } + } + + public static class TaglineExtensions + { + /// + /// Adds the tagline. + /// + /// The tagline. + /// tagline + public static void AddTagline(this IHasTaglines item, string tagline) + { + if (string.IsNullOrWhiteSpace(tagline)) + { + throw new ArgumentNullException("tagline"); + } + + if (!item.Taglines.Contains(tagline, StringComparer.OrdinalIgnoreCase)) + { + item.Taglines.Add(tagline); + } + } + } +} diff --git a/MediaBrowser.Controller/Entities/IHasTags.cs b/MediaBrowser.Controller/Entities/IHasTags.cs new file mode 100644 index 000000000..45a56009d --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasTags.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Controller.Entities +{ + /// + /// Interface IHasTags + /// + public interface IHasTags + { + /// + /// Gets or sets the tags. + /// + /// The tags. + List Tags { get; set; } + } + + public static class TagExtensions + { + public static void AddTag(this IHasTags item, string name) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException("name"); + } + + if (!item.Tags.Contains(name, StringComparer.OrdinalIgnoreCase)) + { + item.Tags.Add(name); + } + } + } +} diff --git a/MediaBrowser.Controller/Entities/IHasThemeMedia.cs b/MediaBrowser.Controller/Entities/IHasThemeMedia.cs new file mode 100644 index 000000000..acc0050ce --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasThemeMedia.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Entities +{ + /// + /// Interface IHasThemeMedia + /// + public interface IHasThemeMedia + { + /// + /// Gets or sets the theme song ids. + /// + /// The theme song ids. + List ThemeSongIds { get; set; } + + /// + /// Gets or sets the theme video ids. + /// + /// The theme video ids. + List ThemeVideoIds { get; set; } + } +} diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 4a6221ee9..a1154482c 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -7,12 +7,13 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// Class BoxSet /// - public class BoxSet : Folder, IHasTrailers + public class BoxSet : Folder, IHasTrailers, IHasTags { public BoxSet() { RemoteTrailers = new List(); LocalTrailerIds = new List(); + Tags = new List(); } public List LocalTrailerIds { get; set; } @@ -22,5 +23,11 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// The remote trailers. public List RemoteTrailers { get; set; } + + /// + /// Gets or sets the tags. + /// + /// The tags. + public List Tags { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 473ea4996..b4cf6c047 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -11,24 +11,43 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// Class Movie /// - public class Movie : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasTrailers + public class Movie : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasTags { public List SpecialFeatureIds { get; set; } public List SoundtrackIds { get; set; } + public List ThemeSongIds { get; set; } + public List ThemeVideoIds { get; set; } + public Movie() { SpecialFeatureIds = new List(); SoundtrackIds = new List(); RemoteTrailers = new List(); LocalTrailerIds = new List(); + ThemeSongIds = new List(); + ThemeVideoIds = new List(); + Taglines = new List(); + Tags = new List(); } public List LocalTrailerIds { get; set; } public List RemoteTrailers { get; set; } + /// + /// Gets or sets the tags. + /// + /// The tags. + public List Tags { get; set; } + + /// + /// Gets or sets the taglines. + /// + /// The taglines. + public List Taglines { get; set; } + /// /// Gets or sets the budget. /// diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 243861da7..832586ab9 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -1,5 +1,4 @@ using MediaBrowser.Model.Dto; -using System; using System.Collections.Generic; using System.Runtime.Serialization; @@ -15,6 +14,12 @@ namespace MediaBrowser.Controller.Entities UserItemCountList = new List(); } + /// + /// Gets or sets the place of birth. + /// + /// The place of birth. + public string PlaceOfBirth { get; set; } + [IgnoreDataMember] public List UserItemCountList { get; set; } diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index b4a3fc811..2312df2a1 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Controller.Entities.TV /// /// Class Series /// - public class Series : Folder, IHasSoundtracks, IHasTrailers + public class Series : Folder, IHasSoundtracks, IHasTrailers, IHasTags { public List SpecialFeatureIds { get; set; } public List SoundtrackIds { get; set; } @@ -27,12 +27,19 @@ namespace MediaBrowser.Controller.Entities.TV SoundtrackIds = new List(); RemoteTrailers = new List(); LocalTrailerIds = new List(); + Tags = new List(); } public List LocalTrailerIds { get; set; } public List RemoteTrailers { get; set; } - + + /// + /// Gets or sets the tags. + /// + /// The tags. + public List Tags { get; set; } + /// /// Gets or sets the status. /// diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 77efe8e8c..591fea14a 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Controller.Entities /// /// Class Trailer /// - public class Trailer : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasTrailers + public class Trailer : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasTrailers, IHasTaglines, IHasTags { public List SoundtrackIds { get; set; } @@ -18,12 +18,25 @@ namespace MediaBrowser.Controller.Entities Taglines = new List(); SoundtrackIds = new List(); LocalTrailerIds = new List(); + Tags = new List(); } public List LocalTrailerIds { get; set; } public List RemoteTrailers { get; set; } - + + /// + /// Gets or sets the tags. + /// + /// The tags. + public List Tags { get; set; } + + /// + /// Gets or sets the taglines. + /// + /// The taglines. + public List Taglines { get; set; } + /// /// Gets or sets the budget. /// diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 2beb3588e..03aa1413b 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -92,7 +92,13 @@ + + + + + + diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index 617e4fd81..78ae35b96 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -63,11 +63,22 @@ namespace MediaBrowser.Controller.Providers ValidationType = ValidationType.None }; - item.Taglines.Clear(); + var hasTaglines = item as IHasTaglines; + if (hasTaglines != null) + { + hasTaglines.Taglines.Clear(); + } + item.Studios.Clear(); item.Genres.Clear(); item.People.Clear(); - item.Tags.Clear(); + + var hasTags = item as IHasTags; + if (hasTags != null) + { + hasTags.Tags.Clear(); + } + var hasTrailers = item as IHasTrailers; if (hasTrailers != null) @@ -242,9 +253,26 @@ namespace MediaBrowser.Controller.Providers { var tagline = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(tagline)) + var hasTaglines = item as IHasTaglines; + if (hasTaglines != null) { - item.AddTagline(tagline); + if (!string.IsNullOrWhiteSpace(tagline)) + { + hasTaglines.AddTagline(tagline); + } + } + + break; + } + + case "Language": + { + var val = reader.ReadElementContentAsString(); + + var hasLanguage = item as IHasLanguage; + if (hasLanguage != null) + { + hasLanguage.Language = val; } break; @@ -256,7 +284,11 @@ namespace MediaBrowser.Controller.Providers if (!string.IsNullOrWhiteSpace(val)) { - item.ProductionLocations = new List { val }; + var person = item as Person; + if (person != null) + { + person.PlaceOfBirth = val; + } } break; @@ -690,7 +722,11 @@ namespace MediaBrowser.Controller.Providers { using (var subtree = reader.ReadSubtree()) { - FetchFromTagsNode(subtree, item); + var hasTags = item as IHasTags; + if (hasTags != null) + { + FetchFromTagsNode(subtree, hasTags); + } } break; } @@ -841,7 +877,14 @@ namespace MediaBrowser.Controller.Providers if (!string.IsNullOrWhiteSpace(val)) { - item.AddTagline(val); + var hasTaglines = item as IHasTaglines; + if (hasTaglines != null) + { + if (!string.IsNullOrWhiteSpace(val)) + { + hasTaglines.AddTagline(val); + } + } } break; } @@ -888,7 +931,7 @@ namespace MediaBrowser.Controller.Providers } } - private void FetchFromTagsNode(XmlReader reader, T item) + private void FetchFromTagsNode(XmlReader reader, IHasTags item) { reader.MoveToContent(); @@ -981,7 +1024,7 @@ namespace MediaBrowser.Controller.Providers } } } - + protected async Task FetchChaptersFromXmlNode(BaseItem item, XmlReader reader, IItemRepository repository, CancellationToken cancellationToken) { var runtime = item.RunTimeTicks ?? 0; @@ -1194,9 +1237,9 @@ namespace MediaBrowser.Controller.Providers var personInfo = new PersonInfo { - Name = name.Trim(), - Role = role, - Type = type, + Name = name.Trim(), + Role = role, + Type = type, SortOrder = sortOrder }; diff --git a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs index 1e4fabc7c..b39205b5d 100644 --- a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs +++ b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs @@ -133,11 +133,6 @@ namespace MediaBrowser.Controller.Resolvers /// if set to true [include creation time]. public static void EnsureDates(IFileSystem fileSystem, BaseItem item, ItemResolveArgs args, bool includeCreationTime) { - if (!Path.IsPathRooted(item.Path)) - { - return; - } - // See if a different path came out of the resolver than what went in if (!string.Equals(args.Path, item.Path, StringComparison.OrdinalIgnoreCase)) { diff --git a/MediaBrowser.Mono.sln b/MediaBrowser.Mono.sln index 0dc78ca2a..b7961816d 100644 --- a/MediaBrowser.Mono.sln +++ b/MediaBrowser.Mono.sln @@ -17,7 +17,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.WebDashboard", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Api", "MediaBrowser.Api\MediaBrowser.Api.csproj", "{4FD51AC5-2C16-4308-A993-C3A84F3B4582}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Mono", "MediaBrowser.Server.Mono\MediaBrowser.Server.Mono.csproj", "{A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Mono", "MediaBrowser.Server.Mono\MediaBrowser.Server.Mono.csproj", "{175A9388-F352-4586-A6B4-070DED62B644}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -25,6 +25,10 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {175A9388-F352-4586-A6B4-070DED62B644}.Debug|x86.ActiveCfg = Debug|x86 + {175A9388-F352-4586-A6B4-070DED62B644}.Debug|x86.Build.0 = Debug|x86 + {175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.ActiveCfg = Release|x86 + {175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.Build.0 = Release|x86 {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|x86.ActiveCfg = Debug|x86 {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|x86.Build.0 = Debug|x86 {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.ActiveCfg = Release|x86 @@ -53,16 +57,12 @@ Global {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|x86.Build.0 = Debug|Any CPU {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.ActiveCfg = Release|Any CPU {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.Build.0 = Release|Any CPU - {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}.Debug|x86.ActiveCfg = Debug|x86 - {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}.Debug|x86.Build.0 = Debug|x86 - {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}.Release|x86.ActiveCfg = Release|x86 - {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}.Release|x86.Build.0 = Release|x86 {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|x86.ActiveCfg = Debug|Any CPU {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|x86.Build.0 = Debug|Any CPU {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x86.ActiveCfg = Release|Any CPU {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = MediaBrowser.Server.Mono\MediaBrowser.Server.Mono.csproj + StartupItem = MediaBrowser.Model\MediaBrowser.Model.csproj EndGlobalSection EndGlobal diff --git a/MediaBrowser.Mono.userprefs b/MediaBrowser.Mono.userprefs index b3c4d6d23..42e34287b 100644 --- a/MediaBrowser.Mono.userprefs +++ b/MediaBrowser.Mono.userprefs @@ -1,32 +1,16 @@  - - + + - - - - - - - + + - - - - - - - - - - - - - + + diff --git a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs index f278a9089..70d9e788d 100644 --- a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs +++ b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs @@ -560,7 +560,11 @@ namespace MediaBrowser.Providers if (screenshotFiles.Count > 0) { - item.ScreenshotImagePaths = screenshotFiles; + var hasScreenshots = item as IHasScreenshots; + if (hasScreenshots != null) + { + hasScreenshots.ScreenshotImagePaths = screenshotFiles; + } } } diff --git a/MediaBrowser.Providers/Movies/MovieDbPersonProvider.cs b/MediaBrowser.Providers/Movies/MovieDbPersonProvider.cs index e8f8c0416..af9bef448 100644 --- a/MediaBrowser.Providers/Movies/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbPersonProvider.cs @@ -310,7 +310,7 @@ namespace MediaBrowser.Providers.Movies { if (!string.IsNullOrEmpty(searchResult.place_of_birth)) { - person.ProductionLocations = new List { searchResult.place_of_birth }; + person.PlaceOfBirth = searchResult.place_of_birth; } } diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 51a2362c0..fb75a9499 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -710,8 +710,12 @@ namespace MediaBrowser.Providers.Movies if (!string.IsNullOrEmpty(movieData.tagline)) { - movie.Taglines.Clear(); - movie.AddTagline(movieData.tagline); + var hasTagline = movie as IHasTaglines; + if (hasTagline != null) + { + hasTagline.Taglines.Clear(); + hasTagline.AddTagline(movieData.tagline); + } } movie.SetProviderId(MetadataProviders.Tmdb, movieData.id.ToString(_usCulture)); @@ -868,7 +872,11 @@ namespace MediaBrowser.Providers.Movies if (movieData.keywords != null && movieData.keywords.keywords != null && !movie.LockedFields.Contains(MetadataFields.Tags)) { - movie.Tags = movieData.keywords.keywords.Select(i => i.name).ToList(); + var hasTags = movie as IHasTags; + if (hasTags != null) + { + hasTags.Tags = movieData.keywords.keywords.Select(i => i.name).ToList(); + } } if (movieData.trailers != null && movieData.trailers.youtube != null && diff --git a/MediaBrowser.Providers/Music/LastfmArtistProvider.cs b/MediaBrowser.Providers/Music/LastfmArtistProvider.cs index 2a7977fa6..ae14d62c7 100644 --- a/MediaBrowser.Providers/Music/LastfmArtistProvider.cs +++ b/MediaBrowser.Providers/Music/LastfmArtistProvider.cs @@ -127,19 +127,6 @@ namespace MediaBrowser.Providers.Music return true; } - /// - /// Finds the id from music artist entity. - /// - /// The item. - /// System.String. - private string FindIdFromMusicArtistEntity(BaseItem item) - { - var artist = LibraryManager.RootFolder.RecursiveChildren.OfType() - .FirstOrDefault(i => string.Compare(i.Name, item.Name, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols) == 0); - - return artist != null ? artist.GetProviderId(MetadataProviders.Musicbrainz) : null; - } - /// /// Finds the id from music brainz. /// @@ -244,7 +231,7 @@ namespace MediaBrowser.Providers.Music if (result != null && result.artist != null) { - LastfmHelper.ProcessArtistData(item, result.artist); + LastfmHelper.ProcessArtistData((MusicArtist)item, result.artist); } } diff --git a/MediaBrowser.Providers/Music/LastfmHelper.cs b/MediaBrowser.Providers/Music/LastfmHelper.cs index 8e2aed50e..3301d5584 100644 --- a/MediaBrowser.Providers/Music/LastfmHelper.cs +++ b/MediaBrowser.Providers/Music/LastfmHelper.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Providers.Music { public static class LastfmHelper { - public static void ProcessArtistData(BaseItem artist, LastfmArtist data) + public static void ProcessArtistData(MusicArtist artist, LastfmArtist data) { var yearFormed = 0; @@ -37,14 +37,9 @@ namespace MediaBrowser.Providers.Music AddTags(artist, data.tags); } - var musicArtist = artist as MusicArtist; - - if (musicArtist != null) - { - string imageSize; - musicArtist.LastFmImageUrl = GetImageUrl(data, out imageSize); - musicArtist.LastFmImageSize = imageSize; - } + string imageSize; + artist.LastFmImageUrl = GetImageUrl(data, out imageSize); + artist.LastFmImageSize = imageSize; } private static string GetImageUrl(IHasLastFmImages data, out string size) @@ -118,7 +113,11 @@ namespace MediaBrowser.Providers.Music { var itemTags = (from tag in tags.tag where !string.IsNullOrEmpty(tag.name) select tag.name).ToList(); - item.Tags = itemTags; + var hasTags = item as IHasTags; + if (hasTags != null) + { + hasTags.Tags = itemTags; + } } } } diff --git a/MediaBrowser.Providers/Savers/PersonXmlSaver.cs b/MediaBrowser.Providers/Savers/PersonXmlSaver.cs index 50dab706e..cefdec9c1 100644 --- a/MediaBrowser.Providers/Savers/PersonXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/PersonXmlSaver.cs @@ -49,9 +49,11 @@ namespace MediaBrowser.Providers.Savers XmlSaverHelpers.AddCommonNodes(item, builder); - if (item.ProductionLocations.Count > 0) + var person = (Person)item; + + if (!string.IsNullOrEmpty(person.PlaceOfBirth)) { - builder.Append("" + SecurityElement.Escape(item.ProductionLocations[0]) + ""); + builder.Append("" + SecurityElement.Escape(person.PlaceOfBirth) + ""); } builder.Append(""); diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs index 186941988..a4e4ce1a8 100644 --- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs @@ -326,9 +326,13 @@ namespace MediaBrowser.Providers.Savers } } - if (!string.IsNullOrEmpty(item.Language)) + var hasLanguage = item as IHasLanguage; + if (hasLanguage != null) { - builder.Append("" + SecurityElement.Escape(item.Language) + ""); + if (!string.IsNullOrEmpty(hasLanguage.Language)) + { + builder.Append("" + SecurityElement.Escape(hasLanguage.Language) + ""); + } } // Use original runtime here, actual file runtime later in MediaInfo @@ -417,18 +421,22 @@ namespace MediaBrowser.Providers.Savers builder.Append("" + SecurityElement.Escape(tmdbCollection) + ""); } - if (item.Taglines.Count > 0) + var hasTagline = item as IHasTaglines; + if (hasTagline != null) { - builder.Append("" + SecurityElement.Escape(item.Taglines[0]) + ""); - - builder.Append(""); - - foreach (var tagline in item.Taglines) + if (hasTagline.Taglines.Count > 0) { - builder.Append("" + SecurityElement.Escape(tagline) + ""); - } + builder.Append("" + SecurityElement.Escape(hasTagline.Taglines[0]) + ""); - builder.Append(""); + builder.Append(""); + + foreach (var tagline in hasTagline.Taglines) + { + builder.Append("" + SecurityElement.Escape(tagline) + ""); + } + + builder.Append(""); + } } if (item.Genres.Count > 0) @@ -457,16 +465,20 @@ namespace MediaBrowser.Providers.Savers builder.Append(""); } - if (item.Tags.Count > 0) + var hasTags = item as IHasTags; + if (hasTags != null) { - builder.Append(""); - - foreach (var tag in item.Tags) + if (hasTags.Tags.Count > 0) { - builder.Append("" + SecurityElement.Escape(tag) + ""); - } + builder.Append(""); - builder.Append(""); + foreach (var tag in hasTags.Tags) + { + builder.Append("" + SecurityElement.Escape(tag) + ""); + } + + builder.Append(""); + } } if (item.People.Count > 0) diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index 382c25863..54e446380 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -471,16 +471,6 @@ namespace MediaBrowser.Providers.TV break; } - case "Language": - { - var val = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(val)) - { - item.Language = val; - } - break; - } - case "filename": { if (string.IsNullOrEmpty(item.PrimaryImagePath)) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index f298c2d4d..bb9ee7e14 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -392,7 +392,13 @@ namespace MediaBrowser.Server.Implementations.Dto /// List{Guid}. private List GetScreenshotImageTags(BaseItem item) { - return item.ScreenshotImagePaths + var hasScreenshots = item as IHasScreenshots; + if (hasScreenshots == null) + { + return new List(); + } + + return hasScreenshots.ScreenshotImagePaths .Select(p => GetImageCacheTag(item, ImageType.Screenshot, p)) .Where(i => i.HasValue) .Select(i => i.Value) @@ -746,12 +752,21 @@ namespace MediaBrowser.Server.Implementations.Dto if (fields.Contains(ItemFields.Tags)) { - dto.Tags = item.Tags; + var hasTags = item as IHasTags; + if (hasTags != null) + { + dto.Tags = hasTags.Tags; + } + + if (dto.Tags == null) + { + dto.Tags = new List(); + } } if (fields.Contains(ItemFields.ProductionLocations)) { - dto.ProductionLocations = item.ProductionLocations; + SetProductionLocations(item, dto); } var hasAspectRatio = item as IHasAspectRatio; @@ -789,10 +804,15 @@ namespace MediaBrowser.Server.Implementations.Dto dto.Id = GetDtoId(item); dto.IndexNumber = item.IndexNumber; dto.IsFolder = item.IsFolder; - dto.Language = item.Language; dto.MediaType = item.MediaType; dto.LocationType = item.LocationType; + var hasLanguage = item as IHasLanguage; + if (hasLanguage != null) + { + dto.Language = hasLanguage.Language; + } + var hasCriticRating = item as IHasCriticRating; if (hasCriticRating != null) { @@ -924,7 +944,16 @@ namespace MediaBrowser.Server.Implementations.Dto if (fields.Contains(ItemFields.Taglines)) { - dto.Taglines = item.Taglines; + var hasTagline = item as IHasTaglines; + if (hasTagline != null) + { + dto.Taglines = hasTagline.Taglines; + } + + if (dto.Taglines == null) + { + dto.Taglines = new List(); + } } dto.Type = item.GetClientTypeName(); @@ -1122,6 +1151,31 @@ namespace MediaBrowser.Server.Implementations.Dto } } + private void SetProductionLocations(BaseItem item, BaseItemDto dto) + { + var hasProductionLocations = item as IHasProductionLocations; + + if (hasProductionLocations != null) + { + dto.ProductionLocations = hasProductionLocations.ProductionLocations; + } + + var person = item as Person; + if (person != null) + { + dto.ProductionLocations = new List(); + if (!string.IsNullOrEmpty(person.PlaceOfBirth)) + { + dto.ProductionLocations.Add(person.PlaceOfBirth); + } + } + + if (dto.ProductionLocations == null) + { + dto.ProductionLocations = new List(); + } + } + /// /// Since it can be slow to make all of these calculations independently, this method will provide a way to do them all at once /// diff --git a/MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs b/MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs index 904b6799b..c7c6ad706 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer var swaggerDirectory = Path.Combine(runningDirectory, "swagger-ui"); - var requestedFile = Path.Combine(swaggerDirectory, request.ResourceName.Replace('/', '\\')); + var requestedFile = Path.Combine(swaggerDirectory, request.ResourceName.Replace('/', Path.DirectorySeparatorChar)); return ResultFactory.GetStaticFileResult(RequestContext, requestedFile); } diff --git a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs index 870a14bd8..a2240f52d 100644 --- a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs @@ -150,7 +150,6 @@ namespace MediaBrowser.Server.Implementations.IO } }) - .Where(Path.IsPathRooted) .Distinct(StringComparer.OrdinalIgnoreCase) .OrderBy(i => i) .ToList(); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index adf914766..121bf53d4 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -43,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV } // Optimization to avoid running these tests against Seasons - if (args.Parent is Series || args.Parent is MusicArtist || args.Parent is MusicAlbum) + if (args.Parent is Series || args.Parent is Season || args.Parent is MusicArtist || args.Parent is MusicAlbum) { return null; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 1ed973353..185a01663 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -308,29 +308,30 @@ namespace MediaBrowser.Server.Implementations.LiveTv internal async Task RefreshChannels(IProgress progress, CancellationToken cancellationToken) { // Avoid implicitly captured closure - var currentCancellationToken = cancellationToken; + var service = ActiveService; - var channelTasks = _services.Select(i => GetChannels(i, currentCancellationToken)); + if (service == null) + { + progress.Report(100); + return; + } progress.Report(10); - var results = await Task.WhenAll(channelTasks).ConfigureAwait(false); - - var allChannels = results.SelectMany(i => i).ToList(); + var allChannels = await GetChannels(service, cancellationToken).ConfigureAwait(false); + var allChannelsList = allChannels.ToList(); var list = new List(); var programs = new List(); var numComplete = 0; - foreach (var channelInfo in allChannels) + foreach (var channelInfo in allChannelsList) { try { var item = await GetChannel(channelInfo.Item2, channelInfo.Item1, cancellationToken).ConfigureAwait(false); - var service = _services.First(i => string.Equals(channelInfo.Item1, i.Name, StringComparison.OrdinalIgnoreCase)); - var channelPrograms = await service.GetProgramsAsync(channelInfo.Item2.Id, cancellationToken).ConfigureAwait(false); programs.AddRange(channelPrograms.Select(program => GetProgramInfoDto(program, item))); @@ -348,7 +349,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv numComplete++; double percent = numComplete; - percent /= allChannels.Count; + percent /= allChannelsList.Count; progress.Report(90 * percent + 10); } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 3bfbdea3e..54fbb502e 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -37,54 +37,14 @@ ..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll - - False - ..\packages\MediaBrowser.BdInfo.1.0.0.5\lib\net20\BDInfo.dll - ..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.70\lib\net35\Mono.Data.Sqlite.dll - - False - ..\packages\ServiceStack.3.9.70\lib\net35\ServiceStack.dll - - - False - ..\packages\ServiceStack.Api.Swagger.3.9.70\lib\net35\ServiceStack.Api.Swagger.dll - - - False - ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll - - - False - ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll - - - False - ..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.70\lib\net35\ServiceStack.OrmLite.dll - ..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.70\lib\net35\ServiceStack.OrmLite.Sqlite.dll - - False - ..\packages\ServiceStack.3.9.70\lib\net35\ServiceStack.ServiceInterface.dll - - - False - ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll - - - False - ..\packages\System.Data.SQLite.x86.1.0.89.0\lib\net45\System.Data.SQLite.dll - - - False - ..\packages\System.Data.SQLite.x86.1.0.89.0\lib\net45\System.Data.SQLite.Linq.dll - ..\packages\Rx-Core.2.1.30214.0\lib\Net45\System.Reactive.Core.dll @@ -109,6 +69,36 @@ ..\packages\ServiceStack.Redis.3.9.43\lib\net35\ServiceStack.Redis.dll + + ..\packages\MediaBrowser.BdInfo.1.0.0.5\lib\net20\BDInfo.dll + + + ..\packages\ServiceStack.3.9.70\lib\net35\ServiceStack.dll + + + ..\packages\ServiceStack.Api.Swagger.3.9.70\lib\net35\ServiceStack.Api.Swagger.dll + + + ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll + + + ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll + + + ..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.70\lib\net35\ServiceStack.OrmLite.dll + + + ..\packages\ServiceStack.3.9.70\lib\net35\ServiceStack.ServiceInterface.dll + + + ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll + + + ..\packages\System.Data.SQLite.x86.1.0.89.0\lib\net45\System.Data.SQLite.dll + + + ..\packages\System.Data.SQLite.x86.1.0.89.0\lib\net45\System.Data.SQLite.Linq.dll + diff --git a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs index e2192535c..8d88b66a0 100644 --- a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs +++ b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs @@ -114,7 +114,8 @@ namespace MediaBrowser.Server.Implementations.Providers } else if (type == ImageType.Screenshot && imageIndex == null) { - imageIndex = item.ScreenshotImagePaths.Count; + var hasScreenshots = (IHasScreenshots)item; + imageIndex = hasScreenshots.ScreenshotImagePaths.Count; } var paths = GetSavePaths(item, type, imageIndex, mimeType, saveLocally); @@ -262,11 +263,12 @@ namespace MediaBrowser.Server.Implementations.Providers { case ImageType.Screenshot: + var hasScreenshots = (IHasScreenshots)item; if (!imageIndex.HasValue) { throw new ArgumentNullException("imageIndex"); } - return item.ScreenshotImagePaths.Count > imageIndex.Value ? item.ScreenshotImagePaths[imageIndex.Value] : null; + return hasScreenshots.ScreenshotImagePaths.Count > imageIndex.Value ? hasScreenshots.ScreenshotImagePaths[imageIndex.Value] : null; case ImageType.Backdrop: if (!imageIndex.HasValue) { @@ -300,13 +302,14 @@ namespace MediaBrowser.Server.Implementations.Providers throw new ArgumentNullException("imageIndex"); } - if (item.ScreenshotImagePaths.Count > imageIndex.Value) + var hasScreenshots = (IHasScreenshots)item; + if (hasScreenshots.ScreenshotImagePaths.Count > imageIndex.Value) { - item.ScreenshotImagePaths[imageIndex.Value] = path; + hasScreenshots.ScreenshotImagePaths[imageIndex.Value] = path; } - else if (!item.ScreenshotImagePaths.Contains(path, StringComparer.OrdinalIgnoreCase)) + else if (!hasScreenshots.ScreenshotImagePaths.Contains(path, StringComparer.OrdinalIgnoreCase)) { - item.ScreenshotImagePaths.Add(path); + hasScreenshots.ScreenshotImagePaths.Add(path); } break; case ImageType.Backdrop: @@ -379,7 +382,8 @@ namespace MediaBrowser.Server.Implementations.Providers { throw new ArgumentNullException("imageIndex"); } - filename = GetBackdropSaveFilename(item.ScreenshotImagePaths, "screenshot", "screenshot", imageIndex.Value); + var hasScreenshots = (IHasScreenshots)item; + filename = GetBackdropSaveFilename(hasScreenshots.ScreenshotImagePaths, "screenshot", "screenshot", imageIndex.Value); break; default: filename = type.ToString().ToLower(); diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index e32dad8d7..8fd4b2b0d 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -5,13 +5,12 @@ x86 10.0.0 2.0 - {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0} - WinExe + {175A9388-F352-4586-A6B4-070DED62B644} + Exe MediaBrowser.Server.Mono MediaBrowser.Server.Mono - v4.5 MediaBrowser.Server.Mono.MainClass - ..\MediaBrowser.ServerApplication\Resources\Images\Icon.ico + v4.5 true @@ -22,7 +21,7 @@ prompt 4 x86 - false + true full @@ -31,20 +30,10 @@ prompt 4 x86 - false + true - - - - - - - - - - ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll @@ -52,18 +41,10 @@ ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll - - - gui.stetic - - Properties\SharedVersion.cs - - - @@ -133,9 +114,6 @@ - - PreserveNewest - PreserveNewest diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index d423017fc..cf0b4c6d7 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -14,8 +14,6 @@ using System.Windows; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; -using Gtk; -using Gdk; using System.Threading.Tasks; using System.Reflection; @@ -27,15 +25,8 @@ namespace MediaBrowser.Server.Mono private static ILogger _logger; - private static MainWindow _mainWindow; - - // The tray Icon - private static StatusIcon trayIcon; - public static void Main (string[] args) { - Application.Init (); - var applicationPath = Assembly.GetEntryAssembly ().Location; var appPaths = CreateApplicationPaths(applicationPath); @@ -98,10 +89,10 @@ namespace MediaBrowser.Server.Mono private static RemoteCertificateValidationCallback _ignoreCertificates = new RemoteCertificateValidationCallback(delegate { return true; }); + private static TaskCompletionSource _applicationTaskCompletionSource = new TaskCompletionSource(); + private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager) { - // TODO: Show splash here - SystemEvents.SessionEnding += SystemEvents_SessionEnding; // Allow all https requests @@ -109,77 +100,19 @@ namespace MediaBrowser.Server.Mono _appHost = new ApplicationHost(appPaths, logManager); + Console.WriteLine ("appHost.Init"); + var task = _appHost.Init(); Task.WaitAll (task); + Console.WriteLine ("Running startup tasks"); + task = _appHost.RunStartupTasks(); Task.WaitAll (task); - // TODO: Hide splash here - _mainWindow = new MainWindow (); + task = _applicationTaskCompletionSource.Task; - // Creation of the Icon - // Creation of the Icon - trayIcon = new StatusIcon(new Pixbuf ("tray.png")); - trayIcon.Visible = true; - - // When the TrayIcon has been clicked. - trayIcon.Activate += delegate { }; - // Show a pop up menu when the icon has been right clicked. - trayIcon.PopupMenu += OnTrayIconPopup; - - // A Tooltip for the Icon - trayIcon.Tooltip = "Media Browser Server"; - - _mainWindow.ShowAll (); - _mainWindow.Visible = false; - - Application.Run (); - } - - // Create the popup menu, on right click. - static void OnTrayIconPopup (object o, EventArgs args) { - - Menu popupMenu = new Menu(); - - var menuItemBrowse = new ImageMenuItem ("Browse Library"); - menuItemBrowse.Image = new Gtk.Image(Stock.MediaPlay, IconSize.Menu); - popupMenu.Add(menuItemBrowse); - menuItemBrowse.Activated += delegate { - BrowserLauncher.OpenWebClient(_appHost.UserManager, _appHost.ServerConfigurationManager, _appHost, _logger); - }; - - var menuItemConfigure = new ImageMenuItem ("Configure Media Browser"); - menuItemConfigure.Image = new Gtk.Image(Stock.Edit, IconSize.Menu); - popupMenu.Add(menuItemConfigure); - menuItemConfigure.Activated += delegate { - BrowserLauncher.OpenDashboard(_appHost.UserManager, _appHost.ServerConfigurationManager, _appHost, _logger); - }; - - var menuItemApi = new ImageMenuItem ("View Api Docs"); - menuItemApi.Image = new Gtk.Image(Stock.Network, IconSize.Menu); - popupMenu.Add(menuItemApi); - menuItemApi.Activated += delegate { - BrowserLauncher.OpenSwagger(_appHost.ServerConfigurationManager, _appHost, _logger); - }; - - var menuItemCommunity = new ImageMenuItem ("Visit Community"); - menuItemCommunity.Image = new Gtk.Image(Stock.Help, IconSize.Menu); - popupMenu.Add(menuItemCommunity); - menuItemCommunity.Activated += delegate { BrowserLauncher.OpenCommunity(_logger); }; - - var menuItemGithub = new ImageMenuItem ("Visit Github"); - menuItemGithub.Image = new Gtk.Image(Stock.Network, IconSize.Menu); - popupMenu.Add(menuItemGithub); - menuItemGithub.Activated += delegate { BrowserLauncher.OpenGithub(_logger); }; - - var menuItemQuit = new ImageMenuItem ("Exit"); - menuItemQuit.Image = new Gtk.Image(Stock.Quit, IconSize.Menu); - popupMenu.Add(menuItemQuit); - menuItemQuit.Activated += delegate { Shutdown(); }; - - popupMenu.ShowAll(); - popupMenu.Popup(); + Task.WaitAll (task); } /// @@ -206,8 +139,6 @@ namespace MediaBrowser.Server.Mono logger.Info("Server: {0}", Environment.MachineName); logger.Info("Operating system: {0}", Environment.OSVersion.ToString()); - - MonoBug11817WorkAround.Apply (); } /// @@ -237,6 +168,9 @@ namespace MediaBrowser.Server.Mono var builder = LogHelper.GetLogMessage(ex); + Console.WriteLine ("UnhandledException"); + Console.WriteLine (builder.ToString()); + File.WriteAllText(path, builder.ToString()); } @@ -253,19 +187,7 @@ namespace MediaBrowser.Server.Mono public static void Shutdown() { - if (trayIcon != null) { - trayIcon.Visible = false; - trayIcon.Dispose (); - trayIcon = null; - } - - if (_mainWindow != null) { - _mainWindow.HideAll (); - _mainWindow.Dispose (); - _mainWindow = null; - } - - Application.Quit (); + _applicationTaskCompletionSource.SetResult (true); } public static void Restart() @@ -285,34 +207,4 @@ namespace MediaBrowser.Server.Mono return true; } } - - public class MonoBug11817WorkAround - { - public static void Apply() - { - var property = typeof(TimeZoneInfo).GetProperty("TimeZoneDirectory", BindingFlags.Static | BindingFlags.NonPublic); - - if (property == null) return; - - var zoneInfo = FindZoneInfoFolder(); - property.SetValue(null, zoneInfo, new object[0]); - } - - public static string FindZoneInfoFolder() - { - var current = new DirectoryInfo(Directory.GetCurrentDirectory()); - - while(current != null) - { - var zoneinfoTestPath = Path.Combine(current.FullName, "zoneinfo"); - - if (Directory.Exists(zoneinfoTestPath)) - return zoneinfoTestPath; - - current = current.Parent; - } - - return null; - } - } } diff --git a/MediaBrowser.Server.Mono/Properties/AssemblyInfo.cs b/MediaBrowser.Server.Mono/Properties/AssemblyInfo.cs index 3d6ac0bc1..15cff7fc3 100644 --- a/MediaBrowser.Server.Mono/Properties/AssemblyInfo.cs +++ b/MediaBrowser.Server.Mono/Properties/AssemblyInfo.cs @@ -10,4 +10,7 @@ using System.Runtime.CompilerServices; [assembly: AssemblyProduct ("")] [assembly: AssemblyCopyright ("Luke")] [assembly: AssemblyTrademark ("")] -[assembly: AssemblyCulture ("")] \ No newline at end of file +[assembly: AssemblyCulture ("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/app.config b/MediaBrowser.Server.Mono/app.config index 843dae41d..7a240c6dd 100644 --- a/MediaBrowser.Server.Mono/app.config +++ b/MediaBrowser.Server.Mono/app.config @@ -8,7 +8,7 @@ - - + + diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index f51238152..ac6959e45 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -57,7 +57,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Net.Http; using System.Reflection; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs b/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs index 1a5f9e2c3..ea346e1be 100644 --- a/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs +++ b/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs @@ -3,10 +3,8 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; -using System; -using System.Linq; -using System.Windows.Forms; using MediaBrowser.ServerApplication.Native; +using System.Linq; namespace MediaBrowser.ServerApplication.EntryPoints { @@ -58,16 +56,7 @@ namespace MediaBrowser.ServerApplication.EntryPoints { var user = _userManager.Users.FirstOrDefault(u => u.Configuration.IsAdministrator); - try - { - BrowserLauncher.OpenDashboardPage("wizardstart.html", user, _configurationManager, _appHost, _logger); - } - catch (Exception ex) - { - _logger.ErrorException("Error launching startup wizard", ex); - - MessageBox.Show("There was an error launching the Media Browser startup wizard. Please ensure a web browser is installed on the machine and is configured as the default browser.", "Media Browser"); - } + BrowserLauncher.OpenDashboardPage("wizardstart.html", user, _configurationManager, _appHost, _logger); } /// diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 5f05bc787..79204e056 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -166,8 +166,6 @@ - - diff --git a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs index 43a698434..39beee563 100644 --- a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs +++ b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs @@ -6,7 +6,6 @@ using MediaBrowser.Model.Logging; using System; using System.Diagnostics; using System.Linq; -using System.Windows.Forms; namespace MediaBrowser.ServerApplication.Native { @@ -107,14 +106,14 @@ namespace MediaBrowser.ServerApplication.Native private static void OpenUrl(string url, ILogger logger) { var process = new Process + { + StartInfo = new ProcessStartInfo { - StartInfo = new ProcessStartInfo - { - FileName = url - }, + FileName = url + }, - EnableRaisingEvents = true - }; + EnableRaisingEvents = true, + }; process.Exited += ProcessExited; @@ -126,7 +125,12 @@ namespace MediaBrowser.ServerApplication.Native { logger.ErrorException("Error launching url: {0}", ex, url); - MessageBox.Show("There was an error launching your web browser. Please check your default browser settings."); + Console.WriteLine("Error launching browser"); + Console.WriteLine(ex.Message); + +#if !__MonoCS__ + System.Windows.Forms.MessageBox.Show("There was an error launching your web browser. Please check your default browser settings."); +#endif } } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 3b2714b2d..89a21121c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -37,24 +37,21 @@ Always - - False - ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll - - - False - ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll - - - False - ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll - + + ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll + + + ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll + + + ..\packages\ServiceStack.Text.3.9.70\lib\net35\ServiceStack.Text.dll +