瀏覽代碼

pass requested fields to data layer

Luke Pulverenti 8 年之前
父節點
當前提交
5cd3276775
共有 64 個文件被更改,包括 739 次插入633 次删除
  1. 3 1
      MediaBrowser.Api/FilterService.cs
  2. 4 3
      MediaBrowser.Api/GamesService.cs
  3. 2 23
      MediaBrowser.Api/ItemUpdateService.cs
  4. 3 2
      MediaBrowser.Api/MediaBrowser.Api.csproj
  5. 14 8
      MediaBrowser.Api/Movies/MoviesService.cs
  6. 4 4
      MediaBrowser.Api/PackageService.cs
  7. 0 3
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  8. 0 1
      MediaBrowser.Api/Playback/StreamState.cs
  9. 0 4
      MediaBrowser.Api/Reports/Data/ReportBuilder.cs
  10. 0 25
      MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs
  11. 2 1
      MediaBrowser.Api/SimilarItemsHelper.cs
  12. 2 0
      MediaBrowser.Api/StartupWizardService.cs
  13. 8 6
      MediaBrowser.Api/TvShowsService.cs
  14. 10 12
      MediaBrowser.Api/UserLibrary/ItemsService.cs
  15. 6 2
      MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
  16. 4 8
      MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
  17. 1 1
      MediaBrowser.Common/Updates/IInstallationManager.cs
  18. 1 17
      MediaBrowser.Controller/Entities/Audio/Audio.cs
  19. 1 8
      MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
  20. 2 0
      MediaBrowser.Controller/Entities/BaseItem.cs
  21. 0 8
      MediaBrowser.Controller/Entities/IArchivable.cs
  22. 0 34
      MediaBrowser.Controller/Entities/IHasProductionLocations.cs
  23. 0 39
      MediaBrowser.Controller/Entities/IHasTaglines.cs
  24. 34 0
      MediaBrowser.Controller/Entities/InternalItemsQuery.cs
  25. 1 3
      MediaBrowser.Controller/Entities/Movies/Movie.cs
  26. 1 3
      MediaBrowser.Controller/Entities/MusicVideo.cs
  27. 1 9
      MediaBrowser.Controller/Entities/Photo.cs
  28. 1 4
      MediaBrowser.Controller/Entities/TV/Series.cs
  29. 1 11
      MediaBrowser.Controller/Entities/Trailer.cs
  30. 1 1
      MediaBrowser.Controller/Entities/UserViewBuilder.cs
  31. 1 17
      MediaBrowser.Controller/Entities/Video.cs
  32. 1 3
      MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
  33. 0 3
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  34. 1 16
      MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
  35. 13 26
      MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
  36. 0 3
      MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
  37. 0 3
      MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
  38. 2 0
      MediaBrowser.Model/Configuration/ServerConfiguration.cs
  39. 1 5
      MediaBrowser.Model/Dto/BaseItemDto.cs
  40. 0 1
      MediaBrowser.Model/MediaBrowser.Model.csproj
  41. 4 0
      MediaBrowser.Model/Querying/ItemFields.cs
  42. 3 3
      MediaBrowser.Model/Updates/PackageInfo.cs
  43. 0 21
      MediaBrowser.Model/Updates/PackageType.cs
  44. 0 6
      MediaBrowser.Providers/Manager/ItemImageProvider.cs
  45. 5 29
      MediaBrowser.Providers/Manager/ProviderUtils.cs
  46. 1 1
      MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
  47. 0 7
      MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
  48. 0 7
      MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
  49. 1 2
      MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
  50. 9 14
      MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
  51. 2 29
      MediaBrowser.Providers/TV/SeriesPostScanTask.cs
  52. 13 32
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  53. 2 1
      MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
  54. 14 9
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  55. 3 2
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  56. 440 107
      MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
  57. 4 4
      MediaBrowser.Server.Implementations/app.config
  58. 90 2
      MediaBrowser.Server.Startup.Common/ApplicationHost.cs
  59. 4 0
      MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
  60. 6 19
      MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
  61. 7 15
      MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
  62. 2 2
      Nuget/MediaBrowser.Common.Internal.nuspec
  63. 1 1
      Nuget/MediaBrowser.Common.nuspec
  64. 2 2
      Nuget/MediaBrowser.Server.Core.nuspec

+ 3 - 1
MediaBrowser.Api/FilterService.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Querying;
 using ServiceStack;
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 
@@ -104,7 +105,8 @@ namespace MediaBrowser.Api
                 MediaTypes = request.GetMediaTypes(),
                 IncludeItemTypes = request.GetIncludeItemTypes(),
                 Recursive = true,
-                EnableTotalRecordCount = false
+                EnableTotalRecordCount = false,
+                Fields = new List<ItemFields> { ItemFields.Genres, ItemFields.Tags }
             };
 
             return query;

+ 4 - 3
MediaBrowser.Api/GamesService.cs

@@ -200,6 +200,8 @@ namespace MediaBrowser.Api
                 (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
                 _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
 
+            var dtoOptions = GetDtoOptions(request);
+
             var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
             {
                 Limit = request.Limit,
@@ -207,12 +209,11 @@ namespace MediaBrowser.Api
                 {
                         typeof(Game).Name
                 },
-                SimilarTo = item
+                SimilarTo = item,
+                Fields = dtoOptions.Fields
 
             }).ToList();
 
-            var dtoOptions = GetDtoOptions(request);
-
             var result = new QueryResult<BaseItemDto>
             {
                 Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(),

+ 2 - 23
MediaBrowser.Api/ItemUpdateService.cs

@@ -274,10 +274,9 @@ namespace MediaBrowser.Api
 
             item.Tags = request.Tags;
 
-            var hasTaglines = item as IHasTaglines;
-            if (hasTaglines != null)
+            if (request.Taglines != null)
             {
-                hasTaglines.Taglines = request.Taglines;
+                item.Tagline = request.Taglines.FirstOrDefault();
             }
 
             var hasShortOverview = item as IHasShortOverview;
@@ -304,8 +303,6 @@ namespace MediaBrowser.Api
             item.OfficialRating = string.IsNullOrWhiteSpace(request.OfficialRating) ? null : request.OfficialRating;
             item.CustomRating = request.CustomRating;
 
-            SetProductionLocations(item, request);
-
             item.PreferredMetadataCountryCode = request.PreferredMetadataCountryCode;
             item.PreferredMetadataLanguage = request.PreferredMetadataLanguage;
 
@@ -413,23 +410,5 @@ namespace MediaBrowser.Api
                 series.AirTime = request.AirTime;
             }
         }
-
-        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();
-            }
-        }
     }
 }

+ 3 - 2
MediaBrowser.Api/MediaBrowser.Api.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -11,9 +11,10 @@
     <AssemblyName>MediaBrowser.Api</AssemblyName>
     <FileAlignment>512</FileAlignment>
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
     <ReleaseVersion>
     </ReleaseVersion>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>

+ 14 - 8
MediaBrowser.Api/Movies/MoviesService.cs

@@ -156,18 +156,19 @@ namespace MediaBrowser.Api.Movies
                 itemTypes.Add(typeof(LiveTvProgram).Name);
             }
 
+            var dtoOptions = GetDtoOptions(request);
+
             var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
             {
                 Limit = request.Limit,
                 IncludeItemTypes = itemTypes.ToArray(),
                 IsMovie = true,
                 SimilarTo = item,
-                EnableGroupByMetadataKey = true
+                EnableGroupByMetadataKey = true,
+                Fields = dtoOptions.Fields
 
             }).ToList();
 
-            var dtoOptions = GetDtoOptions(request);
-
             var result = new QueryResult<BaseItemDto>
             {
                 Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(),
@@ -198,7 +199,8 @@ namespace MediaBrowser.Api.Movies
                 Limit = 7,
                 ParentId = parentIdGuid,
                 Recursive = true,
-                IsPlayed = true
+                IsPlayed = true,
+                Fields = dtoOptions.Fields
             };
 
             var recentlyPlayedMovies = _libraryManager.GetItemList(query).ToList();
@@ -221,7 +223,8 @@ namespace MediaBrowser.Api.Movies
                 ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray(),
                 EnableGroupByMetadataKey = true,
                 ParentId = parentIdGuid,
-                Recursive = true
+                Recursive = true,
+                Fields = dtoOptions.Fields
 
             }).ToList();
 
@@ -302,7 +305,8 @@ namespace MediaBrowser.Api.Movies
                     PersonTypes = new[] { PersonType.Director },
                     IncludeItemTypes = itemTypes.ToArray(),
                     IsMovie = true,
-                    EnableGroupByMetadataKey = true
+                    EnableGroupByMetadataKey = true,
+                    Fields = dtoOptions.Fields
 
                 }).DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N"))
                 .Take(itemLimit)
@@ -339,7 +343,8 @@ namespace MediaBrowser.Api.Movies
                     Limit = itemLimit + 2,
                     IncludeItemTypes = itemTypes.ToArray(),
                     IsMovie = true,
-                    EnableGroupByMetadataKey = true
+                    EnableGroupByMetadataKey = true,
+                    Fields = dtoOptions.Fields
 
                 }).DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N"))
                 .Take(itemLimit)
@@ -375,7 +380,8 @@ namespace MediaBrowser.Api.Movies
                     IncludeItemTypes = itemTypes.ToArray(),
                     IsMovie = true,
                     SimilarTo = item,
-                    EnableGroupByMetadataKey = true
+                    EnableGroupByMetadataKey = true,
+                    Fields = dtoOptions.Fields
 
                 }).ToList();
 

+ 4 - 4
MediaBrowser.Api/PackageService.cs

