private async Task <IEnumerable <RemoteChapterResult> > FetchAsyncInternal(ChapterSearchRequest request, CancellationToken cancellationToken) { string imdbIdText = request.GetProviderId(MetadataProviders.Imdb); long imdbId = 0; long.TryParse(imdbIdText.TrimStart('t'), NumberStyles.Any, _usCulture, out imdbId); var p = new SearchParameters { Type = SearchType.Search, Title = request.Name, Language = request.Language, Show = request.SeriesName, Season = request.ParentIndexNumber, Episode = request.IndexNumber, VideoKind = request.ContentType == VideoContentType.Movie ? "Movie" : "TVShow", ImdbId = imdbId > 0 ? imdbId.ToString() : null, Token = ApiKey, Locked = true, }; var url = BaseUrl + p.BuildQueryString(); using (var stream = await _httpClient.Get(new HttpRequestOptions { Url = url, ResourcePool = _resourcePool, CancellationToken = cancellationToken }).ConfigureAwait(false)) { var result = _xmlSerializer.DeserializeFromStream(typeof(SearchResults), stream) as SearchResults; if (result == null) { return(new List <RemoteChapterResult>()); } var first = result.Movies.FirstOrDefault(); if (first != null) { return(first.Chapters.Items.Select(x => new RemoteChapterResult { Id = x.Index.ToString(), Name = x.Title, RunTimeTicks = x.StartTime.Ticks })); } else { return(new List <RemoteChapterResult>()); } } }
private async Task <IEnumerable <RemoteChapterResult> > SearchAsync(ChapterSearchRequest request, CancellationToken cancellationToken) { var duration = String.Empty; if (request.RuntimeTicks.HasValue) { duration = GetTimeString(request.RuntimeTicks.Value); } var url = BaseUrl + String.Format("search?title={0}&duration={1}", request.Name, duration); var options = GetHttpRequestOptions(cancellationToken, url); using (var stream = await _httpClient.Get(options).ConfigureAwait(false)) { var result = _xmlSerializer.DeserializeFromStream(typeof(Results), stream) as Results; if (result == null) { return(new List <RemoteChapterResult>()); } var details = result.Detail; var runtime = request.RuntimeTicks; details = details .OrderBy(i => { if (!runtime.HasValue) { return(0); } return(Math.Abs(runtime.Value - i.Source.Duration.Ticks)); }) .ThenBy(i => i.Confirmations) .ToList(); return(details.Select(x => { var c = new RemoteChapterResult { Id = x.Ref.ChapterSetId, Name = x.Title, RunTimeTicks = x.Source.Duration.Ticks }; _logger.Debug(string.Format("\"{0}\" results - {1}: {2} [{3}]", request.Name, c.Name, c.Id, GetTimeString(c.RunTimeTicks.Value))); return c; })); } }
private async Task <IEnumerable <RemoteChapterResult> > Search(ChapterSearchRequest request, IChapterProvider provider, CancellationToken cancellationToken) { var searchResults = await provider.Search(request, cancellationToken).ConfigureAwait(false); foreach (var result in searchResults) { result.Id = GetProviderId(provider.Name) + "_" + result.Id; result.ProviderName = provider.Name; } return(searchResults); }
public async Task <IEnumerable <RemoteChapterResult> > Search(ChapterSearchRequest request, CancellationToken cancellationToken) { var contentType = request.ContentType; var providers = GetInternalProviders(false) .Where(i => i.SupportedMediaTypes.Contains(contentType)) .ToList(); // If not searching all, search one at a time until something is found if (!request.SearchAllProviders) { foreach (var provider in providers) { try { var currentResults = await Search(request, provider, cancellationToken).ConfigureAwait(false); if (currentResults.Count > 0) { return(currentResults); } } catch (Exception ex) { _logger.ErrorException("Error downloading subtitles from {0}", ex, provider.Name); } } return(new List <RemoteChapterResult>()); } var tasks = providers.Select(async i => { try { return(await Search(request, i, cancellationToken).ConfigureAwait(false)); } catch (Exception ex) { _logger.ErrorException("Error downloading subtitles from {0}", ex, i.Name); return(new List <RemoteChapterResult>()); } }); var results = await Task.WhenAll(tasks).ConfigureAwait(false); return(results.SelectMany(i => i)); }
public Task <IEnumerable <RemoteChapterResult> > Search(Video video, CancellationToken cancellationToken) { VideoContentType mediaType; if (video is Episode) { mediaType = VideoContentType.Episode; } else if (video is Movie) { mediaType = VideoContentType.Movie; } else { // These are the only supported types return(Task.FromResult <IEnumerable <RemoteChapterResult> >(new List <RemoteChapterResult>())); } var request = new ChapterSearchRequest { ContentType = mediaType, IndexNumber = video.IndexNumber, Language = video.GetPreferredMetadataLanguage(), MediaPath = video.Path, Name = video.Name, ParentIndexNumber = video.ParentIndexNumber, ProductionYear = video.ProductionYear, ProviderIds = video.ProviderIds, RuntimeTicks = video.RunTimeTicks, SearchAllProviders = false }; var episode = video as Episode; if (episode != null) { request.IndexNumberEnd = episode.IndexNumberEnd; request.SeriesName = episode.SeriesName; } return(Search(request, cancellationToken)); }
public Task <IEnumerable <RemoteChapterResult> > Search(ChapterSearchRequest request, CancellationToken cancellationToken) { return(FetchAsyncInternal(request, cancellationToken)); }