mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-03 19:17:24 -05:00 
			
		
		
		
	
						commit
						b09e0a6e29
					
				@ -736,7 +736,8 @@ namespace Emby.Drawing
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    var filename = (originalImagePath + dateModified.Ticks.ToString(UsCulture)).GetMD5().ToString("N");
 | 
					                    var filename = (originalImagePath + dateModified.Ticks.ToString(UsCulture)).GetMD5().ToString("N");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var outputPath = Path.Combine(_appPaths.ImageCachePath, "converted-images", filename + ".webp");
 | 
					                    var cacheExtension = _mediaEncoder().SupportsEncoder("libwebp") ? ".webp" : ".png";
 | 
				
			||||||
 | 
					                    var outputPath = Path.Combine(_appPaths.ImageCachePath, "converted-images", filename + cacheExtension);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var file = _fileSystem.GetFileInfo(outputPath);
 | 
					                    var file = _fileSystem.GetFileInfo(outputPath);
 | 
				
			||||||
                    if (!file.Exists)
 | 
					                    if (!file.Exists)
 | 
				
			||||||
 | 
				
			|||||||
@ -57,7 +57,7 @@ namespace Emby.Server.Implementations.Collections
 | 
				
			|||||||
                        return subItem;
 | 
					                        return subItem;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var parent = subItem.GetParent();
 | 
					                    var parent = subItem.IsOwnedItem ? subItem.GetOwner() : subItem.GetParent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (parent != null && parent.HasImage(ImageType.Primary))
 | 
					                    if (parent != null && parent.HasImage(ImageType.Primary))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
 | 
				
			|||||||
@ -253,6 +253,7 @@ namespace Emby.Server.Implementations.Data
 | 
				
			|||||||
                    AddColumn(db, "TypedBaseItems", "ExternalId", "Text", existingColumnNames);
 | 
					                    AddColumn(db, "TypedBaseItems", "ExternalId", "Text", existingColumnNames);
 | 
				
			||||||
                    AddColumn(db, "TypedBaseItems", "SeriesPresentationUniqueKey", "Text", existingColumnNames);
 | 
					                    AddColumn(db, "TypedBaseItems", "SeriesPresentationUniqueKey", "Text", existingColumnNames);
 | 
				
			||||||
                    AddColumn(db, "TypedBaseItems", "ShowId", "Text", existingColumnNames);
 | 
					                    AddColumn(db, "TypedBaseItems", "ShowId", "Text", existingColumnNames);
 | 
				
			||||||
 | 
					                    AddColumn(db, "TypedBaseItems", "OwnerId", "Text", existingColumnNames);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    existingColumnNames = GetColumnNames(db, "ItemValues");
 | 
					                    existingColumnNames = GetColumnNames(db, "ItemValues");
 | 
				
			||||||
                    AddColumn(db, "ItemValues", "CleanValue", "Text", existingColumnNames);
 | 
					                    AddColumn(db, "ItemValues", "CleanValue", "Text", existingColumnNames);
 | 
				
			||||||
@ -459,7 +460,8 @@ namespace Emby.Server.Implementations.Data
 | 
				
			|||||||
            "AlbumArtists",
 | 
					            "AlbumArtists",
 | 
				
			||||||
            "ExternalId",
 | 
					            "ExternalId",
 | 
				
			||||||
            "SeriesPresentationUniqueKey",
 | 
					            "SeriesPresentationUniqueKey",
 | 
				
			||||||
            "ShowId"
 | 
					            "ShowId",
 | 
				
			||||||
 | 
					            "OwnerId"
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly string[] _mediaStreamSaveColumns =
 | 
					        private readonly string[] _mediaStreamSaveColumns =
 | 
				
			||||||
@ -580,7 +582,8 @@ namespace Emby.Server.Implementations.Data
 | 
				
			|||||||
                "AlbumArtists",
 | 
					                "AlbumArtists",
 | 
				
			||||||
                "ExternalId",
 | 
					                "ExternalId",
 | 
				
			||||||
                "SeriesPresentationUniqueKey",
 | 
					                "SeriesPresentationUniqueKey",
 | 
				
			||||||
                "ShowId"
 | 
					                "ShowId",
 | 
				
			||||||
 | 
					                "OwnerId"
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var saveItemCommandCommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
 | 
					            var saveItemCommandCommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
 | 
				
			||||||
@ -784,13 +787,14 @@ namespace Emby.Server.Implementations.Data
 | 
				
			|||||||
            saveItemStatement.TryBind("@PremiereDate", item.PremiereDate);
 | 
					            saveItemStatement.TryBind("@PremiereDate", item.PremiereDate);
 | 
				
			||||||
            saveItemStatement.TryBind("@ProductionYear", item.ProductionYear);
 | 
					            saveItemStatement.TryBind("@ProductionYear", item.ProductionYear);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (item.ParentId == Guid.Empty)
 | 
					            var parentId = item.ParentId;
 | 
				
			||||||
 | 
					            if (parentId == Guid.Empty)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                saveItemStatement.TryBindNull("@ParentId");
 | 
					                saveItemStatement.TryBindNull("@ParentId");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                saveItemStatement.TryBind("@ParentId", item.ParentId);
 | 
					                saveItemStatement.TryBind("@ParentId", parentId);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (item.Genres.Count > 0)
 | 
					            if (item.Genres.Count > 0)
 | 
				
			||||||