@@ -46,7 +46,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The name.</value>
         [ApiMember(Name = "PackageType", Description = "Optional package type filter (System/UserInstalled)", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
-        public PackageType? PackageType { get; set; }
+        public string PackageType { get; set; }
 
         [ApiMember(Name = "TargetSystems", Description = "Optional. Filter by target system type. Allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET", AllowMultiple = true)]
         public string TargetSystems { get; set; }
@@ -72,7 +72,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The name.</value>
         [ApiMember(Name = "PackageType", Description = "Package type filter (System/UserInstalled)", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
-        public PackageType PackageType { get; set; }
+        public string PackageType { get; set; }
     }
 
     /// <summary>
@@ -149,12 +149,12 @@ namespace MediaBrowser.Api
         {
             var result = new List<PackageVersionInfo>();
 
-            if (request.PackageType == PackageType.UserInstalled || request.PackageType == PackageType.All)
+            if (string.Equals(request.PackageType, "UserInstalled", StringComparison.OrdinalIgnoreCase) || string.Equals(request.PackageType, "All", StringComparison.OrdinalIgnoreCase))
             {
                 result.AddRange(_installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, false, CancellationToken.None).Result.ToList());
             }
 
-            else if (request.PackageType == PackageType.System || request.PackageType == PackageType.All)
+            else if (string.Equals(request.PackageType, "System", StringComparison.OrdinalIgnoreCase) || string.Equals(request.PackageType, "All", StringComparison.OrdinalIgnoreCase))
             {
                 var updateCheckResult = _appHost.CheckForApplicationUpdate(CancellationToken.None, new Progress<double>()).Result;
 

+ 0 - 3
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -1857,9 +1857,6 @@ namespace MediaBrowser.Api.Playback
 
             state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
 
-            var archivable = item as IArchivable;
-            state.IsInputArchive = archivable != null && archivable.IsArchive;
-
             MediaSourceInfo mediaSource = null;
             if (string.IsNullOrWhiteSpace(request.LiveStreamId))
             {

+ 0 - 1
MediaBrowser.Api/Playback/StreamState.cs

@@ -63,7 +63,6 @@ namespace MediaBrowser.Api.Playback
             get { return Request is VideoStreamRequest; }
         }
         public bool IsInputVideo { get; set; }
-        public bool IsInputArchive { get; set; }
 
         public VideoType VideoType { get; set; }
         public IsoType? IsoType { get; set; }

+ 0 - 4
MediaBrowser.Api/Reports/Data/ReportBuilder.cs

@@ -517,10 +517,6 @@ namespace MediaBrowser.Api.Reports
                     internalHeader = HeaderMetadata.Album;
                     break;
 
-                case HeaderMetadata.Countries:
-                    option.Column = (i, r) => this.GetListAsString(this.GetObject<IHasProductionLocations, List<string>>(i, (x) => x.ProductionLocations));
-                    break;
-
                 case HeaderMetadata.Disc:
                     option.Column = (i, r) => i.ParentIndexNumber;
                     break;

+ 0 - 25
MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs

@@ -36,7 +36,6 @@ namespace MediaBrowser.Api.Reports
             result = this.GetResultStudios(result, items, topItem);
             result = this.GetResultPersons(result, items, topItem);
             result = this.GetResultProductionYears(result, items, topItem);
-            result = this.GetResulProductionLocations(result, items, topItem);
             result = this.GetResultCommunityRatings(result, items, topItem);
             result = this.GetResultParentalRatings(result, items, topItem);
 
@@ -100,30 +99,6 @@ namespace MediaBrowser.Api.Reports
             }
         }
 
-        /// <summary> Gets resul production locations. </summary>
-        /// <param name="result"> The result. </param>
-        /// <param name="items"> The items. </param>
-        /// <param name="topItem"> The top item. </param>
-        /// <returns> The resul production locations. </returns>
-        private ReportStatResult GetResulProductionLocations(ReportStatResult result, BaseItem[] items, int topItem = 5)
-        {
-            this.GetGroups(result, GetLocalizedHeader(HeaderMetadata.Countries), topItem,
-                        items.OfType<IHasProductionLocations>()
-                        .Where(x => x.ProductionLocations != null)
-                        .SelectMany(x => x.ProductionLocations)
-                        .GroupBy(x => x)
-                        .OrderByDescending(x => x.Count())
-                        .Take(topItem)
-                        .Select(x => new ReportStatItem
-                        {
-                            Name = x.Key.ToString(),
-                            Value = x.Count().ToString()
-                        })
-            );
-
-            return result;
-        }
-
         /// <summary> Gets result community ratings. </summary>
         /// <param name="result"> The result. </param>
         /// <param name="items"> The items. </param>

+ 2 - 1
MediaBrowser.Api/SimilarItemsHelper.cs

@@ -81,7 +81,8 @@ namespace MediaBrowser.Api
             var query = new InternalItemsQuery(user)
             {
                 IncludeItemTypes = includeTypes.Select(i => i.Name).ToArray(),
-                Recursive = true
+                Recursive = true,
+                Fields = dtoOptions.Fields
             };
 
             // ExcludeArtistIds

+ 2 - 0
MediaBrowser.Api/StartupWizardService.cs

@@ -117,6 +117,8 @@ namespace MediaBrowser.Api
             config.EnableFolderView = true;
             config.SchemaVersion = 109;
             config.EnableSimpleArtistDetection = true;
+            config.SkipDeserializationForBasicTypes = true;
+            config.SkipDeserializationForPrograms = true;
         }
 
         public void Post(UpdateStartupConfiguration request)

+ 8 - 6
MediaBrowser.Api/TvShowsService.cs

@@ -302,6 +302,8 @@ namespace MediaBrowser.Api
                 (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
                 _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
 
+            var dtoOptions = GetDtoOptions(request);
+
             var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
             {
                 Limit = request.Limit,
@@ -309,12 +311,11 @@ namespace MediaBrowser.Api
                 {
                         typeof(Series).Name
                 },
-                SimilarTo = item
+                SimilarTo = item,
+                Fields = dtoOptions.Fields
 
             }).ToList();
 
-            var dtoOptions = GetDtoOptions(request);
-
             var result = new QueryResult<BaseItemDto>
             {
                 Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(),
@@ -333,6 +334,8 @@ namespace MediaBrowser.Api
 
             var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId);
 
+            var options = GetDtoOptions(request);
+
             var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
             {
                 IncludeItemTypes = new[] { typeof(Episode).Name },
@@ -342,12 +345,11 @@ namespace MediaBrowser.Api
                 StartIndex = request.StartIndex,
                 Limit = request.Limit,
                 ParentId = parentIdGuid,
-                Recursive = true
+                Recursive = true,
+                Fields = options.Fields
 
             }).ToList();
 
-            var options = GetDtoOptions(request);
-
             var returnItems = (await _dtoService.GetBaseItemDtos(itemsResult, options, user).ConfigureAwait(false)).ToArray();
 
             var result = new ItemsResult

+ 10 - 12
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -99,8 +99,10 @@ namespace MediaBrowser.Api.UserLibrary
         private async Task<ItemsResult> GetItems(GetItems request)
         {
             var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
-        
-            var result = await GetQueryResult(request, user).ConfigureAwait(false);
+
+            var dtoOptions = GetDtoOptions(request);
+
+            var result = await GetQueryResult(request, dtoOptions, user).ConfigureAwait(false);
 
             if (result == null)
             {
@@ -112,8 +114,6 @@ namespace MediaBrowser.Api.UserLibrary
                 throw new InvalidOperationException("GetItemsToSerialize result.Items returned null");
             }
 
-            var dtoOptions = GetDtoOptions(request);
-
             var dtoList = await _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user).ConfigureAwait(false);
 
             if (dtoList == null)
@@ -131,10 +131,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <summary>
         /// Gets the items to serialize.
         /// </summary>
-        /// <param name="request">The request.</param>
-        /// <param name="user">The user.</param>
-        /// <returns>IEnumerable{BaseItem}.</returns>
-        private async Task<QueryResult<BaseItem>> GetQueryResult(GetItems request, User user)
+        private async Task<QueryResult<BaseItem>> GetQueryResult(GetItems request, DtoOptions dtoOptions, User user)
         {
             var item = string.IsNullOrEmpty(request.ParentId) ?
                 user == null ? _libraryManager.RootFolder : user.RootFolder :
@@ -159,14 +156,14 @@ namespace MediaBrowser.Api.UserLibrary
 
             if (request.Recursive || !string.IsNullOrEmpty(request.Ids) || user == null)
             {
-                return await folder.GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
+                return await folder.GetItems(GetItemsQuery(request, dtoOptions, user)).ConfigureAwait(false);
             }
 
             var userRoot = item as UserRootFolder;
 
             if (userRoot == null)
             {
-                return await folder.GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
+                return await folder.GetItems(GetItemsQuery(request, dtoOptions, user)).ConfigureAwait(false);
             }
 
             IEnumerable<BaseItem> items = folder.GetChildren(user, true);
@@ -180,7 +177,7 @@ namespace MediaBrowser.Api.UserLibrary
             };
         }
 
-        private InternalItemsQuery GetItemsQuery(GetItems request, User user)
+        private InternalItemsQuery GetItemsQuery(GetItems request, DtoOptions dtoOptions, User user)
         {
             var query = new InternalItemsQuery(user)
             {
@@ -241,7 +238,8 @@ namespace MediaBrowser.Api.UserLibrary
                 AiredDuringSeason = request.AiredDuringSeason,
                 AlbumArtistStartsWithOrGreater = request.AlbumArtistStartsWithOrGreater,
                 EnableTotalRecordCount = request.EnableTotalRecordCount,
-                ExcludeItemIds = request.GetExcludeItemIds()
+                ExcludeItemIds = request.GetExcludeItemIds(),
+                Fields = dtoOptions.Fields
             };
 
             if (!string.IsNullOrWhiteSpace(request.Ids))

+ 6 - 2
MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -14,6 +14,7 @@
     <ProductVersion>10.0.0</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -23,7 +24,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>none</DebugType>
@@ -79,6 +80,9 @@
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
     <Reference Include="System.Net" />
+    <Reference Include="System.Text.Json">
+      <HintPath>..\ThirdParty\fastjsonparser\System.Text.Json.dll</HintPath>
+    </Reference>
     <Reference Include="System.Xml" />
     <Reference Include="ServiceStack.Text">
       <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath>

+ 4 - 8
MediaBrowser.Common.Implementations/Updates/InstallationManager.cs

@@ -148,14 +148,10 @@ namespace MediaBrowser.Common.Implementations.Updates
         /// <summary>
         /// Gets all available packages.
         /// </summary>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <param name="withRegistration">if set to <c>true</c> [with registration].</param>
-        /// <param name="packageType">Type of the package.</param>
-        /// <param name="applicationVersion">The application version.</param>
         /// <returns>Task{List{PackageInfo}}.</returns>
         public async Task<IEnumerable<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
             bool withRegistration = true,
-            PackageType? packageType = null,
+            string packageType = null,
             Version applicationVersion = null)
         {
             var data = new Dictionary<string, string>
@@ -293,7 +289,7 @@ namespace MediaBrowser.Common.Implementations.Updates
             return packages;
         }
 
