private Task <Either <ProcessFailedResult, AniDbEpisodeData> > MapEpisodeDataAsync(int aniDbSeriesId, TvDbSeriesData tvDbSeriesData, TvDbEpisodeData tvDbEpisodeData, ProcessResultContext resultContext) { var seriesMapping = this.mappingList.GetSeriesMappingsFromTvDb(tvDbSeriesData.Id, resultContext) .BindAsync(sm => sm.Where(m => m.Ids.AniDbSeriesId == aniDbSeriesId) .Match( () => resultContext.Failed( $"No series mapping between TvDb series Id '{tvDbSeriesData.Id}' and AniDb series id '{aniDbSeriesId}'"), Prelude.Right <ProcessFailedResult, ISeriesMapping>, (head, tail) => resultContext.Failed( $"Multiple series mappings found between TvDb series Id '{tvDbSeriesData.Id}' and AniDb series Id '{aniDbSeriesId}'"))); return(seriesMapping.BindAsync(sm => { var episodeGroupMapping = sm.GetEpisodeGroupMapping(tvDbEpisodeData.AiredEpisodeNumber, tvDbEpisodeData.AiredSeason); var aniDbEpisodeData = this.episodeMapper.MapTvDbEpisodeAsync(tvDbEpisodeData.AiredEpisodeNumber, sm, episodeGroupMapping); return aniDbEpisodeData.ToEither(resultContext.Failed( $"Failed to find a corresponding AniDb episode in AniDb series id '{aniDbSeriesId}'")); })); }
private static Either <ProcessFailedResult, AniListSeriesData> FailUnlessOneResult( IEnumerable <AniListSeriesData> aniListSeriesData, ProcessResultContext resultContext) { return(aniListSeriesData.Match( () => resultContext.Failed("No matching AniList series"), single => Right <ProcessFailedResult, AniListSeriesData>(single), (head, tail) => resultContext.Failed($"Found too many ({SeqExtensions.Count(tail) + 1}) matching AniList series"))); }
public Task <Either <ProcessFailedResult, AniDbSeriesData> > GetSeriesData(IEmbyItemData embyItemData, ProcessResultContext resultContext) { return(embyItemData.GetParentId(MediaItemTypes.Series, this) .ToEitherAsync( resultContext.Failed("No AniDb Id found on parent series")) .BindAsync(aniDbSeriesId => _aniDbClient.GetSeriesAsync(aniDbSeriesId) .ToEitherAsync( resultContext.Failed($"Failed to load parent series with AniDb Id '{aniDbSeriesId}'")))); }
private Task <Either <ProcessFailedResult, int> > MapSeriesDataAsync(int tvDbSeriesId, IdentifierOnlySourceData identifierData, ProcessResultContext resultContext) { var seriesMapping = this.mappingList.GetSeriesMappingsFromTvDb(tvDbSeriesId, resultContext) .BindAsync(sm => sm.Where(m => m.DefaultTvDbSeason.Exists(s => s.Index == identifierData.Identifier.Index)) .Match( () => resultContext.Failed( $"No series mapping between TvDb series Id '{tvDbSeriesId}', season '{identifierData.Identifier.Index}'' and AniDb series"), Prelude.Right <ProcessFailedResult, ISeriesMapping>, (head, tail) => resultContext.Failed( $"Multiple series mappings found between TvDb series Id '{tvDbSeriesId}', season '{identifierData.Identifier.Index}'' and AniDb series"))); return(seriesMapping.MapAsync(sm => sm.Ids.AniDbSeriesId)); }
public Task <Either <ProcessFailedResult, ISourceData> > LoadFrom(IEmbyItemData embyItemData) { var resultContext = new ProcessResultContext(nameof(TvDbEpisodeFromEmbyData), embyItemData.Identifier.Name, embyItemData.ItemType); var seriesId = embyItemData.GetParentId(MediaItemTypes.Series, this.sources.TvDb); return(seriesId.ToEitherAsync(resultContext.Failed("No TvDb Id found on parent series")) .BindAsync(id => this.tvDbClient.GetEpisodesAsync(id) .ToEitherAsync(resultContext.Failed($"Failed to load parent series with TvDb Id '{id}'"))) .BindAsync(episodes => this.FindEpisode(episodes, embyItemData.Identifier.Name, embyItemData.Identifier.Index, embyItemData.Identifier.ParentIndex, resultContext)) .MapAsync(this.CreateSourceData)); }
public Either <ProcessFailedResult, string> SelectTitle(IEnumerable <ItemTitleData> titles, string metadataLanguage, ProcessResultContext resultContext) { return(_titleSelector.SelectTitle(titles, _titlePreferenceConfiguration.TitlePreference, metadataLanguage) .Map(t => t.Title) .ToEither(resultContext.Failed("Failed to find a title"))); }
public async Task <Either <ProcessFailedResult, ISourceData> > LoadFrom(IEmbyItemData embyItemData) { var resultContext = new ProcessResultContext(nameof(AniDbEpisodeFromEmbyData), embyItemData.Identifier.Name, embyItemData.ItemType); if (embyItemData.GetParentId(MediaItemTypes.Series, this.sources.AniDb).IsNone) { var tvDbSeriesId = embyItemData.GetParentId(MediaItemTypes.Series, this.sources.TvDb) .ToEither(resultContext.Failed("Failed to find TvDb series Id")); if (tvDbSeriesId.IsRight && embyItemData.Identifier.ParentIndex.IsSome) { var aniDbSeriesId = await tvDbSeriesId.BindAsync(id => this.MapSeriesDataAsync(id, embyItemData.Identifier.ParentIndex.Single(), resultContext)); aniDbSeriesId.IfRight((anidbId) => { var updatedParentIds = embyItemData.ParentIds.Concat(new List <EmbyItemId> { new EmbyItemId(MediaItemTypes.Series, this.sources.AniDb.Name, anidbId) }); embyItemData = new EmbyItemData(embyItemData.ItemType, embyItemData.Identifier, embyItemData.ExistingIds, embyItemData.Language, updatedParentIds); }); } } return(await this.sources.AniDb.GetSeriesData(embyItemData, resultContext) .BindAsync(seriesData => this.GetAniDbEpisodeData(seriesData, embyItemData, resultContext)) .BindAsync(episodeData => { var title = this.sources.AniDb.SelectTitle(episodeData.Titles, embyItemData.Language, resultContext); return title.Map(t => this.CreateSourceData(episodeData, t, embyItemData.Identifier.ParentIndex.Single())); })); }
private Task <Either <ProcessFailedResult, int> > GetMappedTvDbSeriesId(int aniDbSeriesId, ProcessResultContext resultContext) { return(this.mappingList.GetSeriesMappingFromAniDb(aniDbSeriesId, resultContext) .BindAsync(sm => sm.Ids.TvDbSeriesId.ToEither(resultContext.Failed("No TvDb Id found on matching mapping")))); }
public Either <ProcessFailedResult, string> SelectTitle(AniListTitleData titleData, string metadataLanguage, ProcessResultContext resultContext) { return(this.aniListNameSelector .SelectTitle(titleData, this.titlePreferenceConfiguration.TitlePreference, metadataLanguage) .ToEither(resultContext.Failed("Failed to find a title"))); }
public Task <Either <ProcessFailedResult, ISourceData> > LoadFrom(IMediaItem mediaItem, object sourceData) { var resultContext = new ProcessResultContext(nameof(AniListSeriesFromAniDb), mediaItem.EmbyData.Identifier.Name, mediaItem.ItemType); var aniDbSeriesData = (ISourceData <AniDbSeriesData>)sourceData; var distinctAniDbTitles = aniDbSeriesData.Data.Titles .Where(t => new[] { "en", "ja" }.Contains(t.Language, StringComparer.InvariantCultureIgnoreCase)) .Select(t => t.Title) .Select(this.titleNormaliser.GetNormalisedTitle) .Distinct() .OrderByDescending(t => t.Length); var sourceDataTask = distinctAniDbTitles .Fold(Left <ProcessFailedResult, AniListSeriesData>(resultContext.Failed(string.Empty)).AsTask(), (lastResult, currentTitle) => { return(lastResult.Bind(e => e.IsLeft ? this.FindSingleMatchingSeries(currentTitle, resultContext) : e.AsTask())); }); return(sourceDataTask.BindAsync(sd => this.CreateSourceDataWithTitle(mediaItem, sd, resultContext))); }
public Task <Either <ProcessFailedResult, TvDbSeriesData> > GetSeriesData(IEmbyItemData embyItemData, ProcessResultContext resultContext) { Task <Either <ProcessFailedResult, int> > seriesId; if (embyItemData.ItemType == MediaItemTypes.Series) { seriesId = embyItemData.GetExistingId(Name) .ToEitherAsync(resultContext.Failed("No TvDb Id found on this series")); } else { seriesId = embyItemData.GetParentId(MediaItemTypes.Series, this) .ToEitherAsync(resultContext.Failed("No TvDb Id found on parent series")); } return(seriesId.BindAsync(tvDbSeriesId => GetSeriesData(tvDbSeriesId, resultContext))); }
private Either <ProcessFailedResult, AniDbEpisodeData> GetAniDbEpisodeData(AniDbSeriesData aniDbSeriesData, IEmbyItemData embyItemData, ProcessResultContext resultContext) { return(this.aniDbEpisodeMatcher.FindEpisode(aniDbSeriesData.Episodes, embyItemData.Identifier.ParentIndex, embyItemData.Identifier.Index, embyItemData.Identifier.Name) .ToEither(resultContext.Failed("Failed to find episode in AniDb"))); }
public Task <Either <ProcessFailedResult, ISourceData> > LoadFrom(IEmbyItemData embyItemData) { var resultContext = new ProcessResultContext(nameof(TvDbSeriesFromEmbyData), embyItemData.Identifier.Name, embyItemData.ItemType); return(this.tvDbClient.FindSeriesAsync(embyItemData.Identifier.Name) .ToEitherAsync(resultContext.Failed("Failed to find series in TvDb")) .MapAsync(s => this.CreateSourceData(s, embyItemData))); }
public Task <Either <ProcessFailedResult, ISourceData> > LoadFrom(IMediaItem mediaItem, object sourceData) { var resultContext = new ProcessResultContext(nameof(TvDbSeasonFromAniDb), mediaItem.EmbyData.Identifier.Name, mediaItem.ItemType); return(mediaItem.EmbyData.Identifier.Index .ToEither(resultContext.Failed("No season index provided by Emby")) .Map(this.CreateSourceData) .AsTask()); }
public Task <Either <ProcessFailedResult, IEnumerable <ISeriesMapping> > > GetSeriesMappingsFromTvDb( int tvDbSeriesId, ProcessResultContext resultContext) { return(_mappingListTaskLazy.Value.Map(seriesMappings => seriesMappings.Where(m => m.Ids.TvDbSeriesId == tvDbSeriesId).ToList()) .Map(matchingSeriesMappings => matchingSeriesMappings.Any() ? Right <ProcessFailedResult, IEnumerable <ISeriesMapping> >(matchingSeriesMappings) : Left <ProcessFailedResult, IEnumerable <ISeriesMapping> >( resultContext.Failed($"No series mapping for TvDb series Id '{tvDbSeriesId}'")))); }
public Task <Either <ProcessFailedResult, ISourceData> > LoadFrom(IEmbyItemData embyItemData) { var resultContext = new ProcessResultContext(nameof(AniDbSeriesFromEmbyData), embyItemData.Identifier.Name, embyItemData.ItemType); return(_aniDbClient.FindSeriesAsync(embyItemData.Identifier.Name) .ToEitherAsync(resultContext.Failed("Failed to find series in AniDb")) .BindAsync(s => { var title = _sources.AniDb.SelectTitle(s.Titles, embyItemData.Language, resultContext); return title.Map(t => CreateSourceData(s, embyItemData, t)); })); }
private async Task <Either <ProcessFailedResult, IEnumerable <ISeriesMapping> > > GetFallbackSeriesMappingFromTvDb(int tvDbSeriesId, ProcessResultContext resultContext) { return(await this.xemTvDbMappingListTaskLazy.Value .Map(seriesMappings => seriesMappings.Where(m => m.Ids.TvDbSeriesId == tvDbSeriesId).ToList()) .Map(matchingSeriesMappings => { switch (matchingSeriesMappings.Count) { case 0: return Left <ProcessFailedResult, IEnumerable <ISeriesMapping> >( resultContext.Failed($"No series mapping for TvDb series Id '{tvDbSeriesId}'")); case 1: return Right <ProcessFailedResult, IEnumerable <ISeriesMapping> >(matchingSeriesMappings); default: return Left <ProcessFailedResult, IEnumerable <ISeriesMapping> >( resultContext.Failed( $"Multiple series mappings match TvDb series Id '{tvDbSeriesId}'")); } })); }
public Task <Either <ProcessFailedResult, ISeriesMapping> > GetSeriesMappingFromAniDb(int aniDbSeriesId, ProcessResultContext resultContext) { return(_mappingListTaskLazy.Value .Map(seriesMappings => seriesMappings.Where(m => m.Ids.AniDbSeriesId == aniDbSeriesId).ToList()) .Map(matchingSeriesMappings => { switch (matchingSeriesMappings.Count) { case 0: return Left <ProcessFailedResult, ISeriesMapping>( resultContext.Failed($"No series mapping for AniDb series Id '{aniDbSeriesId}'")); case 1: return Right <ProcessFailedResult, ISeriesMapping>(matchingSeriesMappings.Single()); default: return Left <ProcessFailedResult, ISeriesMapping>( resultContext.Failed( $"Multiple series mappings match AniDb series Id '{aniDbSeriesId}'")); } })); }
public Task <Either <ProcessFailedResult, ISourceData> > LoadFrom(IMediaItem mediaItem, object sourceData) { var aniDbSourceData = (ISourceData <AniDbSeriesData>)sourceData; var resultContext = new ProcessResultContext(nameof(TvDbSeriesFromAniDb), mediaItem.EmbyData.Identifier.Name, mediaItem.ItemType); return(aniDbSourceData.Id.ToEither( resultContext.Failed( "No AniDb Id found on the AniDb data associated with this media item")) .BindAsync(aniDbSeriesId => this.GetMappedTvDbSeriesId(aniDbSeriesId, resultContext)) .BindAsync(tvDbSeriesId => this.sources.TvDb.GetSeriesData(tvDbSeriesId, resultContext)) .MapAsync(this.CreateSourceData)); }
private Task <Either <ProcessFailedResult, TvDbEpisodeData> > MapEpisodeDataAsync(AniDbSeriesData aniDbSeriesData, AniDbEpisodeData aniDbEpisodeData, ProcessResultContext resultContext) { var seriesMapping = _mappingList.GetSeriesMappingFromAniDb(aniDbSeriesData.Id, resultContext); return(seriesMapping.BindAsync(sm => { var episodeGroupMapping = sm.GetEpisodeGroupMapping(aniDbEpisodeData.EpisodeNumber); var tvDbEpisodeData = _episodeMapper.MapAniDbEpisodeAsync(aniDbEpisodeData.EpisodeNumber.Number, sm, episodeGroupMapping); return tvDbEpisodeData.Match( d => Right <ProcessFailedResult, TvDbEpisodeData>(d), () => resultContext.Failed("Found a series mapping but failed to map the episode to TvDb")); })); }
private Task <Either <ProcessFailedResult, TvDbEpisodeData> > FindEpisode(IEnumerable <TvDbEpisodeData> episodes, string title, Option <int> episodeIndex, Option <int> seasonIndex, ProcessResultContext resultContext) { var normalisedTitle = this.titleNormaliser.GetNormalisedTitle(title); var episodeByIndexes = episodeIndex.Bind(i => seasonIndex.Bind(si => episodes.Find(e => e.AiredEpisodeNumber == i && e.AiredSeason == si)) .Match(e => e, () => episodes.Find(e => e.AiredEpisodeNumber == i && e.AiredSeason == 1))); return(episodeByIndexes.Match(Right <ProcessFailedResult, TvDbEpisodeData>, () => Option <TvDbEpisodeData> .Some(episodes.FirstOrDefault(e => this.titleNormaliser.GetNormalisedTitle(e.EpisodeName) == normalisedTitle)) .ToEither(resultContext.Failed( $"Failed to find TvDb episode"))) .AsTask()); }
public Task <Either <ProcessFailedResult, ISourceData> > LoadFrom(IMediaItem mediaItem, object sourceData) { var tvDbSourceData = (ISourceData <TvDbEpisodeData>)sourceData; var resultContext = new ProcessResultContext(nameof(AniDbEpisodeFromTvDb), mediaItem.EmbyData.Identifier.Name, mediaItem.ItemType); var tvDbSeriesData = this.sources.TvDb.GetSeriesData(mediaItem.EmbyData, resultContext); var tvDbEpisodeData = tvDbSourceData.Data; var aniDbSeriesId = mediaItem.EmbyData.GetParentId(MediaItemTypes.Series, this.sources.AniDb) .ToEither(resultContext.Failed("Failed to find AniDb series Id")); var aniDbEpisodeData = tvDbSeriesData.BindAsync(seriesData => aniDbSeriesId.BindAsync(id => this.MapEpisodeDataAsync(id, seriesData, tvDbEpisodeData, resultContext))); return(aniDbEpisodeData.BindAsync(episodeData => this.sources.AniDb.SelectTitle(episodeData.Titles, mediaItem.EmbyData.Language, resultContext) .Map(t => this.CreateSourceData(episodeData, t)))); }
public Task <Either <ProcessFailedResult, AniDbSeriesData> > GetSeriesData(int aniDbSeriesId, ProcessResultContext resultContext) { return(this.aniDbClient.GetSeriesAsync(aniDbSeriesId) .ToEitherAsync(resultContext.Failed($"Failed to load series with AniDb Id '{aniDbSeriesId}'"))); }
public static Func <FailedRequest, ProcessFailedResult> ToFailedResult(ProcessResultContext resultContext) { return(r => resultContext.Failed($"Request failed with {r.StatusCode}: {r.ResponseContent}")); }
public Task <Either <ProcessFailedResult, TvDbSeriesData> > GetSeriesData(int tvDbSeriesId, ProcessResultContext resultContext) { return(_tvDbClient.GetSeriesAsync(tvDbSeriesId) .ToEitherAsync(resultContext.Failed($"Failed to load parent series with TvDb Id '{tvDbSeriesId}'"))); }