@ -1057,6 +1061,16 @@ namespace Emby.Server.Implementations.Data
 | 
				
			|||||||
                saveItemStatement.TryBindNull("@ShowId");
 | 
					                saveItemStatement.TryBindNull("@ShowId");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var ownerId = item.OwnerId;
 | 
				
			||||||
 | 
					            if (ownerId != Guid.Empty)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                saveItemStatement.TryBind("@OwnerId", ownerId);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                saveItemStatement.TryBindNull("@OwnerId");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            saveItemStatement.MoveNext();
 | 
					            saveItemStatement.MoveNext();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1156,16 +1170,14 @@ namespace Emby.Server.Implementations.Data
 | 
				
			|||||||
                   delimeter +
 | 
					                   delimeter +
 | 
				
			||||||
                   image.DateModified.Ticks.ToString(CultureInfo.InvariantCulture) +
 | 
					                   image.DateModified.Ticks.ToString(CultureInfo.InvariantCulture) +
 | 
				
			||||||
                   delimeter +
 | 
					                   delimeter +
 | 
				
			||||||
                   image.Type +
 | 
					                   image.Type;
 | 
				
			||||||
                   delimeter +
 | 
					 | 
				
			||||||
                   image.IsPlaceholder;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ItemImageInfo ItemImageInfoFromValueString(string value)
 | 
					        public ItemImageInfo ItemImageInfoFromValueString(string value)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var parts = value.Split(new[] { '*' }, StringSplitOptions.None);
 | 
					            var parts = value.Split(new[] { '*' }, StringSplitOptions.None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (parts.Length != 4)
 | 
					            if (parts.Length < 3)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -1173,9 +1185,18 @@ namespace Emby.Server.Implementations.Data
 | 
				
			|||||||
            var image = new ItemImageInfo();
 | 
					            var image = new ItemImageInfo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            image.Path = parts[0];
 | 
					            image.Path = parts[0];
 | 
				
			||||||
            image.DateModified = new DateTime(long.Parse(parts[1], CultureInfo.InvariantCulture), DateTimeKind.Utc);
 | 
					
 | 
				
			||||||
            image.Type = (ImageType)Enum.Parse(typeof(ImageType), parts[2], true);
 | 
					            long ticks;
 | 
				
			||||||
            image.IsPlaceholder = string.Equals(parts[3], true.ToString(), StringComparison.OrdinalIgnoreCase);
 | 
					            if (long.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out ticks))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                image.DateModified = new DateTime(ticks, DateTimeKind.Utc);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ImageType type;
 | 
				
			||||||
 | 
					            if (Enum.TryParse(parts[2], true, out type))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                image.Type = type;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return image;
 | 
					            return image;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -1965,6 +1986,12 @@ namespace Emby.Server.Implementations.Data
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!reader.IsDBNull(index))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                item.OwnerId = reader.GetGuid(index);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            index++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return item;
 | 
					            return item;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -4467,7 +4494,6 @@ namespace Emby.Server.Implementations.Data
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
            var includedItemByNameTypes = GetItemByNameTypesInQuery(query).SelectMany(MapIncludeItemTypes).ToList();
 | 
					            var includedItemByNameTypes = GetItemByNameTypesInQuery(query).SelectMany(MapIncludeItemTypes).ToList();
 | 
				
			||||||
            var enableItemsByName = (query.IncludeItemsByName ?? false) && includedItemByNameTypes.Count > 0;
 | 
					            var enableItemsByName = (query.IncludeItemsByName ?? false) && includedItemByNameTypes.Count > 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1487,7 +1487,7 @@ namespace Emby.Server.Implementations.Dto
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var parent = currentItem.DisplayParent ?? currentItem.GetParent();
 | 
					            var parent = currentItem.DisplayParent ?? (currentItem.IsOwnedItem ? currentItem.GetOwner() : currentItem.GetParent());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (parent == null && !(originalItem is UserRootFolder) && !(originalItem is UserView) && !(originalItem is AggregateFolder) && !(originalItem is ICollectionFolder) && !(originalItem is Channel))
 | 
					            if (parent == null && !(originalItem is UserRootFolder) && !(originalItem is UserView) && !(originalItem is AggregateFolder) && !(originalItem is ICollectionFolder) && !(originalItem is Channel))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
				
			|||||||