-        protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages, PackageType? packageType, Version applicationVersion)
+        protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages, string packageType, Version applicationVersion)
         {
             foreach (var package in packages)
             {
@@ -301,9 +297,9 @@ namespace MediaBrowser.Common.Implementations.Updates
                     .OrderByDescending(GetPackageVersion).ToList();
             }
 
-            if (packageType.HasValue)
+            if (!string.IsNullOrWhiteSpace(packageType))
             {
-                packages = packages.Where(p => p.type == packageType.Value).ToList();
+                packages = packages.Where(p => string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase)).ToList();
             }
 
             // If an app version was supplied, filter the versions for each package to only include supported versions

+ 1 - 1
MediaBrowser.Common/Updates/IInstallationManager.cs

@@ -51,7 +51,7 @@ namespace MediaBrowser.Common.Updates
         /// <returns>Task{List{PackageInfo}}.</returns>
         Task<IEnumerable<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
             bool withRegistration = true,
-                                                                                  PackageType? packageType = null,
+                                                                                  string packageType = null,
                                                                                   Version applicationVersion = null);
 
         /// <summary>

+ 1 - 17
MediaBrowser.Controller/Entities/Audio/Audio.cs

@@ -23,8 +23,7 @@ namespace MediaBrowser.Controller.Entities.Audio
         IHasMusicGenres,
         IHasLookupInfo<SongInfo>,
         IHasMediaSources,
-        IThemeMedia,
-        IArchivable
+        IThemeMedia
     {
         public List<ChannelMediaInfo> ChannelMediaSources { get; set; }
 
@@ -84,21 +83,6 @@ namespace MediaBrowser.Controller.Entities.Audio
             }
         }
 
-        [IgnoreDataMember]
-        public bool IsArchive
-        {
-            get
-            {
-                if (string.IsNullOrWhiteSpace(Path))
-                {
-                    return false;
-                }
-                var ext = System.IO.Path.GetExtension(Path) ?? string.Empty;
-
-                return new[] { ".zip", ".rar", ".7z" }.Contains(ext, StringComparer.OrdinalIgnoreCase);
-            }
-        }
-
         public override bool CanDownload()
         {
             var locationType = LocationType;

+ 1 - 8
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -16,7 +16,7 @@ namespace MediaBrowser.Controller.Entities.Audio
     /// <summary>
     /// Class MusicArtist
     /// </summary>
-    public class MusicArtist : Folder, IMetadataContainer, IItemByName, IHasMusicGenres, IHasDualAccess, IHasProductionLocations, IHasLookupInfo<ArtistInfo>
+    public class MusicArtist : Folder, IMetadataContainer, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo>
     {
         [IgnoreDataMember]
         public bool IsAccessedByName
@@ -24,8 +24,6 @@ namespace MediaBrowser.Controller.Entities.Audio
             get { return ParentId == Guid.Empty; }
         }
 
-        public List<string> ProductionLocations { get; set; }
-
         [IgnoreDataMember]
         public override bool IsFolder
         {
@@ -111,11 +109,6 @@ namespace MediaBrowser.Controller.Entities.Audio
             return base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService);
         }
 
-        public MusicArtist()
-        {
-            ProductionLocations = new List<string>();
-        }
-
         public override List<string> GetUserDataKeys()
         {
             var list = base.GetUserDataKeys();

+ 2 - 0
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -73,6 +73,8 @@ namespace MediaBrowser.Controller.Entities
         public long? Size { get; set; }
         public string Container { get; set; }
         public string ShortOverview { get; set; }
+        [IgnoreDataMember]
+        public string Tagline { get; set; }
 
         public List<ItemImageInfo> ImageInfos { get; set; }
 

+ 0 - 8
MediaBrowser.Controller/Entities/IArchivable.cs

@@ -1,8 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
-    public interface IArchivable
-    {
-        bool IsArchive { get; }
-    }
-}

+ 0 - 34
MediaBrowser.Controller/Entities/IHasProductionLocations.cs

@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace MediaBrowser.Controller.Entities
-{
-    /// <summary>
-    /// Interface IHasProductionLocations
-    /// </summary>
-    public interface IHasProductionLocations
-    {
-        /// <summary>
-        /// Gets or sets the production locations.
-        /// </summary>
-        /// <value>The production locations.</value>
-        List<string> 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);
-            }
-        }
-    }
-}

+ 0 - 39
MediaBrowser.Controller/Entities/IHasTaglines.cs

@@ -1,39 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace MediaBrowser.Controller.Entities
-{
-    /// <summary>
-    /// Interface IHasTaglines
-    /// </summary>
-    public interface IHasTaglines
-    {
-        /// <summary>
-        /// Gets or sets the taglines.
-        /// </summary>
-        /// <value>The taglines.</value>
-        List<string> Taglines { get; set; }
-    }
-
-    public static class TaglineExtensions
-    {
-        /// <summary>
-        /// Adds the tagline.
-        /// </summary>
-        /// <param name="tagline">The tagline.</param>
-        /// <exception cref="System.ArgumentNullException">tagline</exception>
-        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);
-            }
-        }
-    }
-}

+ 34 - 0
MediaBrowser.Controller/Entities/InternalItemsQuery.cs

@@ -2,6 +2,8 @@
 using System;
 using System.Collections.Generic;
 using MediaBrowser.Model.Configuration;
+using System.Linq;
+using MediaBrowser.Model.Querying;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -157,11 +159,43 @@ namespace MediaBrowser.Controller.Entities
         public DateTime? MinDateCreated { get; set; }
         public DateTime? MinDateLastSaved { get; set; }
 
+        public List<ItemFields> Fields { get; set; }
+
+        public bool HasField(ItemFields name)
+        {
+            switch (name)
+            {
+                case ItemFields.Keywords:
+                case ItemFields.Taglines:
+                case ItemFields.ShortOverview:
+                case ItemFields.CustomRating:
+                case ItemFields.DateCreated:
+                case ItemFields.SortName:
+                case ItemFields.Overview:
+                case ItemFields.OfficialRatingDescription:
+                case ItemFields.HomePageUrl:
+                case ItemFields.VoteCount:
+                case ItemFields.DisplayMediaType:
+                case ItemFields.ServiceName:
+                case ItemFields.Genres:
+                case ItemFields.Studios:
+                case ItemFields.Settings:
+                case ItemFields.OriginalTitle:
+                case ItemFields.Tags:
+                case ItemFields.DateLastMediaAdded:
+                case ItemFields.CriticRatingSummary:
+                    return Fields.Count == 0 || Fields.Contains(name);
+                default:
+                    return true;
+            }
+        }
+
         public InternalItemsQuery()
         {
             GroupByPresentationUniqueKey = true;
             EnableTotalRecordCount = true;
 
+            Fields = new List<ItemFields>();
             AlbumNames = new string[] { };
             ArtistNames = new string[] { };
             ExcludeArtistIds = new string[] { };

+ 1 - 3
MediaBrowser.Controller/Entities/Movies/Movie.cs

@@ -15,13 +15,12 @@ namespace MediaBrowser.Controller.Entities.Movies
     /// <summary>
     /// Class Movie
     /// </summary>
-    public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle
+    public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasThemeMedia, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle
     {
         public List<Guid> SpecialFeatureIds { get; set; }
 
         public List<Guid> ThemeSongIds { get; set; }
         public List<Guid> ThemeVideoIds { get; set; }
-        public List<string> ProductionLocations { get; set; }
 
         public Movie()
         {
@@ -32,7 +31,6 @@ namespace MediaBrowser.Controller.Entities.Movies
             ThemeSongIds = new List<Guid>();
             ThemeVideoIds = new List<Guid>();
             Taglines = new List<string>();
-            ProductionLocations = new List<string>();
         }
 
         public string AwardSummary { get; set; }

+ 1 - 3
MediaBrowser.Controller/Entities/MusicVideo.cs

@@ -6,7 +6,7 @@ using System.Runtime.Serialization;
 
 namespace MediaBrowser.Controller.Entities
 {
-    public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasProductionLocations, IHasBudget, IHasLookupInfo<MusicVideoInfo>
+    public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasBudget, IHasLookupInfo<MusicVideoInfo>
     {
         /// <summary>
         /// Gets or sets the budget.
@@ -19,12 +19,10 @@ namespace MediaBrowser.Controller.Entities
         /// </summary>
         /// <value>The revenue.</value>
         public double? Revenue { get; set; }
-        public List<string> ProductionLocations { get; set; }
         public List<string> Artists { get; set; }
 
         public MusicVideo()
         {
-            ProductionLocations = new List<string>();
             Artists = new List<string>();
         }
 

+ 1 - 9
MediaBrowser.Controller/Entities/Photo.cs

@@ -1,19 +1,11 @@
 using MediaBrowser.Model.Drawing;
-using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.Serialization;
 
 namespace MediaBrowser.Controller.Entities
 {
-    public class Photo : BaseItem, IHasTaglines
+    public class Photo : BaseItem
     {
-        public List<string> Taglines { get; set; }
-
-        public Photo()
-        {
-            Taglines = new List<string>();
-        }
-
         [IgnoreDataMember]
         public override bool SupportsLocalMetadata
         {

+ 1 - 4
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -17,17 +17,14 @@ namespace MediaBrowser.Controller.Entities.TV
     /// <summary>
     /// Class Series
     /// </summary>
-    public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IHasSpecialFeatures, IMetadataContainer, IHasOriginalTitle
+    public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer, IHasOriginalTitle
     {
-        public List<Guid> SpecialFeatureIds { get; set; }
-
         public int? AnimeSeriesIndex { get; set; }
 
         public Series()
         {
             AirDays = new List<DayOfWeek>();
 
-            SpecialFeatureIds = new List<Guid>();
             RemoteTrailers = new List<MediaUrl>();
             LocalTrailerIds = new List<Guid>();
             RemoteTrailerIds = new List<Guid>();

+ 1 - 11
MediaBrowser.Controller/Entities/Trailer.cs

@@ -10,16 +10,12 @@ namespace MediaBrowser.Controller.Entities
     /// <summary>
     /// Class Trailer
     /// </summary>
-    public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo<TrailerInfo>
+    public class Trailer : Video, IHasCriticRating, IHasBudget, IHasMetascore, IHasOriginalTitle, IHasLookupInfo<TrailerInfo>
     {
-        public List<string> ProductionLocations { get; set; }
-
         public Trailer()
         {
             RemoteTrailers = new List<MediaUrl>();
-            Taglines = new List<string>();
             Keywords = new List<string>();
-            ProductionLocations = new List<string>();
             TrailerTypes = new List<TrailerType> { TrailerType.LocalTrailer };
         }
 
@@ -35,12 +31,6 @@ namespace MediaBrowser.Controller.Entities
             get { return TrailerTypes.Contains(TrailerType.LocalTrailer); }
         }
 
-        /// <summary>
-        /// Gets or sets the taglines.
-        /// </summary>
-        /// <value>The taglines.</value>
-        public List<string> Taglines { get; set; }
-
         /// <summary>
         /// Gets or sets the budget.
         /// </summary>

+ 1 - 1
MediaBrowser.Controller/Entities/UserViewBuilder.cs

@@ -96,7 +96,7 @@ namespace MediaBrowser.Controller.Entities
                             Limit = query.Limit,
                             IsAiring = true
 
-                        }, CancellationToken.None).ConfigureAwait(false);
+                        }, new Dto.DtoOptions(), CancellationToken.None).ConfigureAwait(false);
 
                         return GetResult(result);
                     }

+ 1 - 17
MediaBrowser.Controller/Entities/Video.cs

@@ -25,8 +25,7 @@ namespace MediaBrowser.Controller.Entities
         ISupportsPlaceHolders,
         IHasMediaSources,
         IHasShortOverview,
-        IThemeMedia,
-        IArchivable
+        IThemeMedia
     {
         [IgnoreDataMember]
         public string PrimaryVersionId { get; set; }
@@ -197,21 +196,6 @@ namespace MediaBrowser.Controller.Entities
             get { return LocalAlternateVersions.Count > 0; }
         }
 
-        [IgnoreDataMember]
-        public bool IsArchive
-        {
-            get
-            {
-                if (string.IsNullOrWhiteSpace(Path))
-                {
-                    return false;
-                }
-                var ext = System.IO.Path.GetExtension(Path) ?? string.Empty;
-
-                return new[] { ".zip", ".rar", ".7z" }.Contains(ext, StringComparer.OrdinalIgnoreCase);
-            }
-        }
-
         public IEnumerable<Guid> GetAdditionalPartIds()
         {
             return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));

+ 1 - 3
MediaBrowser.Controller/LiveTv/ILiveTvManager.cs

@@ -242,10 +242,8 @@ namespace MediaBrowser.Controller.LiveTv
         /// <summary>
         /// Gets the recommended programs internal.
         /// </summary>
-        /// <param name="query">The query.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task&lt;QueryResult&lt;LiveTvProgram&gt;&gt;.</returns>
-        Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken);
+        Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken);
 
         /// <summary>
         /// Gets the live tv information.

+ 0 - 3
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -132,7 +132,6 @@
     <Compile Include="Entities\Game.cs" />
     <Compile Include="Entities\GameGenre.cs" />
     <Compile Include="Entities\GameSystem.cs" />
-    <Compile Include="Entities\IArchivable.cs" />
     <Compile Include="Entities\IByReferenceItem.cs" />
     <Compile Include="Entities\IHasAspectRatio.cs" />
     <Compile Include="Entities\IHasBudget.cs" />
@@ -144,14 +143,12 @@
     <Compile Include="Entities\IHasMediaSources.cs" />
     <Compile Include="Entities\IHasMetascore.cs" />
     <Compile Include="Entities\IHasOriginalTitle.cs" />
-    <Compile Include="Entities\IHasProductionLocations.cs" />
     <Compile Include="Entities\IHasProgramAttributes.cs" />
     <Compile Include="Entities\IHasScreenshots.cs" />
     <Compile Include="Entities\IHasSeries.cs" />
     <Compile Include="Entities\IHasShortOverview.cs" />
     <Compile Include="Entities\IHasSpecialFeatures.cs" />
     <Compile Include="Entities\IHasStartDate.cs" />
-    <Compile Include="Entities\IHasTaglines.cs" />
     <Compile Include="Entities\IHasThemeMedia.cs" />
     <Compile Include="Entities\IHasTrailers.cs" />
     <Compile Include="Entities\IHasUserData.cs" />

+ 1 - 16
MediaBrowser.Controller/Providers/BaseItemXmlParser.cs

@@ -893,14 +893,6 @@ namespace MediaBrowser.Controller.Providers
 
                                 if (!string.IsNullOrWhiteSpace(val))
                                 {
-                                    var hasProductionLocations = item as IHasProductionLocations;
-                                    if (hasProductionLocations != null)
-                                    {
-                                        if (!string.IsNullOrWhiteSpace(val))
-                                        {
-                                            hasProductionLocations.AddProductionLocation(val);
-                                        }
-                                    }
                                 }
                                 break;
                             }
