private async Task <TraktSyncResponse> SendLibraryUpdateInternalAsync( IEnumerable <Episode> episodes, TraktUser traktUser, EventType eventType, CancellationToken cancellationToken, bool useProviderIDs = true) { var episodesPayload = new List <TraktEpisodeCollected>(); var showPayload = new List <TraktShowCollected>(); foreach (Episode episode in episodes) { var audioStream = episode.GetMediaStreams().FirstOrDefault(x => x.Type == MediaStreamType.Audio); if (useProviderIDs && HasAnyProviderTvIds(episode) && (!episode.IndexNumber.HasValue || !episode.IndexNumberEnd.HasValue || episode.IndexNumberEnd <= episode.IndexNumber)) { var traktEpisodeCollected = new TraktEpisodeCollected { CollectedAt = episode.DateCreated.ToISO8601(), Ids = GetTraktTvIds <Episode, TraktEpisodeId>(episode) }; if (traktUser.ExportMediaInfo) { // traktEpisodeCollected.Is3D = episode.Is3D; traktEpisodeCollected.AudioChannels = audioStream.GetAudioChannels(); traktEpisodeCollected.Audio = audioStream.GetCodecRepresetation(); traktEpisodeCollected.Resolution = episode.GetDefaultVideoStream().GetResolution(); } episodesPayload.Add(traktEpisodeCollected); } else if (episode.IndexNumber.HasValue) { var indexNumber = episode.IndexNumber.Value; var finalNumber = (episode.IndexNumberEnd ?? episode.IndexNumber).Value; var syncShow = FindShow(showPayload, episode.Series); if (syncShow == null) { syncShow = new TraktShowCollected { Ids = GetTraktTvIds <Series, TraktShowId>(episode.Series), Seasons = new List <TraktSeasonCollected>() }; showPayload.Add(syncShow); } var syncSeason = syncShow.Seasons.FirstOrDefault(ss => ss.Number == episode.GetSeasonNumber()); if (syncSeason == null) { syncSeason = new TraktSeasonCollected { Number = episode.GetSeasonNumber(), Episodes = new List <TraktEpisodeCollected>() }; syncShow.Seasons.Add(syncSeason); } for (var number = indexNumber; number <= finalNumber; number++) { var ids = new TraktEpisodeId(); if (number == indexNumber) { // Omit this from the rest because then we end up attaching the provider IDs of the first episode to the subsequent ones ids = GetTraktTvIds <Episode, TraktEpisodeId>(episode); } var traktEpisodeCollected = new TraktEpisodeCollected { Number = number, CollectedAt = episode.DateCreated.ToISO8601(), Ids = ids }; if (traktUser.ExportMediaInfo) { // traktEpisodeCollected.Is3D = episode.Is3D; traktEpisodeCollected.AudioChannels = audioStream.GetAudioChannels(); traktEpisodeCollected.Audio = audioStream.GetCodecRepresetation(); traktEpisodeCollected.Resolution = episode.GetDefaultVideoStream().GetResolution(); } syncSeason.Episodes.Add(traktEpisodeCollected); } } } var data = new TraktSyncCollected { Episodes = episodesPayload.ToList(), Shows = showPayload.ToList() }; var url = eventType == EventType.Add ? TraktUris.SyncCollectionAdd : TraktUris.SyncCollectionRemove; using (var response = await PostToTrakt(url, data, traktUser, cancellationToken).ConfigureAwait(false)) { var tsr = await JsonSerializer.DeserializeAsync <TraktSyncResponse>(response, _jsonOptions, cancellationToken).ConfigureAwait(false); if (useProviderIDs && tsr.NotFound.Episodes.Count > 0) { // send subset of episodes back to trakt to try without ids _logger.LogDebug("Resend episodes Library update, without episode IDs"); await SendLibraryUpdateInternalAsync(FindNotFoundEpisodes(episodes, tsr), traktUser, eventType, cancellationToken, false).ConfigureAwait(false); } return(tsr); } }
private async Task <TraktSyncResponse> SendLibraryUpdateInternalAsync( IEnumerable <Episode> episodes, TraktUser traktUser, CancellationToken cancellationToken, EventType eventType) { var episodesPayload = new List <TraktEpisodeCollected>(); var showPayload = new List <TraktShowCollected>(); foreach (Episode episode in episodes) { var audioStream = episode.GetMediaStreams().FirstOrDefault(x => x.Type == MediaStreamType.Audio); var tvDbId = episode.GetProviderId(MetadataProvider.Tvdb); if (!string.IsNullOrEmpty(tvDbId) && (!episode.IndexNumber.HasValue || !episode.IndexNumberEnd.HasValue || episode.IndexNumberEnd <= episode.IndexNumber)) { var traktEpisodeCollected = new TraktEpisodeCollected { collected_at = episode.DateCreated.ToISO8601(), ids = new TraktEpisodeId { tvdb = tvDbId.ConvertToInt() } }; if (traktUser.ExportMediaInfo) { //traktEpisodeCollected.Is3D = episode.Is3D; traktEpisodeCollected.audio_channels = audioStream.GetAudioChannels(); traktEpisodeCollected.audio = audioStream.GetCodecRepresetation(); traktEpisodeCollected.resolution = episode.GetDefaultVideoStream().GetResolution(); } episodesPayload.Add(traktEpisodeCollected); } else if (episode.IndexNumber.HasValue) { var indexNumber = episode.IndexNumber.Value; var finalNumber = (episode.IndexNumberEnd ?? episode.IndexNumber).Value; var syncShow = showPayload.FirstOrDefault( sre => sre.ids != null && sre.ids.tvdb == episode.Series.GetProviderId(MetadataProvider.Tvdb).ConvertToInt()); if (syncShow == null) { syncShow = new TraktShowCollected { ids = new TraktShowId { tvdb = episode.Series.GetProviderId(MetadataProvider.Tvdb).ConvertToInt(), imdb = episode.Series.GetProviderId(MetadataProvider.Imdb), tvrage = episode.Series.GetProviderId(MetadataProvider.TvRage).ConvertToInt() }, seasons = new List <TraktShowCollected.TraktSeasonCollected>() }; showPayload.Add(syncShow); } var syncSeason = syncShow.seasons.FirstOrDefault(ss => ss.number == episode.GetSeasonNumber()); if (syncSeason == null) { syncSeason = new TraktShowCollected.TraktSeasonCollected { number = episode.GetSeasonNumber(), episodes = new List <TraktEpisodeCollected>() }; syncShow.seasons.Add(syncSeason); } for (var number = indexNumber; number <= finalNumber; number++) { var ids = new TraktEpisodeId(); if (number == indexNumber) { // Omit this from the rest because then we end up attaching the tvdb of the first episode to the subsequent ones ids.tvdb = tvDbId.ConvertToInt(); } var traktEpisodeCollected = new TraktEpisodeCollected { number = number, collected_at = episode.DateCreated.ToISO8601(), ids = ids }; if (traktUser.ExportMediaInfo) { //traktEpisodeCollected.Is3D = episode.Is3D; traktEpisodeCollected.audio_channels = audioStream.GetAudioChannels(); traktEpisodeCollected.audio = audioStream.GetCodecRepresetation(); traktEpisodeCollected.resolution = episode.GetDefaultVideoStream().GetResolution(); } syncSeason.episodes.Add(traktEpisodeCollected); } } } var data = new TraktSyncCollected { episodes = episodesPayload.ToList(), shows = showPayload.ToList() }; var url = eventType == EventType.Add ? TraktUris.SyncCollectionAdd : TraktUris.SyncCollectionRemove; using (var response = await PostToTrakt(url, data, cancellationToken, traktUser).ConfigureAwait(false)) { return(await JsonSerializer.DeserializeAsync <TraktSyncResponse>(response, _jsonOptions).ConfigureAwait(false)); } }