update owned items

This commit is contained in:
Luke Pulverenti 2017-09-18 12:52:22 -04:00
parent b01489c40f
commit cdd79ec7e2
30 changed files with 375 additions and 179 deletions

View File

@ -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))
{ {

View File

@ -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;

View File

@ -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))
{ {

View File

@ -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);

View File

@ -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
}
};
} }
} }
} }

View File

@ -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)
{ {

View File

@ -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)
{ {

View File

@ -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
{
// item is new
video.ExtraType = ExtraType.Trailer; 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);

View File

@ -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>

View File

@ -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();

View File

@ -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
{ {

View File

@ -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);
} }
} }

View File

@ -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);
}); });
} }

View File

@ -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))
{ {

View File

@ -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

View File

@ -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,10 +324,29 @@ 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>
@ -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
{
// item is new
audio.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong; 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 is new
item.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo; 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);

View File

@ -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
}; };

View File

@ -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);
} }
} }
@ -587,8 +596,11 @@ namespace MediaBrowser.Controller.Entities
await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false); await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false);
} }
else else
{
if (refreshOptions.RefreshItem(child))
{ {
await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); 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); var child = GetLinkedChild(i);
if (child != null) if (child == null)
{ {
var childLocationType = child.LocationType; continue;
}
var childOwner = child.IsOwnedItem ? (child.GetOwner() ?? child) : child;
if (childOwner != null)
{
var childLocationType = childOwner.LocationType;
if (childLocationType == LocationType.Remote || childLocationType == LocationType.Virtual) if (childLocationType == LocationType.Remote || childLocationType == LocationType.Virtual)
{ {
if (!child.IsVisibleStandalone(user)) if (!childOwner.IsVisibleStandalone(user))
{ {
return null; continue;
} }
} }
else if (childLocationType == LocationType.FileSystem) else if (childLocationType == LocationType.FileSystem)
{ {
var itemCollectionFolderIds = var itemCollectionFolderIds =
LibraryManager.GetCollectionFolders(child, allUserRootChildren) LibraryManager.GetCollectionFolders(childOwner, allUserRootChildren).Select(f => f.Id);
.Select(f => f.Id).ToList();
if (!itemCollectionFolderIds.Any(collectionFolderIds.Contains)) if (!itemCollectionFolderIds.Any(collectionFolderIds.Contains))
{ {
return null; continue;
} }
} }
} }
return child; list.Add(child);
}) }
.Where(i => i != null);
return list;
} }
/// <summary> /// <summary>

View File

@ -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.

View File

@ -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
{ {

View File

@ -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);

View File

@ -347,7 +347,10 @@ namespace MediaBrowser.Controller.Entities.TV
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
if (refreshOptions.RefreshItem(item))
{
await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
}
numComplete++; numComplete++;
double percent = numComplete; double percent = numComplete;
@ -381,9 +384,12 @@ namespace MediaBrowser.Controller.Entities.TV
} }
if (!skipItem) if (!skipItem)
{
if (refreshOptions.RefreshItem(item))
{ {
await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
} }
}
numComplete++; numComplete++;
double percent = numComplete; double percent = numComplete;

View File

@ -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>

View File

@ -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;
} }
} }
} }

View File

@ -33,7 +33,6 @@ namespace MediaBrowser.Model.LiveTv
MediaLocationsCreated = new string[] { }; MediaLocationsCreated = new string[] { };
RecordingEncodingFormat = "mkv"; RecordingEncodingFormat = "mkv";
RecordingPostProcessorArguments = "\"{path}\""; RecordingPostProcessorArguments = "\"{path}\"";
EnableRecordingEncoding = true;
} }
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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);

View File

@ -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;
} }