@@ -934,14 +926,7 @@ namespace MediaBrowser.Controller.Providers
 
                                 if (!string.IsNullOrWhiteSpace(val))
                                 {
-                                    var hasTaglines = item as IHasTaglines;
-                                    if (hasTaglines != null)
-                                    {
-                                        if (!string.IsNullOrWhiteSpace(val))
-                                        {
-                                            hasTaglines.AddTagline(val);
-                                        }
-                                    }
+                                    item.Tagline = val;
                                 }
                                 break;
                             }

+ 13 - 26
MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs

@@ -350,21 +350,17 @@ namespace MediaBrowser.LocalMetadata.Savers
                 }
             }
 
-            var hasProductionLocations = item as IHasProductionLocations;
-            if (hasProductionLocations != null)
-            {
-                if (hasProductionLocations.ProductionLocations.Count > 0)
-                {
-                    builder.Append("<Countries>");
+            //if (hasProductionLocations.ProductionLocations.Count > 0)
+            //{
+            //    builder.Append("<Countries>");
 
-                    foreach (var name in hasProductionLocations.ProductionLocations)
-                    {
-                        builder.Append("<Country>" + SecurityElement.Escape(name) + "</Country>");
-                    }
+            //    foreach (var name in hasProductionLocations.ProductionLocations)
+            //    {
+            //        builder.Append("<Country>" + SecurityElement.Escape(name) + "</Country>");
+            //    }
 
-                    builder.Append("</Countries>");
-                }
-            }
+            //    builder.Append("</Countries>");
+            //}
 
             var hasDisplayOrder = item as IHasDisplayOrder;
             if (hasDisplayOrder != null && !string.IsNullOrEmpty(hasDisplayOrder.DisplayOrder))
@@ -457,20 +453,11 @@ namespace MediaBrowser.LocalMetadata.Savers
                 }
             }
 
-            var hasTagline = item as IHasTaglines;
-            if (hasTagline != null)
+            if (!string.IsNullOrWhiteSpace(item.Tagline))
             {
-                if (hasTagline.Taglines.Count > 0)
-                {
-                    builder.Append("<Taglines>");
-
-                    foreach (var tagline in hasTagline.Taglines)
-                    {
-                        builder.Append("<Tagline>" + SecurityElement.Escape(tagline) + "</Tagline>");
-                    }
-
-                    builder.Append("</Taglines>");
-                }
+                builder.Append("<Taglines>");
+                builder.Append("<Tagline>" + SecurityElement.Escape(item.Tagline) + "</Tagline>");
+                builder.Append("</Taglines>");
             }
 
             if (item.Genres.Count > 0)

+ 0 - 3
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -1165,9 +1165,6 @@
     <Compile Include="..\MediaBrowser.Model\Updates\PackageTargetSystem.cs">
       <Link>Updates\PackageTargetSystem.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Updates\PackageType.cs">
-      <Link>Updates\PackageType.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Updates\PackageVersionClass.cs">
       <Link>Updates\PackageVersionClass.cs</Link>
     </Compile>

+ 0 - 3
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -1128,9 +1128,6 @@
     <Compile Include="..\MediaBrowser.Model\Updates\PackageTargetSystem.cs">
       <Link>Updates\PackageTargetSystem.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Updates\PackageType.cs">
-      <Link>Updates\PackageType.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Updates\PackageVersionClass.cs">
       <Link>Updates\PackageVersionClass.cs</Link>
     </Compile>

+ 2 - 0
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -168,6 +168,8 @@ namespace MediaBrowser.Model.Configuration
         public MetadataOptions[] MetadataOptions { get; set; }
 
         public bool EnableAutomaticRestart { get; set; }
+        public bool SkipDeserializationForBasicTypes { get; set; }
+        public bool SkipDeserializationForPrograms { get; set; }
 
         public PathSubstitution[] PathSubstitutions { get; set; }
 

+ 1 - 5
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -787,11 +787,7 @@ namespace MediaBrowser.Model.Dto
         /// <value>The home page URL.</value>
         public string HomePageUrl { get; set; }
 
-        /// <summary>
-        /// Gets or sets the production locations.
-        /// </summary>
-        /// <value>The production locations.</value>
-        public List<string> ProductionLocations { get; set; }
+        public string PlaceOfBirth { get; set; }
 
         /// <summary>
         /// Gets or sets the budget.

+ 0 - 1
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -396,7 +396,6 @@
     <Compile Include="Updates\CheckForUpdateResult.cs" />
     <Compile Include="Updates\PackageTargetSystem.cs" />
     <Compile Include="Updates\InstallationInfo.cs" />
-    <Compile Include="Updates\PackageType.cs" />
     <Compile Include="Updates\PackageVersionClass.cs" />
     <Compile Include="Entities\EmptyRequestResult.cs" />
     <Compile Include="Configuration\UserConfiguration.cs" />

+ 4 - 0
MediaBrowser.Model/Querying/ItemFields.cs

@@ -130,6 +130,8 @@
         /// </summary>
         Metascore,
 
+        OfficialRatingDescription,
+
         OriginalTitle,
 
         /// <summary>
@@ -152,6 +154,8 @@
         /// </summary>
         People,
 
+        PlaceOfBirth,
+
         /// <summary>
         /// The production locations
         /// </summary>

+ 3 - 3
MediaBrowser.Model/Updates/PackageInfo.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Model.Updates
         /// The internal id of this package.
         /// </summary>
         /// <value>The id.</value>
-        public int id { get; set; }
+        public string id { get; set; }
 
         /// <summary>
         /// Gets or sets the name.
@@ -66,7 +66,7 @@ namespace MediaBrowser.Model.Updates
         /// Gets or sets the type.
         /// </summary>
         /// <value>The type.</value>