@ -198,9 +198,10 @@ namespace Emby.Server.Implementations.EntryPoints
 | 
				
			|||||||
                    LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
 | 
					                    LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (e.Item.Parent != null)
 | 
					                var parent = e.Item.GetParent() as Folder;
 | 
				
			||||||
 | 
					                if (parent != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    _foldersAddedTo.Add(e.Item.Parent);
 | 
					                    _foldersAddedTo.Add(parent);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                _itemsAdded.Add(e.Item);
 | 
					                _itemsAdded.Add(e.Item);
 | 
				
			||||||
@ -259,9 +260,10 @@ namespace Emby.Server.Implementations.EntryPoints
 | 
				
			|||||||
                    LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
 | 
					                    LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (e.Item.Parent != null)
 | 
					                var parent = e.Item.GetParent() as Folder;
 | 
				
			||||||
 | 
					                if (parent != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    _foldersRemovedFrom.Add(e.Item.Parent);
 | 
					                    _foldersRemovedFrom.Add(parent);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                _itemsRemoved.Add(e.Item);
 | 
					                _itemsRemoved.Add(e.Item);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,43 +1,74 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using MediaBrowser.Controller.Library;
 | 
					using MediaBrowser.Controller.Library;
 | 
				
			||||||
using MediaBrowser.Controller.Plugins;
 | 
					 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					using MediaBrowser.Model.Tasks;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Providers;
 | 
				
			||||||
 | 
					using MediaBrowser.Model.IO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Emby.Server.Implementations.EntryPoints
 | 
					namespace Emby.Server.Implementations.EntryPoints
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// Class RefreshUsersMetadata
 | 
					    /// Class RefreshUsersMetadata
 | 
				
			||||||
    /// </summary>
 | 
					    /// </summary>
 | 
				
			||||||
    public class RefreshUsersMetadata : IServerEntryPoint
 | 
					    public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// The _user manager
 | 
					        /// The _user manager
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        private readonly IUserManager _userManager;
 | 
					        private readonly IUserManager _userManager;
 | 
				
			||||||
 | 
					        private IFileSystem _fileSystem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Name => "Refresh Users";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Key => "RefreshUsers";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Description => "Refresh user infos";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Category
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get { return "Library"; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public bool IsHidden => true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public bool IsEnabled => true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public bool IsLogged => true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
 | 
					        /// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="userManager">The user manager.</param>
 | 
					        public RefreshUsersMetadata(IUserManager userManager, IFileSystem fileSystem)
 | 
				
			||||||
        public RefreshUsersMetadata(IUserManager userManager)
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _userManager = userManager;
 | 
					            _userManager = userManager;
 | 
				
			||||||
 | 
					            _fileSystem = fileSystem;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
 | 
				
			||||||
        /// Runs this instance.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        public async void Run()
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            await _userManager.RefreshUsersMetadata(CancellationToken.None).ConfigureAwait(false);
 | 
					            var users = _userManager.Users.ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var user in users)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                cancellationToken.ThrowIfCancellationRequested();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                await user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
 | 
				
			||||||
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        public void Dispose()
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            GC.SuppressFinalize(this);
 | 
					            return new List<TaskTriggerInfo>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                new TaskTriggerInfo
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    IntervalTicks = TimeSpan.FromDays(1).Ticks,
 | 
				
			||||||
 | 
					                    Type = TaskTriggerInfo.TriggerInterval
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -77,7 +77,7 @@ namespace Emby.Server.Implementations.EntryPoints
 | 
				
			|||||||
                // Go up one level for indicators
 | 
					                // Go up one level for indicators
 | 
				
			||||||
                if (baseItem != null)
 | 
					                if (baseItem != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var parent = baseItem.GetParent();
 | 
					                    var parent = baseItem.IsOwnedItem ? baseItem.GetOwner() : baseItem.GetParent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (parent != null)
 | 
					                    if (parent != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
 | 
				
			|||||||
@ -209,7 +209,7 @@ namespace Emby.Server.Implementations.IO
 | 
				
			|||||||
                // If the item has been deleted find the first valid parent that still exists
 | 
					                // If the item has been deleted find the first valid parent that still exists
 | 
				
			||||||
                while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path))
 | 
					                while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    item = item.GetParent();
 | 
					                    item = item.IsOwnedItem ? item.GetOwner() : item.GetParent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (item == null)
 | 
					                    if (item == null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
 | 
				
			|||||||
@ -386,7 +386,7 @@ namespace Emby.Server.Implementations.Library
 | 
				
			|||||||
                    item.Id);
 | 
					                    item.Id);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var parent = item.Parent;
 | 
					            var parent = item.IsOwnedItem ? item.GetOwner() : item.GetParent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var locationType = item.LocationType;
 | 
					            var locationType = item.LocationType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -453,12 +453,28 @@ namespace Emby.Server.Implementations.Library
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if (parent != null)
 | 
					                if (parent != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await parent.ValidateChildren(new SimpleProgress<double>(), CancellationToken.None, new MetadataRefreshOptions(_fileSystem), false).ConfigureAwait(false);
 | 
					                    var parentFolder = parent as Folder;
 | 
				
			||||||
 | 
					                    if (parentFolder != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        await parentFolder.ValidateChildren(new SimpleProgress<double>(), CancellationToken.None, new MetadataRefreshOptions(_fileSystem), false).ConfigureAwait(false);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        await parent.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), CancellationToken.None).ConfigureAwait(false);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (parent != null)
 | 
					            else if (parent != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                parent.RemoveChild(item);
 | 
					                var parentFolder = parent as Folder;
 | 
				
			||||||
 | 
					                if (parentFolder != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    parentFolder.RemoveChild(item);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    await parent.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), CancellationToken.None).ConfigureAwait(false);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ItemRepository.DeleteItem(item.Id, CancellationToken.None);
 | 
					            ItemRepository.DeleteItem(item.Id, CancellationToken.None);
 | 
				
			||||||
@ -2604,8 +2620,11 @@ namespace Emby.Server.Implementations.Library
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        video = dbItem;
 | 
					                        video = dbItem;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
                    video.ExtraType = ExtraType.Trailer;
 | 
					                    {
 | 
				
			||||||
 | 
					                        // item is new
 | 
				
			||||||
 | 
					                        video.ExtraType = ExtraType.Trailer;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    video.TrailerTypes = new List<TrailerType> { TrailerType.LocalTrailer };
 | 
					                    video.TrailerTypes = new List<TrailerType> { TrailerType.LocalTrailer };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return video;
 | 
					                    return video;
 | 
				
			||||||
@ -2846,13 +2865,6 @@ namespace Emby.Server.Implementations.Library
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    await _providerManagerFactory().SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false);
 | 
					                    await _providerManagerFactory().SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var newImage = item.GetImageInfo(image.Type, imageIndex);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (newImage != null)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        newImage.IsPlaceholder = image.IsPlaceholder;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    await item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
 | 
					                    await item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return item.GetImageInfo(image.Type, imageIndex);
 | 
					                    return item.GetImageInfo(image.Type, imageIndex);
 | 
				
			||||||
 | 
				
			|||||||
@ -518,11 +518,12 @@ namespace Emby.Server.Implementations.Library
 | 
				
			|||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="cancellationToken">The cancellation token.</param>
 | 
					        /// <param name="cancellationToken">The cancellation token.</param>
 | 
				
			||||||
        /// <returns>Task.</returns>
 | 
					        /// <returns>Task.</returns>
 | 
				
			||||||
        public Task RefreshUsersMetadata(CancellationToken cancellationToken)
 | 
					        public async Task RefreshUsersMetadata(CancellationToken cancellationToken)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var tasks = Users.Select(user => user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken)).ToList();
 | 
					            foreach (var user in Users)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
            return Task.WhenAll(tasks);
 | 
					                await user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private async Task RecordFromDirectStreamProvider(IDirectStreamProvider directStreamProvider, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
 | 
					        private async Task RecordFromDirectStreamProvider(IDirectStreamProvider directStreamProvider, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(targetFile));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
 | 
					            using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                onStarted();
 | 
					                onStarted();
 | 
				
			||||||
@ -76,6 +78,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                _logger.Info("Opened recording stream from tuner provider");
 | 
					                _logger.Info("Opened recording stream from tuner provider");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(targetFile));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
 | 
					                using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    onStarted();
 | 
					                    onStarted();
 | 
				
			||||||
 | 
				
			|||||||
