Example #1
0
        async Task <IEnumerable <RemoteSubtitleInfo> > ISubtitleProvider.Search(SubtitleSearchRequest request,
                                                                                CancellationToken cancellationToken)
        {
            var  imdbIdText = request.GetProviderId(MetadataProviders.Imdb);
            long imdbId     = 0;

            _logger.LogDebug($"{ToDump(request)}");
            //_logger.LogDebug($"Imdb id: {imdbIdText}");
            switch (request.ContentType)
            {
            case VideoContentType.Episode:
                if (!request.IndexNumber.HasValue || !request.ParentIndexNumber.HasValue ||
                    string.IsNullOrEmpty(request.SeriesName))
                {
                    _logger.LogDebug("Episode information missing");
                    return(Enumerable.Empty <RemoteSubtitleInfo>());
                }

                break;

            case VideoContentType.Movie:
                if (string.IsNullOrEmpty(request.Name))
                {
                    _logger.LogDebug("Movie name missing");
                    return(Enumerable.Empty <RemoteSubtitleInfo>());
                }

                if (string.IsNullOrWhiteSpace(imdbIdText) || !long.TryParse(imdbIdText.TrimStart('t'),
                                                                            NumberStyles.Any, _usCulture, out imdbId))
                {
                    //_logger.LogDebug($"Imdb id: `{imdbIdText}` - media name: {request.Name}");
                    _logger.LogDebug("Imdb id missing");
                    //return Enumerable.Empty<RemoteSubtitleInfo>();
                }

                break;
            }

            if (string.IsNullOrEmpty(request.MediaPath))
            {
                _logger.LogDebug("Path Missing");
                return(Enumerable.Empty <RemoteSubtitleInfo>());
            }

            await Login(cancellationToken).ConfigureAwait(false);

            var subLanguageId = NormalizeLanguage(request.Language);

            string hash;

            using (var fileStream = File.OpenRead(request.MediaPath))
            {
                hash = Utilities.ComputeHash(fileStream);
            }

            var fileInfo      = _fileSystem.GetFileInfo(request.MediaPath);
            var movieByteSize = fileInfo.Length;
            //For movies, the imdb id is ued.
            var searchImdbId             = request.ContentType == VideoContentType.Movie && imdbId != 0 ? imdbId.ToString(_usCulture) : "";
            var subtitleSearchParameters = new List <SubtitleSearchParameters>();

            switch (request.ContentType)
            {
            case VideoContentType.Episode:
                subtitleSearchParameters = new List <SubtitleSearchParameters>
                {
                    new SubtitleSearchParameters(subLanguageId,
                                                 query: request.SeriesName,
                                                 season: request.ParentIndexNumber.Value.ToString(_usCulture),
                                                 episode: request.IndexNumber.Value.ToString(_usCulture))
                };
                break;

            case VideoContentType.Movie:
                subtitleSearchParameters = new List <SubtitleSearchParameters> {
                };
                if (!string.IsNullOrEmpty(searchImdbId))
                {
                    subtitleSearchParameters.Add(new SubtitleSearchParameters(subLanguageId, imdbid: searchImdbId));
                    subtitleSearchParameters.Add(new SubtitleSearchParameters(subLanguageId, query: request.Name, imdbid: searchImdbId));
                }
                else
                {
                    subtitleSearchParameters.Add(new SubtitleSearchParameters(subLanguageId, query: request.Name));
                }

                break;
            }

            var parms = new List <SubtitleSearchParameters>
            {
                new SubtitleSearchParameters(subLanguageId,
                                             movieHash: hash,
                                             movieByteSize: movieByteSize,
                                             imdbid: searchImdbId),
            };

            parms.AddRange(subtitleSearchParameters);

            if (_rateLimitLeft == 0)
            {
                await Task.Delay(1000);
            }
            //_logger.LogDebug($"Search params: {ToDump(parms)}");
            IMethodResponse searchResult = null;

            try
            {
                var searchResponse = await OpenSubtitlesHandler.OpenSubtitles
                                     .SearchSubtitlesAsync(parms.ToArray(), cancellationToken)
                                     .ConfigureAwait(false);

                searchResult = searchResponse.Item1;
                //_logger.LogDebug($"Search result: {ToDump(searchResult)}");
                _rateLimitLeft = searchResponse.Item2 ?? _rateLimitLeft;
                if (searchResponse.Item2 != null)
                {
                    if (_rateLimitLeft <= 4)
                    {
                        await Task.Delay(250);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError($"Error while fetching subtitles from opensubtitles.\n{ex}\n{ex.StackTrace}");
            }


            if (!(searchResult is MethodResponseSubtitleSearch))
            {
                _logger.LogError("Invalid response type");
                return(Enumerable.Empty <RemoteSubtitleInfo>());
            }

            //Check if we got a 401 error from opensubtitles
            if (searchResult.Status.Contains("401"))
            {
                _logger.LogError("Not authorized to OpenSubtitles");
                return(Enumerable.Empty <RemoteSubtitleInfo>());
            }

            Predicate <SubtitleSearchResult> mediaFilter = x =>
            {
                switch (request.ContentType)
                {
                case VideoContentType.Episode:
                    return(!string.IsNullOrEmpty(x.SeriesSeason) && !string.IsNullOrEmpty(x.SeriesEpisode) &&
                           int.Parse(x.SeriesSeason, _usCulture) == request.ParentIndexNumber &&
                           int.Parse(x.SeriesEpisode, _usCulture) == request.IndexNumber);

                case VideoContentType.Movie:
                    if (imdbId == 0)
                    {
                        return(x.MovieName.Contains(request.Name));
                    }
                    else
                    {
                        return(!string.IsNullOrEmpty(x.IDMovieImdb) &&
                               long.Parse(x.IDMovieImdb, _usCulture) == imdbId);
                    }
                }
                return(false);
            };


            var results = ((MethodResponseSubtitleSearch)searchResult).Results;

            // Avoid implicitly captured closure
            var hasCopy = hash;

            return(results.Where(x =>
                                 x.SubBad == "0" && mediaFilter(x) &&
                                 (!request.IsPerfectMatch || string.Equals(x.MovieHash, hash, StringComparison.OrdinalIgnoreCase)))
                   .OrderBy(x => (string.Equals(x.MovieHash, hash, StringComparison.OrdinalIgnoreCase) ? 0 : 1))
                   .ThenBy(x => Math.Abs(long.Parse(x.MovieByteSize, _usCulture) - movieByteSize))
                   .ThenByDescending(x => int.Parse(x.SubDownloadsCnt, _usCulture))
                   .ThenByDescending(x => double.Parse(x.SubRating, _usCulture))
                   .Select(i => new RemoteSubtitleInfo
            {
                Author = i.UserNickName,
                Comment = i.SubAuthorComment,
                CommunityRating = float.Parse(i.SubRating, _usCulture),
                DownloadCount = int.Parse(i.SubDownloadsCnt, _usCulture),
                Format = i.SubFormat,
                ProviderName = Name,
                ThreeLetterISOLanguageName = i.SubLanguageID,
                Id = i.SubFormat + "-" + i.SubLanguageID + "-" + i.IDSubtitleFile,
                Name = i.SubFileName,
                DateCreated = DateTime.Parse(i.SubAddDate, _usCulture),
                IsHashMatch = i.MovieHash == hasCopy
            }).Where(i =>
                     !string.Equals(i.Format, "sub", StringComparison.OrdinalIgnoreCase) &&
                     !string.Equals(i.Format, "idx", StringComparison.OrdinalIgnoreCase)));
        }
Example #2
0
        private void FillDataGrid(IMethodResponse<Northwind.CustomersDataTable> methodResponse)
        {
            if(CustomersDataGridView.InvokeRequired)
            {
                CustomersDataGridView.BeginInvoke(new Action<IMethodResponse<Northwind.CustomersDataTable>>(FillDataGrid),
                                                  methodResponse);
                return;
            }

            CustomersDataGridView.DataSource = methodResponse.ReturnValue;
            CustomersDataGridView.Update();
        }