@ -1,13 +1,12 @@
using System.Collections.Generic ;
using System.Threading ;
using System.Threading.Tasks ;
using MediaBrowser.Controller.Dto ;
using MediaBrowser.Controller.Dto ;
using MediaBrowser.Controller.Entities ;
using MediaBrowser.Controller.Library ;
using MediaBrowser.Model.Querying ;
using ServiceStack ;
using System ;
using System.Linq ;
using System.Threading ;
using System.Threading.Tasks ;
namespace MediaBrowser.Api
{
@ -41,37 +40,20 @@ namespace MediaBrowser.Api
public string Id { get ; set ; }
}
[Route("/Videos/{Id}/AlternateVersions", "POST")]
[Api(Description = "Assigns videos as alternates of antoher.")]
public class PostAlternateVersions : IReturnVoid
{
[ApiMember(Name = "AlternateVersionIds", Description = "Item id, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string AlternateVersionIds { get ; set ; }
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get ; set ; }
}
[Route("/Videos/{Id}/AlternateVersions", "DELETE")]
[Api(Description = "Assigns videos as alternates of antoher.")]
public class DeleteAlternateVersions : IReturnVoid
{
[ApiMember(Name = "AlternateVersionIds", Description = "Item id, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
public string AlternateVersionIds { get ; set ; }
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get ; set ; }
}
[ApiMember(Name = "IsAlternateEncoding", Description = "Filter by versions that are considered alternate encodings of the original.", IsRequired = true, DataType = "bool", ParameterType = "path", Verb = "GET")]
public bool? IsAlternateEncoding { get ; set ; }
[Route("/Videos/MergeVersions", "POST")]
[Api(Description = "Merges videos into a single record")]
public class MergeVersions : IReturnVoid
{
[ApiMember(Name = "Ids", Description = "Item id list. This allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)]
public string Ids { get ; set ; }
}
public class VideosService : BaseApiService
@ -152,60 +134,84 @@ namespace MediaBrowser.Api
return ToOptimizedSerializedResultUsingCache ( result ) ;
}
public void Post( Post AlternateVersions request )
public void Delete( Delete AlternateVersions request )
{
var task = Add AlternateVersions( request ) ;
var task = Remove AlternateVersions( request ) ;
Task . WaitAll ( task ) ;
}
p ublic void Delete ( DeleteAlternateVersions request )
p rivate async Task RemoveAlternateVersions ( DeleteAlternateVersions request )
{
var task = RemoveAlternateVersions ( request ) ;
var video = ( Video ) _dtoService . GetItemByDtoId ( request . Id ) ;
foreach ( var link in video . GetLinkedAlternateVersions ( ) )
{
link . PrimaryVersionId = null ;
await link . UpdateToRepository ( ItemUpdateType . MetadataEdit , CancellationToken . None ) . ConfigureAwait ( false ) ;
}
video . LinkedAlternateVersions . Clear ( ) ;
await video . UpdateToRepository ( ItemUpdateType . MetadataEdit , CancellationToken . None ) . ConfigureAwait ( false ) ;
}
public void Post ( MergeVersions request )
{
var task = MergeVersions ( request ) ;
Task . WaitAll ( task ) ;
}
private async Task AddAlternateVersions ( PostAlternateVersions request )
private async Task MergeVersions( Merg eVersions request )
{
var video = ( Video ) _dtoService . GetItemByDtoId ( request . Id ) ;
var items = request . Ids . Split ( ',' )
. Select ( i = > new Guid ( i ) )
. Select ( i = > _libraryManager . GetItemById ( i ) )
. Cast < Video > ( )
. ToList ( ) ;
var list = new List < LinkedChild > ( ) ;
var currentAlternateVersions = video . GetAlternateVersions ( ) . ToList ( ) ;
if ( items . Count < 2 )
{
throw new ArgumentException ( "Please supply at least two videos to merge." ) ;
}
foreach ( var itemId in request . AlternateVersionIds . Split ( ',' ) . Select ( i = > new Guid ( i ) ) )
var videosWithVersions = items . Where ( i = > i . AlternateVersionCount > 0 )
. ToList ( ) ;
if ( videosWithVersions . Count > 1 )
{
var item = _libraryManager . GetItemById ( itemId ) as Video ;
throw new ArgumentException ( "Videos with sub-versions cannot be merged." ) ;
}
if ( item = = null )
{
throw new ArgumentException ( "No item exists with the supplied Id" ) ;
}
var primaryVersion = videosWithVersions . FirstOrDefault ( ) ;
if ( currentAlternateVersions . Any ( i = > i . Id = = itemId ) )
if ( primaryVersion = = null )
{
primaryVersion = items . OrderByDescending ( i = >
{
throw new ArgumentException ( "Item already exists." ) ;
}
var stream = i . GetDefaultVideoStream ( ) ;
list . Add ( new LinkedChild
{
Path = item . Path ,
Type = LinkedChildType . Manual
} ) ;
return stream = = null | | stream . Width = = null ? 0 : stream . Width . Value ;
item . PrimaryVersionId = video . Id ;
} ) . ThenBy ( i = > i . Name . Length )
. First ( ) ;
}
video . LinkedAlternateVersions . AddRange ( list ) ;
foreach ( var item in items . Where ( i = > i . Id ! = primaryVersion . Id ) )
{
item . PrimaryVersionId = primaryVersion . Id ;
await video . UpdateToRepository ( ItemUpdateType . MetadataEdit , CancellationToken . None ) . ConfigureAwait ( false ) ;
await item . UpdateToRepository ( ItemUpdateType . MetadataEdit , CancellationToken . None ) . ConfigureAwait ( false ) ;
await video . RefreshMetadata ( CancellationToken . None ) . ConfigureAwait ( false ) ;
}
primaryVersion . LinkedAlternateVersions . Add ( new LinkedChild
{
Path = item . Path ,
ItemId = item . Id
} ) ;
}
private async Task RemoveAlternateVersions ( DeleteAlternateVersions request )
{
var video = ( Video ) _dtoService . GetItemByDtoId ( request . Id ) ;
await primaryVersion . UpdateToRepository ( ItemUpdateType . MetadataEdit , CancellationToken . None ) . ConfigureAwait ( false ) ;
}
}
}