@ -1429,14 +1429,13 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            string liveStreamId = null;
 | 
					            string liveStreamId = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            OnRecordingStatusChanged();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var recorder = await GetRecorder().ConfigureAwait(false);
 | 
					                var recorder = await GetRecorder().ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var allMediaSources = await GetChannelStreamMediaSources(timer.ChannelId, CancellationToken.None).ConfigureAwait(false);
 | 
					                var allMediaSources = await GetChannelStreamMediaSources(timer.ChannelId, CancellationToken.None).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _logger.Info("Opening recording stream from tuner provider");
 | 
				
			||||||
                var liveStreamInfo = await GetChannelStreamInternal(timer.ChannelId, allMediaSources[0].Id, CancellationToken.None)
 | 
					                var liveStreamInfo = await GetChannelStreamInternal(timer.ChannelId, allMediaSources[0].Id, CancellationToken.None)
 | 
				
			||||||
                            .ConfigureAwait(false);
 | 
					                            .ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1450,23 +1449,20 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
                recordPath = EnsureFileUnique(recordPath, timer.Id);
 | 
					                recordPath = EnsureFileUnique(recordPath, timer.Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                _libraryMonitor.ReportFileSystemChangeBeginning(recordPath);
 | 
					                _libraryMonitor.ReportFileSystemChangeBeginning(recordPath);
 | 
				
			||||||
                _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(recordPath));
 | 
					 | 
				
			||||||
                activeRecordingInfo.Path = recordPath;
 | 
					                activeRecordingInfo.Path = recordPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var duration = recordingEndDate - DateTime.UtcNow;
 | 
					                var duration = recordingEndDate - DateTime.UtcNow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                _logger.Info("Beginning recording. Will record for {0} minutes.",
 | 
					                _logger.Info("Beginning recording. Will record for {0} minutes.", duration.TotalMinutes.ToString(CultureInfo.InvariantCulture));
 | 
				
			||||||
                    duration.TotalMinutes.ToString(CultureInfo.InvariantCulture));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                _logger.Info("Writing file to path: " + recordPath);
 | 
					                _logger.Info("Writing file to path: " + recordPath);
 | 
				
			||||||
                _logger.Info("Opening recording stream from tuner provider");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Action onStarted = () =>
 | 
					                Action onStarted = async () =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    timer.Status = RecordingStatus.InProgress;
 | 
					                    timer.Status = RecordingStatus.InProgress;
 | 
				
			||||||
                    _timerProvider.AddOrUpdate(timer, false);
 | 
					                    _timerProvider.AddOrUpdate(timer, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    SaveRecordingMetadata(timer, recordPath, seriesPath);
 | 
					                    await SaveRecordingMetadata(timer, recordPath, seriesPath).ConfigureAwait(false);
 | 
				
			||||||
                    TriggerRefresh(recordPath);
 | 
					                    TriggerRefresh(recordPath);
 | 
				
			||||||
                    EnforceKeepUpTo(timer, seriesPath);
 | 
					                    EnforceKeepUpTo(timer, seriesPath);
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
@ -1500,7 +1496,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            TriggerRefresh(recordPath);
 | 
					            TriggerRefresh(recordPath);
 | 
				
			||||||
            _libraryMonitor.ReportFileSystemChangeComplete(recordPath, true);
 | 
					            _libraryMonitor.ReportFileSystemChangeComplete(recordPath, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ActiveRecordingInfo removed;
 | 
					            ActiveRecordingInfo removed;
 | 
				
			||||||
            _activeRecordings.TryRemove(timer.Id, out removed);
 | 
					            _activeRecordings.TryRemove(timer.Id, out removed);
 | 
				
			||||||
@ -1526,17 +1522,29 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                _timerProvider.Delete(timer);
 | 
					                _timerProvider.Delete(timer);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            OnRecordingStatusChanged();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void TriggerRefresh(string path)
 | 
					        private void TriggerRefresh(string path)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            _logger.Debug("Triggering refresh on {0}", path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var item = GetAffectedBaseItem(_fileSystem.GetDirectoryName(path));
 | 
					            var item = GetAffectedBaseItem(_fileSystem.GetDirectoryName(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (item != null)
 | 
					            if (item != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                item.ChangedExternally();
 | 
					                _logger.Debug("Refreshing recording parent {0}", item.Path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ValidateChildren = true,
 | 
				
			||||||
 | 
					                    RefreshPaths = new List<string>
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        path,
 | 
				
			||||||
 | 
					                        _fileSystem.GetDirectoryName(path),
 | 
				
			||||||
 | 
					                        _fileSystem.GetDirectoryName(_fileSystem.GetDirectoryName(path))
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }, RefreshPriority.High);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1544,6 +1552,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            BaseItem item = null;
 | 
					            BaseItem item = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var parentPath = _fileSystem.GetDirectoryName(path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            while (item == null && !string.IsNullOrEmpty(path))
 | 
					            while (item == null && !string.IsNullOrEmpty(path))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                item = _libraryManager.FindByPath(path, null);
 | 
					                item = _libraryManager.FindByPath(path, null);
 | 
				
			||||||
@ -1553,14 +1563,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (item != null)
 | 
					            if (item != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // If the item has been deleted find the first valid parent that still exists
 | 
					                if (item.GetType() == typeof(Folder) && string.Equals(item.Path, parentPath, StringComparison.OrdinalIgnoreCase))
 | 
				
			||||||
                while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path))
 | 
					 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    item = item.GetParent();
 | 
					                    var parentItem = item.GetParent();
 | 
				
			||||||
 | 
					                    if (parentItem != null && !(parentItem is AggregateFolder))
 | 
				
			||||||
                    if (item == null)
 | 
					 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        break;
 | 
					                        item = parentItem;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -1568,14 +1576,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
            return item;
 | 
					            return item;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void OnRecordingStatusChanged()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            EventHelper.FireEventIfNotNull(RecordingStatusChanged, this, new RecordingStatusChangedEventArgs
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            }, _logger);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private async void EnforceKeepUpTo(TimerInfo timer, string seriesPath)
 | 
					        private async void EnforceKeepUpTo(TimerInfo timer, string seriesPath)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (string.IsNullOrWhiteSpace(timer.SeriesTimerId))
 | 
					            if (string.IsNullOrWhiteSpace(timer.SeriesTimerId))
 | 
				
			||||||
@ -1960,7 +1960,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void SaveRecordingMetadata(TimerInfo timer, string recordingPath, string seriesPath)
 | 
					        private async Task SaveRecordingMetadata(TimerInfo timer, string recordingPath, string seriesPath)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
				
			|||||||
@ -843,8 +843,7 @@ namespace Emby.Server.Implementations.LiveTv
 | 
				
			|||||||
                    item.SetImage(new ItemImageInfo
 | 
					                    item.SetImage(new ItemImageInfo
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        Path = info.ImagePath,
 | 
					                        Path = info.ImagePath,
 | 
				
			||||||
                        Type = ImageType.Primary,
 | 
					                        Type = ImageType.Primary
 | 
				
			||||||
                        IsPlaceholder = true
 | 
					 | 
				
			||||||
                    }, 0);
 | 
					                    }, 0);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
 | 
					                else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
 | 
				
			||||||
@ -852,8 +851,7 @@ namespace Emby.Server.Implementations.LiveTv
 | 
				
			|||||||
                    item.SetImage(new ItemImageInfo
 | 
					                    item.SetImage(new ItemImageInfo
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        Path = info.ImageUrl,
 | 
					                        Path = info.ImageUrl,
 | 
				
			||||||
                        Type = ImageType.Primary,
 | 
					                        Type = ImageType.Primary
 | 
				
			||||||
                        IsPlaceholder = true
 | 
					 | 
				
			||||||
                    }, 0);
 | 
					                    }, 0);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -134,7 +134,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                _liveStreamTaskCompletionSource.TrySetResult(true);
 | 
					                _liveStreamTaskCompletionSource.TrySetResult(true);
 | 
				
			||||||
                //await DeleteTempFile(_tempFilePath).ConfigureAwait(false);
 | 
					                await DeleteTempFile(_tempFilePath).ConfigureAwait(false);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Playlists
 | 
				
			|||||||
                        return subItem;
 | 
					                        return subItem;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var parent = subItem.GetParent();
 | 
					                    var parent = subItem.IsOwnedItem ? subItem.GetOwner() : subItem.GetParent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (parent != null && parent.HasImage(ImageType.Primary))
 | 
					                    if (parent != null && parent.HasImage(ImageType.Primary))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
 | 
				
			|||||||
@ -137,7 +137,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                FileInfo = FileSystem.GetDirectoryInfo(path),
 | 
					                FileInfo = FileSystem.GetDirectoryInfo(path),
 | 
				
			||||||
                Path = path,
 | 
					                Path = path,
 | 
				
			||||||
                Parent = Parent
 | 
					                Parent = GetParent() as Folder
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Gather child folder and files
 | 
					            // Gather child folder and files
 | 
				
			||||||
 | 
				
			|||||||
