示例#1
0
        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}'"));
            }));
        }
示例#2
0
 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")));
 }
示例#3
0
 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}'"))));
 }
示例#4
0
        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));
        }
示例#6
0
 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")));
 }
示例#7
0
        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")));
 }
示例#10
0
        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)));
        }
示例#12
0
 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")));
 }
示例#13
0
        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());
        }
示例#15
0
 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}'"));
                }
            }));
        }
示例#18
0
        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));
        }
示例#20
0
        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());
        }
示例#22
0
        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))));
        }
示例#23
0
 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}'")));
 }
示例#24
0
 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}'")));
 }