diff options
31 files changed, 581 insertions, 364 deletions
diff --git a/MediaBrowser.Api/ApiService.cs b/MediaBrowser.Api/ApiService.cs index 5a787c0e4..be99ef239 100644 --- a/MediaBrowser.Api/ApiService.cs +++ b/MediaBrowser.Api/ApiService.cs @@ -6,7 +6,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller;
using MediaBrowser.Model.DTO;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.Api
{
@@ -22,72 +21,91 @@ namespace MediaBrowser.Api return Kernel.Instance.GetItemById(guid);
}
- /// <summary>
- /// Takes a BaseItem and returns the actual object that will be serialized by the api
- /// </summary>
- public static BaseItemContainer<BaseItem> GetSerializationObject(BaseItem item, bool includeChildren, Guid userId)
+ public static DTOBaseItem GetDTOBaseItem(BaseItem item, User user,
+ bool includeChildren = true,
+ bool includePeople = true)
{
- User user = Kernel.Instance.Users.First(u => u.Id == userId);
-
- BaseItemContainer<BaseItem> wrapper = new BaseItemContainer<BaseItem>()
- {
- Item = item,
- UserItemData = user.GetItemData(item.Id),
- Type = item.GetType().Name,
- IsFolder = (item is Folder)
- };
-
- if (string.IsNullOrEmpty(item.LogoImagePath))
- {
- wrapper.ParentLogoItemId = GetParentLogoItemId(item);
- }
-
- if (item.BackdropImagePaths == null || !item.BackdropImagePaths.Any())
+ DTOBaseItem dto = new DTOBaseItem();
+
+ dto.AspectRatio = item.AspectRatio;
+ dto.BackdropCount = item.BackdropImagePaths == null ? 0 : item.BackdropImagePaths.Count();
+ dto.DateCreated = item.DateCreated;
+ dto.DisplayMediaType = item.DisplayMediaType;
+ dto.Genres = item.Genres;
+ dto.HasArt = !string.IsNullOrEmpty(item.ArtImagePath);
+ dto.HasBanner = !string.IsNullOrEmpty(item.BannerImagePath);
+ dto.HasLogo = !string.IsNullOrEmpty(item.LogoImagePath);
+ dto.HasPrimaryImage = !string.IsNullOrEmpty(item.LogoImagePath);
+ dto.HasThumb = !string.IsNullOrEmpty(item.ThumbnailImagePath);
+ dto.Id = item.Id;
+ dto.IndexNumber = item.IndexNumber;
+ dto.IsFolder = item is Folder;
+ dto.LocalTrailerCount = item.LocalTrailers == null ? 0 : item.LocalTrailers.Count();
+ dto.Name = item.Name;
+ dto.OfficialRating = item.OfficialRating;
+ dto.Overview = item.Overview;
+
+ // If there are no backdrops, indicate what parent has them in case the UI wants to allow inheritance
+ if (dto.BackdropCount == 0)
{
int backdropCount;
- wrapper.ParentBackdropItemId = GetParentBackdropItemId(item, out backdropCount);
- wrapper.ParentBackdropCount = backdropCount;
+ dto.ParentBackdropItemId = GetParentBackdropItemId(item, out backdropCount);
+ dto.ParentBackdropCount = backdropCount;
}
if (item.Parent != null)
{
- wrapper.ParentId = item.Parent.Id;
+ dto.ParentId = item.Parent.Id;
}
- if (includeChildren)
+ // If there is no logo, indicate what parent has one in case the UI wants to allow inheritance
+ if (!dto.HasLogo)
{
- var folder = item as Folder;
+ dto.ParentLogoItemId = GetParentLogoItemId(item);
+ }
- if (folder != null)
- {
- wrapper.Children = folder.GetParentalAllowedChildren(user).Select(c => GetSerializationObject(c, false, userId));
- }
+ dto.Path = item.Path;
- // Attach People by transforming them into BaseItemPerson (DTO)
- if (item.People != null)
- {
- wrapper.People = item.People.Select(p =>
- {
- BaseItemPerson baseItemPerson = new BaseItemPerson();
+ dto.PremiereDate = item.PremiereDate;
+ dto.ProductionYear = item.ProductionYear;
+ dto.ProviderIds = item.ProviderIds;
+ dto.RunTimeTicks = item.RunTimeTicks;
+ dto.SortName = item.SortName;
+ dto.Taglines = item.Taglines;
+ dto.TrailerUrl = item.TrailerUrl;
+ dto.Type = item.GetType().Name;
+ dto.UserRating = item.UserRating;
- baseItemPerson.PersonInfo = p;
+ dto.UserData = item.GetUserData(user);
- Person ibnObject = Kernel.Instance.ItemController.GetPerson(p.Name);
+ AttachStudios(dto, item);
- if (ibnObject != null)
- {
- baseItemPerson.PrimaryImagePath = ibnObject.PrimaryImagePath;
- }
+ if (includeChildren)
+ {
+ AttachChildren(dto, item, user);
+ }
- return baseItemPerson;
- });
- }
+ if (includePeople)
+ {
+ AttachPeople(dto, item);
}
+ Folder folder = item as Folder;
+
+ if (folder != null)
+ {
+ dto.SpecialCounts = folder.GetSpecialCounts(user);
+ }
+
+ return dto;
+ }
+
+ private static void AttachStudios(DTOBaseItem dto, BaseItem item)
+ {
// Attach Studios by transforming them into BaseItemStudio (DTO)
if (item.Studios != null)
{
- wrapper.Studios = item.Studios.Select(s =>
+ dto.Studios = item.Studios.Select(s =>
{
BaseItemStudio baseItemStudio = new BaseItemStudio();
@@ -97,14 +115,47 @@ namespace MediaBrowser.Api if (ibnObject != null)
{
- baseItemStudio.PrimaryImagePath = ibnObject.PrimaryImagePath;
+ baseItemStudio.HasImage = !string.IsNullOrEmpty(ibnObject.PrimaryImagePath);
}
return baseItemStudio;
});
}
+ }
+
+ private static void AttachChildren(DTOBaseItem dto, BaseItem item, User user)
+ {
+ var folder = item as Folder;
+
+ if (folder != null)
+ {
+ dto.Children = folder.GetParentalAllowedChildren(user).Select(c => GetDTOBaseItem(c, user, false, false));
+ }
- return wrapper;
+ dto.LocalTrailers = item.LocalTrailers;
+ }
+
+ private static void AttachPeople(DTOBaseItem dto, BaseItem item)
+ {
+ // Attach People by transforming them into BaseItemPerson (DTO)
+ if (item.People != null)
+ {
+ dto.People = item.People.Select(p =>
+ {
+ BaseItemPerson baseItemPerson = new BaseItemPerson();
+
+ baseItemPerson.PersonInfo = p;
+
+ Person ibnObject = Kernel.Instance.ItemController.GetPerson(p.Name);
+
+ if (ibnObject != null)
+ {
+ baseItemPerson.HasImage = !string.IsNullOrEmpty(ibnObject.PrimaryImagePath);
+ }
+
+ return baseItemPerson;
+ });
+ }
}
private static Guid? GetParentBackdropItemId(BaseItem item, out int backdropCount)
diff --git a/MediaBrowser.Api/HttpHandlers/GenresHandler.cs b/MediaBrowser.Api/HttpHandlers/GenresHandler.cs index f7d259e45..c0f2e9eb3 100644 --- a/MediaBrowser.Api/HttpHandlers/GenresHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/GenresHandler.cs @@ -5,7 +5,6 @@ using MediaBrowser.Common.Net.Handlers; using MediaBrowser.Controller;
using MediaBrowser.Model.DTO;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.Api.HttpHandlers
{
diff --git a/MediaBrowser.Api/HttpHandlers/ItemHandler.cs b/MediaBrowser.Api/HttpHandlers/ItemHandler.cs index 3df8e914f..dcbdf2a90 100644 --- a/MediaBrowser.Api/HttpHandlers/ItemHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/ItemHandler.cs @@ -1,15 +1,18 @@ using System;
+using System.Linq;
using MediaBrowser.Common.Net.Handlers;
+using MediaBrowser.Controller;
using MediaBrowser.Model.DTO;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Api.HttpHandlers
{
- public class ItemHandler : BaseJsonHandler<BaseItemContainer<BaseItem>>
+ public class ItemHandler : BaseJsonHandler<DTOBaseItem>
{
- protected sealed override BaseItemContainer<BaseItem> GetObjectToSerialize()
+ protected sealed override DTOBaseItem GetObjectToSerialize()
{
Guid userId = Guid.Parse(QueryString["userid"]);
+ User user = Kernel.Instance.Users.First(u => u.Id == userId);
BaseItem item = ItemToSerialize;
@@ -18,7 +21,7 @@ namespace MediaBrowser.Api.HttpHandlers return null;
}
- return ApiService.GetSerializationObject(item, true, userId);
+ return ApiService.GetDTOBaseItem(item, user);
}
protected virtual BaseItem ItemToSerialize
diff --git a/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs b/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs index b4c13540c..84141a6bf 100644 --- a/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs @@ -5,18 +5,18 @@ using MediaBrowser.Common.Net.Handlers; using MediaBrowser.Controller;
using MediaBrowser.Model.DTO;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.Api.HttpHandlers
{
- public class ItemListHandler : BaseJsonHandler<IEnumerable<BaseItemContainer<BaseItem>>>
+ public class ItemListHandler : BaseJsonHandler<IEnumerable<DTOBaseItem>>
{
- protected override IEnumerable<BaseItemContainer<BaseItem>> GetObjectToSerialize()
+ protected override IEnumerable<DTOBaseItem> GetObjectToSerialize()
{
+ User user = Kernel.Instance.Users.First(u => u.Id == UserId);
+
return ItemsToSerialize.Select(i =>
{
- return ApiService.GetSerializationObject(i, false, UserId);
-
+ return ApiService.GetDTOBaseItem(i, user, includeChildren: false, includePeople: false);
});
}
@@ -27,7 +27,7 @@ namespace MediaBrowser.Api.HttpHandlers Folder parent = ApiService.GetItemById(ItemId) as Folder;
User user = Kernel.Instance.Users.First(u => u.Id == UserId);
-
+
if (ListType.Equals("inprogressitems", StringComparison.OrdinalIgnoreCase))
{
return parent.GetInProgressItems(user);
@@ -76,7 +76,7 @@ namespace MediaBrowser.Api.HttpHandlers return Guid.Parse(QueryString["userid"]);
}
}
-
+
private string ListType
{
get
diff --git a/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs b/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs index 54c33416d..bef381000 100644 --- a/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs @@ -5,7 +5,6 @@ using MediaBrowser.Common.Net.Handlers; using MediaBrowser.Controller;
using MediaBrowser.Model.DTO;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.Api.HttpHandlers
{
diff --git a/MediaBrowser.Api/HttpHandlers/UsersHandler.cs b/MediaBrowser.Api/HttpHandlers/UsersHandler.cs index 64239005f..e1fe638ca 100644 --- a/MediaBrowser.Api/HttpHandlers/UsersHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/UsersHandler.cs @@ -1,7 +1,7 @@ using System.Collections.Generic;
using MediaBrowser.Common.Net.Handlers;
using MediaBrowser.Controller;
-using MediaBrowser.Model.Users;
+using MediaBrowser.Model.Entities;
namespace MediaBrowser.Api.HttpHandlers
{
diff --git a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs index 343fcc70b..33a1a9c13 100644 --- a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs @@ -48,11 +48,11 @@ namespace MediaBrowser.Api.HttpHandlers return true;
}
- AudioStream audio = LibraryItem.AudioStreams.FirstOrDefault();
+ AudioStream audioStream = (LibraryItem.AudioStreams ?? new AudioStream[] { }).FirstOrDefault();
- if (audio != null)
+ if (audioStream != null)
{
- if (RequiresAudioConversion(audio))
+ if (RequiresAudioConversion(audioStream))
{
return true;
}
@@ -121,7 +121,7 @@ namespace MediaBrowser.Api.HttpHandlers private string GetAudioArguments(string outputFormat)
{
- AudioStream audioStream = LibraryItem.AudioStreams.FirstOrDefault();
+ AudioStream audioStream = (LibraryItem.AudioStreams ?? new AudioStream[] { }).FirstOrDefault();
if (audioStream == null)
{
@@ -261,7 +261,7 @@ namespace MediaBrowser.Api.HttpHandlers }
}
- if (LibraryItem.VideoCodec.IndexOf("264", StringComparison.OrdinalIgnoreCase) != -1 || LibraryItem.VideoCodec.IndexOf("avc", StringComparison.OrdinalIgnoreCase) != -1)
+ if (LibraryItem.Codec.IndexOf("264", StringComparison.OrdinalIgnoreCase) != -1 || LibraryItem.Codec.IndexOf("avc", StringComparison.OrdinalIgnoreCase) != -1)
{
return false;
}
@@ -279,15 +279,15 @@ namespace MediaBrowser.Api.HttpHandlers }
}
- if (audio.AudioFormat.IndexOf("aac", StringComparison.OrdinalIgnoreCase) != -1)
+ if (audio.Format.IndexOf("aac", StringComparison.OrdinalIgnoreCase) != -1)
{
return false;
}
- if (audio.AudioFormat.IndexOf("ac-3", StringComparison.OrdinalIgnoreCase) != -1 || audio.AudioFormat.IndexOf("ac3", StringComparison.OrdinalIgnoreCase) != -1)
+ if (audio.Format.IndexOf("ac-3", StringComparison.OrdinalIgnoreCase) != -1 || audio.Format.IndexOf("ac3", StringComparison.OrdinalIgnoreCase) != -1)
{
return false;
}
- if (audio.AudioFormat.IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) != -1 || audio.AudioFormat.IndexOf("mp3", StringComparison.OrdinalIgnoreCase) != -1)
+ if (audio.Format.IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) != -1 || audio.Format.IndexOf("mp3", StringComparison.OrdinalIgnoreCase) != -1)
{
return false;
}
diff --git a/MediaBrowser.Api/HttpHandlers/YearsHandler.cs b/MediaBrowser.Api/HttpHandlers/YearsHandler.cs index 071b980a7..3d9ae59f2 100644 --- a/MediaBrowser.Api/HttpHandlers/YearsHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/YearsHandler.cs @@ -5,7 +5,6 @@ using MediaBrowser.Common.Net.Handlers; using MediaBrowser.Controller;
using MediaBrowser.Model.DTO;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.Api.HttpHandlers
{
diff --git a/MediaBrowser.ApiInteraction/ApiClient.cs b/MediaBrowser.ApiInteraction/ApiClient.cs index af79513e0..c30e67747 100644 --- a/MediaBrowser.ApiInteraction/ApiClient.cs +++ b/MediaBrowser.ApiInteraction/ApiClient.cs @@ -1,16 +1,23 @@ using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
+using System.Net;
+using System.Net.Http;
using System.Threading.Tasks;
using MediaBrowser.Model.DTO;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.ApiInteraction
{
public class ApiClient : IDisposable
{
+ public ApiClient(HttpClientHandler handler)
+ {
+ handler.AutomaticDecompression = DecompressionMethods.Deflate;
+
+ HttpClient = new HttpClient(handler);
+ }
+
/// <summary>
/// Gets or sets the server host name (myserver or 192.168.x.x)
/// </summary>
@@ -32,7 +39,7 @@ namespace MediaBrowser.ApiInteraction }
}
- public IHttpClient HttpClient { get; set; }
+ public HttpClient HttpClient { get; private set; }
public IJsonSerializer JsonSerializer { get; set; }
/// <summary>
@@ -84,26 +91,26 @@ namespace MediaBrowser.ApiInteraction /// <summary>
/// This is a helper to get a list of backdrop url's from a given ApiBaseItemWrapper. If the actual item does not have any backdrops it will return backdrops from the first parent that does.
/// </summary>
- /// <param name="itemWrapper">A given item.</param>
+ /// <param name="item">A given item.</param>
/// <param name="width">Use if a fixed width is required. Aspect ratio will be preserved.</param>
/// <param name="height">Use if a fixed height is required. Aspect ratio will be preserved.</param>
/// <param name="maxWidth">Use if a max width is required. Aspect ratio will be preserved.</param>
/// <param name="maxHeight">Use if a max height is required. Aspect ratio will be preserved.</param>
/// <param name="quality">Quality level, from 0-100. Currently only applies to JPG. The default value should suffice.</param>
- public IEnumerable<string> GetBackdropImageUrls(ApiBaseItemContainer itemWrapper, int? width = null, int? height = null, int? maxWidth = null, int? maxHeight = null, int? quality = null)
+ public IEnumerable<string> GetBackdropImageUrls(DTOBaseItem item, int? width = null, int? height = null, int? maxWidth = null, int? maxHeight = null, int? quality = null)
{
Guid? backdropItemId = null;
int backdropCount = 0;
- if (itemWrapper.Item.BackdropImagePaths == null || !itemWrapper.Item.BackdropImagePaths.Any())
+ if (item.BackdropCount == 0)
{
- backdropItemId = itemWrapper.ParentBackdropItemId;
- backdropCount = itemWrapper.ParentBackdropCount ?? 0;
+ backdropItemId = item.ParentBackdropItemId;
+ backdropCount = item.ParentBackdropCount ?? 0;
}
else
{
- backdropItemId = itemWrapper.Item.Id;
- backdropCount = itemWrapper.Item.BackdropImagePaths.Count();
+ backdropItemId = item.Id;
+ backdropCount = item.BackdropCount;
}
if (backdropItemId == null)
@@ -124,15 +131,15 @@ namespace MediaBrowser.ApiInteraction /// <summary>
/// This is a helper to get the logo image url from a given ApiBaseItemWrapper. If the actual item does not have a logo, it will return the logo from the first parent that does, or null.
/// </summary>
- /// <param name="itemWrapper">A given item.</param>
+ /// <param name="item">A given item.</param>
/// <param name="width">Use if a fixed width is required. Aspect ratio will be preserved.</param>
/// <param name="height">Use if a fixed height is required. Aspect ratio will be preserved.</param>
/// <param name="maxWidth">Use if a max width is required. Aspect ratio will be preserved.</param>
/// <param name="maxHeight">Use if a max height is required. Aspect ratio will be preserved.</param>
/// <param name="quality">Quality level, from 0-100. Currently only applies to JPG. The default value should suffice.</param>
- public string GetLogoImageUrl(ApiBaseItemContainer itemWrapper, int? width = null, int? height = null, int? maxWidth = null, int? maxHeight = null, int? quality = null)
+ public string GetLogoImageUrl(DTOBaseItem item, int? width = null, int? height = null, int? maxWidth = null, int? maxHeight = null, int? quality = null)
{
- Guid? logoItemId = !string.IsNullOrEmpty(itemWrapper.Item.LogoImagePath) ? itemWrapper.Item.Id : itemWrapper.ParentLogoItemId;
+ Guid? logoItemId = item.HasLogo ? item.Id : item.ParentLogoItemId;
if (logoItemId.HasValue)
{
@@ -153,7 +160,7 @@ namespace MediaBrowser.ApiInteraction /// <summary>
/// Gets a BaseItem
/// </summary>
- public async Task<ApiBaseItemContainer> GetItemAsync(Guid id, Guid userId)
+ public async Task<DTOBaseItem> GetItemAsync(Guid id, Guid userId)
{
string url = ApiUrl + "/item?userId=" + userId.ToString();
@@ -164,7 +171,7 @@ namespace MediaBrowser.ApiInteraction using (Stream stream = await HttpClient.GetStreamAsync(url))
{
- return JsonSerializer.DeserializeFromStream<ApiBaseItemContainer>(stream);
+ return JsonSerializer.DeserializeFromStream<DTOBaseItem>(stream);
}
}
@@ -210,44 +217,54 @@ namespace MediaBrowser.ApiInteraction /// <summary>
/// Gets all items that contain a given Year
/// </summary>
- public async Task<IEnumerable<ApiBaseItemContainer>> GetItemsWithYearAsync(string name, Guid userId)
+ public async Task<IEnumerable<DTOBaseItem>> GetItemsWithYearAsync(string name, Guid userId)
{
string url = ApiUrl + "/itemlist?listtype=itemswithyear&userId=" + userId.ToString() + "&name=" + name;
using (Stream stream = await HttpClient.GetStreamAsync(url))
{
- return JsonSerializer.DeserializeFromStream<IEnumerable<ApiBaseItemContainer>>(stream);
+ return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
}
}
/// <summary>
/// Gets all items that contain a given Genre
/// </summary>
- public async Task<IEnumerable<ApiBaseItemContainer>> GetItemsWithGenreAsync(string name, Guid userId)
+ public async Task<IEnumerable<DTOBaseItem>> GetItemsWithGenreAsync(string name, Guid userId)
{
string url = ApiUrl + "/itemlist?listtype=itemswithgenre&userId=" + userId.ToString() + "&name=" + name;
using (Stream stream = await HttpClient.GetStreamAsync(url))
{
- return JsonSerializer.DeserializeFromStream<IEnumerable<ApiBaseItemContainer>>(stream);
+ return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
}
}
/// <summary>
/// Gets all items that contain a given Person
/// </summary>
- public async Task<IEnumerable<ApiBaseItemContainer>> GetItemsWithPersonAsync(string name, PersonType? personType, Guid userId)
+ public async Task<IEnumerable<DTOBaseItem>> GetItemsWithPersonAsync(string name, Guid userId)
{
string url = ApiUrl + "/itemlist?listtype=itemswithperson&userId=" + userId.ToString() + "&name=" + name;
- if (personType.HasValue)
+ using (Stream stream = await HttpClient.GetStreamAsync(url))
{
- url += "&persontype=" + personType.Value.ToString();
+ return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
}
+ }
+
+ /// <summary>
+ /// Gets all items that contain a given Person
+ /// </summary>
+ public async Task<IEnumerable<DTOBaseItem>> GetItemsWithPersonAsync(string name, string personType, Guid userId)
+ {
+ string url = ApiUrl + "/itemlist?listtype=itemswithperson&userId=" + userId.ToString() + "&name=" + name;
+
+ url += "&persontype=" + personType;
using (Stream stream = await HttpClient.GetStreamAsync(url))
{
- return JsonSerializer.DeserializeFromStream<IEnumerable<ApiBaseItemContainer>>(stream);
+ return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
}
}
@@ -267,13 +284,13 @@ namespace MediaBrowser.ApiInteraction /// <summary>
/// Gets all items that contain a given Studio
/// </summary>
- public async Task<IEnumerable<ApiBaseItemContainer>> GetItemsWithStudioAsync(string name, Guid userId)
+ public async Task<IEnumerable<DTOBaseItem>> GetItemsWithStudioAsync(string name, Guid userId)
{
string url = ApiUrl + "/itemlist?listtype=itemswithstudio&userId=" + userId.ToString() + "&name=" + name;
using (Stream stream = await HttpClient.GetStreamAsync(url))
{
- return JsonSerializer.DeserializeFromStream<IEnumerable<ApiBaseItemContainer>>(stream);
+ return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
}
}
diff --git a/MediaBrowser.ApiInteraction/IHttpClient.cs b/MediaBrowser.ApiInteraction/IHttpClient.cs deleted file mode 100644 index 40659e019..000000000 --- a/MediaBrowser.ApiInteraction/IHttpClient.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.ApiInteraction
-{
- public interface IHttpClient : IDisposable
- {
- Task<Stream> GetStreamAsync(string url);
- }
-}
diff --git a/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj b/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj index 965b4487d..71b5d9d38 100644 --- a/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj +++ b/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj @@ -40,7 +40,6 @@ </ItemGroup>
<ItemGroup>
<Compile Include="ApiClient.cs" />
- <Compile Include="IHttpClient.cs" />
<Compile Include="IJsonSerializer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
diff --git a/MediaBrowser.Controller/Configuration/ServerConfiguration.cs b/MediaBrowser.Controller/Configuration/ServerConfiguration.cs index 88d1012b1..d58a81db9 100644 --- a/MediaBrowser.Controller/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Controller/Configuration/ServerConfiguration.cs @@ -5,6 +5,5 @@ namespace MediaBrowser.Controller.Configuration {
public class ServerConfiguration : BaseApplicationConfiguration
{
- public string ImagesByNamePath { get; set; }
}
}
diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index 9bf7021e1..22ccfecc1 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -14,7 +14,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Progress;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.Controller
{
@@ -193,7 +192,7 @@ namespace MediaBrowser.Controller return RootFolder;
}
- return RootFolder.FindById(id);
+ return RootFolder.FindItemById(id);
}
/// <summary>
diff --git a/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs b/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs index dccdf57e1..200a2444d 100644 --- a/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs +++ b/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs @@ -137,7 +137,10 @@ namespace MediaBrowser.Controller.Resolvers }
}
- item.BackdropImagePaths = backdropFiles;
+ if (backdropFiles.Any())
+ {
+ item.BackdropImagePaths = backdropFiles;
+ }
}
protected virtual void PopulateLocalTrailers(T item, ItemResolveEventArgs args)
diff --git a/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs b/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs index 30bf3d367..de00adbef 100644 --- a/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs @@ -101,8 +101,24 @@ namespace MediaBrowser.Controller.Xml break;
case "TagLine":
- item.Tagline = reader.ReadString();
- break;
+ {
+ var list = (item.Taglines ?? new string[] { }).ToList();
+ var tagline = reader.ReadString();
+
+ if (!list.Contains(tagline))
+ {
+ list.Add(tagline);
+ }
+
+ item.Taglines = list;
+ break;
+ }
+
+ case "TagLines":
+ {
+ FetchFromTaglinesNode(reader.ReadSubtree(), item);
+ break;
+ }
case "ContentRating":
case "MPAARating":
@@ -138,7 +154,7 @@ namespace MediaBrowser.Controller.Xml case "Director":
{
var list = (item.People ?? new PersonInfo[] { }).ToList();
- list.AddRange(GetSplitValues(reader.ReadString(), '|').Select(v => new PersonInfo() { Name = v, PersonType = PersonType.Director }));
+ list.AddRange(GetSplitValues(reader.ReadString(), '|').Select(v => new PersonInfo() { Name = v, Type = "Director" }));
item.People = list;
break;
@@ -146,7 +162,7 @@ namespace MediaBrowser.Controller.Xml case "Writer":
{
var list = (item.People ?? new PersonInfo[] { }).ToList();
- list.AddRange(GetSplitValues(reader.ReadString(), '|').Select(v => new PersonInfo() { Name = v, PersonType = PersonType.Writer }));
+ list.AddRange(GetSplitValues(reader.ReadString(), '|').Select(v => new PersonInfo() { Name = v, Type = "Writer" }));
item.People = list;
break;
@@ -156,7 +172,7 @@ namespace MediaBrowser.Controller.Xml case "GuestStars":
{
var list = (item.People ?? new PersonInfo[] { }).ToList();
- list.AddRange(GetSplitValues(reader.ReadString(), '|').Select(v => new PersonInfo() { Name = v, PersonType = PersonType.Actor }));
+ list.AddRange(GetSplitValues(reader.ReadString(), '|').Select(v => new PersonInfo() { Name = v, Type = "Actor" }));
item.People = list;
break;
@@ -287,7 +303,7 @@ namespace MediaBrowser.Controller.Xml {
AudioStream stream = FetchMediaInfoAudio(reader.ReadSubtree());
- List<AudioStream> streams = item.AudioStreams.ToList();
+ List<AudioStream> streams = (item.AudioStreams ?? new AudioStream[] { }).ToList();
streams.Add(stream);
item.AudioStreams = streams;
@@ -322,6 +338,14 @@ namespace MediaBrowser.Controller.Xml {
switch (reader.Name)
{
+ case "Default":
+ stream.IsDefault = reader.ReadString() == "True";
+ break;
+
+ case "Forced":
+ stream.IsForced = reader.ReadString() == "True";
+ break;
+
case "BitRate":
stream.BitRate = reader.ReadIntSafe();
break;
@@ -343,40 +367,40 @@ namespace MediaBrowser.Controller.Xml case "dts-es":
case "dts-es matrix":
case "dts-es discrete":
- stream.AudioFormat = "DTS";
- stream.AudioProfile = "ES";
+ stream.Format = "DTS";
+ stream.Profile = "ES";
break;
case "dts-hd hra":
case "dts-hd high resolution":
- stream.AudioFormat = "DTS";
- stream.AudioProfile = "HRA";
+ stream.Format = "DTS";
+ stream.Profile = "HRA";
break;
case "dts ma":
case "dts-hd ma":
case "dts-hd master":
- stream.AudioFormat = "DTS";
- stream.AudioProfile = "MA";
+ stream.Format = "DTS";
+ stream.Profile = "MA";
break;
case "dolby digital":
case "dolby digital surround ex":
case "dolby surround":
- stream.AudioFormat = "AC-3";
+ stream.Format = "AC-3";
break;
case "dolby digital plus":
- stream.AudioFormat = "E-AC-3";
+ stream.Format = "E-AC-3";
break;
case "dolby truehd":
- stream.AudioFormat = "AC-3";
- stream.AudioProfile = "TrueHD";
+ stream.Format = "AC-3";
+ stream.Profile = "TrueHD";
break;
case "mp2":
- stream.AudioFormat = "MPEG Audio";
- stream.AudioProfile = "Layer 2";
+ stream.Format = "MPEG Audio";
+ stream.Profile = "Layer 2";
break;
case "other":
break;
default:
- stream.AudioFormat = codec;
+ stream.Format = codec;
break;
}
@@ -412,7 +436,7 @@ namespace MediaBrowser.Controller.Xml break;
case "BitRate":
- item.VideoBitRate = reader.ReadIntSafe();
+ item.BitRate = reader.ReadIntSafe();
break;
case "FrameRate":
@@ -424,14 +448,14 @@ namespace MediaBrowser.Controller.Xml break;
case "Duration":
- item.RunTimeInMilliseconds = reader.ReadIntSafe() * 60000;
+ item.RunTimeTicks = TimeSpan.FromMinutes(reader.ReadIntSafe()).Ticks;
break;
case "DurationSeconds":
int seconds = reader.ReadIntSafe();
if (seconds > 0)
{
- item.RunTimeInMilliseconds = seconds * 1000;
+ item.RunTimeTicks = TimeSpan.FromSeconds(seconds).Ticks;
}
break;
@@ -442,16 +466,16 @@ namespace MediaBrowser.Controller.Xml switch (videoCodec.ToLower())
{
case "sorenson h.263":
- item.VideoCodec = "Sorenson H263";
+ item.Codec = "Sorenson H263";
break;
case "h.262":
- item.VideoCodec = "MPEG-2 Video";
+ item.Codec = "MPEG-2 Video";
break;
case "h.264":
- item.VideoCodec = "AVC";
+ item.Codec = "AVC";
break;
default:
- item.VideoCodec = videoCodec;
+ item.Codec = videoCodec;
break;
}
@@ -499,6 +523,39 @@ namespace MediaBrowser.Controller.Xml item.Subtitles = list;
}
+ private void FetchFromTaglinesNode(XmlReader reader, T item)
+ {
+ List<string> list = (item.Taglines ?? new string[] { }).ToList();
+
+ reader.MoveToContent();
+
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "Tagline":
+ {
+ string val = reader.ReadString();
+
+ if (!string.IsNullOrWhiteSpace(val))
+ {
+ list.Add(val);
+ }
+ break;
+ }
+
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
+
+ item.Taglines = list;
+ }
+
private void FetchFromGenresNode(XmlReader reader, T item)
{
List<string> list = (item.Genres ?? new string[] { }).ToList();
@@ -668,27 +725,8 @@ namespace MediaBrowser.Controller.Xml break;
case "Type":
- {
- string type = reader.ReadString();
-
- if (type.Equals("Director", StringComparison.OrdinalIgnoreCase))
- {
- person.PersonType = PersonType.Director;
- }
- else if (type.Equals("Actor", StringComparison.OrdinalIgnoreCase))
- {
- person.PersonType = PersonType.Actor;
- }
- else if (type.Equals("Writer", StringComparison.OrdinalIgnoreCase))
- {
- person.PersonType = PersonType.Writer;
- }
- else if (type.Equals("Producer", StringComparison.OrdinalIgnoreCase))
- {
- person.PersonType = PersonType.Producer;
- }
- break;
- }
+ person.Type = reader.ReadString();
+ break;
case "Role":
person.Overview = reader.ReadString();
diff --git a/MediaBrowser.Model/DTO/ApiBaseItem.cs b/MediaBrowser.Model/DTO/ApiBaseItem.cs deleted file mode 100644 index eca45c9f8..000000000 --- a/MediaBrowser.Model/DTO/ApiBaseItem.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
-
-namespace MediaBrowser.Model.DTO
-{
- /// <summary>
- /// This is a concrete class that the UI can use to deserialize
- /// It is flat in the sense that it will be used regardless of the type of BaseItem involved
- /// </summary>
- public class ApiBaseItem : BaseItem
- {
- // Series properties
- public string Status { get; set; }
- public IEnumerable<DayOfWeek> AirDays { get; set; }
- public string AirTime { get; set; }
- }
-
- /// <summary>
- /// This is the full return object when requesting an Item
- /// </summary>
- public class BaseItemContainer<TItemType>
- where TItemType : BaseItem
- {
- public TItemType Item { get; set; }
-
- public UserItemData UserItemData { get; set; }
-
- public IEnumerable<BaseItemContainer<TItemType>> Children { get; set; }
-
- public bool IsFolder { get; set; }
-
- public Guid? ParentId { get; set; }
-
- public string Type { get; set; }
-
- public bool IsType(Type type)
- {
- return IsType(type.Name);
- }
-
- public bool IsType(string type)
- {
- return Type.Equals(type, StringComparison.OrdinalIgnoreCase);
- }
-
- public IEnumerable<BaseItemPerson> People { get; set; }
- public IEnumerable<BaseItemStudio> Studios { get; set; }
-
- /// <summary>
- /// If the item does not have a logo, this will hold the Id of the Parent that has one.
- /// </summary>
- public Guid? ParentLogoItemId { get; set; }
-
- public Guid? ParentBackdropItemId { get; set; }
-
- public int? ParentBackdropCount { get; set; }
- }
-
- /// <summary>
- /// This is strictly for convenience so the UI's don't have to use the verbose generic syntax of BaseItemWrapper<ApiBaseItem>
- /// </summary>
- public class ApiBaseItemContainer : BaseItemContainer<ApiBaseItem>
- {
- }
-}
diff --git a/MediaBrowser.Model/DTO/DTOBaseItem.cs b/MediaBrowser.Model/DTO/DTOBaseItem.cs new file mode 100644 index 000000000..6f41ac578 --- /dev/null +++ b/MediaBrowser.Model/DTO/DTOBaseItem.cs @@ -0,0 +1,86 @@ +using System;
+using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
+
+namespace MediaBrowser.Model.DTO
+{
+ public class DTOBaseItem : IHasProviderIds
+ {
+ public string Name { get; set; }
+ public Guid Id { get; set; }
+ public DateTime DateCreated { get; set; }
+
+ public string SortName { get; set; }
+ public DateTime? PremiereDate { get; set; }
+ public string Path { get; set; }
+ public string OfficialRating { get; set; }
+ public string Overview { get; set; }
+ public IEnumerable<string> Taglines { get; set; }
+
+ public IEnumerable<string> Genres { get; set; }
+
+ public string DisplayMediaType { get; set; }
+
+ public float? UserRating { get; set; }
+ public long? RunTimeTicks { get; set; }
+
+ public string AspectRatio { get; set; }
+ public int? ProductionYear { get; set; }
+
+ public int? IndexNumber { get; set; }
+
+ public string TrailerUrl { get; set; }
+
+ public Dictionary<string, string> ProviderIds { get; set; }
+
+ public bool HasBanner { get; set; }
+ public bool HasArt { get; set; }
+ public bool HasLogo { get; set; }
+ public bool HasThumb { get; set; }
+ public bool HasPrimaryImage { get; set; }
+
+ public int BackdropCount { get; set; }
+
+ public IEnumerable<DTOBaseItem> Children { get; set; }
+
+ public bool IsFolder { get; set; }
+
+ public Guid? ParentId { get; set; }
+
+ public string Type { get; set; }
+
+ public IEnumerable<BaseItemPerson> People { get; set; }
+ public IEnumerable<BaseItemStudio> Studios { get; set; }
+
+ /// <summary>
+ /// If the item does not have a logo, this will hold the Id of the Parent that has one.
+ /// </summary>
+ public Guid? ParentLogoItemId { get; set; }
+
+ /// <summary>
+ /// If the item does not have any backdrops, this will hold the Id of the Parent that has one.
+ /// </summary>
+ public Guid? ParentBackdropItemId { get; set; }
+ public int? ParentBackdropCount { get; set; }
+
+ public IEnumerable<Video> LocalTrailers { get; set; }
+ public int LocalTrailerCount { get; set; }
+
+ /// <summary>
+ /// User data for this item based on the user it's being requested for
+ /// </summary>
+ public UserItemData UserData { get; set; }
+
+ public ItemSpecialCounts SpecialCounts { get; set; }
+
+ public bool IsType(Type type)
+ {
+ return IsType(type.Name);
+ }
+
+ public bool IsType(string type)
+ {
+ return Type.Equals(type, StringComparison.OrdinalIgnoreCase);
+ }
+ }
+}
diff --git a/MediaBrowser.Model/DTO/IBNItem.cs b/MediaBrowser.Model/DTO/IBNItem.cs index 8a0620767..4b29cb2b1 100644 --- a/MediaBrowser.Model/DTO/IBNItem.cs +++ b/MediaBrowser.Model/DTO/IBNItem.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Model.DTO public class BaseItemPerson
{
public PersonInfo PersonInfo { get; set; }
- public string PrimaryImagePath { get; set; }
+ public bool HasImage { get; set; }
}
/// <summary>
@@ -33,6 +33,6 @@ namespace MediaBrowser.Model.DTO public class BaseItemStudio
{
public string Name { get; set; }
- public string PrimaryImagePath { get; set; }
+ public bool HasImage { get; set; }
}
}
diff --git a/MediaBrowser.Model/Entities/BaseItem.cs b/MediaBrowser.Model/Entities/BaseItem.cs index c9d5b936b..506c051c5 100644 --- a/MediaBrowser.Model/Entities/BaseItem.cs +++ b/MediaBrowser.Model/Entities/BaseItem.cs @@ -1,11 +1,10 @@ using System;
using System.Collections.Generic;
-using System.Runtime.Serialization;
-using MediaBrowser.Model.Users;
+using System.Linq;
namespace MediaBrowser.Model.Entities
{
- public abstract class BaseItem : BaseEntity
+ public abstract class BaseItem : BaseEntity, IHasProviderIds
{
public string SortName { get; set; }
@@ -16,25 +15,25 @@ namespace MediaBrowser.Model.Entities public string Path { get; set; }
- [IgnoreDataMember]
public Folder Parent { get; set; }
public string LogoImagePath { get; set; }
+
public string ArtImagePath { get; set; }
+
public string ThumbnailImagePath { get; set; }
+
public string BannerImagePath { get; set; }
public IEnumerable<string> BackdropImagePaths { get; set; }
public string OfficialRating { get; set; }
- [IgnoreDataMember]
public string CustomRating { get; set; }
public string Overview { get; set; }
- public string Tagline { get; set; }
+ public IEnumerable<string> Taglines { get; set; }
- [IgnoreDataMember]
public IEnumerable<PersonInfo> People { get; set; }
public IEnumerable<string> Studios { get; set; }
@@ -44,7 +43,7 @@ namespace MediaBrowser.Model.Entities public string DisplayMediaType { get; set; }
public float? UserRating { get; set; }
- public int? RunTimeInMilliseconds { get; set; }
+ public long? RunTimeTicks { get; set; }
public string AspectRatio { get; set; }
public int? ProductionYear { get; set; }
@@ -61,54 +60,52 @@ namespace MediaBrowser.Model.Entities public Dictionary<string, string> ProviderIds { get; set; }
- /// <summary>
- /// Gets a provider id
- /// </summary>
- public string GetProviderId(MetadataProviders provider)
- {
- return GetProviderId(provider.ToString());
- }
+ public Dictionary<Guid, UserItemData> UserData { get; set; }
- /// <summary>
- /// Gets a provider id
- /// </summary>
- public string GetProviderId(string name)
+ public UserItemData GetUserData(User user)
{
- if (ProviderIds == null)
+ if (UserData == null || !UserData.ContainsKey(user.Id))
{
return null;
}
- return ProviderIds[name];
+ return UserData[user.Id];
}
- /// <summary>
- /// Sets a provider id
- /// </summary>
- public void SetProviderId(string name, string value)
+ public void AddUserData(User user, UserItemData data)
{
- if (ProviderIds == null)
+ if (UserData == null)
{
- ProviderIds = new Dictionary<string, string>();
+ UserData = new Dictionary<Guid, UserItemData>();
}
- ProviderIds[name] = value;
+ UserData[user.Id] = data;
}
/// <summary>
- /// Sets a provider id
+ /// Determines if a given user has access to this item
/// </summary>
- public void SetProviderId(MetadataProviders provider, string value)
+ internal bool IsParentalAllowed(User user)
{
- SetProviderId(provider.ToString(), value);
+ return true;
}
/// <summary>
- /// Determines if a given user has access to this item
+ /// Finds an item by ID, recursively
/// </summary>
- internal bool IsParentalAllowed(User user)
+ public virtual BaseItem FindItemById(Guid id)
{
- return true;
+ if (Id == id)
+ {
+ return this;
+ }
+
+ if (LocalTrailers != null)
+ {
+ return LocalTrailers.FirstOrDefault(i => i.Id == id);
+ }
+
+ return null;
}
}
}
diff --git a/MediaBrowser.Model/Entities/Folder.cs b/MediaBrowser.Model/Entities/Folder.cs index 98f1d8229..105151f31 100644 --- a/MediaBrowser.Model/Entities/Folder.cs +++ b/MediaBrowser.Model/Entities/Folder.cs @@ -1,8 +1,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
-using System.Runtime.Serialization;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.Model.Entities
{
@@ -18,7 +16,6 @@ namespace MediaBrowser.Model.Entities }
}
- [IgnoreDataMember]
public BaseItem[] Children { get; set; }
/// <summary>
@@ -51,6 +48,23 @@ namespace MediaBrowser.Model.Entities }
/// <summary>
+ /// Since it can be slow to make all of these calculations at once, this method will provide a way to get them all back together
+ /// </summary>
+ public ItemSpecialCounts GetSpecialCounts(User user)
+ {
+ ItemSpecialCounts counts = new ItemSpecialCounts();
+
+ IEnumerable<BaseItem> recursiveChildren = GetParentalAllowedRecursiveChildren(user);
+
+ counts.RecentlyAddedItemCount = GetRecentlyAddedItems(recursiveChildren, user).Count();
+ counts.RecentlyAddedUnPlayedItemCount = GetRecentlyAddedUnplayedItems(recursiveChildren, user).Count();
+ counts.InProgressItemCount = GetInProgressItems(recursiveChildren, user).Count();
+ counts.WatchedPercentage = GetWatchedPercentage(recursiveChildren, user);
+
+ return counts;
+ }
+
+ /// <summary>
/// Finds all recursive items within a top-level parent that contain the given genre and are allowed for the current user
/// </summary>
public IEnumerable<BaseItem> GetItemsWithGenre(string genre, User user)
@@ -77,21 +91,30 @@ namespace MediaBrowser.Model.Entities /// <summary>
/// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user
/// </summary>
+ public IEnumerable<BaseItem> GetItemsWithPerson(string person, User user)
+ {
+ return GetParentalAllowedRecursiveChildren(user).Where(c =>
+ {
+ if (c.People != null)
+ {
+ return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase));
+ }
+
+ return false;
+ });
+ }
+
+ /// <summary>
+ /// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user
+ /// </summary>
/// <param name="personType">Specify this to limit results to a specific PersonType</param>
- public IEnumerable<BaseItem> GetItemsWithPerson(string person, PersonType? personType, User user)
+ public IEnumerable<BaseItem> GetItemsWithPerson(string person, string personType, User user)
{
return GetParentalAllowedRecursiveChildren(user).Where(c =>
{
if (c.People != null)
{
- if (personType.HasValue)
- {
- return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase) && p.PersonType == personType.Value);
- }
- else
- {
- return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase));
- }
+ return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase) && p.Type == personType);
}
return false;
@@ -103,9 +126,7 @@ namespace MediaBrowser.Model.Entities /// </summary>
public IEnumerable<BaseItem> GetRecentlyAddedItems(User user)
{
- DateTime now = DateTime.Now;
-
- return GetParentalAllowedRecursiveChildren(user).Where(i => !(i is Folder) && (now - i.DateCreated).TotalDays < user.RecentItemDays);
+ return GetRecentlyAddedItems(GetParentalAllowedRecursiveChildren(user), user);
}
/// <summary>
@@ -113,12 +134,7 @@ namespace MediaBrowser.Model.Entities /// </summary>
public IEnumerable<BaseItem> GetRecentlyAddedUnplayedItems(User user)
{
- return GetRecentlyAddedItems(user).Where(i =>
- {
- var userdata = user.GetItemData(i.Id);
-
- return userdata == null || userdata.PlayCount == 0;
- });
+ return GetRecentlyAddedUnplayedItems(GetParentalAllowedRecursiveChildren(user), user);
}
/// <summary>
@@ -126,45 +142,95 @@ namespace MediaBrowser.Model.Entities /// </summary>
public IEnumerable<BaseItem> GetInProgressItems(User user)
{
- return GetParentalAllowedRecursiveChildren(user).Where(i =>
+ return GetInProgressItems(GetParentalAllowedRecursiveChildren(user), user);
+ }
+
+ private static IEnumerable<BaseItem> GetRecentlyAddedItems(IEnumerable<BaseItem> itemSet, User user)
+ {
+ DateTime now = DateTime.Now;
+
+ return itemSet.Where(i => !(i is Folder) && (now - i.DateCreated).TotalDays < user.RecentItemDays);
+ }
+
+ private static IEnumerable<BaseItem> GetRecentlyAddedUnplayedItems(IEnumerable<BaseItem> itemSet, User user)
+ {
+ return GetRecentlyAddedItems(itemSet, user).Where(i =>
+ {
+ var userdata = i.GetUserData(user);
+
+ return userdata == null || userdata.PlayCount == 0;
+ });
+ }
+
+ private static IEnumerable<BaseItem> GetInProgressItems(IEnumerable<BaseItem> itemSet, User user)
+ {
+ return itemSet.Where(i =>
{
if (i is Folder)
{
return false;
}
- var userdata = user.GetItemData(i.Id);
+ var userdata = i.GetUserData(user);
- return userdata != null && userdata.PlaybackPosition.Ticks > 0;
+ return userdata != null && userdata.PlaybackPositionTicks > 0;
});
}
+ private static decimal GetWatchedPercentage(IEnumerable<BaseItem> itemSet, User user)
+ {
+ itemSet = itemSet.Where(i => !(i is Folder));
+
+ if (!itemSet.Any())
+ {
+ return 0;
+ }
+
+ decimal totalPercent = 0;
+
+ foreach (BaseItem item in itemSet)
+ {
+ UserItemData data = item.GetUserData(user);
+
+ if (data == null)
+ {
+ continue;
+ }
+
+ if (data.PlayCount > 0)
+ {
+ totalPercent += 100;
+ }
+ else if (data.PlaybackPositionTicks > 0 && item.RunTimeTicks.HasValue)
+ {
+ decimal itemPercent = data.PlaybackPositionTicks;
+ itemPercent /= item.RunTimeTicks.Value;
+ totalPercent += itemPercent;
+ }
+ }
+
+ return totalPercent / itemSet.Count();
+ }
+
/// <summary>
/// Finds an item by ID, recursively
/// </summary>
- public BaseItem FindById(Guid id)
+ public override BaseItem FindItemById(Guid id)
{
- if (Id == id)
+ var result = base.FindItemById(id);
+
+ if (result != null)
{
- return this;
+ return result;
}
foreach (BaseItem item in Children)
{
- var folder = item as Folder;
+ result = item.FindItemById(id);
- if (folder != null)
+ if (result != null)
{
- var foundItem = folder.FindById(id);
-
- if (foundItem != null)
- {
- return foundItem;
- }
- }
- else if (item.Id == id)
- {
- return item;
+ return result;
}
}
diff --git a/MediaBrowser.Model/Entities/IHasProviderIds.cs b/MediaBrowser.Model/Entities/IHasProviderIds.cs new file mode 100644 index 000000000..3406d618b --- /dev/null +++ b/MediaBrowser.Model/Entities/IHasProviderIds.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic;
+
+namespace MediaBrowser.Model.Entities
+{
+ /// <summary>
+ /// Since BaseItem and DTOBaseItem both have ProviderIds, this interface helps avoid code repition using extension methods
+ /// </summary>
+ public interface IHasProviderIds
+ {
+ Dictionary<string, string> ProviderIds { get; set; }
+ }
+
+ public static class IProviderIdsExtensions
+ {
+ /// <summary>
+ /// Gets a provider id
+ /// </summary>
+ public static string GetProviderId(this IHasProviderIds instance, MetadataProviders provider)
+ {
+ return instance.GetProviderId(provider.ToString());
+ }
+
+ /// <summary>
+ /// Gets a provider id
+ /// </summary>
+ public static string GetProviderId(this IHasProviderIds instance, string name)
+ {
+ if (instance.ProviderIds == null)
+ {
+ return null;
+ }
+
+ return instance.ProviderIds[name];
+ }
+
+ /// <summary>
+ /// Sets a provider id
+ /// </summary>
+ public static void SetProviderId(this IHasProviderIds instance, string name, string value)
+ {
+ if (instance.ProviderIds == null)
+ {
+ instance.ProviderIds = new Dictionary<string, string>();
+ }
+
+ instance.ProviderIds[name] = value;
+ }
+
+ /// <summary>
+ /// Sets a provider id
+ /// </summary>
+ public static void SetProviderId(this IHasProviderIds instance, MetadataProviders provider, string value)
+ {
+ instance.SetProviderId(provider.ToString(), value);
+ }
+ }
+}
diff --git a/MediaBrowser.Model/Entities/ItemSpecialCounts.cs b/MediaBrowser.Model/Entities/ItemSpecialCounts.cs new file mode 100644 index 000000000..9add9fe99 --- /dev/null +++ b/MediaBrowser.Model/Entities/ItemSpecialCounts.cs @@ -0,0 +1,14 @@ +
+namespace MediaBrowser.Model.Entities
+{
+ /// <summary>
+ /// Since it can be slow to collect this data. This class helps provide a way to calculate them all at once.
+ /// </summary>
+ public class ItemSpecialCounts
+ {
+ public int RecentlyAddedItemCount { get; set; }
+ public int RecentlyAddedUnPlayedItemCount { get; set; }
+ public int InProgressItemCount { get; set; }
+ public decimal WatchedPercentage { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Entities/Person.cs b/MediaBrowser.Model/Entities/Person.cs index e85f8a905..2bd383802 100644 --- a/MediaBrowser.Model/Entities/Person.cs +++ b/MediaBrowser.Model/Entities/Person.cs @@ -15,20 +15,11 @@ namespace MediaBrowser.Model.Entities {
public string Name { get; set; }
public string Overview { get; set; }
- public PersonType PersonType { get; set; }
+ public string Type { get; set; }
public override string ToString()
{
return Name;
}
}
-
- public enum PersonType
- {
- Other,
- Actor,
- Director,
- Writer,
- Producer
- }
}
diff --git a/MediaBrowser.Model/Entities/User.cs b/MediaBrowser.Model/Entities/User.cs new file mode 100644 index 000000000..921727631 --- /dev/null +++ b/MediaBrowser.Model/Entities/User.cs @@ -0,0 +1,15 @@ +
+namespace MediaBrowser.Model.Entities
+{
+ public class User : BaseEntity
+ {
+ public string MaxParentalRating { get; set; }
+
+ public int RecentItemDays { get; set; }
+
+ public User()
+ {
+ RecentItemDays = 14;
+ }
+ }
+}
diff --git a/MediaBrowser.Model/Users/UserItemData.cs b/MediaBrowser.Model/Entities/UserItemData.cs index 9782711b0..817cf640e 100644 --- a/MediaBrowser.Model/Users/UserItemData.cs +++ b/MediaBrowser.Model/Entities/UserItemData.cs @@ -1,13 +1,12 @@ -using MediaBrowser.Model.Entities;
-using System;
+using System;
-namespace MediaBrowser.Model.Users
+namespace MediaBrowser.Model.Entities
{
public class UserItemData
{
public UserItemRating Rating { get; set; }
- public TimeSpan PlaybackPosition { get; set; }
+ public long PlaybackPositionTicks { get; set; }
public int PlayCount { get; set; }
}
diff --git a/MediaBrowser.Model/Entities/Video.cs b/MediaBrowser.Model/Entities/Video.cs index b99cacd13..688226634 100644 --- a/MediaBrowser.Model/Entities/Video.cs +++ b/MediaBrowser.Model/Entities/Video.cs @@ -6,28 +6,27 @@ namespace MediaBrowser.Model.Entities {
public VideoType VideoType { get; set; }
- private IEnumerable<string> _Subtitles = new string[] { };
- public IEnumerable<string> Subtitles { get { return _Subtitles; } set { _Subtitles = value; } }
-
- private IEnumerable<AudioStream> _AudioStreams = new AudioStream[] { };
- public IEnumerable<AudioStream> AudioStreams { get { return _AudioStreams; } set { _AudioStreams = value; } }
+ public IEnumerable<string> Subtitles { get; set; }
+ public IEnumerable<AudioStream> AudioStreams { get; set; }
public int Height { get; set; }
public int Width { get; set; }
public string ScanType { get; set; }
public string FrameRate { get; set; }
- public int VideoBitRate { get; set; }
- public string VideoCodec { get; set; }
+ public int BitRate { get; set; }
+ public string Codec { get; set; }
}
public class AudioStream
{
- public string AudioFormat { get; set; }
- public string AudioProfile { get; set; }
+ public string Format { get; set; }
+ public string Profile { get; set; }
public string Language { get; set; }
public int BitRate { get; set; }
public int Channels { get; set; }
public int SampleRate { get; set; }
+ public bool IsDefault { get; set; }
+ public bool IsForced { get; set; }
}
public enum VideoType
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 14c7843ed..77f4403d8 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -32,7 +32,7 @@ <WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Compile Include="DTO\ApiBaseItem.cs" />
+ <Compile Include="DTO\DTOBaseItem.cs" />
<Compile Include="Entities\Audio.cs" />
<Compile Include="Entities\BaseEntity.cs" />
<Compile Include="Entities\BaseItem.cs" />
@@ -40,6 +40,8 @@ <Compile Include="Entities\Folder.cs" />
<Compile Include="Entities\Genre.cs" />
<Compile Include="Entities\ImageType.cs" />
+ <Compile Include="Entities\IHasProviderIds.cs" />
+ <Compile Include="Entities\ItemSpecialCounts.cs" />
<Compile Include="Entities\MetadataProviders.cs" />
<Compile Include="Entities\Person.cs" />
<Compile Include="Entities\Studio.cs" />
@@ -49,8 +51,8 @@ <Compile Include="DTO\PluginInfo.cs" />
<Compile Include="Progress\TaskProgress.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Users\User.cs" />
- <Compile Include="Users\UserItemData.cs" />
+ <Compile Include="Entities\User.cs" />
+ <Compile Include="Entities\UserItemData.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/MediaBrowser.Model/Users/User.cs b/MediaBrowser.Model/Users/User.cs deleted file mode 100644 index dcef153c5..000000000 --- a/MediaBrowser.Model/Users/User.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.Entities;
-
-namespace MediaBrowser.Model.Users
-{
- public class User : BaseEntity
- {
- public string MaxParentalRating { get; set; }
-
- private Dictionary<Guid, UserItemData> _ItemData = new Dictionary<Guid, UserItemData>();
- public Dictionary<Guid, UserItemData> ItemData { get { return _ItemData; } set { _ItemData = value; } }
-
- public int RecentItemDays { get; set; }
-
- public User()
- {
- RecentItemDays = 14;
- }
-
- /// <summary>
- /// Gets user data for an item, if there is any
- /// </summary>
- public UserItemData GetItemData(Guid itemId)
- {
- if (ItemData.ContainsKey(itemId))
- {
- return ItemData[itemId];
- }
-
- return null;
- }
- }
-}
diff --git a/MediaBrowser.Movies/Entities/Movie.cs b/MediaBrowser.Movies/Entities/Movie.cs index 25fb1327c..213615816 100644 --- a/MediaBrowser.Movies/Entities/Movie.cs +++ b/MediaBrowser.Movies/Entities/Movie.cs @@ -1,12 +1,10 @@ using System.Collections.Generic;
-using System.Runtime.Serialization;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Movies.Entities
{
public class Movie : Video
{
- [IgnoreDataMember]
public IEnumerable<Video> SpecialFeatures { get; set; }
}
}
diff --git a/MediaBrowser.TV/Entities/Season.cs b/MediaBrowser.TV/Entities/Season.cs index 08c1fcac1..1618feecc 100644 --- a/MediaBrowser.TV/Entities/Season.cs +++ b/MediaBrowser.TV/Entities/Season.cs @@ -9,7 +9,6 @@ namespace MediaBrowser.TV.Entities /// <summary>
/// Store these to reduce disk access in Episode Resolver
/// </summary>
- [IgnoreDataMember]
internal IEnumerable<string> MetadataFiles { get; set; }
}
}
diff --git a/MediaBrowser.TV/Metadata/SeriesXmlParser.cs b/MediaBrowser.TV/Metadata/SeriesXmlParser.cs index 57b8047f8..8cb828355 100644 --- a/MediaBrowser.TV/Metadata/SeriesXmlParser.cs +++ b/MediaBrowser.TV/Metadata/SeriesXmlParser.cs @@ -71,7 +71,7 @@ namespace MediaBrowser.TV.Metadata int runtime;
if (int.TryParse(text.Split(' ')[0], out runtime))
{
- item.RunTimeInMilliseconds = runtime * 60000;
+ item.RunTimeTicks = TimeSpan.FromMinutes(runtime).Ticks;
}
}
break;
|