-        public PackageType type { get; set; }
+        public string type { get; set; }
 
         /// <summary>
         /// Gets or sets the target filename.
@@ -127,7 +127,7 @@ namespace MediaBrowser.Model.Updates
         /// Gets or sets the total number of ratings for this package.
         /// </summary>
         /// <value>The total ratings.</value>
-        public int totalRatings { get; set; }
+        public int? totalRatings { get; set; }
 
         /// <summary>
         /// Gets or sets the average rating for this package .

+ 0 - 21
MediaBrowser.Model/Updates/PackageType.cs

@@ -1,21 +0,0 @@
-namespace MediaBrowser.Model.Updates
-{
-    /// <summary>
-    /// Enum PackageType
-    /// </summary>
-    public enum PackageType
-    {
-        /// <summary>
-        /// All
-        /// </summary>
-        All,
-        /// <summary>
-        /// The system
-        /// </summary>
-        System,
-        /// <summary>
-        /// The user installed
-        /// </summary>
-        UserInstalled
-    }
-}

+ 0 - 6
MediaBrowser.Providers/Manager/ItemImageProvider.cs

@@ -555,12 +555,6 @@ namespace MediaBrowser.Providers.Manager
                     return false;
                 case ImageType.Thumb:
                     return false;
-                case ImageType.Logo:
-                    return false;
-                case ImageType.Backdrop:
-                    return false;
-                case ImageType.Screenshot:
-                    return false;
                 default:
                     return true;
             }

+ 5 - 29
MediaBrowser.Providers/Manager/ProviderUtils.cs

@@ -99,6 +99,11 @@ namespace MediaBrowser.Providers.Manager
                 target.CustomRating = source.CustomRating;
             }
 
+            if (replaceData || string.IsNullOrEmpty(target.Tagline))
+            {
+                target.Tagline = source.Tagline;
+            }
+
             if (!lockedFields.Contains(MetadataFields.Overview))
             {
                 if (replaceData || string.IsNullOrEmpty(target.Overview))
@@ -165,20 +170,6 @@ namespace MediaBrowser.Providers.Manager
                 }
             }
 
-            if (!lockedFields.Contains(MetadataFields.ProductionLocations))
-            {
-                var sourceHasProductionLocations = source as IHasProductionLocations;
-                var targetHasProductionLocations = target as IHasProductionLocations;
-
-                if (sourceHasProductionLocations != null && targetHasProductionLocations != null)
-                {
-                    if (replaceData || targetHasProductionLocations.ProductionLocations.Count == 0)
-                    {
-                        targetHasProductionLocations.ProductionLocations = sourceHasProductionLocations.ProductionLocations;
-                    }
-                }
-            }
-
             if (replaceData || !target.VoteCount.HasValue)
             {
                 target.VoteCount = source.VoteCount;
@@ -200,7 +191,6 @@ namespace MediaBrowser.Providers.Manager
             MergeMetascore(source, target, lockedFields, replaceData);
             MergeCriticRating(source, target, lockedFields, replaceData);
             MergeAwards(source, target, lockedFields, replaceData);
-            MergeTaglines(source, target, lockedFields, replaceData);
             MergeTrailers(source, target, lockedFields, replaceData);
             MergeShortOverview(source, target, lockedFields, replaceData);
 
@@ -330,20 +320,6 @@ namespace MediaBrowser.Providers.Manager
             }
         }
 
-        private static void MergeTaglines(BaseItem source, BaseItem target, List<MetadataFields> lockedFields, bool replaceData)
-        {
-            var sourceCast = source as IHasTaglines;
-            var targetCast = target as IHasTaglines;
-
-            if (sourceCast != null && targetCast != null)
-            {
-                if (replaceData || targetCast.Taglines.Count == 0)
-                {
-                    targetCast.Taglines = sourceCast.Taglines;
-                }
-            }
-        }
-
         private static void MergeTrailers(BaseItem source, BaseItem target, List<MetadataFields> lockedFields, bool replaceData)
         {
             var sourceCast = source as IHasTrailers;

+ 1 - 1
MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs

@@ -162,7 +162,7 @@ namespace MediaBrowser.Providers.MediaInfo
         {
             var audio = item as Audio;
 
-            return item.LocationType == LocationType.FileSystem && audio != null && !audio.IsArchive;
+            return item.LocationType == LocationType.FileSystem && audio != null;
         }
 
         public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)

+ 0 - 7
MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs

@@ -38,13 +38,6 @@ namespace MediaBrowser.Providers.MediaInfo
         public async Task<ItemUpdateType> Probe<T>(T item, CancellationToken cancellationToken)
             where T : Audio
         {
-            if (item.IsArchive)
-            {
-                var ext = Path.GetExtension(item.Path) ?? string.Empty;
-                item.Container = ext.TrimStart('.');
-                return ItemUpdateType.MetadataImport;
-            }
-
             var result = await GetMediaInfo(item, cancellationToken).ConfigureAwait(false);
 
             cancellationToken.ThrowIfCancellationRequested();

+ 0 - 7
MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs

@@ -72,13 +72,6 @@ namespace MediaBrowser.Providers.MediaInfo
             CancellationToken cancellationToken)
             where T : Video
         {
-            if (item.IsArchive)
-            {
-                var ext = Path.GetExtension(item.Path) ?? string.Empty;
-                item.Container = ext.TrimStart('.');
-                return ItemUpdateType.MetadataImport;
-            }
-
             var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false);
 
             BlurayDiscInfo blurayDiscInfo = null;

+ 1 - 2
MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs

@@ -174,8 +174,7 @@ namespace MediaBrowser.Providers.MediaInfo
         {
             var video = item as Video;
 
-            if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder &&
-                !video.IsShortcut && !video.IsArchive)
+            if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut)
             {
                 return true;
             }

+ 9 - 14
MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs

@@ -143,24 +143,19 @@ namespace MediaBrowser.Providers.Movies
 
             if (!string.IsNullOrEmpty(movieData.tagline))
             {
-                var hasTagline = movie as IHasTaglines;
-                if (hasTagline != null)
-                {
-                    hasTagline.Taglines.Clear();
-                    hasTagline.AddTagline(movieData.tagline);
-                }
+                movie.Tagline = movieData.tagline;
             }
 
             if (movieData.production_countries != null)
             {
-                var hasProductionLocations = movie as IHasProductionLocations;
-                if (hasProductionLocations != null)
-                {
-                    hasProductionLocations.ProductionLocations = movieData
-                        .production_countries
-                        .Select(i => i.name)
-                        .ToList();
-                }
+                //var hasProductionLocations = movie as IHasProductionLocations;
+                //if (hasProductionLocations != null)
+                //{
+                //    hasProductionLocations.ProductionLocations = movieData
+                //        .production_countries
+                //        .Select(i => i.name)
+                //        .ToList();
+                //}
             }
 
             movie.SetProviderId(MetadataProviders.Tmdb, movieData.id.ToString(_usCulture));

+ 2 - 29
MediaBrowser.Providers/TV/SeriesPostScanTask.cs

@@ -47,7 +47,7 @@ namespace MediaBrowser.Providers.TV
             return RunInternal(progress, cancellationToken);
         }
 
-        private async Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
+        private Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
         {
             var seriesList = _libraryManager.GetItemList(new InternalItemsQuery()
             {
@@ -59,34 +59,7 @@ namespace MediaBrowser.Providers.TV
 
             var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList();
 
-            await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem)
-                .Run(seriesGroups, true, cancellationToken).ConfigureAwait(false);
-
-            var numComplete = 0;
-
-            foreach (var series in seriesList)
-            {
-                cancellationToken.ThrowIfCancellationRequested();
-
-                var episodes = series.GetRecursiveChildren(i => i is Episode)
-                    .Cast<Episode>()
-                    .ToList();
-
-                var physicalEpisodes = episodes.Where(i => i.LocationType != LocationType.Virtual)
-                    .ToList();
-
-                series.SpecialFeatureIds = physicalEpisodes
-                    .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
-                    .Select(i => i.Id)
-                    .ToList();
-
-                numComplete++;
-                double percent = numComplete;
-                percent /= seriesList.Count;
-                percent *= 100;
-
-                progress.Report(percent);
-            }
+            return new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem).Run(seriesGroups, true, cancellationToken);
         }
 
         internal static IEnumerable<IGrouping<string, Series>> FindSeriesGroups(List<Series> seriesList)

+ 13 - 32
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -907,9 +907,13 @@ namespace MediaBrowser.Server.Implementations.Dto
                 dto.Keywords = item.Keywords;
             }
 
-            if (fields.Contains(ItemFields.ProductionLocations))
+            if (fields.Contains(ItemFields.PlaceOfBirth))
             {
-                SetProductionLocations(item, dto);
+                var person = item as Person;
+                if (person != null)
+                {
+                    dto.PlaceOfBirth = person.PlaceOfBirth;
+                }
             }
 
             var hasAspectRatio = item as IHasAspectRatio;
@@ -998,8 +1002,11 @@ namespace MediaBrowser.Server.Implementations.Dto
             }
             dto.Audio = item.Audio;
 
-            dto.PreferredMetadataCountryCode = item.PreferredMetadataCountryCode;
-            dto.PreferredMetadataLanguage = item.PreferredMetadataLanguage;
+            if (fields.Contains(ItemFields.Settings))
+            {
+                dto.PreferredMetadataCountryCode = item.PreferredMetadataCountryCode;
+                dto.PreferredMetadataLanguage = item.PreferredMetadataLanguage;
+            }
 
             dto.CriticRating = item.CriticRating;
 
@@ -1089,10 +1096,9 @@ namespace MediaBrowser.Server.Implementations.Dto
 
             if (fields.Contains(ItemFields.Taglines))
             {
-                var hasTagline = item as IHasTaglines;
-                if (hasTagline != null)
+                if (!string.IsNullOrWhiteSpace(item.Tagline))
                 {
-                    dto.Taglines = hasTagline.Taglines;
+                    dto.Taglines = new List<string> { item.Tagline };
                 }
 
                 if (dto.Taglines == null)
@@ -1529,31 +1535,6 @@ namespace MediaBrowser.Server.Implementations.Dto
             return path;
         }
 
-        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<string>();
-                if (!string.IsNullOrEmpty(person.PlaceOfBirth))
-                {
-                    dto.ProductionLocations.Add(person.PlaceOfBirth);
-                }
-            }
-
-            if (dto.ProductionLocations == null)
-            {
-                dto.ProductionLocations = new List<string>();
-            }
-        }
-
         /// <summary>
         /// Attaches the primary image aspect ratio.
         /// </summary>

