mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-06-23 15:30:56 -04:00
Added a completely separate DTOBaseItem to remove the ApiBaseItemWrapper mess and shrink json output size.
This commit is contained in:
parent
f32f000298
commit
7835d690a1
@ -6,7 +6,6 @@ using MediaBrowser.Common.Configuration;
|
|||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.DTO;
|
using MediaBrowser.Model.DTO;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Api
|
namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
@ -22,72 +21,91 @@ namespace MediaBrowser.Api
|
|||||||
return Kernel.Instance.GetItemById(guid);
|
return Kernel.Instance.GetItemById(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static DTOBaseItem GetDTOBaseItem(BaseItem item, User user,
|
||||||
/// Takes a BaseItem and returns the actual object that will be serialized by the api
|
bool includeChildren = true,
|
||||||
/// </summary>
|
bool includePeople = true)
|
||||||
public static BaseItemContainer<BaseItem> GetSerializationObject(BaseItem item, bool includeChildren, Guid userId)
|
|
||||||
{
|
{
|
||||||
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
DTOBaseItem dto = new DTOBaseItem();
|
||||||
|
|
||||||
BaseItemContainer<BaseItem> wrapper = new BaseItemContainer<BaseItem>()
|
dto.AspectRatio = item.AspectRatio;
|
||||||
{
|
dto.BackdropCount = item.BackdropImagePaths == null ? 0 : item.BackdropImagePaths.Count();
|
||||||
Item = item,
|
dto.DateCreated = item.DateCreated;
|
||||||
UserItemData = user.GetItemData(item.Id),
|
dto.DisplayMediaType = item.DisplayMediaType;
|
||||||
Type = item.GetType().Name,
|
dto.Genres = item.Genres;
|
||||||
IsFolder = (item is Folder)
|
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 (string.IsNullOrEmpty(item.LogoImagePath))
|
// If there are no backdrops, indicate what parent has them in case the UI wants to allow inheritance
|
||||||
{
|
if (dto.BackdropCount == 0)
|
||||||
wrapper.ParentLogoItemId = GetParentLogoItemId(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.BackdropImagePaths == null || !item.BackdropImagePaths.Any())
|
|
||||||
{
|
{
|
||||||
int backdropCount;
|
int backdropCount;
|
||||||
wrapper.ParentBackdropItemId = GetParentBackdropItemId(item, out backdropCount);
|
dto.ParentBackdropItemId = GetParentBackdropItemId(item, out backdropCount);
|
||||||
wrapper.ParentBackdropCount = backdropCount;
|
dto.ParentBackdropCount = backdropCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.Parent != null)
|
if (item.Parent != null)
|
||||||
{
|
{
|
||||||
wrapper.ParentId = item.Parent.Id;
|
dto.ParentId = item.Parent.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there is no logo, indicate what parent has one in case the UI wants to allow inheritance
|
||||||
|
if (!dto.HasLogo)
|
||||||
|
{
|
||||||
|
dto.ParentLogoItemId = GetParentLogoItemId(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
dto.Path = item.Path;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
dto.UserData = item.GetUserData(user);
|
||||||
|
|
||||||
|
AttachStudios(dto, item);
|
||||||
|
|
||||||
if (includeChildren)
|
if (includeChildren)
|
||||||
{
|
{
|
||||||
var folder = item as Folder;
|
AttachChildren(dto, item, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includePeople)
|
||||||
|
{
|
||||||
|
AttachPeople(dto, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
Folder folder = item as Folder;
|
||||||
|
|
||||||
if (folder != null)
|
if (folder != null)
|
||||||
{
|
{
|
||||||
wrapper.Children = folder.GetParentalAllowedChildren(user).Select(c => GetSerializationObject(c, false, userId));
|
dto.SpecialCounts = folder.GetSpecialCounts(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach People by transforming them into BaseItemPerson (DTO)
|
return dto;
|
||||||
if (item.People != null)
|
}
|
||||||
|
|
||||||
|
private static void AttachStudios(DTOBaseItem dto, BaseItem item)
|
||||||
{
|
{
|
||||||
wrapper.People = item.People.Select(p =>
|
|
||||||
{
|
|
||||||
BaseItemPerson baseItemPerson = new BaseItemPerson();
|
|
||||||
|
|
||||||
baseItemPerson.PersonInfo = p;
|
|
||||||
|
|
||||||
Person ibnObject = Kernel.Instance.ItemController.GetPerson(p.Name);
|
|
||||||
|
|
||||||
if (ibnObject != null)
|
|
||||||
{
|
|
||||||
baseItemPerson.PrimaryImagePath = ibnObject.PrimaryImagePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
return baseItemPerson;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attach Studios by transforming them into BaseItemStudio (DTO)
|
// Attach Studios by transforming them into BaseItemStudio (DTO)
|
||||||
if (item.Studios != null)
|
if (item.Studios != null)
|
||||||
{
|
{
|
||||||
wrapper.Studios = item.Studios.Select(s =>
|
dto.Studios = item.Studios.Select(s =>
|
||||||
{
|
{
|
||||||
BaseItemStudio baseItemStudio = new BaseItemStudio();
|
BaseItemStudio baseItemStudio = new BaseItemStudio();
|
||||||
|
|
||||||
@ -97,14 +115,47 @@ namespace MediaBrowser.Api
|
|||||||
|
|
||||||
if (ibnObject != null)
|
if (ibnObject != null)
|
||||||
{
|
{
|
||||||
baseItemStudio.PrimaryImagePath = ibnObject.PrimaryImagePath;
|
baseItemStudio.HasImage = !string.IsNullOrEmpty(ibnObject.PrimaryImagePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseItemStudio;
|
return baseItemStudio;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return wrapper;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
private static Guid? GetParentBackdropItemId(BaseItem item, out int backdropCount)
|
||||||
|
@ -5,7 +5,6 @@ using MediaBrowser.Common.Net.Handlers;
|
|||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.DTO;
|
using MediaBrowser.Model.DTO;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using MediaBrowser.Common.Net.Handlers;
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.DTO;
|
using MediaBrowser.Model.DTO;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
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"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
||||||
|
|
||||||
BaseItem item = ItemToSerialize;
|
BaseItem item = ItemToSerialize;
|
||||||
|
|
||||||
@ -18,7 +21,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ApiService.GetSerializationObject(item, true, userId);
|
return ApiService.GetDTOBaseItem(item, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual BaseItem ItemToSerialize
|
protected virtual BaseItem ItemToSerialize
|
||||||
|
@ -5,18 +5,18 @@ using MediaBrowser.Common.Net.Handlers;
|
|||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.DTO;
|
using MediaBrowser.Model.DTO;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
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 ItemsToSerialize.Select(i =>
|
||||||
{
|
{
|
||||||
return ApiService.GetSerializationObject(i, false, UserId);
|
return ApiService.GetDTOBaseItem(i, user, includeChildren: false, includePeople: false);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ using MediaBrowser.Common.Net.Handlers;
|
|||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.DTO;
|
using MediaBrowser.Model.DTO;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MediaBrowser.Common.Net.Handlers;
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.Users;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
|
@ -48,11 +48,11 @@ namespace MediaBrowser.Api.HttpHandlers
|
|||||||
return true;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
|||||||
|
|
||||||
private string GetAudioArguments(string outputFormat)
|
private string GetAudioArguments(string outputFormat)
|
||||||
{
|
{
|
||||||
AudioStream audioStream = LibraryItem.AudioStreams.FirstOrDefault();
|
AudioStream audioStream = (LibraryItem.AudioStreams ?? new AudioStream[] { }).FirstOrDefault();
|
||||||
|
|
||||||
if (audioStream == null)
|
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;
|
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;
|
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;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ using MediaBrowser.Common.Net.Handlers;
|
|||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.DTO;
|
using MediaBrowser.Model.DTO;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
|
@ -1,16 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.DTO;
|
using MediaBrowser.Model.DTO;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.ApiInteraction
|
namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
public class ApiClient : IDisposable
|
public class ApiClient : IDisposable
|
||||||
{
|
{
|
||||||
|
public ApiClient(HttpClientHandler handler)
|
||||||
|
{
|
||||||
|
handler.AutomaticDecompression = DecompressionMethods.Deflate;
|
||||||
|
|
||||||
|
HttpClient = new HttpClient(handler);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the server host name (myserver or 192.168.x.x)
|
/// Gets or sets the server host name (myserver or 192.168.x.x)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -32,7 +39,7 @@ namespace MediaBrowser.ApiInteraction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHttpClient HttpClient { get; set; }
|
public HttpClient HttpClient { get; private set; }
|
||||||
public IJsonSerializer JsonSerializer { get; set; }
|
public IJsonSerializer JsonSerializer { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -84,26 +91,26 @@ namespace MediaBrowser.ApiInteraction
|
|||||||
/// <summary>
|
/// <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.
|
/// 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>
|
/// </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="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="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="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="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>
|
/// <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;
|
Guid? backdropItemId = null;
|
||||||
int backdropCount = 0;
|
int backdropCount = 0;
|
||||||
|
|
||||||
if (itemWrapper.Item.BackdropImagePaths == null || !itemWrapper.Item.BackdropImagePaths.Any())
|
if (item.BackdropCount == 0)
|
||||||
{
|
{
|
||||||
backdropItemId = itemWrapper.ParentBackdropItemId;
|
backdropItemId = item.ParentBackdropItemId;
|
||||||
backdropCount = itemWrapper.ParentBackdropCount ?? 0;
|
backdropCount = item.ParentBackdropCount ?? 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
backdropItemId = itemWrapper.Item.Id;
|
backdropItemId = item.Id;
|
||||||
backdropCount = itemWrapper.Item.BackdropImagePaths.Count();
|
backdropCount = item.BackdropCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backdropItemId == null)
|
if (backdropItemId == null)
|
||||||
@ -124,15 +131,15 @@ namespace MediaBrowser.ApiInteraction
|
|||||||
/// <summary>
|
/// <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.
|
/// 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>
|
/// </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="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="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="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="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>
|
/// <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)
|
if (logoItemId.HasValue)
|
||||||
{
|
{
|
||||||
@ -153,7 +160,7 @@ namespace MediaBrowser.ApiInteraction
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a BaseItem
|
/// Gets a BaseItem
|
||||||
/// </summary>
|
/// </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();
|
string url = ApiUrl + "/item?userId=" + userId.ToString();
|
||||||
|
|
||||||
@ -164,7 +171,7 @@ namespace MediaBrowser.ApiInteraction
|
|||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
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>
|
/// <summary>
|
||||||
/// Gets all items that contain a given Year
|
/// Gets all items that contain a given Year
|
||||||
/// </summary>
|
/// </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;
|
string url = ApiUrl + "/itemlist?listtype=itemswithyear&userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<ApiBaseItemContainer>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all items that contain a given Genre
|
/// Gets all items that contain a given Genre
|
||||||
/// </summary>
|
/// </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;
|
string url = ApiUrl + "/itemlist?listtype=itemswithgenre&userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<ApiBaseItemContainer>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all items that contain a given Person
|
/// Gets all items that contain a given Person
|
||||||
/// </summary>
|
/// </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;
|
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))
|
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>
|
/// <summary>
|
||||||
/// Gets all items that contain a given Studio
|
/// Gets all items that contain a given Studio
|
||||||
/// </summary>
|
/// </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;
|
string url = ApiUrl + "/itemlist?listtype=itemswithstudio&userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<ApiBaseItemContainer>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -40,7 +40,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ApiClient.cs" />
|
<Compile Include="ApiClient.cs" />
|
||||||
<Compile Include="IHttpClient.cs" />
|
|
||||||
<Compile Include="IJsonSerializer.cs" />
|
<Compile Include="IJsonSerializer.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -5,6 +5,5 @@ namespace MediaBrowser.Controller.Configuration
|
|||||||
{
|
{
|
||||||
public class ServerConfiguration : BaseApplicationConfiguration
|
public class ServerConfiguration : BaseApplicationConfiguration
|
||||||
{
|
{
|
||||||
public string ImagesByNamePath { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ using MediaBrowser.Controller.Library;
|
|||||||
using MediaBrowser.Controller.Resolvers;
|
using MediaBrowser.Controller.Resolvers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Progress;
|
using MediaBrowser.Model.Progress;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller
|
namespace MediaBrowser.Controller
|
||||||
{
|
{
|
||||||
@ -193,7 +192,7 @@ namespace MediaBrowser.Controller
|
|||||||
return RootFolder;
|
return RootFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RootFolder.FindById(id);
|
return RootFolder.FindItemById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -137,8 +137,11 @@ namespace MediaBrowser.Controller.Resolvers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (backdropFiles.Any())
|
||||||
|
{
|
||||||
item.BackdropImagePaths = backdropFiles;
|
item.BackdropImagePaths = backdropFiles;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void PopulateLocalTrailers(T item, ItemResolveEventArgs args)
|
protected virtual void PopulateLocalTrailers(T item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
|
@ -101,8 +101,24 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "TagLine":
|
case "TagLine":
|
||||||
item.Tagline = reader.ReadString();
|
{
|
||||||
|
var list = (item.Taglines ?? new string[] { }).ToList();
|
||||||
|
var tagline = reader.ReadString();
|
||||||
|
|
||||||
|
if (!list.Contains(tagline))
|
||||||
|
{
|
||||||
|
list.Add(tagline);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.Taglines = list;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "TagLines":
|
||||||
|
{
|
||||||
|
FetchFromTaglinesNode(reader.ReadSubtree(), item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "ContentRating":
|
case "ContentRating":
|
||||||
case "MPAARating":
|
case "MPAARating":
|
||||||
@ -138,7 +154,7 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
case "Director":
|
case "Director":
|
||||||
{
|
{
|
||||||
var list = (item.People ?? new PersonInfo[] { }).ToList();
|
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;
|
item.People = list;
|
||||||
break;
|
break;
|
||||||
@ -146,7 +162,7 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
case "Writer":
|
case "Writer":
|
||||||
{
|
{
|
||||||
var list = (item.People ?? new PersonInfo[] { }).ToList();
|
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;
|
item.People = list;
|
||||||
break;
|
break;
|
||||||
@ -156,7 +172,7 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
case "GuestStars":
|
case "GuestStars":
|
||||||
{
|
{
|
||||||
var list = (item.People ?? new PersonInfo[] { }).ToList();
|
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;
|
item.People = list;
|
||||||
break;
|
break;
|
||||||
@ -287,7 +303,7 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
{
|
{
|
||||||
AudioStream stream = FetchMediaInfoAudio(reader.ReadSubtree());
|
AudioStream stream = FetchMediaInfoAudio(reader.ReadSubtree());
|
||||||
|
|
||||||
List<AudioStream> streams = item.AudioStreams.ToList();
|
List<AudioStream> streams = (item.AudioStreams ?? new AudioStream[] { }).ToList();
|
||||||
streams.Add(stream);
|
streams.Add(stream);
|
||||||
item.AudioStreams = streams;
|
item.AudioStreams = streams;
|
||||||
|
|
||||||
@ -322,6 +338,14 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
{
|
{
|
||||||
switch (reader.Name)
|
switch (reader.Name)
|
||||||
{
|
{
|
||||||
|
case "Default":
|
||||||
|
stream.IsDefault = reader.ReadString() == "True";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Forced":
|
||||||
|
stream.IsForced = reader.ReadString() == "True";
|
||||||
|
break;
|
||||||
|
|
||||||
case "BitRate":
|
case "BitRate":
|
||||||
stream.BitRate = reader.ReadIntSafe();
|
stream.BitRate = reader.ReadIntSafe();
|
||||||
break;
|
break;
|
||||||
@ -343,40 +367,40 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
case "dts-es":
|
case "dts-es":
|
||||||
case "dts-es matrix":
|
case "dts-es matrix":
|
||||||
case "dts-es discrete":
|
case "dts-es discrete":
|
||||||
stream.AudioFormat = "DTS";
|
stream.Format = "DTS";
|
||||||
stream.AudioProfile = "ES";
|
stream.Profile = "ES";
|
||||||
break;
|
break;
|
||||||
case "dts-hd hra":
|
case "dts-hd hra":
|
||||||
case "dts-hd high resolution":
|
case "dts-hd high resolution":
|
||||||
stream.AudioFormat = "DTS";
|
stream.Format = "DTS";
|
||||||
stream.AudioProfile = "HRA";
|
stream.Profile = "HRA";
|
||||||
break;
|
break;
|
||||||
case "dts ma":
|
case "dts ma":
|
||||||
case "dts-hd ma":
|
case "dts-hd ma":
|
||||||
case "dts-hd master":
|
case "dts-hd master":
|
||||||
stream.AudioFormat = "DTS";
|
stream.Format = "DTS";
|
||||||
stream.AudioProfile = "MA";
|
stream.Profile = "MA";
|
||||||
break;
|
break;
|
||||||
case "dolby digital":
|
case "dolby digital":
|
||||||
case "dolby digital surround ex":
|
case "dolby digital surround ex":
|
||||||
case "dolby surround":
|
case "dolby surround":
|
||||||
stream.AudioFormat = "AC-3";
|
stream.Format = "AC-3";
|
||||||
break;
|
break;
|
||||||
case "dolby digital plus":
|
case "dolby digital plus":
|
||||||
stream.AudioFormat = "E-AC-3";
|
stream.Format = "E-AC-3";
|
||||||
break;
|
break;
|
||||||
case "dolby truehd":
|
case "dolby truehd":
|
||||||
stream.AudioFormat = "AC-3";
|
stream.Format = "AC-3";
|
||||||
stream.AudioProfile = "TrueHD";
|
stream.Profile = "TrueHD";
|
||||||
break;
|
break;
|
||||||
case "mp2":
|
case "mp2":
|
||||||
stream.AudioFormat = "MPEG Audio";
|
stream.Format = "MPEG Audio";
|
||||||
stream.AudioProfile = "Layer 2";
|
stream.Profile = "Layer 2";
|
||||||
break;
|
break;
|
||||||
case "other":
|
case "other":
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
stream.AudioFormat = codec;
|
stream.Format = codec;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,7 +436,7 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "BitRate":
|
case "BitRate":
|
||||||
item.VideoBitRate = reader.ReadIntSafe();
|
item.BitRate = reader.ReadIntSafe();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "FrameRate":
|
case "FrameRate":
|
||||||
@ -424,14 +448,14 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "Duration":
|
case "Duration":
|
||||||
item.RunTimeInMilliseconds = reader.ReadIntSafe() * 60000;
|
item.RunTimeTicks = TimeSpan.FromMinutes(reader.ReadIntSafe()).Ticks;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "DurationSeconds":
|
case "DurationSeconds":
|
||||||
int seconds = reader.ReadIntSafe();
|
int seconds = reader.ReadIntSafe();
|
||||||
if (seconds > 0)
|
if (seconds > 0)
|
||||||
{
|
{
|
||||||
item.RunTimeInMilliseconds = seconds * 1000;
|
item.RunTimeTicks = TimeSpan.FromSeconds(seconds).Ticks;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -442,16 +466,16 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
switch (videoCodec.ToLower())
|
switch (videoCodec.ToLower())
|
||||||
{
|
{
|
||||||
case "sorenson h.263":
|
case "sorenson h.263":
|
||||||
item.VideoCodec = "Sorenson H263";
|
item.Codec = "Sorenson H263";
|
||||||
break;
|
break;
|
||||||
case "h.262":
|
case "h.262":
|
||||||
item.VideoCodec = "MPEG-2 Video";
|
item.Codec = "MPEG-2 Video";
|
||||||
break;
|
break;
|
||||||
case "h.264":
|
case "h.264":
|
||||||
item.VideoCodec = "AVC";
|
item.Codec = "AVC";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
item.VideoCodec = videoCodec;
|
item.Codec = videoCodec;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,6 +523,39 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
item.Subtitles = list;
|
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)
|
private void FetchFromGenresNode(XmlReader reader, T item)
|
||||||
{
|
{
|
||||||
List<string> list = (item.Genres ?? new string[] { }).ToList();
|
List<string> list = (item.Genres ?? new string[] { }).ToList();
|
||||||
@ -668,27 +725,8 @@ namespace MediaBrowser.Controller.Xml
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "Type":
|
case "Type":
|
||||||
{
|
person.Type = reader.ReadString();
|
||||||
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;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case "Role":
|
case "Role":
|
||||||
person.Overview = reader.ReadString();
|
person.Overview = reader.ReadString();
|
||||||
|
@ -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>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
86
MediaBrowser.Model/DTO/DTOBaseItem.cs
Normal file
86
MediaBrowser.Model/DTO/DTOBaseItem.cs
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ namespace MediaBrowser.Model.DTO
|
|||||||
public class BaseItemPerson
|
public class BaseItemPerson
|
||||||
{
|
{
|
||||||
public PersonInfo PersonInfo { get; set; }
|
public PersonInfo PersonInfo { get; set; }
|
||||||
public string PrimaryImagePath { get; set; }
|
public bool HasImage { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -33,6 +33,6 @@ namespace MediaBrowser.Model.DTO
|
|||||||
public class BaseItemStudio
|
public class BaseItemStudio
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string PrimaryImagePath { get; set; }
|
public bool HasImage { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.Serialization;
|
using System.Linq;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Model.Entities
|
namespace MediaBrowser.Model.Entities
|
||||||
{
|
{
|
||||||
public abstract class BaseItem : BaseEntity
|
public abstract class BaseItem : BaseEntity, IHasProviderIds
|
||||||
{
|
{
|
||||||
public string SortName { get; set; }
|
public string SortName { get; set; }
|
||||||
|
|
||||||
@ -16,25 +15,25 @@ namespace MediaBrowser.Model.Entities
|
|||||||
|
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
|
||||||
[IgnoreDataMember]
|
|
||||||
public Folder Parent { get; set; }
|
public Folder Parent { get; set; }
|
||||||
|
|
||||||
public string LogoImagePath { get; set; }
|
public string LogoImagePath { get; set; }
|
||||||
|
|
||||||
public string ArtImagePath { get; set; }
|
public string ArtImagePath { get; set; }
|
||||||
|
|
||||||
public string ThumbnailImagePath { get; set; }
|
public string ThumbnailImagePath { get; set; }
|
||||||
|
|
||||||
public string BannerImagePath { get; set; }
|
public string BannerImagePath { get; set; }
|
||||||
|
|
||||||
public IEnumerable<string> BackdropImagePaths { get; set; }
|
public IEnumerable<string> BackdropImagePaths { get; set; }
|
||||||
|
|
||||||
public string OfficialRating { get; set; }
|
public string OfficialRating { get; set; }
|
||||||
|
|
||||||
[IgnoreDataMember]
|
|
||||||
public string CustomRating { get; set; }
|
public string CustomRating { get; set; }
|
||||||
|
|
||||||
public string Overview { 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<PersonInfo> People { get; set; }
|
||||||
|
|
||||||
public IEnumerable<string> Studios { get; set; }
|
public IEnumerable<string> Studios { get; set; }
|
||||||
@ -44,7 +43,7 @@ namespace MediaBrowser.Model.Entities
|
|||||||
public string DisplayMediaType { get; set; }
|
public string DisplayMediaType { get; set; }
|
||||||
|
|
||||||
public float? UserRating { get; set; }
|
public float? UserRating { get; set; }
|
||||||
public int? RunTimeInMilliseconds { get; set; }
|
public long? RunTimeTicks { get; set; }
|
||||||
|
|
||||||
public string AspectRatio { get; set; }
|
public string AspectRatio { get; set; }
|
||||||
public int? ProductionYear { get; set; }
|
public int? ProductionYear { get; set; }
|
||||||
@ -61,46 +60,26 @@ namespace MediaBrowser.Model.Entities
|
|||||||
|
|
||||||
public Dictionary<string, string> ProviderIds { get; set; }
|
public Dictionary<string, string> ProviderIds { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
public Dictionary<Guid, UserItemData> UserData { get; set; }
|
||||||
/// Gets a provider id
|
|
||||||
/// </summary>
|
|
||||||
public string GetProviderId(MetadataProviders provider)
|
|
||||||
{
|
|
||||||
return GetProviderId(provider.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
public UserItemData GetUserData(User user)
|
||||||
/// Gets a provider id
|
|
||||||
/// </summary>
|
|
||||||
public string GetProviderId(string name)
|
|
||||||
{
|
{
|
||||||
if (ProviderIds == null)
|
if (UserData == null || !UserData.ContainsKey(user.Id))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProviderIds[name];
|
return UserData[user.Id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public void AddUserData(User user, UserItemData data)
|
||||||
/// Sets a provider id
|
|
||||||
/// </summary>
|
|
||||||
public void SetProviderId(string name, string value)
|
|
||||||
{
|
{
|
||||||
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
|
|
||||||
/// </summary>
|
|
||||||
public void SetProviderId(MetadataProviders provider, string value)
|
|
||||||
{
|
|
||||||
SetProviderId(provider.ToString(), value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -110,5 +89,23 @@ namespace MediaBrowser.Model.Entities
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds an item by ID, recursively
|
||||||
|
/// </summary>
|
||||||
|
public virtual BaseItem FindItemById(Guid id)
|
||||||
|
{
|
||||||
|
if (Id == id)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LocalTrailers != null)
|
||||||
|
{
|
||||||
|
return LocalTrailers.FirstOrDefault(i => i.Id == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Model.Entities
|
namespace MediaBrowser.Model.Entities
|
||||||
{
|
{
|
||||||
@ -18,7 +16,6 @@ namespace MediaBrowser.Model.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
|
||||||
public BaseItem[] Children { get; set; }
|
public BaseItem[] Children { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -50,6 +47,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>
|
/// <summary>
|
||||||
/// Finds all recursive items within a top-level parent that contain the given genre and are allowed for the current user
|
/// Finds all recursive items within a top-level parent that contain the given genre and are allowed for the current user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -77,21 +91,30 @@ namespace MediaBrowser.Model.Entities
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user
|
/// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="personType">Specify this to limit results to a specific PersonType</param>
|
public IEnumerable<BaseItem> GetItemsWithPerson(string person, User user)
|
||||||
public IEnumerable<BaseItem> GetItemsWithPerson(string person, PersonType? personType, User user)
|
|
||||||
{
|
{
|
||||||
return GetParentalAllowedRecursiveChildren(user).Where(c =>
|
return GetParentalAllowedRecursiveChildren(user).Where(c =>
|
||||||
{
|
{
|
||||||
if (c.People != null)
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, string personType, User user)
|
||||||
|
{
|
||||||
|
return GetParentalAllowedRecursiveChildren(user).Where(c =>
|
||||||
|
{
|
||||||
|
if (c.People != null)
|
||||||
|
{
|
||||||
|
return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase) && p.Type == personType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -103,9 +126,7 @@ namespace MediaBrowser.Model.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<BaseItem> GetRecentlyAddedItems(User user)
|
public IEnumerable<BaseItem> GetRecentlyAddedItems(User user)
|
||||||
{
|
{
|
||||||
DateTime now = DateTime.Now;
|
return GetRecentlyAddedItems(GetParentalAllowedRecursiveChildren(user), user);
|
||||||
|
|
||||||
return GetParentalAllowedRecursiveChildren(user).Where(i => !(i is Folder) && (now - i.DateCreated).TotalDays < user.RecentItemDays);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -113,12 +134,7 @@ namespace MediaBrowser.Model.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<BaseItem> GetRecentlyAddedUnplayedItems(User user)
|
public IEnumerable<BaseItem> GetRecentlyAddedUnplayedItems(User user)
|
||||||
{
|
{
|
||||||
return GetRecentlyAddedItems(user).Where(i =>
|
return GetRecentlyAddedUnplayedItems(GetParentalAllowedRecursiveChildren(user), user);
|
||||||
{
|
|
||||||
var userdata = user.GetItemData(i.Id);
|
|
||||||
|
|
||||||
return userdata == null || userdata.PlayCount == 0;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -126,45 +142,95 @@ namespace MediaBrowser.Model.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<BaseItem> GetInProgressItems(User user)
|
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)
|
if (i is Folder)
|
||||||
{
|
{
|
||||||
return false;
|
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>
|
/// <summary>
|
||||||
/// Finds an item by ID, recursively
|
/// Finds an item by ID, recursively
|
||||||
/// </summary>
|
/// </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)
|
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);
|
return result;
|
||||||
|
|
||||||
if (foundItem != null)
|
|
||||||
{
|
|
||||||
return foundItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (item.Id == id)
|
|
||||||
{
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
57
MediaBrowser.Model/Entities/IHasProviderIds.cs
Normal file
57
MediaBrowser.Model/Entities/IHasProviderIds.cs
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
MediaBrowser.Model/Entities/ItemSpecialCounts.cs
Normal file
14
MediaBrowser.Model/Entities/ItemSpecialCounts.cs
Normal file
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
@ -15,20 +15,11 @@ namespace MediaBrowser.Model.Entities
|
|||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
public PersonType PersonType { get; set; }
|
public string Type { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PersonType
|
|
||||||
{
|
|
||||||
Other,
|
|
||||||
Actor,
|
|
||||||
Director,
|
|
||||||
Writer,
|
|
||||||
Producer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
15
MediaBrowser.Model/Entities/User.cs
Normal file
15
MediaBrowser.Model/Entities/User.cs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,12 @@
|
|||||||
using MediaBrowser.Model.Entities;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Model.Users
|
namespace MediaBrowser.Model.Entities
|
||||||
{
|
{
|
||||||
public class UserItemData
|
public class UserItemData
|
||||||
{
|
{
|
||||||
public UserItemRating Rating { get; set; }
|
public UserItemRating Rating { get; set; }
|
||||||
|
|
||||||
public TimeSpan PlaybackPosition { get; set; }
|
public long PlaybackPositionTicks { get; set; }
|
||||||
|
|
||||||
public int PlayCount { get; set; }
|
public int PlayCount { get; set; }
|
||||||
}
|
}
|
@ -6,28 +6,27 @@ namespace MediaBrowser.Model.Entities
|
|||||||
{
|
{
|
||||||
public VideoType VideoType { get; set; }
|
public VideoType VideoType { get; set; }
|
||||||
|
|
||||||
private IEnumerable<string> _Subtitles = new string[] { };
|
public IEnumerable<string> Subtitles { get; set; }
|
||||||
public IEnumerable<string> Subtitles { get { return _Subtitles; } set { _Subtitles = value; } }
|
public IEnumerable<AudioStream> AudioStreams { get; set; }
|
||||||
|
|
||||||
private IEnumerable<AudioStream> _AudioStreams = new AudioStream[] { };
|
|
||||||
public IEnumerable<AudioStream> AudioStreams { get { return _AudioStreams; } set { _AudioStreams = value; } }
|
|
||||||
|
|
||||||
public int Height { get; set; }
|
public int Height { get; set; }
|
||||||
public int Width { get; set; }
|
public int Width { get; set; }
|
||||||
public string ScanType { get; set; }
|
public string ScanType { get; set; }
|
||||||
public string FrameRate { get; set; }
|
public string FrameRate { get; set; }
|
||||||
public int VideoBitRate { get; set; }
|
public int BitRate { get; set; }
|
||||||
public string VideoCodec { get; set; }
|
public string Codec { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AudioStream
|
public class AudioStream
|
||||||
{
|
{
|
||||||
public string AudioFormat { get; set; }
|
public string Format { get; set; }
|
||||||
public string AudioProfile { get; set; }
|
public string Profile { get; set; }
|
||||||
public string Language { get; set; }
|
public string Language { get; set; }
|
||||||
public int BitRate { get; set; }
|
public int BitRate { get; set; }
|
||||||
public int Channels { get; set; }
|
public int Channels { get; set; }
|
||||||
public int SampleRate { get; set; }
|
public int SampleRate { get; set; }
|
||||||
|
public bool IsDefault { get; set; }
|
||||||
|
public bool IsForced { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VideoType
|
public enum VideoType
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="DTO\ApiBaseItem.cs" />
|
<Compile Include="DTO\DTOBaseItem.cs" />
|
||||||
<Compile Include="Entities\Audio.cs" />
|
<Compile Include="Entities\Audio.cs" />
|
||||||
<Compile Include="Entities\BaseEntity.cs" />
|
<Compile Include="Entities\BaseEntity.cs" />
|
||||||
<Compile Include="Entities\BaseItem.cs" />
|
<Compile Include="Entities\BaseItem.cs" />
|
||||||
@ -40,6 +40,8 @@
|
|||||||
<Compile Include="Entities\Folder.cs" />
|
<Compile Include="Entities\Folder.cs" />
|
||||||
<Compile Include="Entities\Genre.cs" />
|
<Compile Include="Entities\Genre.cs" />
|
||||||
<Compile Include="Entities\ImageType.cs" />
|
<Compile Include="Entities\ImageType.cs" />
|
||||||
|
<Compile Include="Entities\IHasProviderIds.cs" />
|
||||||
|
<Compile Include="Entities\ItemSpecialCounts.cs" />
|
||||||
<Compile Include="Entities\MetadataProviders.cs" />
|
<Compile Include="Entities\MetadataProviders.cs" />
|
||||||
<Compile Include="Entities\Person.cs" />
|
<Compile Include="Entities\Person.cs" />
|
||||||
<Compile Include="Entities\Studio.cs" />
|
<Compile Include="Entities\Studio.cs" />
|
||||||
@ -49,8 +51,8 @@
|
|||||||
<Compile Include="DTO\PluginInfo.cs" />
|
<Compile Include="DTO\PluginInfo.cs" />
|
||||||
<Compile Include="Progress\TaskProgress.cs" />
|
<Compile Include="Progress\TaskProgress.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Users\User.cs" />
|
<Compile Include="Entities\User.cs" />
|
||||||
<Compile Include="Users\UserItemData.cs" />
|
<Compile Include="Entities\UserItemData.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
<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.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Movies.Entities
|
namespace MediaBrowser.Movies.Entities
|
||||||
{
|
{
|
||||||
public class Movie : Video
|
public class Movie : Video
|
||||||
{
|
{
|
||||||
[IgnoreDataMember]
|
|
||||||
public IEnumerable<Video> SpecialFeatures { get; set; }
|
public IEnumerable<Video> SpecialFeatures { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ namespace MediaBrowser.TV.Entities
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Store these to reduce disk access in Episode Resolver
|
/// Store these to reduce disk access in Episode Resolver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IgnoreDataMember]
|
|
||||||
internal IEnumerable<string> MetadataFiles { get; set; }
|
internal IEnumerable<string> MetadataFiles { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ namespace MediaBrowser.TV.Metadata
|
|||||||
int runtime;
|
int runtime;
|
||||||
if (int.TryParse(text.Split(' ')[0], out runtime))
|
if (int.TryParse(text.Split(' ')[0], out runtime))
|
||||||
{
|
{
|
||||||
item.RunTimeInMilliseconds = runtime * 60000;
|
item.RunTimeTicks = TimeSpan.FromMinutes(runtime).Ticks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user