mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-08 20:38:24 +02:00
commit
c25610e0d5
40 changed files with 798 additions and 80 deletions
|
@ -66,6 +66,7 @@
|
||||||
<Compile Include="..\SharedVersion.cs">
|
<Compile Include="..\SharedVersion.cs">
|
||||||
<Link>Properties\SharedVersion.cs</Link>
|
<Link>Properties\SharedVersion.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Movies\CollectionService.cs" />
|
||||||
<Compile Include="Music\AlbumsService.cs" />
|
<Compile Include="Music\AlbumsService.cs" />
|
||||||
<Compile Include="AppThemeService.cs" />
|
<Compile Include="AppThemeService.cs" />
|
||||||
<Compile Include="BaseApiService.cs" />
|
<Compile Include="BaseApiService.cs" />
|
||||||
|
@ -91,7 +92,7 @@
|
||||||
<Compile Include="Library\LibraryStructureService.cs" />
|
<Compile Include="Library\LibraryStructureService.cs" />
|
||||||
<Compile Include="LiveTv\LiveTvService.cs" />
|
<Compile Include="LiveTv\LiveTvService.cs" />
|
||||||
<Compile Include="LocalizationService.cs" />
|
<Compile Include="LocalizationService.cs" />
|
||||||
<Compile Include="MoviesService.cs" />
|
<Compile Include="Movies\MoviesService.cs" />
|
||||||
<Compile Include="NewsService.cs" />
|
<Compile Include="NewsService.cs" />
|
||||||
<Compile Include="NotificationsService.cs" />
|
<Compile Include="NotificationsService.cs" />
|
||||||
<Compile Include="PackageReviewService.cs" />
|
<Compile Include="PackageReviewService.cs" />
|
||||||
|
@ -118,7 +119,7 @@
|
||||||
<Compile Include="SessionsService.cs" />
|
<Compile Include="SessionsService.cs" />
|
||||||
<Compile Include="SimilarItemsHelper.cs" />
|
<Compile Include="SimilarItemsHelper.cs" />
|
||||||
<Compile Include="SystemService.cs" />
|
<Compile Include="SystemService.cs" />
|
||||||
<Compile Include="TrailersService.cs" />
|
<Compile Include="Movies\TrailersService.cs" />
|
||||||
<Compile Include="TvShowsService.cs" />
|
<Compile Include="TvShowsService.cs" />
|
||||||
<Compile Include="UserLibrary\ArtistsService.cs" />
|
<Compile Include="UserLibrary\ArtistsService.cs" />
|
||||||
<Compile Include="UserLibrary\BaseItemsByNameService.cs" />
|
<Compile Include="UserLibrary\BaseItemsByNameService.cs" />
|
||||||
|
|
80
MediaBrowser.Api/Movies/CollectionService.cs
Normal file
80
MediaBrowser.Api/Movies/CollectionService.cs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
using MediaBrowser.Controller.Collections;
|
||||||
|
using ServiceStack;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Api.Movies
|
||||||
|
{
|
||||||
|
[Route("/Collections", "POST")]
|
||||||
|
[Api(Description = "Creates a new collection")]
|
||||||
|
public class CreateCollection : IReturnVoid
|
||||||
|
{
|
||||||
|
[ApiMember(Name = "IsLocked", Description = "Whether or not to lock the new collection.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
|
||||||
|
public bool IsLocked { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "Name", Description = "The name of the new collection.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "ParentId", Description = "Optional - create the collection within a specific folder", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||||
|
public Guid? ParentId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("/Collections/{Id}/Items", "POST")]
|
||||||
|
[Api(Description = "Adds items to a collection")]
|
||||||
|
public class AddToCollection : IReturnVoid
|
||||||
|
{
|
||||||
|
[ApiMember(Name = "Ids", Description = "Item id, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||||
|
public string Ids { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("/Collections/{Id}/Items", "DELETE")]
|
||||||
|
[Api(Description = "Removes items from a collection")]
|
||||||
|
public class RemoveFromCollection : IReturnVoid
|
||||||
|
{
|
||||||
|
[ApiMember(Name = "Ids", Description = "Item id, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||||
|
public string Ids { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CollectionService : BaseApiService
|
||||||
|
{
|
||||||
|
private readonly ICollectionManager _collectionManager;
|
||||||
|
|
||||||
|
public CollectionService(ICollectionManager collectionManager)
|
||||||
|
{
|
||||||
|
_collectionManager = collectionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Post(CreateCollection request)
|
||||||
|
{
|
||||||
|
var task = _collectionManager.CreateCollection(new CollectionCreationOptions
|
||||||
|
{
|
||||||
|
IsLocked = request.IsLocked,
|
||||||
|
Name = request.Name,
|
||||||
|
ParentId = request.ParentId
|
||||||
|
});
|
||||||
|
|
||||||
|
Task.WaitAll(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Post(AddToCollection request)
|
||||||
|
{
|
||||||
|
var task = _collectionManager.AddToCollection(request.Id, request.Ids.Split(',').Select(i => new Guid(i)));
|
||||||
|
|
||||||
|
Task.WaitAll(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Delete(RemoveFromCollection request)
|
||||||
|
{
|
||||||
|
var task = _collectionManager.RemoveFromCollection(request.Id, request.Ids.Split(',').Select(i => new Guid(i)));
|
||||||
|
|
||||||
|
Task.WaitAll(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
|
|
||||||
namespace MediaBrowser.Api
|
namespace MediaBrowser.Api.Movies
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class GetSimilarMovies
|
/// Class GetSimilarMovies
|
|
@ -5,7 +5,7 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
|
|
||||||
namespace MediaBrowser.Api
|
namespace MediaBrowser.Api.Movies
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class GetSimilarTrailers
|
/// Class GetSimilarTrailers
|
|
@ -63,6 +63,9 @@ namespace MediaBrowser.Api
|
||||||
[ApiMember(Name = "IncludeArtists", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
[ApiMember(Name = "IncludeArtists", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||||
public bool IncludeArtists { get; set; }
|
public bool IncludeArtists { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "IncludeItemTypes", Description = "Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||||
|
public string IncludeItemTypes { get; set; }
|
||||||
|
|
||||||
public GetSearchHints()
|
public GetSearchHints()
|
||||||
{
|
{
|
||||||
IncludeArtists = true;
|
IncludeArtists = true;
|
||||||
|
@ -130,7 +133,8 @@ namespace MediaBrowser.Api
|
||||||
IncludePeople = request.IncludePeople,
|
IncludePeople = request.IncludePeople,
|
||||||
IncludeStudios = request.IncludeStudios,
|
IncludeStudios = request.IncludeStudios,
|
||||||
StartIndex = request.StartIndex,
|
StartIndex = request.StartIndex,
|
||||||
UserId = request.UserId
|
UserId = request.UserId,
|
||||||
|
IncludeItemTypes = (request.IncludeItemTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray()
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,22 @@
|
||||||
using System;
|
using MediaBrowser.Model.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Collections
|
namespace MediaBrowser.Controller.Collections
|
||||||
{
|
{
|
||||||
public class CollectionCreationOptions
|
public class CollectionCreationOptions : IHasProviderIds
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
public Guid ParentId { get; set; }
|
public Guid? ParentId { get; set; }
|
||||||
|
|
||||||
public bool IsLocked { get; set; }
|
public bool IsLocked { get; set; }
|
||||||
|
|
||||||
|
public Dictionary<string, string> ProviderIds { get; set; }
|
||||||
|
|
||||||
|
public CollectionCreationOptions()
|
||||||
|
{
|
||||||
|
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Collections
|
namespace MediaBrowser.Controller.Collections
|
||||||
|
@ -16,16 +17,16 @@ namespace MediaBrowser.Controller.Collections
|
||||||
/// Adds to collection.
|
/// Adds to collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="collectionId">The collection identifier.</param>
|
/// <param name="collectionId">The collection identifier.</param>
|
||||||
/// <param name="itemId">The item identifier.</param>
|
/// <param name="itemIds">The item ids.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task AddToCollection(Guid collectionId, Guid itemId);
|
Task AddToCollection(Guid collectionId, IEnumerable<Guid> itemIds);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes from collection.
|
/// Removes from collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="collectionId">The collection identifier.</param>
|
/// <param name="collectionId">The collection identifier.</param>
|
||||||
/// <param name="itemId">The item identifier.</param>
|
/// <param name="itemIds">The item ids.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task RemoveFromCollection(Guid collectionId, Guid itemId);
|
Task RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,15 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public virtual bool IsHidden
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public virtual bool IsOwnedItem
|
public virtual bool IsOwnedItem
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities
|
namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -8,18 +7,6 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BasePluginFolder : Folder, ICollectionFolder, IByReferenceItem
|
public abstract class BasePluginFolder : Folder, ICollectionFolder, IByReferenceItem
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the type of the location.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The type of the location.</value>
|
|
||||||
public override LocationType LocationType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return LocationType.Virtual;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected BasePluginFolder()
|
protected BasePluginFolder()
|
||||||
{
|
{
|
||||||
DisplayMediaType = "CollectionFolder";
|
DisplayMediaType = "CollectionFolder";
|
||||||
|
|
|
@ -264,7 +264,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public IEnumerable<BaseItem> Children
|
public IEnumerable<BaseItem> Children
|
||||||
{
|
{
|
||||||
get { return ActualChildren; }
|
get { return ActualChildren.Where(i => !i.IsHidden); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -745,9 +745,9 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
var list = new List<BaseItem>();
|
var list = new List<BaseItem>();
|
||||||
|
|
||||||
AddChildrenToList(user, includeLinkedChildren, list, false, null);
|
var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, false, null);
|
||||||
|
|
||||||
return list;
|
return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -905,13 +905,6 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <returns>BaseItem.</returns>
|
/// <returns>BaseItem.</returns>
|
||||||
private BaseItem GetLinkedChild(LinkedChild info)
|
private BaseItem GetLinkedChild(LinkedChild info)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(info.Path))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Encountered linked child with empty path.");
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseItem item = null;
|
|
||||||
|
|
||||||
// First get using the cached Id
|
// First get using the cached Id
|
||||||
if (info.ItemId.HasValue)
|
if (info.ItemId.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -920,20 +913,19 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
item = LibraryManager.GetItemById(info.ItemId.Value);
|
var itemById = LibraryManager.GetItemById(info.ItemId.Value);
|
||||||
|
|
||||||
|
if (itemById != null)
|
||||||
|
{
|
||||||
|
return itemById;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If still null, search by path
|
var item = FindLinkedChild(info);
|
||||||
if (item == null)
|
|
||||||
{
|
|
||||||
item = LibraryManager.RootFolder.FindByPath(info.Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If still null, log
|
// If still null, log
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
Logger.Warn("Unable to find linked item at {0}", info.Path);
|
|
||||||
|
|
||||||
// Don't keep searching over and over
|
// Don't keep searching over and over
|
||||||
info.ItemId = Guid.Empty;
|
info.ItemId = Guid.Empty;
|
||||||
}
|
}
|
||||||
|
@ -946,6 +938,43 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BaseItem FindLinkedChild(LinkedChild info)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(info.Path))
|
||||||
|
{
|
||||||
|
var itemByPath = LibraryManager.RootFolder.FindByPath(info.Path);
|
||||||
|
|
||||||
|
if (itemByPath == null)
|
||||||
|
{
|
||||||
|
Logger.Warn("Unable to find linked item at path {0}", info.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemByPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(info.ItemName) && !string.IsNullOrWhiteSpace(info.ItemType))
|
||||||
|
{
|
||||||
|
return LibraryManager.RootFolder.RecursiveChildren.FirstOrDefault(i =>
|
||||||
|
{
|
||||||
|
if (string.Equals(i.Name, info.ItemName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
if (string.Equals(i.GetType().Name, info.ItemType, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
if (info.ItemYear.HasValue)
|
||||||
|
{
|
||||||
|
return info.ItemYear.Value == (i.ProductionYear ?? -1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var changesFound = false;
|
var changesFound = false;
|
||||||
|
@ -1106,5 +1135,10 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return GetRecursiveChildren(user).Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual)
|
return GetRecursiveChildren(user).Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual)
|
||||||
.All(i => i.IsUnplayed(user));
|
.All(i => i.IsUnplayed(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<BaseItem> GetHiddenChildren()
|
||||||
|
{
|
||||||
|
return ActualChildren.Where(i => i.IsHidden);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public LinkedChildType Type { get; set; }
|
public LinkedChildType Type { get; set; }
|
||||||
|
|
||||||
|
public string ItemName { get; set; }
|
||||||
|
public string ItemType { get; set; }
|
||||||
|
public int? ItemYear { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serves as a cache
|
/// Serves as a cache
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -18,8 +22,8 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
public enum LinkedChildType
|
public enum LinkedChildType
|
||||||
{
|
{
|
||||||
Manual = 1,
|
Manual = 0,
|
||||||
Shortcut = 2
|
Shortcut = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LinkedChildComparer : IEqualityComparer<LinkedChild>
|
public class LinkedChildComparer : IEqualityComparer<LinkedChild>
|
||||||
|
@ -35,7 +39,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
public int GetHashCode(LinkedChild obj)
|
public int GetHashCode(LinkedChild obj)
|
||||||
{
|
{
|
||||||
return (obj.Path + obj.Type.ToString()).GetHashCode();
|
return (obj.Path + obj.Type).GetHashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,8 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// Refreshes metadata for each user
|
/// Refreshes metadata for each user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <param name="force">if set to <c>true</c> [force].</param>
|
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task RefreshUsersMetadata(CancellationToken cancellationToken, bool force = false);
|
Task RefreshUsersMetadata(CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Renames the user.
|
/// Renames the user.
|
||||||
|
|
|
@ -1016,6 +1016,15 @@ namespace MediaBrowser.Model.ApiClient
|
||||||
/// <returns>Task{QueryResult{ProgramInfoDto}}.</returns>
|
/// <returns>Task{QueryResult{ProgramInfoDto}}.</returns>
|
||||||
Task<QueryResult<ProgramInfoDto>> GetLiveTvProgramsAsync(ProgramQuery query, CancellationToken cancellationToken);
|
Task<QueryResult<ProgramInfoDto>> GetLiveTvProgramsAsync(ProgramQuery query, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the live tv program asynchronous.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The identifier.</param>
|
||||||
|
/// <param name="userId">The user identifier.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task{ProgramInfoDto}.</returns>
|
||||||
|
Task<ProgramInfoDto> GetLiveTvProgramAsync(string id, string userId, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the recommended live tv programs asynchronous.
|
/// Gets the recommended live tv programs asynchronous.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1024,6 +1033,38 @@ namespace MediaBrowser.Model.ApiClient
|
||||||
/// <returns>Task{QueryResult{ProgramInfoDto}}.</returns>
|
/// <returns>Task{QueryResult{ProgramInfoDto}}.</returns>
|
||||||
Task<QueryResult<ProgramInfoDto>> GetRecommendedLiveTvProgramsAsync(RecommendedProgramQuery query, CancellationToken cancellationToken);
|
Task<QueryResult<ProgramInfoDto>> GetRecommendedLiveTvProgramsAsync(RecommendedProgramQuery query, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the live tv timer asynchronous.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timer">The timer.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task CreateLiveTvTimerAsync(TimerInfoDto timer, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the live tv timer asynchronous.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timer">The timer.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task UpdateLiveTvTimerAsync(TimerInfoDto timer, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the live tv series timer asynchronous.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timer">The timer.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task CreateLiveTvSeriesTimerAsync(SeriesTimerInfoDto timer, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the live tv series timer asynchronous.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timer">The timer.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task UpdateLiveTvSeriesTimerAsync(SeriesTimerInfoDto timer, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the live tv timer asynchronous.
|
/// Gets the live tv timer asynchronous.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1071,5 +1112,27 @@ namespace MediaBrowser.Model.ApiClient
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task DeleteLiveTvRecordingAsync(string id, CancellationToken cancellationToken);
|
Task DeleteLiveTvRecordingAsync(string id, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the default timer information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task{SeriesTimerInfoDto}.</returns>
|
||||||
|
Task<SeriesTimerInfoDto> GetDefaultLiveTvTimerInfo(CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the live tv guide information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task{GuideInfo}.</returns>
|
||||||
|
Task<GuideInfo> GetLiveTvGuideInfo(CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the default timer information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="programId">The program identifier.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task{SeriesTimerInfoDto}.</returns>
|
||||||
|
Task<SeriesTimerInfoDto> GetDefaultLiveTvTimerInfo(string programId, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -86,5 +86,8 @@ namespace MediaBrowser.Model.Querying
|
||||||
public const string VideoBitRate = "VideoBitRate";
|
public const string VideoBitRate = "VideoBitRate";
|
||||||
public const string AirTime = "AirTime";
|
public const string AirTime = "AirTime";
|
||||||
public const string Metascore = "Metascore";
|
public const string Metascore = "Metascore";
|
||||||
|
public const string Studio = "Studio";
|
||||||
|
public const string Players = "Players";
|
||||||
|
public const string GameSystem = "GameSystem";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ namespace MediaBrowser.Model.Search
|
||||||
public bool IncludeStudios { get; set; }
|
public bool IncludeStudios { get; set; }
|
||||||
public bool IncludeArtists { get; set; }
|
public bool IncludeArtists { get; set; }
|
||||||
|
|
||||||
|
public string[] IncludeItemTypes { get; set; }
|
||||||
|
|
||||||
public SearchQuery()
|
public SearchQuery()
|
||||||
{
|
{
|
||||||
IncludeArtists = true;
|
IncludeArtists = true;
|
||||||
|
@ -40,6 +42,8 @@ namespace MediaBrowser.Model.Search
|
||||||
IncludeMedia = true;
|
IncludeMedia = true;
|
||||||
IncludePeople = true;
|
IncludePeople = true;
|
||||||
IncludeStudios = true;
|
IncludeStudios = true;
|
||||||
|
|
||||||
|
IncludeItemTypes = new string[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -37,6 +38,15 @@ namespace MediaBrowser.Providers.BoxSets
|
||||||
protected override void MergeData(BoxSet source, BoxSet target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
|
protected override void MergeData(BoxSet source, BoxSet target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
|
||||||
{
|
{
|
||||||
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
||||||
|
|
||||||
|
if (mergeMetadataSettings)
|
||||||
|
{
|
||||||
|
var list = source.LinkedChildren.ToList();
|
||||||
|
|
||||||
|
list.AddRange(target.LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut));
|
||||||
|
|
||||||
|
target.LinkedChildren = list;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override ItemUpdateType BeforeSave(BoxSet item)
|
protected override ItemUpdateType BeforeSave(BoxSet item)
|
||||||
|
|
129
MediaBrowser.Providers/BoxSets/BoxSetXmlParser.cs
Normal file
129
MediaBrowser.Providers/BoxSets/BoxSetXmlParser.cs
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
|
using MediaBrowser.Controller.Providers;
|
||||||
|
using MediaBrowser.Model.Logging;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Providers.BoxSets
|
||||||
|
{
|
||||||
|
public class BoxSetXmlParser : BaseItemXmlParser<BoxSet>
|
||||||
|
{
|
||||||
|
private readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
|
public BoxSetXmlParser(ILogger logger)
|
||||||
|
: base(logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void FetchDataFromXmlNode(XmlReader reader, BoxSet item)
|
||||||
|
{
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "CollectionItems":
|
||||||
|
|
||||||
|
using (var subReader = reader.ReadSubtree())
|
||||||
|
{
|
||||||
|
FetchFromCollectionItemsNode(subReader, item);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
base.FetchDataFromXmlNode(reader, item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FetchFromCollectionItemsNode(XmlReader reader, BoxSet item)
|
||||||
|
{
|
||||||
|
reader.MoveToContent();
|
||||||
|
|
||||||
|
var list = new List<LinkedChild>();
|
||||||
|
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
if (reader.NodeType == XmlNodeType.Element)
|
||||||
|
{
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "CollectionItem":
|
||||||
|
{
|
||||||
|
using (var subReader = reader.ReadSubtree())
|
||||||
|
{
|
||||||
|
var child = GetLinkedChild(subReader);
|
||||||
|
|
||||||
|
if (child != null)
|
||||||
|
{
|
||||||
|
list.Add(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item.LinkedChildren = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LinkedChild GetLinkedChild(XmlReader reader)
|
||||||
|
{
|
||||||
|
reader.MoveToContent();
|
||||||
|
|
||||||
|
var linkedItem = new LinkedChild
|
||||||
|
{
|
||||||
|
Type = LinkedChildType.Manual
|
||||||
|
};
|
||||||
|
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
if (reader.NodeType == XmlNodeType.Element)
|
||||||
|
{
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "Name":
|
||||||
|
{
|
||||||
|
linkedItem.ItemName = reader.ReadElementContentAsString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "Type":
|
||||||
|
{
|
||||||
|
linkedItem.ItemType = reader.ReadElementContentAsString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "Year":
|
||||||
|
{
|
||||||
|
var val = reader.ReadElementContentAsString();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(val))
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
|
||||||
|
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
|
||||||
|
{
|
||||||
|
linkedItem.ItemYear = rval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.IsNullOrWhiteSpace(linkedItem.ItemName) || string.IsNullOrWhiteSpace(linkedItem.ItemType) ? null : linkedItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.BoxSets
|
||||||
|
|
||||||
protected override void Fetch(LocalMetadataResult<BoxSet> result, string path, CancellationToken cancellationToken)
|
protected override void Fetch(LocalMetadataResult<BoxSet> result, string path, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
new BaseItemXmlParser<BoxSet>(_logger).Fetch(result.Item, path, cancellationToken);
|
new BoxSetXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
<Compile Include="All\LocalImageProvider.cs" />
|
<Compile Include="All\LocalImageProvider.cs" />
|
||||||
<Compile Include="Books\BookMetadataService.cs" />
|
<Compile Include="Books\BookMetadataService.cs" />
|
||||||
<Compile Include="BoxSets\BoxSetMetadataService.cs" />
|
<Compile Include="BoxSets\BoxSetMetadataService.cs" />
|
||||||
|
<Compile Include="BoxSets\BoxSetXmlParser.cs" />
|
||||||
<Compile Include="BoxSets\MovieDbBoxSetImageProvider.cs" />
|
<Compile Include="BoxSets\MovieDbBoxSetImageProvider.cs" />
|
||||||
<Compile Include="BoxSets\MovieDbBoxSetProvider.cs" />
|
<Compile Include="BoxSets\MovieDbBoxSetProvider.cs" />
|
||||||
<Compile Include="Folders\CollectionFolderImageProvider.cs" />
|
<Compile Include="Folders\CollectionFolderImageProvider.cs" />
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace MediaBrowser.Providers.Photos
|
||||||
public Task<ItemUpdateType> FetchAsync(Photo item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(Photo item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
item.SetImagePath(ImageType.Primary, item.Path);
|
item.SetImagePath(ImageType.Primary, item.Path);
|
||||||
|
item.SetImagePath(ImageType.Backdrop, item.Path);
|
||||||
|
|
||||||
if (item.Path.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || item.Path.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase))
|
if (item.Path.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || item.Path.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -82,7 +83,8 @@ namespace MediaBrowser.Providers.Savers
|
||||||
"TVRageId",
|
"TVRageId",
|
||||||
"VoteCount",
|
"VoteCount",
|
||||||
"Website",
|
"Website",
|
||||||
"Zap2ItId"
|
"Zap2ItId",
|
||||||
|
"CollectionItems"
|
||||||
|
|
||||||
}.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
}.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
@ -580,6 +582,12 @@ namespace MediaBrowser.Providers.Savers
|
||||||
|
|
||||||
builder.Append("</Persons>");
|
builder.Append("</Persons>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var folder = item as BoxSet;
|
||||||
|
if (folder != null)
|
||||||
|
{
|
||||||
|
AddCollectionItems(folder, builder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddChapters(Video item, StringBuilder builder, IItemRepository repository)
|
public static void AddChapters(Video item, StringBuilder builder, IItemRepository repository)
|
||||||
|
@ -631,5 +639,34 @@ namespace MediaBrowser.Providers.Savers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AddCollectionItems(Folder item, StringBuilder builder)
|
||||||
|
{
|
||||||
|
var items = item.LinkedChildren
|
||||||
|
.Where(i => i.Type == LinkedChildType.Manual && !string.IsNullOrWhiteSpace(i.ItemName))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (items.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.Append("<CollectionItems>");
|
||||||
|
foreach (var link in items)
|
||||||
|
{
|
||||||
|
builder.Append("<CollectionItem>");
|
||||||
|
|
||||||
|
builder.Append("<Name>" + SecurityElement.Escape(link.ItemName) + "</Name>");
|
||||||
|
builder.Append("<Type>" + SecurityElement.Escape(link.ItemType) + "</Type>");
|
||||||
|
|
||||||
|
if (link.ItemYear.HasValue)
|
||||||
|
{
|
||||||
|
builder.Append("<Year>" + SecurityElement.Escape(link.ItemYear.Value.ToString(UsCulture)) + "</Year>");
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.Append("</CollectionItem>");
|
||||||
|
}
|
||||||
|
builder.Append("</CollectionItems>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -28,9 +30,12 @@ namespace MediaBrowser.Server.Implementations.Collections
|
||||||
{
|
{
|
||||||
var name = options.Name;
|
var name = options.Name;
|
||||||
|
|
||||||
var folderName = _fileSystem.GetValidFilename(name);
|
// Need to use the [boxset] suffix
|
||||||
|
// If internet metadata is not found, or if xml saving is off there will be no collection.xml
|
||||||
|
// This could cause it to get re-resolved as a plain folder
|
||||||
|
var folderName = _fileSystem.GetValidFilename(name) + " [boxset]";
|
||||||
|
|
||||||
var parentFolder = _libraryManager.GetItemById(options.ParentId) as Folder;
|
var parentFolder = GetParentFolder(options.ParentId);
|
||||||
|
|
||||||
if (parentFolder == null)
|
if (parentFolder == null)
|
||||||
{
|
{
|
||||||
|
@ -51,7 +56,8 @@ namespace MediaBrowser.Server.Implementations.Collections
|
||||||
Parent = parentFolder,
|
Parent = parentFolder,
|
||||||
DisplayMediaType = "Collection",
|
DisplayMediaType = "Collection",
|
||||||
Path = path,
|
Path = path,
|
||||||
DontFetchMeta = options.IsLocked
|
DontFetchMeta = options.IsLocked,
|
||||||
|
ProviderIds = options.ProviderIds
|
||||||
};
|
};
|
||||||
|
|
||||||
await parentFolder.AddChild(collection, CancellationToken.None).ConfigureAwait(false);
|
await parentFolder.AddChild(collection, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
@ -66,14 +72,124 @@ namespace MediaBrowser.Server.Implementations.Collections
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task AddToCollection(Guid collectionId, Guid itemId)
|
private Folder GetParentFolder(Guid? parentId)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (parentId.HasValue)
|
||||||
|
{
|
||||||
|
if (parentId.Value == Guid.Empty)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("parentId");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _libraryManager.GetItemById(parentId.Value) as Folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _libraryManager.RootFolder.Children.OfType<ManualCollectionsFolder>().FirstOrDefault() ??
|
||||||
|
_libraryManager.RootFolder.GetHiddenChildren().OfType<ManualCollectionsFolder>().FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task RemoveFromCollection(Guid collectionId, Guid itemId)
|
public async Task AddToCollection(Guid collectionId, IEnumerable<Guid> ids)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
|
||||||
|
|
||||||
|
if (collection == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("No collection exists with the supplied Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
var list = new List<LinkedChild>();
|
||||||
|
|
||||||
|
foreach (var itemId in ids)
|
||||||
|
{
|
||||||
|
var item = _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("No item exists with the supplied Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collection.LinkedChildren.Any(i => i.ItemId.HasValue && i.ItemId == itemId))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Item already exists in collection");
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(new LinkedChild
|
||||||
|
{
|
||||||
|
ItemName = item.Name,
|
||||||
|
ItemYear = item.ProductionYear,
|
||||||
|
ItemType = item.GetType().Name,
|
||||||
|
Type = LinkedChildType.Manual
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
collection.LinkedChildren.AddRange(list);
|
||||||
|
|
||||||
|
await collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
|
await collection.RefreshMetadata(CancellationToken.None).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds)
|
||||||
|
{
|
||||||
|
var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
|
||||||
|
|
||||||
|
if (collection == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("No collection exists with the supplied Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
var list = new List<LinkedChild>();
|
||||||
|
|
||||||
|
foreach (var itemId in itemIds)
|
||||||
|
{
|
||||||
|
var child = collection.LinkedChildren.FirstOrDefault(i => i.ItemId.HasValue && i.ItemId.Value == itemId);
|
||||||
|
|
||||||
|
if (child == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("No collection title exists with the supplied Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
var shortcutFiles = Directory
|
||||||
|
.EnumerateFiles(collection.Path, "*", SearchOption.TopDirectoryOnly)
|
||||||
|
.Where(i => _fileSystem.IsShortcut(i))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var shortcutFilesToDelete = list.Where(child => !string.IsNullOrWhiteSpace(child.Path) && child.Type == LinkedChildType.Shortcut)
|
||||||
|
.Select(child => shortcutFiles.FirstOrDefault(i => string.Equals(child.Path, _fileSystem.ResolveShortcut(i), StringComparison.OrdinalIgnoreCase)))
|
||||||
|
.Where(i => !string.IsNullOrWhiteSpace(i))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var file in shortcutFilesToDelete)
|
||||||
|
{
|
||||||
|
_iLibraryMonitor.ReportFileSystemChangeBeginning(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var file in shortcutFilesToDelete)
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var child in list)
|
||||||
|
{
|
||||||
|
collection.LinkedChildren.Remove(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
foreach (var file in shortcutFilesToDelete)
|
||||||
|
{
|
||||||
|
_iLibraryMonitor.ReportFileSystemChangeComplete(file, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
|
await collection.RefreshMetadata(CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
using MediaBrowser.Common.Configuration;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Server.Implementations.Collections
|
||||||
|
{
|
||||||
|
public class CollectionsDynamicFolder : IVirtualFolderCreator
|
||||||
|
{
|
||||||
|
private readonly IApplicationPaths _appPaths;
|
||||||
|
|
||||||
|
public CollectionsDynamicFolder(IApplicationPaths appPaths)
|
||||||
|
{
|
||||||
|
_appPaths = appPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BasePluginFolder GetFolder()
|
||||||
|
{
|
||||||
|
var path = Path.Combine(_appPaths.DataPath, "collections");
|
||||||
|
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
|
||||||
|
return new ManualCollectionsFolder
|
||||||
|
{
|
||||||
|
Path = path
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ManualCollectionsFolder : BasePluginFolder
|
||||||
|
{
|
||||||
|
public ManualCollectionsFolder()
|
||||||
|
{
|
||||||
|
Name = "Collections";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsVisible(User user)
|
||||||
|
{
|
||||||
|
if (!GetChildren(user, true).Any())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.IsVisible(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsHidden
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return !ActualChildren.Any() || base.IsHidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,12 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
|
|
||||||
var results = await GetSearchHints(inputItems, query).ConfigureAwait(false);
|
var results = await GetSearchHints(inputItems, query).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// Include item types
|
||||||
|
if (query.IncludeItemTypes.Length > 0)
|
||||||
|
{
|
||||||
|
results = results.Where(f => query.IncludeItemTypes.Contains(f.Item.GetType().Name, StringComparer.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
var searchResultArray = results.ToArray();
|
var searchResultArray = results.ToArray();
|
||||||
results = searchResultArray;
|
results = searchResultArray;
|
||||||
|
|
||||||
|
|
|
@ -189,15 +189,10 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
/// Refreshes metadata for each user
|
/// Refreshes metadata for each user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <param name="force">if set to <c>true</c> [force].</param>
|
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public Task RefreshUsersMetadata(CancellationToken cancellationToken, bool force = false)
|
public Task RefreshUsersMetadata(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tasks = Users.Select(user => user.RefreshMetadata(new MetadataRefreshOptions
|
var tasks = Users.Select(user => user.RefreshMetadata(new MetadataRefreshOptions(), cancellationToken)).ToList();
|
||||||
{
|
|
||||||
ReplaceAllMetadata = force
|
|
||||||
|
|
||||||
}, cancellationToken)).ToList();
|
|
||||||
|
|
||||||
return Task.WhenAll(tasks);
|
return Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
|
|
|
@ -582,7 +582,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
.Select(i => _libraryManager.GetGenre(i))
|
.Select(i => _libraryManager.GetGenre(i))
|
||||||
.ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
|
.ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
programs = programList.OrderByDescending(i => GetRecommendationScore(i, user.Id, serviceName, genres))
|
programs = programList.OrderBy(i => i.HasImage(ImageType.Primary) ? 0 : 1)
|
||||||
|
.ThenByDescending(i => GetRecommendationScore(i, user.Id, serviceName, genres))
|
||||||
.ThenBy(i => i.StartDate);
|
.ThenBy(i => i.StartDate);
|
||||||
|
|
||||||
if (query.Limit.HasValue)
|
if (query.Limit.HasValue)
|
||||||
|
|
|
@ -65,12 +65,9 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Data.SQLite, Version=1.0.90.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86" Condition=" '$(ConfigurationName)' != 'Release Mono' ">
|
<Reference Include="System.Data.SQLite, Version=1.0.91.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.90.0\lib\net45\System.Data.SQLite.dll</HintPath>
|
<HintPath>..\packages\System.Data.SQLite.Core.1.0.91.3\lib\net45\System.Data.SQLite.dll</HintPath>
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Data.SQLite.Linq" Condition=" '$(ConfigurationName)' != 'Release Mono' ">
|
|
||||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.90.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
@ -110,6 +107,7 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="BdInfo\BdInfoExaminer.cs" />
|
<Compile Include="BdInfo\BdInfoExaminer.cs" />
|
||||||
<Compile Include="Collections\CollectionManager.cs" />
|
<Compile Include="Collections\CollectionManager.cs" />
|
||||||
|
<Compile Include="Collections\CollectionsDynamicFolder.cs" />
|
||||||
<Compile Include="Configuration\ServerConfigurationManager.cs" />
|
<Compile Include="Configuration\ServerConfigurationManager.cs" />
|
||||||
<Compile Include="Drawing\ImageHeader.cs" />
|
<Compile Include="Drawing\ImageHeader.cs" />
|
||||||
<Compile Include="Drawing\PercentPlayedDrawer.cs" />
|
<Compile Include="Drawing\PercentPlayedDrawer.cs" />
|
||||||
|
@ -227,6 +225,7 @@
|
||||||
<Compile Include="Sorting\DateCreatedComparer.cs" />
|
<Compile Include="Sorting\DateCreatedComparer.cs" />
|
||||||
<Compile Include="Sorting\DatePlayedComparer.cs" />
|
<Compile Include="Sorting\DatePlayedComparer.cs" />
|
||||||
<Compile Include="Sorting\EpisodeCountComparer.cs" />
|
<Compile Include="Sorting\EpisodeCountComparer.cs" />
|
||||||
|
<Compile Include="Sorting\GameSystemComparer.cs" />
|
||||||
<Compile Include="Sorting\IsFolderComparer.cs" />
|
<Compile Include="Sorting\IsFolderComparer.cs" />
|
||||||
<Compile Include="Sorting\IsUnplayedComparer.cs" />
|
<Compile Include="Sorting\IsUnplayedComparer.cs" />
|
||||||
<Compile Include="Sorting\MetascoreComparer.cs" />
|
<Compile Include="Sorting\MetascoreComparer.cs" />
|
||||||
|
@ -235,6 +234,7 @@
|
||||||
<Compile Include="Sorting\NameComparer.cs" />
|
<Compile Include="Sorting\NameComparer.cs" />
|
||||||
<Compile Include="Sorting\OfficialRatingComparer.cs" />
|
<Compile Include="Sorting\OfficialRatingComparer.cs" />
|
||||||
<Compile Include="Sorting\PlayCountComparer.cs" />
|
<Compile Include="Sorting\PlayCountComparer.cs" />
|
||||||
|
<Compile Include="Sorting\PlayersComparer.cs" />
|
||||||
<Compile Include="Sorting\PremiereDateComparer.cs" />
|
<Compile Include="Sorting\PremiereDateComparer.cs" />
|
||||||
<Compile Include="Sorting\ProductionYearComparer.cs" />
|
<Compile Include="Sorting\ProductionYearComparer.cs" />
|
||||||
<Compile Include="Sorting\RandomComparer.cs" />
|
<Compile Include="Sorting\RandomComparer.cs" />
|
||||||
|
@ -248,6 +248,7 @@
|
||||||
<Compile Include="Persistence\SqliteItemRepository.cs" />
|
<Compile Include="Persistence\SqliteItemRepository.cs" />
|
||||||
<Compile Include="Persistence\SqliteUserDataRepository.cs" />
|
<Compile Include="Persistence\SqliteUserDataRepository.cs" />
|
||||||
<Compile Include="Persistence\SqliteUserRepository.cs" />
|
<Compile Include="Persistence\SqliteUserRepository.cs" />
|
||||||
|
<Compile Include="Sorting\StudioComparer.cs" />
|
||||||
<Compile Include="Sorting\TrailerCountComparer.cs" />
|
<Compile Include="Sorting\TrailerCountComparer.cs" />
|
||||||
<Compile Include="Sorting\VideoBitRateComparer.cs" />
|
<Compile Include="Sorting\VideoBitRateComparer.cs" />
|
||||||
<Compile Include="Themes\AppThemeManager.cs" />
|
<Compile Include="Themes\AppThemeManager.cs" />
|
||||||
|
@ -378,6 +379,12 @@
|
||||||
<Link>swagger-ui\swagger-ui.min.js</Link>
|
<Link>swagger-ui\swagger-ui.min.js</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="x64\SQLite.Interop.dll" Condition=" '$(ConfigurationName)' != 'Release Mono' ">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="x86\SQLite.Interop.dll" Condition=" '$(ConfigurationName)' != 'Release Mono' ">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<EmbeddedResource Include="Localization\Ratings\be.txt" />
|
<EmbeddedResource Include="Localization\Ratings\be.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Sorting;
|
||||||
|
using MediaBrowser.Model.Querying;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Server.Implementations.Sorting
|
||||||
|
{
|
||||||
|
public class GameSystemComparer : IBaseItemComparer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Compares the specified x.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The x.</param>
|
||||||
|
/// <param name="y">The y.</param>
|
||||||
|
/// <returns>System.Int32.</returns>
|
||||||
|
public int Compare(BaseItem x, BaseItem y)
|
||||||
|
{
|
||||||
|
return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The x.</param>
|
||||||
|
/// <returns>System.String.</returns>
|
||||||
|
private string GetValue(BaseItem x)
|
||||||
|
{
|
||||||
|
var game = x as Game;
|
||||||
|
|
||||||
|
if (game != null)
|
||||||
|
{
|
||||||
|
return game.GameSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
var system = x as GameSystem;
|
||||||
|
|
||||||
|
if (system != null)
|
||||||
|
{
|
||||||
|
return system.GameSystemName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The name.</value>
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return ItemSortBy.GameSystem; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Sorting;
|
||||||
|
using MediaBrowser.Model.Querying;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Server.Implementations.Sorting
|
||||||
|
{
|
||||||
|
public class PlayersComparer : IBaseItemComparer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Compares the specified x.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The x.</param>
|
||||||
|
/// <param name="y">The y.</param>
|
||||||
|
/// <returns>System.Int32.</returns>
|
||||||
|
public int Compare(BaseItem x, BaseItem y)
|
||||||
|
{
|
||||||
|
return GetValue(x).CompareTo(GetValue(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The x.</param>
|
||||||
|
/// <returns>System.String.</returns>
|
||||||
|
private int GetValue(BaseItem x)
|
||||||
|
{
|
||||||
|
var game = x as Game;
|
||||||
|
|
||||||
|
if (game != null)
|
||||||
|
{
|
||||||
|
return game.PlayersSupported ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The name.</value>
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return ItemSortBy.Players; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Sorting;
|
||||||
|
using MediaBrowser.Model.Querying;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Server.Implementations.Sorting
|
||||||
|
{
|
||||||
|
public class StudioComparer : IBaseItemComparer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Compares the specified x.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The x.</param>
|
||||||
|
/// <param name="y">The y.</param>
|
||||||
|
/// <returns>System.Int32.</returns>
|
||||||
|
public int Compare(BaseItem x, BaseItem y)
|
||||||
|
{
|
||||||
|
return AlphanumComparator.CompareValues(x.Studios.FirstOrDefault() ?? string.Empty, y.Studios.FirstOrDefault() ?? string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The name.</value>
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return ItemSortBy.Studio; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,5 +4,5 @@
|
||||||
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
|
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
|
||||||
<package id="Mono.Nat" version="1.2.3" targetFramework="net45" />
|
<package id="Mono.Nat" version="1.2.3" targetFramework="net45" />
|
||||||
<package id="morelinq" version="1.0.16006" targetFramework="net45" />
|
<package id="morelinq" version="1.0.16006" targetFramework="net45" />
|
||||||
<package id="System.Data.SQLite.x86" version="1.0.90.0" targetFramework="net45" />
|
<package id="System.Data.SQLite.Core" version="1.0.91.3" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -2,6 +2,8 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<configSections>
|
<configSections>
|
||||||
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
|
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
|
||||||
|
|
||||||
|
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||||
</configSections>
|
</configSections>
|
||||||
<system.diagnostics>
|
<system.diagnostics>
|
||||||
<assert assertuienabled="false" />
|
<assert assertuienabled="false" />
|
||||||
|
@ -43,7 +45,7 @@
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" />
|
<assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-1.0.89.0" newVersion="1.0.89.0" />
|
<bindingRedirect oldVersion="0.0.0.0-1.0.91.0" newVersion="1.0.91.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="SimpleInjector" publicKeyToken="984cb50dea722e99" culture="neutral" />
|
<assemblyIdentity name="SimpleInjector" publicKeyToken="984cb50dea722e99" culture="neutral" />
|
||||||
|
@ -63,4 +65,16 @@
|
||||||
</providers>
|
</providers>
|
||||||
</roleManager>
|
</roleManager>
|
||||||
</system.web>
|
</system.web>
|
||||||
|
<entityFramework>
|
||||||
|
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
|
||||||
|
<parameters>
|
||||||
|
<parameter value="v11.0" />
|
||||||
|
</parameters>
|
||||||
|
</defaultConnectionFactory>
|
||||||
|
<providers>
|
||||||
|
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||||
|
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
|
||||||
|
</providers>
|
||||||
|
</entityFramework>
|
||||||
|
|
||||||
</configuration>
|
</configuration>
|
|
@ -9,6 +9,7 @@ using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Common.Progress;
|
using MediaBrowser.Common.Progress;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
|
using MediaBrowser.Controller.Collections;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
|
@ -36,6 +37,7 @@ using MediaBrowser.Model.Updates;
|
||||||
using MediaBrowser.Providers.Manager;
|
using MediaBrowser.Providers.Manager;
|
||||||
using MediaBrowser.Server.Implementations;
|
using MediaBrowser.Server.Implementations;
|
||||||
using MediaBrowser.Server.Implementations.BdInfo;
|
using MediaBrowser.Server.Implementations.BdInfo;
|
||||||
|
using MediaBrowser.Server.Implementations.Collections;
|
||||||
using MediaBrowser.Server.Implementations.Configuration;
|
using MediaBrowser.Server.Implementations.Configuration;
|
||||||
using MediaBrowser.Server.Implementations.Drawing;
|
using MediaBrowser.Server.Implementations.Drawing;
|
||||||
using MediaBrowser.Server.Implementations.Dto;
|
using MediaBrowser.Server.Implementations.Dto;
|
||||||
|
@ -488,6 +490,9 @@ namespace MediaBrowser.ServerApplication
|
||||||
var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
|
var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
|
||||||
RegisterSingleInstance<IAppThemeManager>(appThemeManager);
|
RegisterSingleInstance<IAppThemeManager>(appThemeManager);
|
||||||
|
|
||||||
|
var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor);
|
||||||
|
RegisterSingleInstance<ICollectionManager>(collectionManager);
|
||||||
|
|
||||||
LiveTvManager = new LiveTvManager(ServerConfigurationManager, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager);
|
LiveTvManager = new LiveTvManager(ServerConfigurationManager, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager);
|
||||||
RegisterSingleInstance(LiveTvManager);
|
RegisterSingleInstance(LiveTvManager);
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,12 @@ xcopy "$(TargetDir)*.dll" "$(SolutionDir)..\Deploy\Server\System" /y
|
||||||
mkdir "$(SolutionDir)..\Deploy\Server\System\dashboard-ui"
|
mkdir "$(SolutionDir)..\Deploy\Server\System\dashboard-ui"
|
||||||
xcopy "$(TargetDir)dashboard-ui" "$(SolutionDir)..\Deploy\Server\System\dashboard-ui" /y /s
|
xcopy "$(TargetDir)dashboard-ui" "$(SolutionDir)..\Deploy\Server\System\dashboard-ui" /y /s
|
||||||
|
|
||||||
|
mkdir "$(SolutionDir)..\Deploy\Server\System\x86"
|
||||||
|
xcopy "$(TargetDir)x86" "$(SolutionDir)..\Deploy\Server\System\x86" /y /s
|
||||||
|
|
||||||
|
mkdir "$(SolutionDir)..\Deploy\Server\System\x64"
|
||||||
|
xcopy "$(TargetDir)x64" "$(SolutionDir)..\Deploy\Server\System\x64" /y /s
|
||||||
|
|
||||||
del "$(SolutionDir)..\Deploy\MBServer.zip"
|
del "$(SolutionDir)..\Deploy\MBServer.zip"
|
||||||
"$(SolutionDir)ThirdParty\7zip\7za" a -mx9 "$(SolutionDir)..\Deploy\MBServer.zip" "$(SolutionDir)..\Deploy\Server\*"
|
"$(SolutionDir)ThirdParty\7zip\7za" a -mx9 "$(SolutionDir)..\Deploy\MBServer.zip" "$(SolutionDir)..\Deploy\Server\*"
|
||||||
)</PostBuildEvent>
|
)</PostBuildEvent>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" />
|
<assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-1.0.89.0" newVersion="1.0.89.0" />
|
<bindingRedirect oldVersion="0.0.0.0-1.0.91.0" newVersion="1.0.91.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
|
|
|
@ -480,6 +480,7 @@ namespace MediaBrowser.WebDashboard.Api
|
||||||
"dashboardinfo.js",
|
"dashboardinfo.js",
|
||||||
"dashboardpage.js",
|
"dashboardpage.js",
|
||||||
"directorybrowser.js",
|
"directorybrowser.js",
|
||||||
|
"editcollectionitems.js",
|
||||||
"edititemmetadata.js",
|
"edititemmetadata.js",
|
||||||
"edititempeople.js",
|
"edititempeople.js",
|
||||||
"edititemimages.js",
|
"edititemimages.js",
|
||||||
|
|
|
@ -213,6 +213,9 @@
|
||||||
<Content Include="dashboard-ui\dashboardinfopage.html">
|
<Content Include="dashboard-ui\dashboardinfopage.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="dashboard-ui\editcollectionitems.html">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="dashboard-ui\encodingsettings.html">
|
<Content Include="dashboard-ui\encodingsettings.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
@ -261,7 +264,7 @@
|
||||||
<Content Include="dashboard-ui\allusersettings.html">
|
<Content Include="dashboard-ui\allusersettings.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="dashboard-ui\boxsets.html">
|
<Content Include="dashboard-ui\collections.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="dashboard-ui\css\images\clients\mbkinect.png">
|
<Content Include="dashboard-ui\css\images\clients\mbkinect.png">
|
||||||
|
@ -480,6 +483,9 @@
|
||||||
<Content Include="dashboard-ui\scripts\dashboardinfo.js">
|
<Content Include="dashboard-ui\scripts\dashboardinfo.js">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="dashboard-ui\scripts\editcollectionitems.js">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="dashboard-ui\scripts\encodingsettings.js">
|
<Content Include="dashboard-ui\scripts\encodingsettings.js">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Common.Internal</id>
|
<id>MediaBrowser.Common.Internal</id>
|
||||||
<version>3.0.336</version>
|
<version>3.0.339</version>
|
||||||
<title>MediaBrowser.Common.Internal</title>
|
<title>MediaBrowser.Common.Internal</title>
|
||||||
<authors>Luke</authors>
|
<authors>Luke</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
|
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
|
||||||
<copyright>Copyright © Media Browser 2013</copyright>
|
<copyright>Copyright © Media Browser 2013</copyright>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="MediaBrowser.Common" version="3.0.336" />
|
<dependency id="MediaBrowser.Common" version="3.0.339" />
|
||||||
<dependency id="NLog" version="2.1.0" />
|
<dependency id="NLog" version="2.1.0" />
|
||||||
<dependency id="SimpleInjector" version="2.4.1" />
|
<dependency id="SimpleInjector" version="2.4.1" />
|
||||||
<dependency id="sharpcompress" version="0.10.2" />
|
<dependency id="sharpcompress" version="0.10.2" />
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Common</id>
|
<id>MediaBrowser.Common</id>
|
||||||
<version>3.0.336</version>
|
<version>3.0.339</version>
|
||||||
<title>MediaBrowser.Common</title>
|
<title>MediaBrowser.Common</title>
|
||||||
<authors>Media Browser Team</authors>
|
<authors>Media Browser Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Server.Core</id>
|
<id>MediaBrowser.Server.Core</id>
|
||||||
<version>3.0.336</version>
|
<version>3.0.339</version>
|
||||||
<title>Media Browser.Server.Core</title>
|
<title>Media Browser.Server.Core</title>
|
||||||
<authors>Media Browser Team</authors>
|
<authors>Media Browser Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<description>Contains core components required to build plugins for Media Browser Server.</description>
|
<description>Contains core components required to build plugins for Media Browser Server.</description>
|
||||||
<copyright>Copyright © Media Browser 2013</copyright>
|
<copyright>Copyright © Media Browser 2013</copyright>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="MediaBrowser.Common" version="3.0.336" />
|
<dependency id="MediaBrowser.Common" version="3.0.339" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
|
Loading…
Reference in a new issue