@ -27,6 +27,7 @@ using MediaBrowser.Server.Implementations.Library.Validators;
using MediaBrowser.Server.Implementations.Logging ;
using MediaBrowser.Server.Implementations.ScheduledTasks ;
using System ;
using System.Collections ;
using System.Collections.Concurrent ;
using System.Collections.Generic ;
using System.Globalization ;
@ -36,6 +37,7 @@ using System.Threading;
using System.Threading.Tasks ;
using CommonIO ;
using MediaBrowser.Model.Extensions ;
using MediaBrowser.Model.Library ;
using MoreLinq ;
using SortOrder = MediaBrowser . Model . Entities . SortOrder ;
@ -140,6 +142,7 @@ namespace MediaBrowser.Server.Implementations.Library
private readonly Func < ILibraryMonitor > _libraryMonitorFactory ;
private readonly Func < IProviderManager > _providerManagerFactory ;
private readonly Func < IUserViewManager > _userviewManager ;
/// <summary>
/// The _library items cache
@ -167,7 +170,7 @@ namespace MediaBrowser.Server.Implementations.Library
/// <param name="userManager">The user manager.</param>
/// <param name="configurationManager">The configuration manager.</param>
/// <param name="userDataRepository">The user data repository.</param>
public LibraryManager ( ILogger logger , ITaskManager taskManager , IUserManager userManager , IServerConfigurationManager configurationManager , IUserDataManager userDataRepository , Func < ILibraryMonitor > libraryMonitorFactory , IFileSystem fileSystem , Func < IProviderManager > providerManagerFactory )
public LibraryManager ( ILogger logger , ITaskManager taskManager , IUserManager userManager , IServerConfigurationManager configurationManager , IUserDataManager userDataRepository , Func < ILibraryMonitor > libraryMonitorFactory , IFileSystem fileSystem , Func < IProviderManager > providerManagerFactory , Func < IUserViewManager > userviewManager )
{
_logger = logger ;
_taskManager = taskManager ;
@ -177,6 +180,7 @@ namespace MediaBrowser.Server.Implementations.Library
_libraryMonitorFactory = libraryMonitorFactory ;
_fileSystem = fileSystem ;
_providerManagerFactory = providerManagerFactory ;
_userviewManager = userviewManager ;
ByReferenceItems = new ConcurrentDictionary < Guid , BaseItem > ( ) ;
_libraryItemsCache = new ConcurrentDictionary < Guid , BaseItem > ( ) ;
@ -401,12 +405,12 @@ namespace MediaBrowser.Server.Implementations.Library
{
foreach ( var path in item . GetDeletePaths ( ) . ToList ( ) )
{
if ( _fileSystem . DirectoryExists ( path ) )
if ( _fileSystem . DirectoryExists ( path ) )
{
_logger . Debug ( "Deleting path {0}" , path ) ;
_fileSystem . DeleteDirectory ( path , true ) ;
}
else if ( _fileSystem . FileExists ( path ) )
else if ( _fileSystem . FileExists ( path ) )
{
_logger . Debug ( "Deleting path {0}" , path ) ;
_fileSystem . DeleteFile ( path ) ;
@ -580,7 +584,7 @@ namespace MediaBrowser.Server.Implementations.Library
} ;
// Return null if ignore rules deem that we should do so
if ( EntityResolutionIgnoreRules. Any ( r = > r . ShouldIgnore ( args ) ) )
if ( IgnoreFile( args . FileInfo , args . Parent ) )
{
return null ;
}
@ -599,9 +603,9 @@ namespace MediaBrowser.Server.Implementations.Library
// Example: if \\server\movies exists, then strip out \\server\movies\action
if ( isPhysicalRoot )
{
var paths = NormalizeRootPathList ( fileSystemDictionary . Value s) ;
var paths = NormalizeRootPathList ( fileSystemDictionary . Key s) ;
fileSystemDictionary = paths . ToDictionary( i = > i . FullName ) ;
fileSystemDictionary = paths . Select( _fileSystem . GetDirectoryInfo ) . ToDictionary( i = > i . FullName ) ;
}
args . FileSystemDictionary = fileSystemDictionary ;
@ -616,12 +620,14 @@ namespace MediaBrowser.Server.Implementations.Library
return ResolveItem ( args ) ;
}
public IEnumerable < FileSystemMetadata > NormalizeRootPathList ( IEnumerable < FileSystemMetadata > paths )
public bool IgnoreFile ( FileSystemMetadata file , BaseItem parent )
{
var originalList = paths . ToList ( ) ;
return EntityResolutionIgnoreRules . Any ( r = > r . ShouldIgnore ( file , parent ) ) ;
}
var list = originalList . Where ( i = > i . IsDirectory )
. Select ( i = > _fileSystem . NormalizePath ( i . FullName ) )
public IEnumerable < string > NormalizeRootPathList ( IEnumerable < string > paths )
{
var list = paths . Select ( _fileSystem . NormalizePath )
. Distinct ( StringComparer . OrdinalIgnoreCase )
. ToList ( ) ;
@ -633,9 +639,7 @@ namespace MediaBrowser.Server.Implementations.Library
_logger . Info ( "Found duplicate path: {0}" , dupe ) ;
}
var newList = list . Except ( dupes , StringComparer . OrdinalIgnoreCase ) . Select ( _fileSystem . GetDirectoryInfo ) . ToList ( ) ;
newList . AddRange ( originalList . Where ( i = > ! i . IsDirectory ) ) ;
return newList ;
return list . Except ( dupes , StringComparer . OrdinalIgnoreCase ) ;
}
/// <summary>
@ -651,7 +655,7 @@ namespace MediaBrowser.Server.Implementations.Library
public IEnumerable < BaseItem > ResolvePaths ( IEnumerable < FileSystemMetadata > files , IDirectoryService directoryService , Folder parent , string collectionType )
{
var fileList = files . ToList( ) ;
var fileList = files . Where( i = > ! IgnoreFile ( i , parent ) ) . ToList( ) ;
if ( parent ! = null )
{
@ -702,7 +706,7 @@ namespace MediaBrowser.Server.Implementations.Library
{
var rootFolderPath = ConfigurationManager . ApplicationPaths . RootFolderPath ;
_fileSystem . CreateDirectory ( rootFolderPath ) ;
_fileSystem . CreateDirectory ( rootFolderPath ) ;
var rootFolder = GetItemById ( GetNewItemId ( rootFolderPath , typeof ( AggregateFolder ) ) ) as AggregateFolder ? ? ( AggregateFolder ) ResolvePath ( _fileSystem . GetDirectoryInfo ( rootFolderPath ) ) ;
@ -732,6 +736,13 @@ namespace MediaBrowser.Server.Implementations.Library
folder = dbItem ;
}
if ( folder . ParentId ! = rootFolder . Id )
{
folder . ParentId = rootFolder . Id ;
var task = folder . UpdateToRepository ( ItemUpdateType . MetadataImport , CancellationToken . None ) ;
Task . WaitAll ( task ) ;
}
rootFolder . AddVirtualChild ( folder ) ;
RegisterItem ( folder ) ;
@ -753,7 +764,7 @@ namespace MediaBrowser.Server.Implementations.Library
{
var userRootPath = ConfigurationManager . ApplicationPaths . DefaultUserViewsPath ;
_fileSystem . CreateDirectory ( userRootPath ) ;
_fileSystem . CreateDirectory ( userRootPath ) ;
var tmpItem = GetItemById ( GetNewItemId ( userRootPath , typeof ( UserRootFolder ) ) ) as UserRootFolder ;
@ -1018,7 +1029,7 @@ namespace MediaBrowser.Server.Implementations.Library
public Task ValidatePeople ( CancellationToken cancellationToken , IProgress < double > progress )
{
// Ensure the location is available.
_fileSystem . CreateDirectory ( ConfigurationManager . ApplicationPaths . PeoplePath ) ;
_fileSystem . CreateDirectory ( ConfigurationManager . ApplicationPaths . PeoplePath ) ;
return new PeopleValidator ( this , _logger , ConfigurationManager , _fileSystem ) . ValidatePeople ( cancellationToken , progress ) ;
}
@ -1265,6 +1276,11 @@ namespace MediaBrowser.Server.Implementations.Library
public QueryResult < BaseItem > GetItems ( InternalItemsQuery query )
{
if ( query . User ! = null )
{
AddUserToQuery ( query , query . User ) ;
}
var result = ItemRepository . GetItemIdsList ( query ) ;
var items = result . Select ( GetItemById ) . Where ( i = > i ! = null ) . ToArray ( ) ;
@ -1277,14 +1293,66 @@ namespace MediaBrowser.Server.Implementations.Library
public QueryResult < BaseItem > QueryItems ( InternalItemsQuery query )
{
if ( query . User ! = null )
{
AddUserToQuery ( query , query . User ) ;
}
return ItemRepository . GetItems ( query ) ;
}
public List < Guid > GetItemIds ( InternalItemsQuery query )
{
if ( query . User ! = null )
{
AddUserToQuery ( query , query . User ) ;
}
return ItemRepository . GetItemIdsList ( query ) ;
}
public IEnumerable < BaseItem > GetItems ( InternalItemsQuery query , IEnumerable < string > parentIds )
{
var parents = parentIds . Select ( i = > GetItemById ( new Guid ( i ) ) ) . ToList ( ) ;
query . AncestorIds = parents . SelectMany ( i = > i . GetIdsForAncestorQuery ( ) ) . Select ( i = > i . ToString ( "N" ) ) . ToArray ( ) ;
return GetItemIds ( query ) . Select ( GetItemById ) ;
}
public QueryResult < BaseItem > GetItemsResult ( InternalItemsQuery query , IEnumerable < string > parentIds )
{
var parents = parentIds . Select ( i = > GetItemById ( new Guid ( i ) ) ) . ToList ( ) ;
query . AncestorIds = parents . SelectMany ( i = > i . GetIdsForAncestorQuery ( ) ) . Select ( i = > i . ToString ( "N" ) ) . ToArray ( ) ;
return GetItems ( query ) ;
}
private void AddUserToQuery ( InternalItemsQuery query , User user )
{
if ( query . AncestorIds . Length = = 0 & & ! query . ParentId . HasValue & & query . ChannelIds . Length = = 0 )
{
//var userViews = _userviewManager().GetUserViews(new UserViewQuery
//{
// UserId = user.Id.ToString("N"),
// IncludeHidden = true
//}, CancellationToken.None).Result.ToList();
//query.AncestorIds = userViews.SelectMany(i => i.GetIdsForAncestorQuery()).Distinct().Select(i => i.ToString("N")).ToArray();
}
// TODO: handle blocking by tags
query . MaxParentalRating = user . Policy . MaxParentalRating ;
if ( user . Policy . MaxParentalRating . HasValue )
{
query . BlockUnratedItems = user . Policy . BlockUnratedItems ;
}
}
/// <summary>
/// Gets the intros.
/// </summary>
@ -1577,9 +1645,9 @@ namespace MediaBrowser.Server.Implementations.Library
public IEnumerable < Folder > GetCollectionFolders ( BaseItem item )
{
while ( ! ( item . Parent is AggregateFolder ) & & item . Parent ! = null )
while ( ! ( item . Get Parent( ) is AggregateFolder ) & & item . Get Parent( ) ! = null )
{
item = item . Parent;
item = item . Get Parent( ) ;
}
if ( item = = null )
@ -1616,7 +1684,7 @@ namespace MediaBrowser.Server.Implementations.Library
return type ;
}
return item . Parents
return item . Get Parents( )
. Select ( GetConfiguredContentType )
. LastOrDefault ( i = > ! string . IsNullOrWhiteSpace ( i ) ) ;
}
@ -1653,9 +1721,9 @@ namespace MediaBrowser.Server.Implementations.Library
private string GetTopFolderContentType ( BaseItem item )
{
while ( ! ( item . Parent is AggregateFolder ) & & item . Parent ! = null )
while ( ! ( item . Get Parent( ) is AggregateFolder ) & & item . Get Parent( ) ! = null )
{
item = item . Parent;
item = item . Get Parent( ) ;
}
if ( item = = null )
@ -1700,7 +1768,7 @@ namespace MediaBrowser.Server.Implementations.Library
if ( item = = null | |
! string . Equals ( item . Path , path , StringComparison . OrdinalIgnoreCase ) )
{
_fileSystem . CreateDirectory ( path ) ;
_fileSystem . CreateDirectory ( path ) ;
item = new UserView
{
@ -1719,8 +1787,7 @@ namespace MediaBrowser.Server.Implementations.Library
if ( ! string . Equals ( viewType , item . ViewType , StringComparison . OrdinalIgnoreCase ) )
{
item . ViewType = viewType ;
await item . UpdateToRepository ( ItemUpdateType . MetadataEdit , cancellationToken ) . ConfigureAwait ( false ) ;
refresh = true ;
}
if ( ! refresh )
@ -1793,7 +1860,7 @@ namespace MediaBrowser.Server.Implementations.Library
if ( item = = null )
{
_fileSystem . CreateDirectory ( path ) ;
_fileSystem . CreateDirectory ( path ) ;
item = new UserView
{
@ -1816,14 +1883,9 @@ namespace MediaBrowser.Server.Implementations.Library
isNew = true ;
}
if ( ! item . UserId . HasValue )
if ( ! item . UserId . HasValue | | ! string . Equals ( viewType , item . ViewType , StringComparison . OrdinalIgnoreCase ) )
{
item . UserId = user . Id ;
await item . UpdateToRepository ( ItemUpdateType . MetadataEdit , cancellationToken ) . ConfigureAwait ( false ) ;
}
if ( ! string . Equals ( viewType , item . ViewType , StringComparison . OrdinalIgnoreCase ) )
{
item . ViewType = viewType ;
await item . UpdateToRepository ( ItemUpdateType . MetadataEdit , cancellationToken ) . ConfigureAwait ( false ) ;
}
@ -1951,7 +2013,7 @@ namespace MediaBrowser.Server.Implementations.Library
if ( item = = null )
{
_fileSystem . CreateDirectory ( path ) ;
_fileSystem . CreateDirectory ( path ) ;
item = new UserView
{
@ -2198,21 +2260,21 @@ namespace MediaBrowser.Server.Implementations.Library
return ResolvePaths ( files , directoryService , null , null )
. OfType < Video > ( )
. Select ( video = >
{
// Try to retrieve it from the db. If we don't find it, use the resolved version
var dbItem = GetItemById ( video . Id ) as Video ;
if ( dbItem ! = null )
{
video = dbItem ;
}
// Try to retrieve it from the db. If we don't find it, use the resolved version
var dbItem = GetItemById ( video . Id ) as Video ;
video . ExtraType = ExtraType . Trailer ;
if ( dbItem ! = null )
{
video = dbItem ;
}
return video ;
video . ExtraType = ExtraType . Trailer ;
// Sort them so that the list can be easily compared for changes
} ) . OrderBy ( i = > i . Path ) . ToList ( ) ;
return video ;
// Sort them so that the list can be easily compared for changes
} ) . OrderBy ( i = > i . Path ) . ToList ( ) ;
}
public IEnumerable < Video > FindExtras ( BaseItem owner , List < FileSystemMetadata > fileSystemChildren , IDirectoryService directoryService )
@ -2384,7 +2446,7 @@ namespace MediaBrowser.Server.Implementations.Library
return ItemRepository . UpdatePeople ( item . Id , people ) ;
}
private readonly SemaphoreSlim _dynamicImageResourcePool = new SemaphoreSlim ( 1 , 1 ) ;
private readonly SemaphoreSlim _dynamicImageResourcePool = new SemaphoreSlim ( 1 , 1 ) ;
public async Task < ItemImageInfo > ConvertImageToLocal ( IHasImages item , ItemImageInfo image , int imageIndex )
{
_logger . Debug ( "ConvertImageToLocal item {0}" , item . Id ) ;