diff options
Diffstat (limited to 'Emby.Server.Implementations')
14 files changed, 157 insertions, 83 deletions
diff --git a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs index c7378956d..f47e2d10a 100644 --- a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs +++ b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs @@ -57,7 +57,7 @@ namespace Emby.Server.Implementations.Collections return subItem; } - var parent = subItem.GetParent(); + var parent = subItem.IsOwnedItem ? subItem.GetOwner() : subItem.GetParent(); if (parent != null && parent.HasImage(ImageType.Primary)) { diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 6811e42ec..2186982d3 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -253,6 +253,7 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "TypedBaseItems", "ExternalId", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "SeriesPresentationUniqueKey", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "ShowId", "Text", existingColumnNames); + AddColumn(db, "TypedBaseItems", "OwnerId", "Text", existingColumnNames); existingColumnNames = GetColumnNames(db, "ItemValues"); AddColumn(db, "ItemValues", "CleanValue", "Text", existingColumnNames); @@ -459,7 +460,8 @@ namespace Emby.Server.Implementations.Data "AlbumArtists", "ExternalId", "SeriesPresentationUniqueKey", - "ShowId" + "ShowId", + "OwnerId" }; private readonly string[] _mediaStreamSaveColumns = @@ -580,7 +582,8 @@ namespace Emby.Server.Implementations.Data "AlbumArtists", "ExternalId", "SeriesPresentationUniqueKey", - "ShowId" + "ShowId", + "OwnerId" }; 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("@ProductionYear", item.ProductionYear); - if (item.ParentId == Guid.Empty) + var parentId = item.ParentId; + if (parentId == Guid.Empty) { saveItemStatement.TryBindNull("@ParentId"); } else { - saveItemStatement.TryBind("@ParentId", item.ParentId); + saveItemStatement.TryBind("@ParentId", parentId); } if (item.Genres.Count > 0) @@ -1057,6 +1061,16 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBindNull("@ShowId"); } + var ownerId = item.OwnerId; + if (ownerId != Guid.Empty) + { + saveItemStatement.TryBind("@OwnerId", ownerId); + } + else + { + saveItemStatement.TryBindNull("@OwnerId"); + } + saveItemStatement.MoveNext(); } @@ -1156,16 +1170,14 @@ namespace Emby.Server.Implementations.Data delimeter + image.DateModified.Ticks.ToString(CultureInfo.InvariantCulture) + delimeter + - image.Type + - delimeter + - image.IsPlaceholder; + image.Type; } public ItemImageInfo ItemImageInfoFromValueString(string value) { var parts = value.Split(new[] { '*' }, StringSplitOptions.None); - if (parts.Length != 4) + if (parts.Length < 3) { return null; } @@ -1173,9 +1185,18 @@ namespace Emby.Server.Implementations.Data var image = new ItemImageInfo(); 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); - image.IsPlaceholder = string.Equals(parts[3], true.ToString(), StringComparison.OrdinalIgnoreCase); + + long ticks; + 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; } @@ -1965,6 +1986,12 @@ namespace Emby.Server.Implementations.Data } } + if (!reader.IsDBNull(index)) + { + item.OwnerId = reader.GetGuid(index); + } + index++; + return item; } @@ -4467,7 +4494,6 @@ namespace Emby.Server.Implementations.Data } } - var includedItemByNameTypes = GetItemByNameTypesInQuery(query).SelectMany(MapIncludeItemTypes).ToList(); var enableItemsByName = (query.IncludeItemsByName ?? false) && includedItemByNameTypes.Count > 0; diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index b57662e31..1854829a2 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -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)) { diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 796d8cf48..299da0744 100644 --- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -198,9 +198,10 @@ namespace Emby.Server.Implementations.EntryPoints 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); @@ -259,9 +260,10 @@ namespace Emby.Server.Implementations.EntryPoints 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); diff --git a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs index 13e14be36..4c16b1d39 100644 --- a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs +++ b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs @@ -1,43 +1,74 @@ using System; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Plugins; 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 { /// <summary> /// Class RefreshUsersMetadata /// </summary> - public class RefreshUsersMetadata : IServerEntryPoint + public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask { /// <summary> /// The _user manager /// </summary> 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> /// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class. /// </summary> - /// <param name="userManager">The user manager.</param> - public RefreshUsersMetadata(IUserManager userManager) + public RefreshUsersMetadata(IUserManager userManager, IFileSystem fileSystem) { _userManager = userManager; + _fileSystem = fileSystem; } - /// <summary> - /// Runs this instance. - /// </summary> - public async void Run() + public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { - 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> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() + public IEnumerable<TaskTriggerInfo> GetDefaultTriggers() { - GC.SuppressFinalize(this); + return new List<TaskTriggerInfo> + { + new TaskTriggerInfo + { + IntervalTicks = TimeSpan.FromDays(1).Ticks, + Type = TaskTriggerInfo.TriggerInterval + } + }; } } } diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index 4a7182a43..13c72bf3c 100644 --- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -77,7 +77,7 @@ namespace Emby.Server.Implementations.EntryPoints // Go up one level for indicators if (baseItem != null) { - var parent = baseItem.GetParent(); + var parent = baseItem.IsOwnedItem ? baseItem.GetOwner() : baseItem.GetParent(); if (parent != null) { diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs index 20de8a518..315bee103 100644 --- a/Emby.Server.Implementations/IO/FileRefresher.cs +++ b/Emby.Server.Implementations/IO/FileRefresher.cs @@ -209,7 +209,7 @@ namespace Emby.Server.Implementations.IO // If the item has been deleted find the first valid parent that still exists while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path)) { - item = item.GetParent(); + item = item.IsOwnedItem ? item.GetOwner() : item.GetParent(); if (item == null) { diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 139435faa..eab52e5e8 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -386,7 +386,7 @@ namespace Emby.Server.Implementations.Library item.Id); } - var parent = item.Parent; + var parent = item.IsOwnedItem ? item.GetOwner() : item.GetParent(); var locationType = item.LocationType; @@ -453,12 +453,28 @@ namespace Emby.Server.Implementations.Library 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) { - 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); @@ -2604,8 +2620,11 @@ namespace Emby.Server.Implementations.Library { video = dbItem; } - - video.ExtraType = ExtraType.Trailer; + else + { + // item is new + video.ExtraType = ExtraType.Trailer; + } video.TrailerTypes = new List<TrailerType> { TrailerType.LocalTrailer }; return video; @@ -2846,13 +2865,6 @@ namespace Emby.Server.Implementations.Library 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); return item.GetImageInfo(image.Type, imageIndex); diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index c9de3c01b..0f48ff46b 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -518,11 +518,12 @@ namespace Emby.Server.Implementations.Library /// </summary> /// <param name="cancellationToken">The cancellation token.</param> /// <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(); - - return Task.WhenAll(tasks); + foreach (var user in Users) + { + await user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken).ConfigureAwait(false); + } } /// <summary> diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs index 2a2e1886f..f0578d9ef 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs @@ -42,6 +42,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV 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)) { onStarted(); @@ -76,6 +78,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { _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)) { onStarted(); diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index bd9754f26..1975a6b01 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1429,14 +1429,13 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV string liveStreamId = null; - OnRecordingStatusChanged(); - try { var recorder = await GetRecorder().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) .ConfigureAwait(false); @@ -1450,23 +1449,20 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV recordPath = EnsureFileUnique(recordPath, timer.Id); _libraryMonitor.ReportFileSystemChangeBeginning(recordPath); - _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(recordPath)); activeRecordingInfo.Path = recordPath; var duration = recordingEndDate - DateTime.UtcNow; - _logger.Info("Beginning recording. Will record for {0} minutes.", - duration.TotalMinutes.ToString(CultureInfo.InvariantCulture)); + _logger.Info("Beginning recording. Will record for {0} minutes.", duration.TotalMinutes.ToString(CultureInfo.InvariantCulture)); _logger.Info("Writing file to path: " + recordPath); - _logger.Info("Opening recording stream from tuner provider"); - Action onStarted = () => + Action onStarted = async () => { timer.Status = RecordingStatus.InProgress; _timerProvider.AddOrUpdate(timer, false); - SaveRecordingMetadata(timer, recordPath, seriesPath); + await SaveRecordingMetadata(timer, recordPath, seriesPath).ConfigureAwait(false); TriggerRefresh(recordPath); EnforceKeepUpTo(timer, seriesPath); }; @@ -1500,7 +1496,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } TriggerRefresh(recordPath); - _libraryMonitor.ReportFileSystemChangeComplete(recordPath, true); + _libraryMonitor.ReportFileSystemChangeComplete(recordPath, false); ActiveRecordingInfo removed; _activeRecordings.TryRemove(timer.Id, out removed); @@ -1526,17 +1522,29 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { _timerProvider.Delete(timer); } - - OnRecordingStatusChanged(); } private void TriggerRefresh(string path) { + _logger.Debug("Triggering refresh on {0}", path); + var item = GetAffectedBaseItem(_fileSystem.GetDirectoryName(path)); 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; + var parentPath = _fileSystem.GetDirectoryName(path); + while (item == null && !string.IsNullOrEmpty(path)) { item = _libraryManager.FindByPath(path, null); @@ -1553,14 +1563,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV if (item != null) { - // If the item has been deleted find the first valid parent that still exists - while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path)) + if (item.GetType() == typeof(Folder) && string.Equals(item.Path, parentPath, StringComparison.OrdinalIgnoreCase)) { - item = item.GetParent(); - - if (item == null) + var parentItem = item.GetParent(); + if (parentItem != null && !(parentItem is AggregateFolder)) { - break; + item = parentItem; } } } @@ -1568,14 +1576,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return item; } - private void OnRecordingStatusChanged() - { - EventHelper.FireEventIfNotNull(RecordingStatusChanged, this, new RecordingStatusChangedEventArgs - { - - }, _logger); - } - private async void EnforceKeepUpTo(TimerInfo timer, string seriesPath) { 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 { diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 870a3b493..38d2fd3c6 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -843,8 +843,7 @@ namespace Emby.Server.Implementations.LiveTv item.SetImage(new ItemImageInfo { Path = info.ImagePath, - Type = ImageType.Primary, - IsPlaceholder = true + Type = ImageType.Primary }, 0); } else if (!string.IsNullOrWhiteSpace(info.ImageUrl)) @@ -852,8 +851,7 @@ namespace Emby.Server.Implementations.LiveTv item.SetImage(new ItemImageInfo { Path = info.ImageUrl, - Type = ImageType.Primary, - IsPlaceholder = true + Type = ImageType.Primary }, 0); } } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs index 4dcbc4b54..af064755d 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs @@ -134,7 +134,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun } _liveStreamTaskCompletionSource.TrySetResult(true); - //await DeleteTempFile(_tempFilePath).ConfigureAwait(false); + await DeleteTempFile(_tempFilePath).ConfigureAwait(false); }); } diff --git a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs index 525df0350..36e8b4dd8 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs @@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Playlists return subItem; } - var parent = subItem.GetParent(); + var parent = subItem.IsOwnedItem ? subItem.GetOwner() : subItem.GetParent(); if (parent != null && parent.HasImage(ImageType.Primary)) { |