+ 2 - 1
MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -91,10 +91,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             HostConfig.Instance.DebugMode = false;
 
             HostConfig.Instance.LogFactory = LogManager.LogFactory;
+            HostConfig.Instance.AllowJsonpRequests = false;
 
             // The Markdown feature causes slow startup times (5 mins+) on cold boots for some users
             // Custom format allows images
-            HostConfig.Instance.EnableFeatures = Feature.Html | Feature.Json | Feature.CustomFormat;
+            HostConfig.Instance.EnableFeatures = Feature.Html | Feature.Json | Feature.Xml | Feature.CustomFormat;
 
             container.Adapter = _containerAdapter;
 

+ 14 - 9
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -869,7 +869,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 SortBy = query.SortBy,
                 SortOrder = query.SortOrder ?? SortOrder.Ascending,
                 EnableTotalRecordCount = query.EnableTotalRecordCount,
-                TopParentIds = new[] { topFolder.Id.ToString("N") }
+                TopParentIds = new[] { topFolder.Id.ToString("N") },
+                Fields = options.Fields
             };
 
             if (!string.IsNullOrWhiteSpace(query.SeriesTimerId))
@@ -920,7 +921,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return result;
         }
 
-        public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken)
+        public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken)
         {
             var user = _userManager.GetUserById(query.UserId);
 
@@ -937,7 +938,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 IsKids = query.IsKids,
                 EnableTotalRecordCount = query.EnableTotalRecordCount,
                 SortBy = new[] { ItemSortBy.StartDate },
-                TopParentIds = new[] { topFolder.Id.ToString("N") }
+                TopParentIds = new[] { topFolder.Id.ToString("N") },
+                Fields = options.Fields
             };
 
             if (query.Limit.HasValue)
@@ -987,7 +989,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         public async Task<QueryResult<BaseItemDto>> GetRecommendedPrograms(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken)
         {
-            var internalResult = await GetRecommendedProgramsInternal(query, cancellationToken).ConfigureAwait(false);
+            var internalResult = await GetRecommendedProgramsInternal(query, options, cancellationToken).ConfigureAwait(false);
 
             var user = _userManager.GetUserById(query.UserId);
 
@@ -1315,6 +1317,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                         }
                     }
 
+                    _logger.Debug("Channel {0} has {1} new programs and {2} updated programs", currentChannel.Name, newPrograms.Count, updatedPrograms.Count);
+
                     if (newPrograms.Count > 0)
                     {
                         await _libraryManager.CreateItems(newPrograms, cancellationToken).ConfigureAwait(false);
@@ -1476,7 +1480,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             }
         }
 
-        private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, User user)
+        private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, User user)
         {
             if (user == null || (query.IsInProgress ?? false))
             {
@@ -1552,7 +1556,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 EnableTotalRecordCount = query.EnableTotalRecordCount,
                 IncludeItemTypes = includeItemTypes.ToArray(),
                 ExcludeItemTypes = excludeItemTypes.ToArray(),
-                Genres = genres.ToArray()
+                Genres = genres.ToArray(),
+                Fields = dtoOptions.Fields
             });
         }
 
@@ -1625,7 +1630,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             if (_services.Count == 1)
             {
-                return GetEmbyRecordings(query, user);
+                return GetEmbyRecordings(query, new DtoOptions(), user);
             }
 
             await RefreshRecordings(cancellationToken).ConfigureAwait(false);
@@ -2717,7 +2722,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         public async Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true)
         {
-            info = (TunerHostInfo)_jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(info), typeof(TunerHostInfo));
+            info = _jsonSerializer.DeserializeFromString<TunerHostInfo>(_jsonSerializer.SerializeToString(info));
 
             var provider = _tunerHosts.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase));
 
@@ -2758,7 +2763,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         public async Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings)
         {
-            info = (ListingsProviderInfo)_jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(info), typeof(ListingsProviderInfo));
+            info = _jsonSerializer.DeserializeFromString< ListingsProviderInfo>(_jsonSerializer.SerializeToString(info));
 
             var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase));
 

+ 3 - 2
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -11,9 +11,10 @@
     <AssemblyName>MediaBrowser.Server.Implementations</AssemblyName>
     <FileAlignment>512</FileAlignment>
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
     <ReleaseVersion>
     </ReleaseVersion>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>

+ 440 - 107
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -274,6 +274,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
             _connection.AddColumn(Logger, "TypedBaseItems", "SeriesId", "GUID");
             _connection.AddColumn(Logger, "TypedBaseItems", "SeriesSortName", "Text");
             _connection.AddColumn(Logger, "TypedBaseItems", "ExternalSeriesId", "Text");
+            _connection.AddColumn(Logger, "TypedBaseItems", "ShortOverview", "Text");
+            _connection.AddColumn(Logger, "TypedBaseItems", "Tagline", "Text");
+            _connection.AddColumn(Logger, "TypedBaseItems", "Keywords", "Text");
+            _connection.AddColumn(Logger, "TypedBaseItems", "ProviderIds", "Text");
+            _connection.AddColumn(Logger, "TypedBaseItems", "Images", "Text");
 
             _connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT");
             _connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text");
@@ -418,7 +423,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
             "PresentationUniqueKey",
             "InheritedParentalRatingValue",
             "InheritedTags",
-            "ExternalSeriesId"
+            "ExternalSeriesId",
+            "ShortOverview",
+            "Tagline",
+            "Keywords",
+            "ProviderIds",
+            "Images"
         };
 
         private readonly string[] _mediaStreamSaveColumns =
@@ -541,7 +551,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 "SeasonId",
                 "SeriesId",
                 "SeriesSortName",
-                "ExternalSeriesId"
+                "ExternalSeriesId",
+                "ShortOverview",
+                "Tagline",
+                "Keywords",
+                "ProviderIds",
+                "Images"
             };
             _saveItemCommand = _connection.CreateCommand();
             _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
@@ -982,6 +997,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     }
 
                     _saveItemCommand.GetParameter(index++).Value = item.ExternalSeriesId;
+                    _saveItemCommand.GetParameter(index++).Value = item.ShortOverview;
+                    _saveItemCommand.GetParameter(index++).Value = item.Tagline;
+                    _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Keywords.ToArray());
+                    _saveItemCommand.GetParameter(index++).Value = SerializeProviderIds(item);
+                    _saveItemCommand.GetParameter(index++).Value = SerializeImages(item);
 
                     _saveItemCommand.Transaction = transaction;
 
@@ -1031,6 +1051,99 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
         }
 
+        private string SerializeProviderIds(BaseItem item)
+        {
+            var ids = item.ProviderIds.ToList();
+
+            if (ids.Count == 0)
+            {
+                return null;
+            }
+
+            return string.Join("|", ids.Select(i => i.Key + "=" + i.Value).ToArray());
+        }
+
+        private void DeserializeProviderIds(string value, BaseItem item)
+        {
+            if (string.IsNullOrWhiteSpace(value))
+            {
+                return;
+            }
+
+            if (item.ProviderIds.Count > 0)
+            {
+                return;
+            }
+
+            var parts = value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+
+            foreach (var part in parts)
+            {
+                var idParts = part.Split('=');
+
+                item.SetProviderId(idParts[0], idParts[1]);
+            }
+        }
+
+        private string SerializeImages(BaseItem item)
+        {
+            var images = item.ImageInfos.ToList();
+
+            if (images.Count == 0)
+            {
+                return null;
+            }
+
+            return string.Join("|", images.Select(ToValueString).ToArray());
+        }
+
+        private void DeserializeImages(string value, BaseItem item)
+        {
+            if (string.IsNullOrWhiteSpace(value))
+            {
+                return;
+            }
+
+            if (item.ImageInfos.Count > 0)
+            {
+                return;
+            }
+
+            var parts = value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+
+            foreach (var part in parts)
+            {
+                item.ImageInfos.Add(ItemImageInfoFromValueString(part));
+            }
+        }
+
+        public string ToValueString(ItemImageInfo image)
+        {
+            var delimeter = "*";
+
+            return (image.Path ?? string.Empty) +
+                delimeter +
+                image.DateModified.Ticks.ToString(CultureInfo.InvariantCulture) +
+                delimeter +
+                image.Type +
+                delimeter +
+                image.IsPlaceholder;
+        }
+
+        public ItemImageInfo ItemImageInfoFromValueString(string value)
+        {
+            var parts = value.Split(new[] { '*' }, StringSplitOptions.RemoveEmptyEntries);
+
+            var image = new ItemImageInfo();
+
+            image.Path = parts[0];
+            image.DateModified = new DateTime(long.Parse(parts[1], CultureInfo.InvariantCulture), DateTimeKind.Utc);
+            image.Type = (ImageType)Enum.Parse(typeof(ImageType), parts[2], true);
+            image.IsPlaceholder = string.Equals(parts[3], true.ToString(), StringComparison.OrdinalIgnoreCase);
+
+            return image;
+        }
+
         /// <summary>
         /// Internal retrieve from items or users table
         /// </summary>
@@ -1064,6 +1177,51 @@ namespace MediaBrowser.Server.Implementations.Persistence
         }
 
         private BaseItem GetItem(IDataReader reader)