@ -97,7 +97,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        public string Tagline { get; set; }
 | 
					        public string Tagline { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [IgnoreDataMember]
 | 
					        [IgnoreDataMember]
 | 
				
			||||||
        public ItemImageInfo[] ImageInfos { get; set; }
 | 
					        public virtual ItemImageInfo[] ImageInfos { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [IgnoreDataMember]
 | 
					        [IgnoreDataMember]
 | 
				
			||||||
        public bool IsVirtualItem { get; set; }
 | 
					        public bool IsVirtualItem { get; set; }
 | 
				
			||||||
@ -216,6 +216,9 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        [IgnoreDataMember]
 | 
					        [IgnoreDataMember]
 | 
				
			||||||
        public Guid Id { get; set; }
 | 
					        public Guid Id { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [IgnoreDataMember]
 | 
				
			||||||
 | 
					        public Guid OwnerId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Gets or sets a value indicating whether this instance is hd.
 | 
					        /// Gets or sets a value indicating whether this instance is hd.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
@ -321,12 +324,31 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            get
 | 
					            get
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
					                if (OwnerId != Guid.Empty)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // legacy 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Local trailer, special feature, theme video, etc.
 | 
					                // Local trailer, special feature, theme video, etc.
 | 
				
			||||||
                // An item that belongs to another item but is not part of the Parent-Child tree
 | 
					                // An item that belongs to another item but is not part of the Parent-Child tree
 | 
				
			||||||
                return !IsFolder && ParentId == Guid.Empty && LocationType == LocationType.FileSystem;
 | 
					                // This is a hack for now relying on ExtraType. Eventually we may need to persist this
 | 
				
			||||||
 | 
					                if (ParentId == Guid.Empty && !IsFolder && LocationType == LocationType.FileSystem)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public BaseItem GetOwner()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var ownerId = OwnerId;
 | 
				
			||||||
 | 
					            return ownerId == Guid.Empty ? null : LibraryManager.GetItemById(ownerId);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Gets or sets the type of the location.
 | 
					        /// Gets or sets the type of the location.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
@ -727,17 +749,12 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            ParentId = parent == null ? Guid.Empty : parent.Id;
 | 
					            ParentId = parent == null ? Guid.Empty : parent.Id;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [IgnoreDataMember]
 | 
					 | 
				
			||||||
        public IEnumerable<Folder> Parents
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            get { return GetParents().OfType<Folder>(); }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public BaseItem GetParent()
 | 
					        public BaseItem GetParent()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (ParentId != Guid.Empty)
 | 
					            var parentId = ParentId;
 | 
				
			||||||
 | 
					            if (parentId != Guid.Empty)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return LibraryManager.GetItemById(ParentId);
 | 
					                return LibraryManager.GetItemById(parentId);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
@ -779,11 +796,13 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            get
 | 
					            get
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (ParentId == Guid.Empty)
 | 
					                var parentId = ParentId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (parentId == Guid.Empty)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    return null;
 | 
					                    return null;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return ParentId;
 | 
					                return parentId;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1002,8 +1021,11 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        audio = dbItem;
 | 
					                        audio = dbItem;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
                    audio.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong;
 | 
					                    {
 | 
				
			||||||
 | 
					                        // item is new
 | 
				
			||||||
 | 
					                        audio.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return audio;
 | 
					                    return audio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1032,8 +1054,11 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        item = dbItem;
 | 
					                        item = dbItem;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
                    item.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo;
 | 
					                    {
 | 
				
			||||||
 | 
					                        // item is new
 | 
				
			||||||
 | 
					                        item.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return item;
 | 
					                    return item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1178,8 +1203,25 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            var newItemIds = newItems.Select(i => i.Id).ToArray();
 | 
					            var newItemIds = newItems.Select(i => i.Id).ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var itemsChanged = !item.LocalTrailerIds.SequenceEqual(newItemIds);
 | 
					            var itemsChanged = !item.LocalTrailerIds.SequenceEqual(newItemIds);
 | 
				
			||||||
 | 
					            var ownerId = item.Id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var tasks = newItems.Select(i => RefreshMetadataForOwnedItem(i, true, options, cancellationToken));
 | 
					            var tasks = newItems.Select(i =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var subOptions = new MetadataRefreshOptions(options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!i.ExtraType.HasValue ||
 | 
				
			||||||
 | 
					                    i.ExtraType.Value != Model.Entities.ExtraType.Trailer ||
 | 
				
			||||||
 | 
					                    i.OwnerId != ownerId ||
 | 
				
			||||||
 | 
					                    i.ParentId != Guid.Empty)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    i.ExtraType = Model.Entities.ExtraType.Trailer;
 | 
				
			||||||
 | 
					                    i.OwnerId = ownerId;
 | 
				
			||||||
 | 
					                    i.ParentId = Guid.Empty;
 | 
				
			||||||
 | 
					                    subOptions.ForceSave = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return RefreshMetadataForOwnedItem(i, true, subOptions, cancellationToken);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await Task.WhenAll(tasks).ConfigureAwait(false);
 | 
					            await Task.WhenAll(tasks).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1196,13 +1238,20 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var themeVideosChanged = !item.ThemeVideoIds.SequenceEqual(newThemeVideoIds);
 | 
					            var themeVideosChanged = !item.ThemeVideoIds.SequenceEqual(newThemeVideoIds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var ownerId = item.Id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var tasks = newThemeVideos.Select(i =>
 | 
					            var tasks = newThemeVideos.Select(i =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var subOptions = new MetadataRefreshOptions(options);
 | 
					                var subOptions = new MetadataRefreshOptions(options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!i.IsThemeMedia)
 | 
					                if (!i.ExtraType.HasValue ||
 | 
				
			||||||
 | 
					                    i.ExtraType.Value != Model.Entities.ExtraType.ThemeVideo ||
 | 
				
			||||||
 | 
					                    i.OwnerId != ownerId ||
 | 
				
			||||||
 | 
					                    i.ParentId != Guid.Empty)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    i.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo;
 | 
					                    i.ExtraType = Model.Entities.ExtraType.ThemeVideo;
 | 
				
			||||||
 | 
					                    i.OwnerId = ownerId;
 | 
				
			||||||
 | 
					                    i.ParentId = Guid.Empty;
 | 
				
			||||||
                    subOptions.ForceSave = true;
 | 
					                    subOptions.ForceSave = true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1226,13 +1275,20 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var themeSongsChanged = !item.ThemeSongIds.SequenceEqual(newThemeSongIds);
 | 
					            var themeSongsChanged = !item.ThemeSongIds.SequenceEqual(newThemeSongIds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var ownerId = item.Id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var tasks = newThemeSongs.Select(i =>
 | 
					            var tasks = newThemeSongs.Select(i =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var subOptions = new MetadataRefreshOptions(options);
 | 
					                var subOptions = new MetadataRefreshOptions(options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!i.IsThemeMedia)
 | 
					                if (!i.ExtraType.HasValue || 
 | 
				
			||||||
 | 
					                    i.ExtraType.Value != Model.Entities.ExtraType.ThemeSong || 
 | 
				
			||||||
 | 
					                    i.OwnerId != ownerId ||
 | 
				
			||||||
 | 
					                    i.ParentId != Guid.Empty)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    i.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong;
 | 
					                    i.ExtraType = Model.Entities.ExtraType.ThemeSong;
 | 
				
			||||||
 | 
					                    i.OwnerId = ownerId;
 | 
				
			||||||
 | 
					                    i.ParentId = Guid.Empty;
 | 
				
			||||||
                    subOptions.ForceSave = true;
 | 
					                    subOptions.ForceSave = true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1868,7 +1924,6 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                existingImage.Path = image.Path;
 | 
					                existingImage.Path = image.Path;
 | 
				
			||||||
                existingImage.DateModified = image.DateModified;
 | 
					                existingImage.DateModified = image.DateModified;
 | 
				
			||||||
                existingImage.IsPlaceholder = image.IsPlaceholder;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
@ -1902,7 +1957,6 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                image.Path = file.FullName;
 | 
					                image.Path = file.FullName;
 | 
				
			||||||
                image.DateModified = imageInfo.DateModified;
 | 
					                image.DateModified = imageInfo.DateModified;
 | 
				
			||||||
                image.IsPlaceholder = false;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2359,6 +2413,14 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                newOptions.ForceSave = true;
 | 
					                newOptions.ForceSave = true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //var parentId = Id;
 | 
				
			||||||
 | 
					            //if (!video.IsOwnedItem || video.ParentId != parentId)
 | 
				
			||||||
 | 
					            //{
 | 
				
			||||||
 | 
					            //    video.IsOwnedItem = true;
 | 
				
			||||||
 | 
					            //    video.ParentId = parentId;
 | 
				
			||||||
 | 
					            //    newOptions.ForceSave = true;
 | 
				
			||||||
 | 
					            //}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (video == null)
 | 
					            if (video == null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return Task.FromResult(true);
 | 
					                return Task.FromResult(true);
 | 
				
			||||||
 | 
				
			|||||||
@ -280,7 +280,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                FileInfo = FileSystem.GetDirectoryInfo(path),
 | 
					                FileInfo = FileSystem.GetDirectoryInfo(path),
 | 
				
			||||||
                Path = path,
 | 
					                Path = path,
 | 
				
			||||||
                Parent = Parent,
 | 
					                Parent = GetParent() as Folder,
 | 
				
			||||||
                CollectionType = CollectionType
 | 
					                CollectionType = CollectionType
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -378,6 +378,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            cancellationToken.ThrowIfCancellationRequested();
 | 
					            cancellationToken.ThrowIfCancellationRequested();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var validChildren = new List<BaseItem>();
 | 
					            var validChildren = new List<BaseItem>();
 | 
				
			||||||
 | 
					            var validChildrenNeedGeneration = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var allLibraryPaths = LibraryManager
 | 
					            var allLibraryPaths = LibraryManager
 | 
				
			||||||
              .GetVirtualFolders()
 | 
					              .GetVirtualFolders()
 | 
				
			||||||
@ -474,11 +475,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (recursive || refreshChildMetadata)
 | 
					                validChildrenNeedGeneration = true;
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    // used below
 | 
					 | 
				
			||||||
                    validChildren = Children.ToList();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            progress.Report(10);
 | 
					            progress.Report(10);
 | 
				
			||||||
@ -502,6 +499,12 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                        ProviderManager.OnRefreshProgress(folder, newPct);
 | 
					                        ProviderManager.OnRefreshProgress(folder, newPct);
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (validChildrenNeedGeneration)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        validChildren = Children.ToList();
 | 
				
			||||||
 | 
					                        validChildrenNeedGeneration = false;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    await ValidateSubFolders(validChildren.OfType<Folder>().ToList(), directoryService, innerProgress, cancellationToken).ConfigureAwait(false);
 | 
					                    await ValidateSubFolders(validChildren.OfType<Folder>().ToList(), directoryService, innerProgress, cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -536,6 +539,12 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
 | 
					                        if (validChildrenNeedGeneration)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            validChildren = Children.ToList();
 | 
				
			||||||
 | 
					                            validChildrenNeedGeneration = false;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        await RefreshMetadataRecursive(validChildren, refreshOptions, recursive, innerProgress, cancellationToken);
 | 
					                        await RefreshMetadataRecursive(validChildren, refreshOptions, recursive, innerProgress, cancellationToken);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -565,7 +574,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    await RefreshChildMetadata(child, refreshOptions, recursive && child.IsFolder, innerProgress, cancellationToken)
 | 
					                    await RefreshChildMetadata(child, refreshOptions, recursive && child.IsFolder, innerProgress, cancellationToken)
 | 
				
			||||||
                      .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                numComplete++;
 | 
					                numComplete++;
 | 
				
			||||||
@ -588,7 +597,10 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
 | 
					                if (refreshOptions.RefreshItem(child))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (recursive)
 | 
					                if (recursive)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@ -1196,11 +1208,21 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        /// Gets the linked children.
 | 
					        /// Gets the linked children.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <returns>IEnumerable{BaseItem}.</returns>
 | 
					        /// <returns>IEnumerable{BaseItem}.</returns>
 | 
				
			||||||
        public IEnumerable<BaseItem> GetLinkedChildren()
 | 
					        public List<BaseItem> GetLinkedChildren()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return LinkedChildren
 | 
					            var linkedChildren = LinkedChildren;
 | 
				
			||||||
                .Select(GetLinkedChild)
 | 
					            var list = new List<BaseItem>(linkedChildren.Length);
 | 
				
			||||||
                .Where(i => i != null);
 | 
					
 | 
				
			||||||
 | 
					            foreach (var i in linkedChildren)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var child = GetLinkedChild(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (child != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    list.Add(child);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return list;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected virtual bool FilterLinkedChildrenPerUser
 | 
					        protected virtual bool FilterLinkedChildrenPerUser
 | 
				
			||||||
@ -1211,16 +1233,19 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public IEnumerable<BaseItem> GetLinkedChildren(User user)
 | 
					        public List<BaseItem> GetLinkedChildren(User user)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!FilterLinkedChildrenPerUser || user == null)
 | 
					            if (!FilterLinkedChildrenPerUser || user == null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return GetLinkedChildren();
 | 
					                return GetLinkedChildren();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (LinkedChildren.Length == 0)
 | 
					            var linkedChildren = LinkedChildren;
 | 
				
			||||||
 | 
					            var list = new List<BaseItem>(linkedChildren.Length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (linkedChildren.Length == 0)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return new List<BaseItem>();
 | 
					                return list;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var allUserRootChildren = user.RootFolder.Children.OfType<Folder>().ToList();
 | 
					            var allUserRootChildren = user.RootFolder.Children.OfType<Folder>().ToList();
 | 
				
			||||||
@ -1231,37 +1256,43 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                .Select(i => i.Id)
 | 
					                .Select(i => i.Id)
 | 
				
			||||||
                .ToList();
 | 
					                .ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return LinkedChildren
 | 
					            foreach (var i in linkedChildren)
 | 
				
			||||||
                .Select(i =>
 | 
					            {
 | 
				
			||||||
 | 
					                var child = GetLinkedChild(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (child == null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var child = GetLinkedChild(i);
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (child != null)
 | 
					                var childOwner = child.IsOwnedItem ? (child.GetOwner() ?? child) : child;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (childOwner != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var childLocationType = childOwner.LocationType;
 | 
				
			||||||
 | 
					                    if (childLocationType == LocationType.Remote || childLocationType == LocationType.Virtual)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var childLocationType = child.LocationType;
 | 
					                        if (!childOwner.IsVisibleStandalone(user))
 | 
				
			||||||
                        if (childLocationType == LocationType.Remote || childLocationType == LocationType.Virtual)
 | 
					 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            if (!child.IsVisibleStandalone(user))
 | 
					                            continue;
 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                return null;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        else if (childLocationType == LocationType.FileSystem)
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            var itemCollectionFolderIds =
 | 
					 | 
				
			||||||
                                LibraryManager.GetCollectionFolders(child, allUserRootChildren)
 | 
					 | 
				
			||||||
                                .Select(f => f.Id).ToList();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            if (!itemCollectionFolderIds.Any(collectionFolderIds.Contains))
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                return null;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if (childLocationType == LocationType.FileSystem)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        var itemCollectionFolderIds =
 | 
				
			||||||
 | 
					                            LibraryManager.GetCollectionFolders(childOwner, allUserRootChildren).Select(f => f.Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return child;
 | 
					                        if (!itemCollectionFolderIds.Any(collectionFolderIds.Contains))
 | 
				
			||||||
                })
 | 
					                        {
 | 
				
			||||||
                .Where(i => i != null);
 | 
					                            continue;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                list.Add(child);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return list;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ using System.Linq;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace MediaBrowser.Controller.Entities
 | 
					namespace MediaBrowser.Controller.Entities
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public interface IHasTrailers : IHasProviderIds
 | 
					    public interface IHasTrailers : IHasMetadata
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Gets or sets the remote trailers.
 | 
					        /// Gets or sets the remote trailers.
 | 
				
			||||||
 | 
				
			|||||||
@ -24,12 +24,6 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        /// <value>The date modified.</value>
 | 
					        /// <value>The date modified.</value>
 | 
				
			||||||
        public DateTime DateModified { get; set; }
 | 
					        public DateTime DateModified { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets a value indicating whether this instance is placeholder.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value><c>true</c> if this instance is placeholder; otherwise, <c>false</c>.</value>
 | 
					 | 
				
			||||||
        public bool IsPlaceholder { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [IgnoreDataMember]
 | 
					        [IgnoreDataMember]
 | 
				
			||||||
        public bool IsLocalFile
 | 
					        public bool IsLocalFile
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
				
			|||||||
@ -81,7 +81,20 @@ namespace MediaBrowser.Controller.Entities.Movies
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var itemsChanged = !SpecialFeatureIds.SequenceEqual(newItemIds);
 | 
					            var itemsChanged = !SpecialFeatureIds.SequenceEqual(newItemIds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var tasks = newItems.Select(i => RefreshMetadataForOwnedItem(i, false, options, cancellationToken));
 | 
					            var ownerId = Id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var tasks = newItems.Select(i =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var subOptions = new MetadataRefreshOptions(options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (i.OwnerId != ownerId)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    i.OwnerId = ownerId;
 | 
				
			||||||
 | 
					                    subOptions.ForceSave = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return RefreshMetadataForOwnedItem(i, false, subOptions, cancellationToken);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await Task.WhenAll(tasks).ConfigureAwait(false);
 | 
					            await Task.WhenAll(tasks).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -347,7 +347,10 @@ namespace MediaBrowser.Controller.Entities.TV
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                cancellationToken.ThrowIfCancellationRequested();
 | 
					                cancellationToken.ThrowIfCancellationRequested();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
 | 
					                if (refreshOptions.RefreshItem(item))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                numComplete++;
 | 
					                numComplete++;
 | 
				
			||||||
                double percent = numComplete;
 | 
					                double percent = numComplete;
 | 
				
			||||||
@ -382,7 +385,10 @@ namespace MediaBrowser.Controller.Entities.TV
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if (!skipItem)
 | 
					                if (!skipItem)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
 | 
					                    if (refreshOptions.RefreshItem(item))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                numComplete++;
 | 
					                numComplete++;
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,9 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        public UserLinkType? ConnectLinkType { get; set; }
 | 
					        public UserLinkType? ConnectLinkType { get; set; }
 | 
				
			||||||
        public string ConnectAccessKey { get; set; }
 | 
					        public string ConnectAccessKey { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Strictly to remove IgnoreDataMember
 | 
				
			||||||
 | 
					        public override ItemImageInfo[] ImageInfos { get => base.ImageInfos; set => base.ImageInfos = value; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Gets or sets the path.
 | 
					        /// Gets or sets the path.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,7 @@
 | 
				
			|||||||
using System.Linq;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Entities;
 | 
				
			||||||
using MediaBrowser.Controller.IO;
 | 
					using MediaBrowser.Controller.IO;
 | 
				
			||||||
using MediaBrowser.Model.IO;
 | 
					using MediaBrowser.Model.IO;
 | 
				
			||||||
using MediaBrowser.Model.Logging;
 | 
					using MediaBrowser.Model.Logging;
 | 
				
			||||||
@ -20,6 +22,8 @@ namespace MediaBrowser.Controller.Providers
 | 
				
			|||||||
        public MetadataRefreshMode MetadataRefreshMode { get; set; }
 | 
					        public MetadataRefreshMode MetadataRefreshMode { get; set; }
 | 
				
			||||||
        public RemoteSearchResult SearchResult { get; set; }
 | 
					        public RemoteSearchResult SearchResult { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public List<string> RefreshPaths { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public bool ForceSave { get; set; }
 | 
					        public bool ForceSave { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public MetadataRefreshOptions(IFileSystem fileSystem)
 | 
					        public MetadataRefreshOptions(IFileSystem fileSystem)
 | 
				
			||||||
@ -44,6 +48,26 @@ namespace MediaBrowser.Controller.Providers
 | 
				
			|||||||
            ReplaceAllImages = copy.ReplaceAllImages;
 | 
					            ReplaceAllImages = copy.ReplaceAllImages;
 | 
				
			||||||
            ReplaceImages = copy.ReplaceImages.ToList();
 | 
					            ReplaceImages = copy.ReplaceImages.ToList();
 | 
				
			||||||
            SearchResult = copy.SearchResult;
 | 
					            SearchResult = copy.SearchResult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (copy.RefreshPaths != null && copy.RefreshPaths.Count > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (RefreshPaths == null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    RefreshPaths = new List<string>();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                RefreshPaths.AddRange(copy.RefreshPaths);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public bool RefreshItem(BaseItem item)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (RefreshPaths != null && RefreshPaths.Count > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return RefreshPaths.Contains(item.Path ?? string.Empty, StringComparer.OrdinalIgnoreCase);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,6 @@ namespace MediaBrowser.Model.LiveTv
 | 
				
			|||||||
            MediaLocationsCreated = new string[] { };
 | 
					            MediaLocationsCreated = new string[] { };
 | 
				
			||||||
            RecordingEncodingFormat = "mkv";
 | 
					            RecordingEncodingFormat = "mkv";
 | 
				
			||||||
            RecordingPostProcessorArguments = "\"{path}\"";
 | 
					            RecordingPostProcessorArguments = "\"{path}\"";
 | 
				
			||||||
            EnableRecordingEncoding = true;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections;
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Runtime.CompilerServices;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -66,9 +67,7 @@ namespace Priority_Queue
 | 
				
			|||||||
        /// Removes every node from the queue.
 | 
					        /// Removes every node from the queue.
 | 
				
			||||||
        /// O(n) (So, don't do this often!)
 | 
					        /// O(n) (So, don't do this often!)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
#if NET_VERSION_4_5
 | 
					 | 
				
			||||||
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
					        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        public void Clear()
 | 
					        public void Clear()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Array.Clear(_nodes, 1, _numNodes);
 | 
					            Array.Clear(_nodes, 1, _numNodes);
 | 
				
			||||||
@ -78,9 +77,7 @@ namespace Priority_Queue
 | 
				
			|||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Returns (in O(1)!) whether the given node is in the queue.  O(1)
 | 
					        /// Returns (in O(1)!) whether the given node is in the queue.  O(1)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
#if NET_VERSION_4_5
 | 
					 | 
				
			||||||
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
					        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        public bool Contains(TItem node)
 | 
					        public bool Contains(TItem node)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
#if DEBUG
 | 
					#if DEBUG
 | 
				
			||||||
@ -103,9 +100,7 @@ namespace Priority_Queue
 | 
				
			|||||||
        /// If the node is already enqueued, the result is undefined.
 | 
					        /// If the node is already enqueued, the result is undefined.
 | 
				
			||||||
        /// O(log n)
 | 
					        /// O(log n)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
#if NET_VERSION_4_5
 | 
					 | 
				
			||||||
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
					        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        public void Enqueue(TItem node, TPriority priority)
 | 
					        public void Enqueue(TItem node, TPriority priority)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
#if DEBUG
 | 
					#if DEBUG
 | 
				
			||||||
@ -131,9 +126,7 @@ namespace Priority_Queue
 | 
				
			|||||||
            CascadeUp(_nodes[_numNodes]);
 | 
					            CascadeUp(_nodes[_numNodes]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if NET_VERSION_4_5
 | 
					 | 
				
			||||||
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
					        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        private void Swap(TItem node1, TItem node2)
 | 
					        private void Swap(TItem node1, TItem node2)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            //Swap the nodes
 | 
					            //Swap the nodes
 | 
				
			||||||
@ -164,9 +157,7 @@ namespace Priority_Queue
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if NET_VERSION_4_5
 | 
					 | 
				
			||||||
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
					        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        private void CascadeDown(TItem node)
 | 
					        private void CascadeDown(TItem node)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            //aka Heapify-down
 | 
					            //aka Heapify-down
 | 
				
			||||||
@ -228,9 +219,7 @@ namespace Priority_Queue
 | 
				
			|||||||
        /// Returns true if 'higher' has higher priority than 'lower', false otherwise.
 | 
					        /// Returns true if 'higher' has higher priority than 'lower', false otherwise.
 | 
				
			||||||
        /// Note that calling HasHigherPriority(node, node) (ie. both arguments the same node) will return false
 | 
					        /// Note that calling HasHigherPriority(node, node) (ie. both arguments the same node) will return false
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
#if NET_VERSION_4_5
 | 
					 | 
				
			||||||
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
					        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        private bool HasHigherPriority(TItem higher, TItem lower)
 | 
					        private bool HasHigherPriority(TItem higher, TItem lower)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var cmp = higher.Priority.CompareTo(lower.Priority);
 | 
					            var cmp = higher.Priority.CompareTo(lower.Priority);
 | 
				
			||||||
@ -319,9 +308,7 @@ namespace Priority_Queue
 | 
				
			|||||||
        /// Calling this method on a node not in the queue results in undefined behavior
 | 
					        /// Calling this method on a node not in the queue results in undefined behavior
 | 
				
			||||||
        /// O(log n)
 | 
					        /// O(log n)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
#if NET_VERSION_4_5
 | 
					 | 
				
			||||||
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
					        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        public void UpdatePriority(TItem node, TPriority priority)
 | 
					        public void UpdatePriority(TItem node, TPriority priority)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
#if DEBUG
 | 
					#if DEBUG
 | 
				
			||||||
 | 
				
			|||||||
@ -206,8 +206,7 @@ namespace MediaBrowser.Providers.Manager
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            var image = item.GetImageInfo(type, 0);
 | 
					            var image = item.GetImageInfo(type, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // if it's a placeholder image then pretend like it's not there so that we can replace it
 | 
					            return image != null;
 | 
				
			||||||
            return image != null && !image.IsPlaceholder;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
@ -547,7 +546,7 @@ namespace MediaBrowser.Providers.Manager
 | 
				
			|||||||
            switch (type)
 | 
					            switch (type)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                case ImageType.Primary:
 | 
					                case ImageType.Primary:
 | 
				
			||||||
                    return !(item is Movie || item is Series || item is Game);
 | 
					                    return true;
 | 
				
			||||||
                default:
 | 
					                default:
 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -262,8 +262,7 @@ namespace MediaBrowser.Providers.Manager
 | 
				
			|||||||
            personEntity.SetImage(new ItemImageInfo
 | 
					            personEntity.SetImage(new ItemImageInfo
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Path = imageUrl,
 | 
					                Path = imageUrl,
 | 
				
			||||||
                Type = ImageType.Primary,
 | 
					                Type = ImageType.Primary
 | 
				
			||||||
                IsPlaceholder = true
 | 
					 | 
				
			||||||
            }, 0);
 | 
					            }, 0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -146,6 +146,11 @@ namespace MediaBrowser.Providers.MediaInfo
 | 
				
			|||||||
                return _cachedTask;
 | 
					                return _cachedTask;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!item.IsCompleteMedia)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return _cachedTask;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (item.IsShortcut)
 | 
					            if (item.IsShortcut)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                FetchShortcutInfo(item);
 | 
					                FetchShortcutInfo(item);
 | 
				
			||||||
 | 
				
			|||||||
@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.MediaInfo
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            var video = item as Video;
 | 
					            var video = item as Video;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut)
 | 
					            if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut && video.IsCompleteMedia)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,3 @@
 | 
				
			|||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[assembly: AssemblyVersion("3.2.30.24")]
 | 
					[assembly: AssemblyVersion("3.2.30.25")]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user