using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using ServiceStack.ServiceHost;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Api
{
[Route("/Items/{Id}/File", "GET")]
[Api(Description = "Gets the original file of an item")]
public class GetFile
{
///
/// Gets or sets the id.
///
/// The id.
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
///
/// Class GetCriticReviews
///
[Route("/Items/{Id}/CriticReviews", "GET")]
[Api(Description = "Gets critic reviews for an item")]
public class GetCriticReviews : IReturn
{
///
/// Gets or sets the id.
///
/// The id.
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
///
/// Skips over a given number of items within the results. Use for paging.
///
/// The start index.
[ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? StartIndex { get; set; }
///
/// The maximum number of items to return
///
/// The limit.
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Limit { get; set; }
}
///
/// Class GetThemeSongs
///
[Route("/Items/{Id}/ThemeSongs", "GET")]
[Api(Description = "Gets theme songs for an item")]
public class GetThemeSongs : IReturn
{
///
/// Gets or sets the user id.
///
/// The user id.
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid? UserId { get; set; }
///
/// Gets or sets the id.
///
/// The id.
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
[ApiMember(Name = "InheritFromParent", Description = "Determines whether or not parent items should be searched for theme media.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool InheritFromParent { get; set; }
}
///
/// Class GetThemeVideos
///
[Route("/Items/{Id}/ThemeVideos", "GET")]
[Api(Description = "Gets theme videos for an item")]
public class GetThemeVideos : IReturn
{
///
/// Gets or sets the user id.
///
/// The user id.
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid? UserId { get; set; }
///
/// Gets or sets the id.
///
/// The id.
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
[ApiMember(Name = "InheritFromParent", Description = "Determines whether or not parent items should be searched for theme media.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool InheritFromParent { get; set; }
}
///
/// Class GetThemeVideos
///
[Route("/Items/{Id}/ThemeMedia", "GET")]
[Api(Description = "Gets theme videos and songs for an item")]
public class GetThemeMedia : IReturn
{
///
/// Gets or sets the user id.
///
/// The user id.
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid? UserId { get; set; }
///
/// Gets or sets the id.
///
/// The id.
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
[ApiMember(Name = "InheritFromParent", Description = "Determines whether or not parent items should be searched for theme media.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool InheritFromParent { get; set; }
}
[Route("/Library/Refresh", "POST")]
[Api(Description = "Starts a library scan")]
public class RefreshLibrary : IReturnVoid
{
}
[Route("/Items/{Id}", "DELETE")]
[Api(Description = "Deletes an item from the library and file system")]
public class DeleteItem : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get; set; }
}
[Route("/Items/Counts", "GET")]
[Api(Description = "Gets counts of various item types")]
public class GetItemCounts : IReturn
{
[ApiMember(Name = "UserId", Description = "Optional. Get counts from a specific user's library.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid? UserId { get; set; }
}
[Route("/Items/{Id}/Ancestors", "GET")]
[Api(Description = "Gets all parents of an item")]
public class GetAncestors : IReturn
{
///
/// Gets or sets the user id.
///
/// The user id.
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid? UserId { get; set; }
///
/// Gets or sets the id.
///
/// The id.
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
///
/// Class LibraryService
///
public class LibraryService : BaseApiService
{
///
/// The _item repo
///
private readonly IItemRepository _itemRepo;
private readonly ILibraryManager _libraryManager;
private readonly IUserManager _userManager;
private readonly IUserDataRepository _userDataRepository;
///
/// Initializes a new instance of the class.
///
/// The item repo.
/// The library manager.
/// The user manager.
/// The user data repository.
public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager,
IUserDataRepository userDataRepository)
{
_itemRepo = itemRepo;
_libraryManager = libraryManager;
_userManager = userManager;
_userDataRepository = userDataRepository;
}
public object Get(GetFile request)
{
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager);
if (item.LocationType == LocationType.Remote || item.LocationType == LocationType.Virtual)
{
throw new ArgumentException("This command cannot be used for remote or virtual items.");
}
if (Directory.Exists(item.Path))
{
throw new ArgumentException("This command cannot be used for directories.");
}
return ToStaticFileResult(item.Path);
}
///
/// Gets the specified request.
///
/// The request.
/// System.Object.
public object Get(GetAncestors request)
{
var result = GetAncestors(request).Result;
return ToOptimizedResult(result);
}
///
/// Gets the ancestors.
///
/// The request.
/// Task{BaseItemDto[]}.
public async Task GetAncestors(GetAncestors request)
{
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager);
var tasks = new List>();
var user = request.UserId.HasValue ? _userManager.GetUserById(request.UserId.Value) : null;
// Get everything
var fields = Enum.GetNames(typeof(ItemFields))
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
.ToList();
var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository, _itemRepo);
BaseItem parent = item.Parent;
while (parent != null)
{
if (user != null)
{
parent = TranslateParentItem(parent, user);
}
tasks.Add(dtoBuilder.GetBaseItemDto(parent, fields, user));
if (parent is UserRootFolder)
{
break;
}
parent = parent.Parent;
}
return await Task.WhenAll(tasks).ConfigureAwait(false);
}
private BaseItem TranslateParentItem(BaseItem item, User user)
{
if (item.Parent is AggregateFolder)
{
return user.RootFolder.GetChildren(user, true).FirstOrDefault(i =>
{
try
{
return i.LocationType == LocationType.FileSystem &&
i.ResolveArgs.PhysicalLocations.Contains(item.Path);
}
catch (Exception ex)
{
Logger.ErrorException("Error getting ResolveArgs for {0}", ex, i.Path);
return false;
}
});
}
return item;
}
///
/// Gets the specified request.
///
/// The request.
/// System.Object.
public object Get(GetCriticReviews request)
{
var result = GetCriticReviewsAsync(request).Result;
return ToOptimizedResult(result);
}
///
/// Gets the specified request.
///
/// The request.
/// System.Object.
public object Get(GetItemCounts request)
{
var items = GetItems(request.UserId).ToList();
var counts = new ItemCounts
{
AlbumCount = items.OfType().Count(),
EpisodeCount = items.OfType().Count(),
GameCount = items.OfType().Count(),
MovieCount = items.OfType().Count(),
SeriesCount = items.OfType().Count(),
SongCount = items.OfType