diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 216f1cf81f..bf86c049f2 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -411,6 +411,7 @@ + diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 97591551c1..fd373050f0 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -152,7 +152,7 @@ namespace MediaBrowser.Controller.Sync /// /// The query. /// QueryResult<System.String>. - QueryResult GetLibraryItemIds(SyncJobItemQuery query); + QueryResult GetSyncedItemProgresses(SyncJobItemQuery query); /// /// Reports the synchronize job item transfer beginning. diff --git a/MediaBrowser.Controller/Sync/ISyncRepository.cs b/MediaBrowser.Controller/Sync/ISyncRepository.cs index 315f5f5414..2af09dbaad 100644 --- a/MediaBrowser.Controller/Sync/ISyncRepository.cs +++ b/MediaBrowser.Controller/Sync/ISyncRepository.cs @@ -74,6 +74,6 @@ namespace MediaBrowser.Controller.Sync /// /// The query. /// QueryResult<System.String>. - QueryResult GetLibraryItemIds(SyncJobItemQuery query); + QueryResult GetSyncedItemProgresses(SyncJobItemQuery query); } } diff --git a/MediaBrowser.Controller/Sync/SyncedItemProgress.cs b/MediaBrowser.Controller/Sync/SyncedItemProgress.cs new file mode 100644 index 0000000000..edb42eb0f1 --- /dev/null +++ b/MediaBrowser.Controller/Sync/SyncedItemProgress.cs @@ -0,0 +1,10 @@ +using MediaBrowser.Model.Sync; + +namespace MediaBrowser.Controller.Sync +{ + public class SyncedItemProgress + { + public string ItemId { get; set; } + public SyncJobItemStatus Status { get; set; } + } +} diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index fb157e9ae7..7c5d9e9a11 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -100,6 +100,11 @@ namespace MediaBrowser.Model.Dto /// /// The synchronize status. public SyncJobItemStatus? SyncStatus { get; set; } + /// + /// Gets or sets the synchronize percent. + /// + /// The synchronize percent. + public double? SyncPercent { get; set; } /// /// Gets or sets the DVD season number. diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 5853b5b750..f9dfb13508 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -87,13 +87,14 @@ namespace MediaBrowser.Server.Implementations.Dto public IEnumerable GetBaseItemDtos(IEnumerable items, DtoOptions options, User user = null, BaseItem owner = null) { - var tuple = GetItemIdsWithSyncJobs(options); + var syncJobItems = GetSyncedItemProgress(options); + var syncDictionary = syncJobItems.ToDictionary(i => i.ItemId); var list = new List(); foreach (var item in items) { - var dto = GetBaseItemDtoInternal(item, options, user, owner); + var dto = GetBaseItemDtoInternal(item, options, syncDictionary, user, owner); var byName = item as IItemByName; @@ -111,7 +112,7 @@ namespace MediaBrowser.Server.Implementations.Dto } } - FillSyncInfo(dto, item, tuple.Item1, tuple.Item2, options, user); + FillSyncInfo(dto, item, syncJobItems, options, user); list.Add(dto); } @@ -121,7 +122,9 @@ namespace MediaBrowser.Server.Implementations.Dto public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) { - var dto = GetBaseItemDtoInternal(item, options, user, owner); + var syncProgress = GetSyncedItemProgress(options); + + var dto = GetBaseItemDtoInternal(item, options, syncProgress.ToDictionary(i => i.ItemId), user, owner); var byName = item as IItemByName; @@ -138,35 +141,35 @@ namespace MediaBrowser.Server.Implementations.Dto SetItemByNameInfo(item, dto, libraryItems.ToList(), user); } - FillSyncInfo(dto, item, options, user); + FillSyncInfo(dto, item, options, user, syncProgress); return dto; } - FillSyncInfo(dto, item, options, user); + FillSyncInfo(dto, item, options, user, syncProgress); return dto; } - private Tuple, IEnumerable> GetItemIdsWithSyncJobs(DtoOptions options) + private SyncedItemProgress[] GetSyncedItemProgress(DtoOptions options) { if (!options.Fields.Contains(ItemFields.SyncInfo)) { - return new Tuple, IEnumerable>(new List(), new List()); + return new SyncedItemProgress[]{}; } var deviceId = options.DeviceId; if (string.IsNullOrWhiteSpace(deviceId)) { - return new Tuple, IEnumerable>(new List(), new List()); + return new SyncedItemProgress[] { }; } var caps = _deviceManager().GetCapabilities(deviceId); if (caps == null || !caps.SupportsSync) { - return new Tuple, IEnumerable>(new List(), new List()); + return new SyncedItemProgress[] { }; } - var result1 = _syncManager.GetLibraryItemIds(new SyncJobItemQuery + return _syncManager.GetSyncedItemProgresses(new SyncJobItemQuery { TargetId = deviceId, Statuses = new[] @@ -174,38 +177,28 @@ namespace MediaBrowser.Server.Implementations.Dto SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, SyncJobItemStatus.Transferring, - SyncJobItemStatus.ReadyToTransfer - } - }); - - var result2 = _syncManager.GetLibraryItemIds(new SyncJobItemQuery - { - TargetId = deviceId, - Statuses = new[] - { + SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced } - }); - - return new Tuple, IEnumerable>(result1.Items, result2.Items); + }).Items; } public void FillSyncInfo(IEnumerable dtos, DtoOptions options, User user) { if (options.Fields.Contains(ItemFields.SyncInfo)) { - var tuple = GetItemIdsWithSyncJobs(options); + var syncProgress = GetSyncedItemProgress(options); foreach (var dto in dtos) { var item = _libraryManager.GetItemById(dto.Id); - FillSyncInfo(dto, item, tuple.Item1, tuple.Item2, options, user); + FillSyncInfo(dto, item, syncProgress, options, user); } } } - private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, DtoOptions options, User user) + private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, DtoOptions options, User user, SyncedItemProgress[] syncProgress) { if (options.Fields.Contains(ItemFields.SyncInfo)) { @@ -215,10 +208,8 @@ namespace MediaBrowser.Server.Implementations.Dto if (dto.SupportsSync ?? false) { - var tuple = GetItemIdsWithSyncJobs(options); - - dto.HasSyncJob = tuple.Item1.Contains(dto.Id, StringComparer.OrdinalIgnoreCase); - dto.IsSynced = tuple.Item2.Contains(dto.Id, StringComparer.OrdinalIgnoreCase); + dto.HasSyncJob = syncProgress.Any(i => i.Status != SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); + dto.IsSynced = syncProgress.Any(i => i.Status == SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); if (dto.IsSynced.Value) { @@ -232,7 +223,7 @@ namespace MediaBrowser.Server.Implementations.Dto } } - private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, IEnumerable itemIdsWithPendingSyncJobs, IEnumerable syncedItemIds, DtoOptions options, User user) + private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, SyncedItemProgress[] syncProgress, DtoOptions options, User user) { if (options.Fields.Contains(ItemFields.SyncInfo)) { @@ -242,8 +233,8 @@ namespace MediaBrowser.Server.Implementations.Dto if (dto.SupportsSync ?? false) { - dto.HasSyncJob = itemIdsWithPendingSyncJobs.Contains(dto.Id, StringComparer.OrdinalIgnoreCase); - dto.IsSynced = syncedItemIds.Contains(dto.Id, StringComparer.OrdinalIgnoreCase); + dto.HasSyncJob = syncProgress.Any(i => i.Status != SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); + dto.IsSynced = syncProgress.Any(i => i.Status == SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); if (dto.IsSynced.Value) { @@ -257,7 +248,7 @@ namespace MediaBrowser.Server.Implementations.Dto } } - private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) + private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, Dictionary syncProgress, User user = null, BaseItem owner = null) { var fields = options.Fields; @@ -301,7 +292,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (user != null) { - AttachUserSpecificInfo(dto, item, user, fields); + AttachUserSpecificInfo(dto, item, user, fields, syncProgress); } var hasMediaSources = item as IHasMediaSources; @@ -368,14 +359,16 @@ namespace MediaBrowser.Server.Implementations.Dto public BaseItemDto GetItemByNameDto(T item, DtoOptions options, List taggedItems, User user = null) where T : BaseItem, IItemByName { - var dto = GetBaseItemDtoInternal(item, options, user); + var syncProgress = GetSyncedItemProgress(options); + + var dto = GetBaseItemDtoInternal(item, options, syncProgress.ToDictionary(i => i.ItemId), user); if (options.Fields.Contains(ItemFields.ItemCounts)) { SetItemByNameInfo(item, dto, taggedItems, user); } - FillSyncInfo(dto, item, options, user); + FillSyncInfo(dto, item, options, user, syncProgress); return dto; } @@ -415,7 +408,8 @@ namespace MediaBrowser.Server.Implementations.Dto /// The item. /// The user. /// The fields. - private void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List fields) + /// The synchronize progress. + private void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List fields, Dictionary syncProgress) { if (item.IsFolder) { @@ -433,7 +427,7 @@ namespace MediaBrowser.Server.Implementations.Dto // TODO: Disable for CollectionFolder if (!(folder is UserRootFolder) && !(folder is UserView)) { - SetSpecialCounts(folder, user, dto, fields); + SetSpecialCounts(folder, user, dto, fields, syncProgress); } dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && dto.UserData.PlayedPercentage.Value >= 100; @@ -1599,8 +1593,9 @@ namespace MediaBrowser.Server.Implementations.Dto /// The user. /// The dto. /// The fields. + /// The synchronize progress. /// Task. - private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List fields) + private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List fields, Dictionary syncProgress) { var recursiveItemCount = 0; var unplayed = 0; @@ -1608,6 +1603,8 @@ namespace MediaBrowser.Server.Implementations.Dto DateTime? dateLastMediaAdded = null; double totalPercentPlayed = 0; + double totalSyncPercent = 0; + var addSyncInfo = fields.Contains(ItemFields.SyncInfo); IEnumerable children; @@ -1666,6 +1663,27 @@ namespace MediaBrowser.Server.Implementations.Dto } runtime += child.RunTimeTicks ?? 0; + + if (addSyncInfo) + { + double percent = 0; + SyncedItemProgress syncItemProgress; + if (syncProgress.TryGetValue(dto.Id, out syncItemProgress)) + { + switch (syncItemProgress.Status) + { + case SyncJobItemStatus.Synced: + percent = 100; + break; + case SyncJobItemStatus.Converting: + case SyncJobItemStatus.ReadyToTransfer: + case SyncJobItemStatus.Transferring: + percent = 50; + break; + } + } + totalSyncPercent += percent; + } } dto.RecursiveItemCount = recursiveItemCount; @@ -1674,6 +1692,11 @@ namespace MediaBrowser.Server.Implementations.Dto if (recursiveItemCount > 0) { dto.UserData.PlayedPercentage = totalPercentPlayed / recursiveItemCount; + + if (addSyncInfo) + { + dto.SyncPercent = totalSyncPercent / recursiveItemCount; + } } if (runtime > 0 && fields.Contains(ItemFields.CumulativeRunTimeTicks)) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index d47135c65c..8461176b4d 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1131,9 +1131,9 @@ namespace MediaBrowser.Server.Implementations.Sync await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } - public QueryResult GetLibraryItemIds(SyncJobItemQuery query) + public QueryResult GetSyncedItemProgresses(SyncJobItemQuery query) { - return _repo.GetLibraryItemIds(query); + return _repo.GetSyncedItemProgresses(query); } public SyncJobOptions GetAudioOptions(SyncJobItem jobItem, SyncJob job) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 5ad351af52..75c9290164 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -627,9 +627,9 @@ namespace MediaBrowser.Server.Implementations.Sync } } - public QueryResult GetLibraryItemIds(SyncJobItemQuery query) + public QueryResult GetSyncedItemProgresses(SyncJobItemQuery query) { - return GetJobItemReader(query, "select ItemId from SyncJobItems", GetItemId); + return GetJobItemReader(query, "select ItemId,Status from SyncJobItems", GetSyncedItemProgress); } public QueryResult GetJobItems(SyncJobItemQuery query) @@ -788,9 +788,18 @@ namespace MediaBrowser.Server.Implementations.Sync return info; } - private string GetItemId(IDataReader reader) + private SyncedItemProgress GetSyncedItemProgress(IDataReader reader) { - return reader.GetString(0); + var item = new SyncedItemProgress(); + + item.ItemId = reader.GetString(0); + + if (!reader.IsDBNull(1)) + { + item.Status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(1), true); + } + + return item; } /// diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 84b0d2d851..a4a5b672e1 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -117,7 +117,7 @@ PreserveNewest - + PreserveNewest @@ -201,7 +201,7 @@ PreserveNewest - + PreserveNewest