diff --git a/MediaBrowser.Api/UserLibrary/ItemByNameUserDataService.cs b/MediaBrowser.Api/UserLibrary/ItemByNameUserDataService.cs index 4834dcbef..7913b8c8a 100644 --- a/MediaBrowser.Api/UserLibrary/ItemByNameUserDataService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemByNameUserDataService.cs @@ -228,7 +228,7 @@ namespace MediaBrowser.Api.UserLibrary // Set favorite status data.IsFavorite = isFavorite; - await UserDataRepository.SaveUserData(userId, key, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false); + await UserDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false); data = UserDataRepository.GetUserData(userId, key); @@ -254,7 +254,7 @@ namespace MediaBrowser.Api.UserLibrary data.Likes = likes; - await UserDataRepository.SaveUserData(userId, key, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false); + await UserDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false); data = UserDataRepository.GetUserData(userId, key); diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 4b3f35e96..6b7980b1f 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -608,7 +608,7 @@ namespace MediaBrowser.Api.UserLibrary // Set favorite status data.IsFavorite = isFavorite; - await _userDataRepository.SaveUserData(user.Id, key, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false); + await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false); data = _userDataRepository.GetUserData(user.Id, key); @@ -657,7 +657,7 @@ namespace MediaBrowser.Api.UserLibrary data.Likes = likes; - await _userDataRepository.SaveUserData(user.Id, key, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false); + await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false); data = _userDataRepository.GetUserData(user.Id, key); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 6832ca714..3f670b807 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1339,7 +1339,7 @@ namespace MediaBrowser.Controller.Entities data.LastPlayedDate = datePlayed ?? data.LastPlayedDate; data.Played = true; - await userManager.SaveUserData(user.Id, key, data, UserDataSaveReason.TogglePlayed, CancellationToken.None).ConfigureAwait(false); + await userManager.SaveUserData(user.Id, this, data, UserDataSaveReason.TogglePlayed, CancellationToken.None).ConfigureAwait(false); } /// @@ -1368,7 +1368,7 @@ namespace MediaBrowser.Controller.Entities data.LastPlayedDate = null; data.Played = false; - await userManager.SaveUserData(user.Id, key, data, UserDataSaveReason.TogglePlayed, CancellationToken.None).ConfigureAwait(false); + await userManager.SaveUserData(user.Id, this, data, UserDataSaveReason.TogglePlayed, CancellationToken.None).ConfigureAwait(false); } /// diff --git a/MediaBrowser.Controller/Library/IUserDataManager.cs b/MediaBrowser.Controller/Library/IUserDataManager.cs index 5a4dcd55d..d6d5f99aa 100644 --- a/MediaBrowser.Controller/Library/IUserDataManager.cs +++ b/MediaBrowser.Controller/Library/IUserDataManager.cs @@ -20,12 +20,12 @@ namespace MediaBrowser.Controller.Library /// Saves the user data. /// /// The user id. - /// The key. + /// The item. /// The user data. /// The reason. /// The cancellation token. /// Task. - Task SaveUserData(Guid userId, string key, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken); + Task SaveUserData(Guid userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken); /// /// Gets the user data. diff --git a/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs b/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs index 752bed618..87e7f647a 100644 --- a/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs +++ b/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs @@ -32,5 +32,11 @@ namespace MediaBrowser.Controller.Library /// /// The user data. public UserItemData UserData { get; set; } + + /// + /// Gets or sets the item. + /// + /// The item. + public BaseItem Item { get; set; } } } diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs index ee854018b..de7e8e98d 100644 --- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs @@ -248,11 +248,6 @@ namespace MediaBrowser.Controller.Providers return true; } - if (RequiresInternet && DateTime.UtcNow > (providerInfo.LastRefreshed.AddDays(ConfigurationManager.Configuration.MetadataRefreshDays))) - { - return true; - } - if (providerInfo.LastRefreshStatus != ProviderRefreshStatus.Success) { return true; diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index b17ff6268..b15414fdd 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -123,17 +123,13 @@ namespace MediaBrowser.Providers.TV if (parts.Length == 3) { - var seasonNumberString = parts[1]; - int seasonNumber; - if (int.TryParse(seasonNumberString, NumberStyles.Integer, UsCulture, out seasonNumber)) + if (int.TryParse(parts[1], NumberStyles.Integer, UsCulture, out seasonNumber)) { - var episodeNumberString = parts[2]; - int episodeNumber; - if (int.TryParse(episodeNumberString, NumberStyles.Integer, UsCulture, out episodeNumber)) + if (int.TryParse(parts[2], NumberStyles.Integer, UsCulture, out episodeNumber)) { return new Tuple(seasonNumber, episodeNumber); } @@ -145,22 +141,17 @@ namespace MediaBrowser.Providers.TV .Where(i => i.Item1 != -1 && i.Item2 != -1) .ToList(); - var existingEpisodes = series.RecursiveChildren - .OfType() - .Where(i => i.IndexNumber.HasValue && i.ParentIndexNumber.HasValue) - .ToList(); - var hasChanges = false; if (_config.Configuration.CreateVirtualMissingEpisodes || _config.Configuration.CreateVirtualFutureEpisodes) { if (_config.Configuration.EnableInternetProviders) { - hasChanges = await AddMissingEpisodes(series, seriesDataPath, existingEpisodes, episodeLookup, cancellationToken).ConfigureAwait(false); + hasChanges = await AddMissingEpisodes(series, seriesDataPath, episodeLookup, cancellationToken).ConfigureAwait(false); } } - var anyRemoved = await RemoveObsoleteMissingEpisodes(series, existingEpisodes, cancellationToken).ConfigureAwait(false); + var anyRemoved = await RemoveObsoleteMissingEpisodes(series, cancellationToken).ConfigureAwait(false); if (hasChanges || anyRemoved) { @@ -174,12 +165,15 @@ namespace MediaBrowser.Providers.TV /// /// The series. /// The series data path. - /// The existing episodes. /// The episode lookup. /// The cancellation token. /// Task. - private async Task AddMissingEpisodes(Series series, string seriesDataPath, List existingEpisodes, IEnumerable> episodeLookup, CancellationToken cancellationToken) + private async Task AddMissingEpisodes(Series series, string seriesDataPath, IEnumerable> episodeLookup, CancellationToken cancellationToken) { + var existingEpisodes = series.RecursiveChildren + .OfType() + .ToList(); + var hasChanges = false; foreach (var tuple in episodeLookup) @@ -209,8 +203,9 @@ namespace MediaBrowser.Providers.TV { continue; } + var now = DateTime.UtcNow; - if (airDate.Value < DateTime.UtcNow && _config.Configuration.CreateVirtualMissingEpisodes) + if (airDate.Value < now && _config.Configuration.CreateVirtualMissingEpisodes) { // tvdb has a lot of nearly blank episodes _logger.Info("Creating virtual missing episode {0} {1}x{2}", series.Name, tuple.Item1, tuple.Item2); @@ -219,7 +214,7 @@ namespace MediaBrowser.Providers.TV hasChanges = true; } - else if (airDate.Value > DateTime.UtcNow && _config.Configuration.CreateVirtualFutureEpisodes) + else if (airDate.Value > now && _config.Configuration.CreateVirtualFutureEpisodes) { // tvdb has a lot of nearly blank episodes _logger.Info("Creating virtual future episode {0} {1}x{2}", series.Name, tuple.Item1, tuple.Item2); @@ -236,14 +231,21 @@ namespace MediaBrowser.Providers.TV /// /// Removes the virtual entry after a corresponding physical version has been added /// - private async Task RemoveObsoleteMissingEpisodes(Series series, List existingEpisodes, CancellationToken cancellationToken) + private async Task RemoveObsoleteMissingEpisodes(Series series, CancellationToken cancellationToken) { + var existingEpisodes = series.RecursiveChildren + .OfType() + .ToList(); + var physicalEpisodes = existingEpisodes .Where(i => i.LocationType != LocationType.Virtual) .ToList(); - var episodesToRemove = existingEpisodes + var virtualEpisodes = existingEpisodes .Where(i => i.LocationType == LocationType.Virtual) + .ToList(); + + var episodesToRemove = virtualEpisodes .Where(i => { if (i.IndexNumber.HasValue && i.ParentIndexNumber.HasValue) @@ -279,7 +281,8 @@ namespace MediaBrowser.Providers.TV /// Task. private async Task AddEpisode(Series series, int seasonNumber, int episodeNumber, CancellationToken cancellationToken) { - var season = series.Children.OfType().FirstOrDefault(i => i.IndexNumber.HasValue && i.IndexNumber.Value == seasonNumber); + var season = series.Children.OfType() + .FirstOrDefault(i => i.IndexNumber.HasValue && i.IndexNumber.Value == seasonNumber); if (season == null) { @@ -290,7 +293,7 @@ namespace MediaBrowser.Providers.TV var episode = new Episode { - Name = string.Format("Episode {0}", episodeNumber.ToString(UsCulture)), + Name = name, IndexNumber = episodeNumber, ParentIndexNumber = seasonNumber, Parent = season, diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs index bf62e09c3..8d010aecc 100644 --- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs @@ -37,37 +37,37 @@ namespace MediaBrowser.Server.Implementations.Library /// Saves the user data. /// /// The user id. - /// The key. + /// The item. /// The user data. /// The reason. /// The cancellation token. /// Task. - /// - /// userData + /// userData /// or /// cancellationToken /// or /// userId /// or - /// key - /// - public async Task SaveUserData(Guid userId, string key, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken) + /// key + public async Task SaveUserData(Guid userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken) { if (userData == null) { throw new ArgumentNullException("userData"); } + if (item == null) + { + throw new ArgumentNullException("item"); + } if (userId == Guid.Empty) { throw new ArgumentNullException("userId"); } - if (string.IsNullOrEmpty(key)) - { - throw new ArgumentNullException("key"); - } cancellationToken.ThrowIfCancellationRequested(); + var key = item.GetUserDataKey(); + try { await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false); @@ -89,7 +89,8 @@ namespace MediaBrowser.Server.Implementations.Library Key = key, UserData = userData, SaveReason = reason, - UserId = userId + UserId = userId, + Item = item }, _logger); } diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 473f2c67a..47a9ab1bd 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -254,7 +254,7 @@ namespace MediaBrowser.Server.Implementations.Session data.Played = true; } - await _userDataRepository.SaveUserData(user.Id, key, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false); + await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false); // Nothing to save here // Fire events to inform plugins @@ -298,7 +298,7 @@ namespace MediaBrowser.Server.Implementations.Session UpdatePlayState(info.Item, data, info.PositionTicks.Value); - await _userDataRepository.SaveUserData(user.Id, key, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); + await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); } EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs @@ -361,7 +361,7 @@ namespace MediaBrowser.Server.Implementations.Session data.PlaybackPositionTicks = 0; } - await _userDataRepository.SaveUserData(user.Id, key, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false); + await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false); EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackProgressEventArgs {