diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index decd19602..82931e11e 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -201,10 +201,10 @@ namespace MediaBrowser.Api.Library var rootFolderPath = _appPaths.DefaultUserViewsPath; var virtualFolderPath = Path.Combine(rootFolderPath, name); - - if (_fileSystem.DirectoryExists(virtualFolderPath)) + while (_fileSystem.DirectoryExists(virtualFolderPath)) { - throw new ArgumentException("There is already a media library with the name " + name + "."); + name += "1"; + virtualFolderPath = Path.Combine(rootFolderPath, name); } if (request.Paths != null) @@ -236,7 +236,7 @@ namespace MediaBrowser.Api.Library { foreach (var path in request.Paths) { - LibraryHelpers.AddMediaPath(_fileSystem, request.Name, path, _appPaths); + LibraryHelpers.AddMediaPath(_fileSystem, name, path, _appPaths); } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index bd4ede466..4106c7197 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -57,7 +57,9 @@ namespace MediaBrowser.Controller.Entities public static string ThemeSongFilename = "theme"; public static string ThemeVideosFolderName = "backdrops"; + [IgnoreDataMember] public string PreferredMetadataCountryCode { get; set; } + [IgnoreDataMember] public string PreferredMetadataLanguage { get; set; } public List ImageInfos { get; set; } @@ -88,6 +90,7 @@ namespace MediaBrowser.Controller.Entities /// Gets a value indicating whether this instance is in mixed folder. /// /// true if this instance is in mixed folder; otherwise, false. + [IgnoreDataMember] public bool IsInMixedFolder { get; set; } [IgnoreDataMember] @@ -342,6 +345,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public DateTime DateModified { get; set; } + [IgnoreDataMember] public DateTime DateLastSaved { get; set; } [IgnoreDataMember] @@ -380,6 +384,7 @@ namespace MediaBrowser.Controller.Entities /// Gets or sets the locked fields. /// /// The locked fields. + [IgnoreDataMember] public List LockedFields { get; set; } /// @@ -620,6 +625,7 @@ namespace MediaBrowser.Controller.Entities /// Gets or sets the studios. /// /// The studios. + [IgnoreDataMember] public List Studios { get; set; } /// @@ -633,6 +639,7 @@ namespace MediaBrowser.Controller.Entities /// Gets or sets the tags. /// /// The tags. + [IgnoreDataMember] public List Tags { get; set; } /// diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index f006fedd2..5ef098ff8 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.Configuration; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Users; @@ -9,6 +10,7 @@ namespace MediaBrowser.Controller.Entities { public class Book : BaseItem, IHasTags, IHasLookupInfo, IHasSeries { + [IgnoreDataMember] public override string MediaType { get diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 3c7d39e0d..3bff5bc64 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -14,7 +14,6 @@ namespace MediaBrowser.Controller.Entities /// /// Class Trailer /// - [Obsolete] public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasLookupInfo { public List ProductionLocations { get; set; } diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index d1a415f73..937a3f8fd 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -488,7 +488,7 @@ namespace MediaBrowser.Dlna.ContentDirectory var itemsResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user) { Person = person.Name, - IncludeItemTypes = new[] { typeof(Movie).Name, typeof(Series).Name, typeof(ChannelVideoItem).Name }, + IncludeItemTypes = new[] { typeof(Movie).Name, typeof(Series).Name, typeof(Trailer).Name, typeof(ChannelVideoItem).Name }, SortBy = new[] { ItemSortBy.SortName }, Limit = limit, StartIndex = startIndex diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 93bfcbbab..c6452d8f5 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -21,6 +21,7 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Server.Implementations.HttpServer { @@ -342,16 +343,26 @@ namespace MediaBrowser.Server.Implementations.HttpServer urlToLog = GetUrlToLog(urlString); LoggerUtils.LogRequest(_logger, urlToLog, httpReq.HttpMethod, httpReq.UserAgent); } - + if (string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase) || - string.Equals(localPath, "/emby/", StringComparison.OrdinalIgnoreCase)) + string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase) || + localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1 || + localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1) { - httpRes.RedirectToUrl(DefaultRedirectPath); + httpRes.StatusCode = 200; + httpRes.ContentType = "text/html"; + var newUrl = urlString.Replace("mediabrowser", "emby", StringComparison.OrdinalIgnoreCase) + .Replace("/dashboard/", "/web/", StringComparison.OrdinalIgnoreCase); + + httpRes.Write("EmbyPlease update your Emby bookmark to " + newUrl + ""); + + httpRes.Close(); return Task.FromResult(true); } - if (string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(localPath, "/emby/", StringComparison.OrdinalIgnoreCase)) { - httpRes.RedirectToUrl("mediabrowser/" + DefaultRedirectPath); + httpRes.RedirectToUrl(DefaultRedirectPath); return Task.FromResult(true); } if (string.Equals(localPath, "/emby", StringComparison.OrdinalIgnoreCase)) @@ -385,7 +396,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer httpRes.RedirectToUrl("web/pin.html"); return Task.FromResult(true); } - + if (!string.IsNullOrWhiteSpace(GlobalResponse)) { httpRes.StatusCode = 503; @@ -461,6 +472,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer Priority = route.Priority, Summary = route.Summary }); + routes.Add(new RouteAttribute(NormalizeRoutePath(route.Path), route.Verbs) { Notes = route.Notes, @@ -468,13 +480,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer Summary = route.Summary }); - // TODO: This is a hack for iOS. Remove it asap. - routes.Add(new RouteAttribute(DoubleNormalizeRoutePath(route.Path), route.Verbs) - { - Notes = route.Notes, - Priority = route.Priority, - Summary = route.Summary - }); routes.Add(new RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs) { Notes = route.Notes, @@ -516,16 +521,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer return "mediabrowser/" + path; } - private string DoubleNormalizeRoutePath(string path) - { - if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase)) - { - return "/mediabrowser/mediabrowser" + path; - } - - return "mediabrowser/mediabrowser/" + path; - } - /// /// Releases the specified instance. /// diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 18a41d82a..56daff78a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -348,7 +348,12 @@ namespace MediaBrowser.Server.Implementations.Persistence "Genres", "ParentId", "Audio", - "ExternalServiceId" + "ExternalServiceId", + "IsInMixedFolder", + "DateLastSaved", + "LockedFields", + "Studios", + "Tags" }; private readonly string[] _mediaStreamSaveColumns = @@ -1079,6 +1084,31 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + if (!reader.IsDBNull(44)) + { + item.IsInMixedFolder = reader.GetBoolean(44); + } + + if (!reader.IsDBNull(45)) + { + item.DateLastSaved = reader.GetDateTime(45).ToUniversalTime(); + } + + if (!reader.IsDBNull(46)) + { + item.LockedFields = reader.GetString(46).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => (MetadataFields)Enum.Parse(typeof(MetadataFields), i, true)).ToList(); + } + + if (!reader.IsDBNull(47)) + { + item.Studios = reader.GetString(47).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + } + + if (!reader.IsDBNull(48)) + { + item.Tags = reader.GetString(48).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + } + return item; } @@ -2013,6 +2043,7 @@ namespace MediaBrowser.Server.Implementations.Persistence typeof(MusicGenre), typeof(MusicVideo), typeof(Movie), + typeof(Trailer), typeof(BoxSet), typeof(Episode), typeof(ChannelVideoItem), diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index a5bfebea9..ab9ff8e6f 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -25,7 +25,6 @@ namespace MediaBrowser.WebDashboard.Api /// /// Class GetDashboardConfigurationPages /// - [Route("/dashboard/ConfigurationPages", "GET")] [Route("/web/ConfigurationPages", "GET")] public class GetDashboardConfigurationPages : IReturn> { @@ -39,7 +38,6 @@ namespace MediaBrowser.WebDashboard.Api /// /// Class GetDashboardConfigurationPage /// - [Route("/dashboard/ConfigurationPage", "GET")] [Route("/web/ConfigurationPage", "GET")] public class GetDashboardConfigurationPage { @@ -51,7 +49,6 @@ namespace MediaBrowser.WebDashboard.Api } [Route("/web/Package", "GET")] - [Route("/dashboard/Package", "GET")] public class GetDashboardPackage { public string Mode { get; set; } @@ -66,7 +63,6 @@ namespace MediaBrowser.WebDashboard.Api /// Class GetDashboardResource /// [Route("/web/{ResourceName*}", "GET")] - [Route("/dashboard/{ResourceName*}", "GET")] public class GetDashboardResource { /// @@ -142,7 +138,7 @@ namespace MediaBrowser.WebDashboard.Api { var page = ServerEntryPoint.Instance.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase)); - return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml(null, page.GetHtmlStream(), null, _appHost.ApplicationVersion.ToString(), null, false)); + return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml("dummy.html", page.GetHtmlStream(), null, _appHost.ApplicationVersion.ToString(), null, false)); } /// diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 55f6ca7a4..726205671 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -261,11 +261,21 @@ namespace MediaBrowser.WebDashboard.Api { html = ModifyForCordova(html); } - else if (!string.IsNullOrWhiteSpace(path) && !string.Equals(path, "index.html", StringComparison.OrdinalIgnoreCase) && html.IndexOf("", StringComparison.OrdinalIgnoreCase); + if (index != -1) + { + html = html.Substring(0, index+7); + } + } + var mainFile = File.ReadAllText(GetDashboardResourcePath("index.html")); - html = ReplaceFirst(indexFile, "
", "
" + html + "
"); + html = ReplaceFirst(mainFile, "
", "
" + html + "
"); } if (!string.IsNullOrWhiteSpace(localizationCulture)) @@ -305,6 +315,13 @@ namespace MediaBrowser.WebDashboard.Api html = html.Replace("", "" + GetMetaTags(mode) + GetCommonCss(mode, appVersion)); + // Disable embedded scripts from plugins. We'll run them later once resources have loaded + if (html.IndexOf("", "-->"); + } + html = html.Replace("", GetCommonJavascript(mode, appVersion) + ""); var bytes = Encoding.UTF8.GetBytes(html); diff --git a/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs index 14c214f04..f27f0a191 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs @@ -36,13 +36,24 @@ namespace MediaBrowser.XbmcMetadata.Parsers switch (reader.Name) { case "id": - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) { - item.SetProviderId(MetadataProviders.Imdb, id); - } - break; + string imdbId = reader.GetAttribute("IMDB"); + string tmdbId = reader.GetAttribute("TMDB"); + if (string.IsNullOrWhiteSpace(imdbId)) + { + imdbId = reader.ReadElementContentAsString(); + } + if (!string.IsNullOrWhiteSpace(imdbId)) + { + item.SetProviderId(MetadataProviders.Imdb, imdbId); + } + if (!string.IsNullOrWhiteSpace(tmdbId)) + { + item.SetProviderId(MetadataProviders.Tmdb, tmdbId); + } + break; + } case "set": { var movie = item as Movie; diff --git a/MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs index 03dba56e0..d5b5428c0 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs @@ -27,13 +27,29 @@ namespace MediaBrowser.XbmcMetadata.Parsers switch (reader.Name) { case "id": - string id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) { - item.SetProviderId(MetadataProviders.Tvdb, id); - } - break; + string imdbId = reader.GetAttribute("IMDB"); + string tmdbId = reader.GetAttribute("TMDB"); + string tvdbId = reader.GetAttribute("TVDB"); + if (string.IsNullOrWhiteSpace(tvdbId)) + { + tvdbId = reader.ReadElementContentAsString(); + } + if (!string.IsNullOrWhiteSpace(imdbId)) + { + item.SetProviderId(MetadataProviders.Imdb, imdbId); + } + if (!string.IsNullOrWhiteSpace(tmdbId)) + { + item.SetProviderId(MetadataProviders.Tmdb, tmdbId); + } + if (!string.IsNullOrWhiteSpace(tvdbId)) + { + item.SetProviderId(MetadataProviders.Tvcom, tvdbId); + } + break; + } case "airs_dayofweek": { item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());