+        {
+            return GetItem(reader, new InternalItemsQuery());
+        }
+
+        private bool TypeRequiresDeserialization(Type type)
+        {
+            if (_config.Configuration.SkipDeserializationForBasicTypes)
+            {
+                if (type == typeof(MusicGenre))
+                {
+                    return false;
+                }
+                if (type == typeof(GameGenre))
+                {
+                    return false;
+                }
+                if (type == typeof(Genre))
+                {
+                    return false;
+                }
+                if (type == typeof(Studio))
+                {
+                    return false;
+                }
+                if (type == typeof(Year))
+                {
+                    return false;
+                }
+                if (type == typeof(Book))
+                {
+                    return false;
+                }
+            }
+            if (_config.Configuration.SkipDeserializationForPrograms)
+            {
+                if (type == typeof(LiveTvProgram))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private BaseItem GetItem(IDataReader reader, InternalItemsQuery query)
         {
             var typeString = reader.GetString(0);
 
@@ -1078,34 +1236,37 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             BaseItem item = null;
 
-            using (var stream = reader.GetMemoryStream(1, _memoryStreamProvider))
+            if (TypeRequiresDeserialization(type))
             {
-                try
-                {
-                    item = _jsonSerializer.DeserializeFromStream(stream, type) as BaseItem;
-                }
-                catch (SerializationException ex)
-                {
-                    Logger.ErrorException("Error deserializing item", ex);
-                }
-
-                if (item == null)
+                using (var stream = reader.GetMemoryStream(1, _memoryStreamProvider))
                 {
                     try
                     {
-                        item = Activator.CreateInstance(type) as BaseItem;
+                        item = _jsonSerializer.DeserializeFromStream(stream, type) as BaseItem;
                     }
-                    catch
+                    catch (SerializationException ex)
                     {
+                        Logger.ErrorException("Error deserializing item", ex);
                     }
                 }
+            }
 
-                if (item == null)
+            if (item == null)
+            {
+                try
+                {
+                    item = Activator.CreateInstance(type) as BaseItem;
+                }
+                catch
                 {
-                    return null;
                 }
             }
 
+            if (item == null)
+            {
+                return null;
+            }
+
             if (!reader.IsDBNull(2))
             {
                 var hasStartDate = item as IHasStartDate;
@@ -1179,194 +1340,275 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 }
             }
 
-            if (!reader.IsDBNull(15))
-            {
-                item.CommunityRating = reader.GetFloat(15);
-            }
+            var index = 15;
 
-            if (!reader.IsDBNull(16))
+            if (!reader.IsDBNull(index))
             {
-                item.CustomRating = reader.GetString(16);
+                item.CommunityRating = reader.GetFloat(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(17))
+            if (query.HasField(ItemFields.CustomRating))
             {
-                item.IndexNumber = reader.GetInt32(17);
+                if (!reader.IsDBNull(index))
+                {
+                    item.CustomRating = reader.GetString(index);
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(18))
+            if (!reader.IsDBNull(index))
             {
-                item.IsLocked = reader.GetBoolean(18);
+                item.IndexNumber = reader.GetInt32(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(19))
+            if (query.HasField(ItemFields.Settings))
             {
-                item.PreferredMetadataLanguage = reader.GetString(19);
-            }
+                if (!reader.IsDBNull(index))
+                {
+                    item.IsLocked = reader.GetBoolean(index);
+                }
+                index++;
 
-            if (!reader.IsDBNull(20))
-            {
-                item.PreferredMetadataCountryCode = reader.GetString(20);
+                if (!reader.IsDBNull(index))
+                {
+                    item.PreferredMetadataLanguage = reader.GetString(index);
+                }
+                index++;
+
+                if (!reader.IsDBNull(index))
+                {
+                    item.PreferredMetadataCountryCode = reader.GetString(index);
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(21))
+            if (!reader.IsDBNull(index))
             {
-                item.IsHD = reader.GetBoolean(21);
+                item.IsHD = reader.GetBoolean(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(22))
+            if (!reader.IsDBNull(index))
             {
-                item.ExternalEtag = reader.GetString(22);
+                item.ExternalEtag = reader.GetString(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(23))
+            if (!reader.IsDBNull(index))
             {
-                item.DateLastRefreshed = reader.GetDateTime(23).ToUniversalTime();
+                item.DateLastRefreshed = reader.GetDateTime(index).ToUniversalTime();
             }
+            index++;
 
-            if (!reader.IsDBNull(24))
+            if (!reader.IsDBNull(index))
             {
-                item.Name = reader.GetString(24);
+                item.Name = reader.GetString(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(25))
+            if (!reader.IsDBNull(index))
             {
-                item.Path = reader.GetString(25);
+                item.Path = reader.GetString(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(26))
+            if (!reader.IsDBNull(index))
             {
-                item.PremiereDate = reader.GetDateTime(26).ToUniversalTime();
+                item.PremiereDate = reader.GetDateTime(index).ToUniversalTime();
             }
+            index++;
 
-            if (!reader.IsDBNull(27))
+            if (query.HasField(ItemFields.Overview))
             {
-                item.Overview = reader.GetString(27);
+                if (!reader.IsDBNull(index))
+                {
+                    item.Overview = reader.GetString(index);
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(28))
+            if (!reader.IsDBNull(index))
             {
-                item.ParentIndexNumber = reader.GetInt32(28);
+                item.ParentIndexNumber = reader.GetInt32(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(29))
+            if (!reader.IsDBNull(index))
             {
-                item.ProductionYear = reader.GetInt32(29);
+                item.ProductionYear = reader.GetInt32(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(30))
+            if (!reader.IsDBNull(index))
             {
-                item.OfficialRating = reader.GetString(30);
+                item.OfficialRating = reader.GetString(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(31))
+            if (query.HasField(ItemFields.OfficialRatingDescription))
             {
-                item.OfficialRatingDescription = reader.GetString(31);
+                if (!reader.IsDBNull(index))
+                {
+                    item.OfficialRatingDescription = reader.GetString(index);
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(32))
+            if (query.HasField(ItemFields.HomePageUrl))
             {
-                item.HomePageUrl = reader.GetString(32);
+                if (!reader.IsDBNull(index))
+                {
+                    item.HomePageUrl = reader.GetString(index);
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(33))
+            if (query.HasField(ItemFields.DisplayMediaType))
             {
-                item.DisplayMediaType = reader.GetString(33);
+                if (!reader.IsDBNull(index))
+                {
+                    item.DisplayMediaType = reader.GetString(index);
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(34))
+            if (query.HasField(ItemFields.SortName))
             {
-                item.ForcedSortName = reader.GetString(34);
+                if (!reader.IsDBNull(index))
+                {
+                    item.ForcedSortName = reader.GetString(index);
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(35))
+            if (!reader.IsDBNull(index))
             {
-                item.RunTimeTicks = reader.GetInt64(35);
+                item.RunTimeTicks = reader.GetInt64(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(36))
+            if (query.HasField(ItemFields.VoteCount))
             {
-                item.VoteCount = reader.GetInt32(36);
+                if (!reader.IsDBNull(index))
+                {
+                    item.VoteCount = reader.GetInt32(index);
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(37))
+            if (query.HasField(ItemFields.DateCreated))
             {
-                item.DateCreated = reader.GetDateTime(37).ToUniversalTime();
+                if (!reader.IsDBNull(index))
+                {
+                    item.DateCreated = reader.GetDateTime(index).ToUniversalTime();
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(38))
+            if (!reader.IsDBNull(index))
             {
-                item.DateModified = reader.GetDateTime(38).ToUniversalTime();
+                item.DateModified = reader.GetDateTime(index).ToUniversalTime();
             }
+            index++;
 
-            item.Id = reader.GetGuid(39);
+            item.Id = reader.GetGuid(index);
+            index++;
 
-            if (!reader.IsDBNull(40))
+            if (query.HasField(ItemFields.Genres))
             {
-                item.Genres = reader.GetString(40).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+                if (!reader.IsDBNull(index))
+                {
+                    item.Genres = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(41))
+            if (!reader.IsDBNull(index))
             {
-                item.ParentId = reader.GetGuid(41);
+                item.ParentId = reader.GetGuid(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(42))
+            if (!reader.IsDBNull(index))
             {
-                item.Audio = (ProgramAudio)Enum.Parse(typeof(ProgramAudio), reader.GetString(42), true);
+                item.Audio = (ProgramAudio)Enum.Parse(typeof(ProgramAudio), reader.GetString(index), true);
             }
+            index++;
 
-            if (!reader.IsDBNull(43))
+            if (query.HasField(ItemFields.ServiceName))
             {
-                item.ServiceName = reader.GetString(43);
+                if (!reader.IsDBNull(index))
+                {
+                    item.ServiceName = reader.GetString(index);
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(44))
+            if (!reader.IsDBNull(index))
             {
-                item.IsInMixedFolder = reader.GetBoolean(44);
+                item.IsInMixedFolder = reader.GetBoolean(index);
             }
+            index++;
 
-            if (!reader.IsDBNull(45))
+            if (!reader.IsDBNull(index))
             {
-                item.DateLastSaved = reader.GetDateTime(45).ToUniversalTime();
+                item.DateLastSaved = reader.GetDateTime(index).ToUniversalTime();
             }
+            index++;
 
-            if (!reader.IsDBNull(46))
+            if (query.HasField(ItemFields.Settings))
             {
-                item.LockedFields = reader.GetString(46).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => (MetadataFields)Enum.Parse(typeof(MetadataFields), i, true)).ToList();
+                if (!reader.IsDBNull(index))
+                {
+                    item.LockedFields = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => (MetadataFields)Enum.Parse(typeof(MetadataFields), i, true)).ToList();
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(47))
+            if (query.HasField(ItemFields.Studios))
             {
-                item.Studios = reader.GetString(47).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+                if (!reader.IsDBNull(index))
+                {
+                    item.Studios = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(48))
+            if (query.HasField(ItemFields.Tags))
             {
-                item.Tags = reader.GetString(48).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+                if (!reader.IsDBNull(index))
+                {
+                    item.Tags = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+                }
+                index++;
             }
 
-            if (!reader.IsDBNull(49))
+            if (!reader.IsDBNull(index))
             {
-                item.SourceType = (SourceType)Enum.Parse(typeof(SourceType), reader.GetString(49), true);
+                item.SourceType = (SourceType)Enum.Parse(typeof(SourceType), reader.GetString(index), true);
             }
+            index++;
 
             var trailer = item as Trailer;
             if (trailer != null)
             {
-                if (!reader.IsDBNull(50))
+                if (!reader.IsDBNull(index))
                 {
-                    trailer.TrailerTypes = reader.GetString(50).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => (TrailerType)Enum.Parse(typeof(TrailerType), i, true)).ToList();
+                    trailer.TrailerTypes = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => (TrailerType)Enum.Parse(typeof(TrailerType), i, true)).ToList();
                 }
             }
+            index++;
 
-            var index = 51;
-
-            if (!reader.IsDBNull(index))
+            if (query.HasField(ItemFields.OriginalTitle))
             {
-                item.OriginalTitle = reader.GetString(index);
+                if (!reader.IsDBNull(index))
+                {
+                    item.OriginalTitle = reader.GetString(index);
+                }
+                index++;
             }
-            index++;
 
             var video = item as Video;
             if (video != null)
@@ -1378,12 +1620,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
             index++;
 
-            var folder = item as Folder;
-            if (folder != null && !reader.IsDBNull(index))
+            if (query.HasField(ItemFields.DateLastMediaAdded))
             {
-                folder.DateLastMediaAdded = reader.GetDateTime(index).ToUniversalTime();
+                var folder = item as Folder;
+                if (folder != null && !reader.IsDBNull(index))
+                {
+                    folder.DateLastMediaAdded = reader.GetDateTime(index).ToUniversalTime();
+                }
+                index++;
             }
-            index++;
 
             if (!reader.IsDBNull(index))
             {
@@ -1397,11 +1642,14 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
             index++;
 
-            if (!reader.IsDBNull(index))
+            if (query.HasField(ItemFields.CriticRatingSummary))
             {
-                item.CriticRatingSummary = reader.GetString(index);
+                if (!reader.IsDBNull(index))
+                {
+                    item.CriticRatingSummary = reader.GetString(index);
+                }
+                index++;
             }
-            index++;
 
             if (!reader.IsDBNull(index))
             {
@@ -1480,6 +1728,54 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
             index++;
 
+            if (query.HasField(ItemFields.ShortOverview))
+            {
+                if (!reader.IsDBNull(index))
+                {
+                    item.ShortOverview = reader.GetString(index);
+                }
+                index++;
+            }
+
+            if (query.HasField(ItemFields.Taglines))
+            {
+                if (!reader.IsDBNull(index))
+                {
+                    item.Tagline = reader.GetString(index);
+                }
+                index++;
+            }
+
+            if (query.HasField(ItemFields.Keywords))
+            {
+                if (!reader.IsDBNull(index))
+                {
+                    item.Keywords = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+                }
+                index++;
+            }
+
+            if (!reader.IsDBNull(index))
+            {
+                DeserializeProviderIds(reader.GetString(index), item);
+            }
+            index++;
+
+            if (!reader.IsDBNull(index))
+            {
+                DeserializeImages(reader.GetString(index), item);
+            }
+            index++;
+
+            if (string.IsNullOrWhiteSpace(item.Tagline))
+            {
+                var movie = item as Movie;
+                if (movie != null && movie.Taglines.Count > 0)
+                {
+                    movie.Tagline = movie.Taglines[0];
+                }
+            }
+
             return item;
         }
 
@@ -1796,10 +2092,47 @@ namespace MediaBrowser.Server.Implementations.Persistence
             return false;
         }
 
+        private List<ItemFields> allFields = Enum.GetNames(typeof(ItemFields))
+                    .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
+                    .ToList();
+
+        private IEnumerable<string> GetColumnNamesFromField(ItemFields field)
+        {
+            if (field == ItemFields.Settings)
+            {
+                return new[] { "IsLocked", "PreferredMetadataCountryCode", "PreferredMetadataLanguage", "LockedFields" };
+            }
+            if (field == ItemFields.ServiceName)
+            {
+                return new[] { "ExternalServiceId" };
+            }
+            if (field == ItemFields.SortName)
+            {
+                return new[] { "ForcedSortName" };
+            }
+            if (field == ItemFields.Taglines)
+            {
+                return new[] { "Tagline" };
+            }
+
+            return new[] { field.ToString() };
+        }
+
         private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns, IDbCommand cmd)
         {
             var list = startColumns.ToList();
 
+            foreach (var field in allFields)
+            {
+                if (!query.HasField(field))
+                {
+                    foreach (var fieldToRemove in GetColumnNamesFromField(field).ToList())
+                    {
+                        list.Remove(fieldToRemove);
+                    }
+                }
+            }
+
             if (EnableJoinUserData(query))
             {
                 list.Add("UserDataDb.UserData.UserId");
@@ -1954,7 +2287,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
                     while (reader.Read())
                     {
-                        var item = GetItem(reader);
+                        var item = GetItem(reader, query);
                         if (item != null)
                         {
                             list.Add(item);
@@ -2141,7 +2474,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     {
                         while (reader.Read())
                         {
-                            var item = GetItem(reader);
+                            var item = GetItem(reader, query);
                             if (item != null)
                             {
                                 list.Add(item);
@@ -2652,7 +2985,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 }
                 if (programAttribtues.Count > 0)
                 {
-                    whereClauses.Add("("+string.Join(" OR ", programAttribtues.ToArray())+")");
+                    whereClauses.Add("(" + string.Join(" OR ", programAttribtues.ToArray()) + ")");
                 }
             }
 

+ 4 - 4
MediaBrowser.Server.Implementations/app.config

@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
-        <assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-1.0.94.0" newVersion="1.0.94.0" />
+        <assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral"/>
+        <bindingRedirect oldVersion="0.0.0.0-1.0.94.0" newVersion="1.0.94.0"/>
       </dependentAssembly>
     </assemblyBinding>
   </runtime>
-</configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/></startup></configuration>

+ 90 - 2
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -102,7 +102,12 @@ using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
 using MediaBrowser.Api.Playback;
+using MediaBrowser.Common.Implementations.Serialization;
 using MediaBrowser.Common.Implementations.Updates;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Model.Serialization;
 
 namespace MediaBrowser.Server.Startup.Common
 {
@@ -363,6 +368,89 @@ namespace MediaBrowser.Server.Startup.Common
             LogManager.RemoveConsoleOutput();
         }
 
+        protected override IJsonSerializer CreateJsonSerializer()
+        {
+            var result = base.CreateJsonSerializer();
+
+            ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ShortOverview" };
+            ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "Taglines" };
+            ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "Keywords" };
+            ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ShortOverview" };
+            ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ShortOverview" };
+
+            ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ProviderIds" };
+            ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ProviderIds" };
+
+            ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ImageInfos" };
+            ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ImageInfos" };
+
+            return result;
+        }
+
         public override Task Init(IProgress<double> progress)
         {
             HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
@@ -435,7 +523,7 @@ namespace MediaBrowser.Server.Startup.Common
             RegisterSingleInstance(UserDataManager);
 
             UserRepository = await GetUserRepository().ConfigureAwait(false);
-            
+
             var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector(), MemoryStreamProvider);
             DisplayPreferencesRepository = displayPreferencesRepo;
             RegisterSingleInstance(DisplayPreferencesRepository);
@@ -781,7 +869,7 @@ namespace MediaBrowser.Server.Startup.Common
                 }
                 catch
                 {
-                    
+
                 }
             }
             if (!isAuthorized)

+ 4 - 0
MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj

@@ -48,6 +48,10 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath>
     </Reference>
+    <Reference Include="ServiceStack.Text, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
     <Reference Include="System.Core" />

+ 6 - 19
MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs

@@ -492,13 +492,9 @@ namespace MediaBrowser.XbmcMetadata.Parsers
                     {
                         var val = reader.ReadElementContentAsString();
 
-                        var hasTagline = item as IHasTaglines;
-                        if (hasTagline != null)
+                        if (!string.IsNullOrWhiteSpace(val))
                         {
-                            if (!string.IsNullOrWhiteSpace(val))
-                            {
-                                hasTagline.AddTagline(val);
-                            }
+                            item.Tagline = val;
                         }
                         break;
                     }
@@ -507,20 +503,11 @@ namespace MediaBrowser.XbmcMetadata.Parsers
                     {
                         var val = reader.ReadElementContentAsString();
 
-                        var hasProductionLocations = item as IHasProductionLocations;
-                        if (hasProductionLocations != null)
+                        if (!string.IsNullOrWhiteSpace(val))
                         {
-                            if (!string.IsNullOrWhiteSpace(val))
-                            {
-                                var parts = val.Split('/')
-                                    .Select(i => i.Trim())
-                                    .Where(i => !string.IsNullOrWhiteSpace(i));
-
-                                foreach (var p in parts)
-                                {
-                                    hasProductionLocations.AddProductionLocation(p);
-                                }
-                            }
+                            //var countries = val.Split('/')
+                            //    .Select(i => i.Trim())
+                            //    .Where(i => !string.IsNullOrWhiteSpace(i));
                         }
                         break;
                     }

+ 7 - 15
MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs

@@ -80,7 +80,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
                     "imdbid",
                     "imdb_id",
                     "plotkeyword",
-                    "country",
+                    //"country",
                     "audiodbalbumid",
                     "audiodbartistid",
                     "awardsummary",
@@ -718,23 +718,15 @@ namespace MediaBrowser.XbmcMetadata.Savers
                 writer.WriteElementString("runtime", Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture));
             }
 
-            var hasTaglines = item as IHasTaglines;
-            if (hasTaglines != null)
+            if (!string.IsNullOrWhiteSpace(item.Tagline))
             {
-                foreach (var tagline in hasTaglines.Taglines)
-                {
-                    writer.WriteElementString("tagline", tagline);
-                }
+                writer.WriteElementString("tagline", item.Tagline);
             }
 
-            var hasProductionLocations = item as IHasProductionLocations;
-            if (hasProductionLocations != null)
-            {
-                foreach (var country in hasProductionLocations.ProductionLocations)
-                {
-                    writer.WriteElementString("country", country);
-                }
-            }
+            //foreach (var country in hasProductionLocations.ProductionLocations)
+            //{
+            //    writer.WriteElementString("country", country);
+            //}
 
             foreach (var genre in item.Genres)
             {

+ 2 - 2
Nuget/MediaBrowser.Common.Internal.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Common.Internal</id>
-        <version>3.0.660</version>
+        <version>3.0.661</version>
         <title>MediaBrowser.Common.Internal</title>
         <authors>Luke</authors>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
         <copyright>Copyright © Emby 2013</copyright>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.660" />
+            <dependency id="MediaBrowser.Common" version="3.0.661" />
             <dependency id="NLog" version="4.3.8" />
             <dependency id="SimpleInjector" version="3.2.2" />
         </dependencies>

+ 1 - 1
Nuget/MediaBrowser.Common.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Common</id>
-        <version>3.0.660</version>
+        <version>3.0.661</version>
         <title>MediaBrowser.Common</title>
         <authors>Emby Team</authors>
         <owners>ebr,Luke,scottisafool</owners>

+ 2 - 2
Nuget/MediaBrowser.Server.Core.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Server.Core</id>
-        <version>3.0.660</version>
+        <version>3.0.661</version>
         <title>Media Browser.Server.Core</title>
         <authors>Emby Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains core components required to build plugins for Emby Server.</description>
         <copyright>Copyright © Emby 2013</copyright>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.660" />
+            <dependency id="MediaBrowser.Common" version="3.0.661" />
 			<dependency id="Interfaces.IO" version="1.0.0.5" />
         </dependencies>
     </metadata>