public Tuple <Series, List <Episode> > GetSeriesInfo(int tvdbSeriesId) { var httpRequest = _requestBuilder.Build(tvdbSeriesId.ToString()); httpRequest.AddSegment("route", "shows"); httpRequest.AllowAutoRedirect = true; httpRequest.SuppressHttpError = true; var httpResponse = _httpClient.Get <ShowResource>(httpRequest); if (httpResponse.HasHttpError) { if (httpResponse.StatusCode == HttpStatusCode.NotFound) { throw new SeriesNotFoundException(tvdbSeriesId); } else { throw new HttpException(httpRequest, httpResponse); } } var episodes = httpResponse.Resource.Episodes.Select(MapEpisode); var series = MapSeries(httpResponse.Resource); return(new Tuple <Series, List <Episode> >(series, episodes.ToList())); }
private string ProcessRequest(HttpRequestBuilder requestBuilder, QBittorrentSettings settings) { AuthenticateClient(requestBuilder, settings); var request = requestBuilder.Build(); request.LogResponseContent = true; request.SuppressHttpErrorStatusCodes = new[] { HttpStatusCode.Forbidden }; HttpResponse response; try { response = _httpClient.Execute(request); if (response.StatusCode == HttpStatusCode.Forbidden) { _logger.Debug("Authentication required, logging in."); AuthenticateClient(requestBuilder, settings, true); request = requestBuilder.Build(); response = _httpClient.Execute(request); } } catch (HttpException ex) { throw new DownloadClientException("Failed to connect to qBittorrent, check your settings.", ex); } catch (WebException ex) { throw new DownloadClientException("Failed to connect to qBittorrent, please check your settings.", ex); } return response.Content; }
public List <int> GetXemSeriesIds() { _logger.Debug("Fetching Series IDs from"); var request = _xemRequestBuilder.Build("/havemap"); var response = _httpClient.Get <XemResult <List <int> > >(request).Resource; CheckForFailureResult(response); return(response.Data.ToList()); }
public Tuple <Series, List <Episode> > GetSeriesInfo(int tvdbSeriesId) { var httpRequest = _requestBuilder.Build(tvdbSeriesId.ToString()); httpRequest.AddSegment("route", "shows"); var httpResponse = _httpClient.Get <ShowResource>(httpRequest); var episodes = httpResponse.Resource.Episodes.Select(MapEpisode); var series = MapSeries(httpResponse.Resource); return(new Tuple <Series, List <Episode> >(series, episodes.ToList())); }
private T ProcessRequest <T>(HttpRequestBuilder requestBuilder, bool requiresAuthentication, NzbVortexSettings settings) where T : NzbVortexResponseBase, new() { if (requiresAuthentication) { AuthenticateClient(requestBuilder, settings); } HttpResponse response = null; try { response = _httpClient.Execute(requestBuilder.Build()); var result = Json.Deserialize <T>(response.Content); if (result.Result == NzbVortexResultType.NotLoggedIn) { _logger.Debug("Not logged in response received, reauthenticating and retrying"); AuthenticateClient(requestBuilder, settings, true); response = _httpClient.Execute(requestBuilder.Build()); result = Json.Deserialize <T>(response.Content); if (result.Result == NzbVortexResultType.NotLoggedIn) { throw new DownloadClientException("Unable to connect to remain authenticated to NzbVortex"); } } return(result); } catch (JsonException ex) { throw new DownloadClientException("NzbVortex response could not be processed {0}: {1}", ex.Message, response.Content); } catch (HttpException ex) { throw new DownloadClientException("Unable to connect to NZBVortex, please check your settings", ex); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.TrustFailure) { throw new DownloadClientUnavailableException("Unable to connect to NZBVortex, certificate validation failed.", ex); } throw new DownloadClientUnavailableException("Unable to connect to NZBVortex, please check your settings", ex); } }
private string ProcessRequest(HttpRequestBuilder requestBuilder) { var httpRequest = requestBuilder.Build(); HttpResponse response; _logger.Debug("Url: {0}", httpRequest.Url); try { response = _httpClient.Execute(httpRequest); } catch (HttpException ex) { if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) { throw new PlexAuthenticationException("Unauthorized - AuthToken is invalid"); } throw new PlexException("Unable to connect to Plex Media Server. Status Code: {0}", ex.Response.StatusCode); } catch (WebException ex) { throw new PlexException("Unable to connect to Plex Media Server", ex); } return(response.Content); }
private IEnumerable <IndexerRequest> GetMovieRequest(MovieSearchCriteria searchCriteria) { var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl) .Resource("/pubapi_v2.php") .Accept(HttpAccept.Json); if (Settings.CaptchaToken.IsNotNullOrWhiteSpace()) { requestBuilder.UseSimplifiedUserAgent = true; requestBuilder.SetCookie("cf_clearance", Settings.CaptchaToken); } requestBuilder.AddQueryParam("mode", "search"); requestBuilder.AddQueryParam("search_imdb", searchCriteria.Movie.ImdbId); if (!Settings.RankedOnly) { requestBuilder.AddQueryParam("ranked", "0"); } requestBuilder.AddQueryParam("category", "movies"); requestBuilder.AddQueryParam("limit", "100"); requestBuilder.AddQueryParam("token", _tokenProvider.GetToken(Settings)); requestBuilder.AddQueryParam("format", "json_extended"); requestBuilder.AddQueryParam("app_id", "Bonarr"); yield return(new IndexerRequest(requestBuilder.Build())); }
public HttpRequest GetWatchlist(string authToken) { var clientIdentifier = _configService.PlexClientIdentifier; var requestBuilder = new HttpRequestBuilder("https://metadata.provider.plex.tv/library/sections/watchlist/all") .Accept(HttpAccept.Json) .AddQueryParam("clientID", clientIdentifier) .AddQueryParam("context[device][product]", BuildInfo.AppName) .AddQueryParam("context[device][platform]", "Windows") .AddQueryParam("context[device][platformVersion]", "7") .AddQueryParam("context[device][version]", BuildInfo.Version.ToString()) .AddQueryParam("includeFields", "title,type,year,ratingKey") .AddQueryParam("includeElements", "Guid") .AddQueryParam("sort", "watchlistedAt:desc") .AddQueryParam("type", (int)PlexMediaType.Show); if (!string.IsNullOrWhiteSpace(authToken)) { requestBuilder.AddQueryParam("X-Plex-Token", authToken); } var request = requestBuilder.Build(); return(request); }
private string ProcessRequest(HttpRequestBuilder requestBuilder, SabnzbdSettings settings) { var httpRequest = requestBuilder.Build(); HttpResponse response; _logger.Debug("Url: {0}", httpRequest.Url); try { response = _httpClient.Execute(httpRequest); } catch (HttpException ex) { throw new DownloadClientException("Unable to connect to SABnzbd, please check your settings", ex); } catch (WebException ex) { throw new DownloadClientException("Unable to connect to SABnzbd, please check your settings", ex); } CheckForError(response); return(response.Content); }
public List <PushBulletDevice> GetDevices(PushBulletSettings settings) { try { var requestBuilder = new HttpRequestBuilder(DEVICE_URL); var request = requestBuilder.Build(); request.Method = HttpMethod.Get; request.Credentials = new BasicNetworkCredential(settings.ApiKey, string.Empty); var response = _httpClient.Execute(request); return(Json.Deserialize <PushBulletDevicesResponse>(response.Content).Devices); } catch (HttpException ex) { if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) { _logger.Error(ex, "Access token is invalid"); throw; } } return(new List <PushBulletDevice>()); }
private HttpRequest BuildRequest(LazyLibrarianSettings settings, string resource, string command, HttpMethod method, Dictionary <string, string> parameters = null) { var baseUrl = settings.BaseUrl.TrimEnd('/'); var requestBuilder = new HttpRequestBuilder(baseUrl).Resource(resource) .AddQueryParam("cmd", command) .AddQueryParam("apikey", settings.ApiKey); if (parameters != null) { foreach (var param in parameters) { requestBuilder.AddQueryParam(param.Key, param.Value); } } var request = requestBuilder.Build(); request.Headers.ContentType = "application/json"; request.Method = method; request.AllowAutoRedirect = true; return(request); }
private IEnumerable <IndexerRequest> GetMovieRequest(MovieSearchCriteria searchCriteria) { var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl) .Accept(HttpAccept.Json); requestBuilder.AddQueryParam("passkey", Settings.Passkey); if (!string.IsNullOrWhiteSpace(Settings.User)) { requestBuilder.AddQueryParam("user", Settings.User); } else { requestBuilder.AddQueryParam("user", ""); } if (searchCriteria.Movie.ImdbId.IsNotNullOrWhiteSpace()) { requestBuilder.AddQueryParam("imdbid", searchCriteria.Movie.ImdbId); } else { requestBuilder.AddQueryParam("search", $"{searchCriteria.Movie.Title} {searchCriteria.Movie.Year}"); } yield return(new IndexerRequest(requestBuilder.Build())); }
private IEnumerable <IndexerRequest> GetPagedRequests(string mode, int?tvdbId, string query, params object[] args) { var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl) .Resource("/pubapi_v2.php") .Accept(HttpAccept.Json); requestBuilder.AddQueryParam("mode", mode); if (tvdbId.HasValue) { requestBuilder.AddQueryParam("search_tvdb", tvdbId.Value); } if (query.IsNotNullOrWhiteSpace()) { requestBuilder.AddQueryParam("search_string", string.Format(query, args)); } if (!Settings.RankedOnly) { requestBuilder.AddQueryParam("ranked", "0"); } requestBuilder.AddQueryParam("category", "18;41"); requestBuilder.AddQueryParam("limit", "100"); requestBuilder.AddQueryParam("token", _tokenProvider.GetToken(Settings)); requestBuilder.AddQueryParam("format", "json_extended"); requestBuilder.AddQueryParam("app_id", "Sonarr"); yield return(new IndexerRequest(requestBuilder.Build())); }
private DiskStationResponse <T> ProcessRequest <T>(HttpRequestBuilder requestBuilder, string operation, DiskStationApi api, DownloadStationSettings settings) where T : new() { var request = requestBuilder.Build(); HttpResponse response; try { response = _httpClient.Execute(request); } catch (HttpException ex) { throw new DownloadClientException("Unable to connect to Diskstation, please check your settings", ex); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.TrustFailure) { throw new DownloadClientUnavailableException("Unable to connect to Diskstation, certificate validation failed.", ex); } throw new DownloadClientUnavailableException("Unable to connect to Diskstation, please check your settings", ex); } _logger.Debug("Trying to {0}", operation); if (response.StatusCode == HttpStatusCode.OK) { var responseContent = Json.Deserialize <DiskStationResponse <T> >(response.Content); if (responseContent.Success) { return(responseContent); } else { var msg = $"Failed to {operation}. Reason: {responseContent.Error.GetMessage(api)}"; _logger.Error(msg); if (responseContent.Error.SessionError) { _sessionCache.Remove(GenerateSessionCacheKey(settings)); if (responseContent.Error.Code == 105) { throw new DownloadClientAuthenticationException(msg); } } throw new DownloadClientException(msg); } } else { throw new HttpException(request, response); } }
public Task <HttpResponseMessage> UpdateSuite(string suiteId, RequestSuiteModel requestSuiteModel) { var request = HttpRequestBuilder.Build($"index.php?/api/v2/update_suite/{suiteId}", HttpMethod.Post, requestSuiteModel); return(_clientExtended.ExecuteAsync(request)); }
public void SendNotification(string title, string message, PushoverSettings settings) { var requestBuilder = new HttpRequestBuilder(URL).Post(); requestBuilder.AddFormParameter("token", settings.ApiKey) .AddFormParameter("user", settings.UserKey) .AddFormParameter("device", string.Join(",", settings.Devices)) .AddFormParameter("title", title) .AddFormParameter("message", message) .AddFormParameter("priority", settings.Priority); if ((PushoverPriority)settings.Priority == PushoverPriority.Emergency) { requestBuilder.AddFormParameter("retry", settings.Retry); requestBuilder.AddFormParameter("expire", settings.Expire); } if (!settings.Sound.IsNullOrWhiteSpace()) { requestBuilder.AddFormParameter("sound", settings.Sound); } var request = requestBuilder.Build(); _httpClient.Post(request); }
private string ProcessRequest(HttpRequestBuilder requestBuilder, SabnzbdSettings settings) { var httpRequest = requestBuilder.Build(); HttpResponse response; _logger.Debug("Url: {0}", httpRequest.Url); try { response = _httpClient.Execute(httpRequest); } catch (HttpException ex) { throw new DownloadClientException("Unable to connect to SABnzbd, {0}", ex, ex.Message); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.TrustFailure) { throw new DownloadClientUnavailableException("Unable to connect to SABnzbd, certificate validation failed.", ex); } throw new DownloadClientUnavailableException("Unable to connect to SABnzbd, {0}", ex, ex.Message); } CheckForError(response); return(response.Content); }
protected Common.Http.HttpResponse OAuthExecute(HttpRequestBuilder builder) { var auth = OAuthRequest.ForProtectedResource(builder.Method.ToString(), null, null, Settings.AccessToken, Settings.AccessTokenSecret); var request = builder.Build(); request.LogResponseContent = true; // we need the url without the query to sign auth.RequestUrl = request.Url.SetQuery(null).FullUri; if (builder.Method == HttpMethod.GET) { auth.Parameters = builder.QueryParams.ToDictionary(x => x.Key, x => x.Value); } else if (builder.Method == HttpMethod.POST) { auth.Parameters = builder.FormData.ToDictionary(x => x.Name, x => Encoding.UTF8.GetString(x.ContentData)); } var header = GetAuthorizationHeader(auth); request.Headers.Add("Authorization", header); return(_httpClient.Execute(request)); }
private void SendNotification(string title, string message, HttpRequestBuilder requestBuilder, PushBulletSettings settings) { try { requestBuilder.AddFormParameter("type", "note") .AddFormParameter("title", title) .AddFormParameter("body", message); if (settings.SenderId.IsNotNullOrWhiteSpace()) { requestBuilder.AddFormParameter("source_device_iden", settings.SenderId); } var request = requestBuilder.Build(); request.Credentials = new BasicNetworkCredential(settings.ApiKey, string.Empty); _httpClient.Execute(request); } catch (HttpException ex) { if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) { _logger.Error(ex, "Access token is invalid"); throw; } throw new PushBulletException("Unable to send text message: {0}", ex, ex.Message); } }
private void ProcessNotification(StringDictionary message, DiscordNotifierSettings settings) { try { var requestBuilder = new HttpRequestBuilder(URL).Post(); requestBuilder.AddFormParameter("api", settings.APIKey).Build(); foreach (string key in message.Keys) { requestBuilder.AddFormParameter(key, message[key]); } var request = requestBuilder.Build(); _httpClient.Post(request); } catch (HttpException ex) { if (ex.Response.StatusCode == HttpStatusCode.BadRequest) { _logger.Error(ex, "API key is invalid"); throw; } throw new DiscordNotifierException("Unable to send notification", ex); } }
private string ProcessRequest(HttpRequestBuilder requestBuilder) { var request = requestBuilder.Build(); request.LogResponseContent = true; request.SuppressHttpErrorStatusCodes = new[] { HttpStatusCode.Forbidden }; var cookie = _sessionCookieCache.Find(requestBuilder.BaseUrl.FullUri); if (cookie != null) { _logger.Trace("Adding cookie {0}", cookie); request.Cookies.Add("connect.sid", cookie); } HttpResponse response; try { response = _httpClient.Execute(request); } catch (HttpException ex) { throw new DownloadClientException("Failed to connect to Deemix, check your settings.", ex); } catch (WebException ex) { throw new DownloadClientException("Failed to connect to Deemix, please check your settings.", ex); } return(response.Content); }
private IEnumerable <Show> SearchTrakt(string title) { HttpRequest request; var lowerTitle = title.ToLowerInvariant(); if (lowerTitle.StartsWith("tvdb:") || lowerTitle.StartsWith("tvdbid:") || lowerTitle.StartsWith("slug:")) { var slug = lowerTitle.Split(':')[1].Trim(); if (slug.IsNullOrWhiteSpace() || slug.Any(char.IsWhiteSpace)) { return(Enumerable.Empty <Show>()); } request = _requestBuilder.Build("/{slug}/extended"); request.AddSegment("path", "show"); request.AddSegment("resource", "summary"); request.AddSegment("slug", GetSearchTerm(slug)); return(new List <Show> { _httpClient.Get <Show>(request).Resource }); } if (lowerTitle.StartsWith("imdb:") || lowerTitle.StartsWith("imdbid:")) { var slug = lowerTitle.Split(':')[1].TrimStart('t').Trim(); if (slug.IsNullOrWhiteSpace() || !slug.All(char.IsDigit) || slug.Length < 7) { return(Enumerable.Empty <Show>()); } title = "tt" + slug; } request = _requestBuilder.Build(""); request.AddSegment("path", "search"); request.AddSegment("resource", "shows"); request.UriBuilder.SetQueryParam("query", GetSearchTerm(title)); request.UriBuilder.SetQueryParam("seasons", true); return(_httpClient.Get <List <Show> >(request).Resource); }
public List <int> GetXemSeriesIds() { _logger.Debug("Fetching Series IDs from"); var request = _xemRequestBuilder.Build("/havemap"); var response = _httpClient.Get <XemResult <List <string> > >(request).Resource; CheckForFailureResult(response); return(response.Data.Select(d => { int tvdbId = 0; Int32.TryParse(d, out tvdbId); return tvdbId; }).Where(t => t > 0).ToList()); }
public void should_remove_duplicated_slashes() { var builder = new HttpRequestBuilder("http://domain/"); var request = builder.Build("/v1/"); request.Url.ToString().Should().Be("http://domain/v1/"); }
public void should_add_single_segment_url_segments(string url, string result) { var requestBuilder = new HttpRequestBuilder(url); requestBuilder.SetSegment("seg", "dir"); requestBuilder.Build().Url.Should().Be(result); }
protected override async Task DoLogin() { var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl) { LogResponseContent = true, AllowAutoRedirect = true }; var indexPage = await ExecuteAuth(requestBuilder.Build()); var loginUrl = string.Format("{0}/{1}", Settings.BaseUrl.TrimEnd('/'), "login.php"); var requestBuilder2 = new HttpRequestBuilder(loginUrl) { LogResponseContent = true, AllowAutoRedirect = true }; var authLoginRequest = requestBuilder2 .SetCookies(indexPage.GetCookies()) .Build(); // Get login page -- (not used, but simulation needed by tracker security's checks) await ExecuteAuth(authLoginRequest); var requestBuilder3 = new HttpRequestBuilder(string.Format("{0}/{1}", Settings.BaseUrl.TrimEnd('/'), "takelogin.php")) { LogResponseContent = true, AllowAutoRedirect = true, Method = HttpMethod.Post }; var authLoginCheckRequest = requestBuilder3 .AddFormParameter("username", Settings.Username) .AddFormParameter("password", Settings.Password) .SetCookies(indexPage.GetCookies()) .SetHeader("Referer", loginUrl) .Build(); var loginResponse = await ExecuteAuth(authLoginCheckRequest); if (!loginResponse.GetCookies().ContainsKey("uid")) { // Default error message var message = "Error during attempt !"; // Oops, unable to login _logger.Info("NorBits - Login failed: " + message, "error"); throw new IndexerAuthException(message); } var cookies = loginResponse.GetCookies(); UpdateCookies(cookies, DateTime.Now + TimeSpan.FromDays(30)); _logger.Debug("NorBits authentication succeeded."); }
public async Task <int> GetProducts(bool getAll = false, string dateTime = "") { int count; try { var httpRequestBuilder = new HttpRequestBuilder().WithMethod(HttpMethod.Get) .WithRequestUri($"{Program.AppSettings.ApiUrl}{Program.AppSettings.ProductDetailsEndPoint}") .AddHeader(Program.AppSettings.ApiKeyName, Program.AppSettings.ApiKey) .AddQueryParameter("maxResults", 30000); if (!getAll) { httpRequestBuilder.AddQueryParameter("changedSince", dateTime); } var httpRequestMessage = httpRequestBuilder.Build(); Logger.Log($"Fetching from {httpRequestMessage.RequestUri}"); var stopwatch = Stopwatch.StartNew(); var response = await m_client.SendAsync(httpRequestMessage); Logger.Log($"Request duration: {stopwatch.Elapsed}"); stopwatch.Stop(); response.EnsureSuccessStatusCode(); Logger.Log($"{response.StatusCode}: {response.ReasonPhrase}"); var content = await response.Content.ReadAsStringAsync(); var alcoholicEntities = JsonConvert.DeserializeObject <List <AlcoholicEntity> >(content); count = alcoholicEntities.Count; Logger.Log($"Retrieved count: {count}"); if (!getAll) { await UpdateProducts(alcoholicEntities); } else { await AddAllToDb(alcoholicEntities); } } catch (Exception e) { Logger.Log($"{e.Message}\n{e.StackTrace}\nInner Exception:\n{e?.InnerException?.Message}\n{e?.InnerException?.StackTrace}"); return(-1); } return(0); }
private List <PreDBResult> GetResults(string category = "", string search = "") { return(new List <PreDBResult>()); var builder = new HttpRequestBuilder("http://predb.me").AddQueryParam("rss", "1"); if (category.IsNotNullOrWhiteSpace()) { builder.AddQueryParam("cats", category); } if (search.IsNotNullOrWhiteSpace()) { builder.AddQueryParam("search", search); } var request = builder.Build(); request.AllowAutoRedirect = true; request.SuppressHttpError = true; var response = _httpClient.Get(request); if (response.StatusCode != System.Net.HttpStatusCode.OK) { _logger.Warn("Non 200 StatusCode {0} encountered while searching PreDB.", response.StatusCode); return(new List <PreDBResult>()); } try { var reader = XmlReader.Create(new StringReader(response.Content)); var items = SyndicationFeed.Load(reader); var results = new List <PreDBResult>(); foreach (SyndicationItem item in items.Items) { var result = new PreDBResult(); result.Title = item.Title.Text; result.Link = item.Links[0].Uri.ToString(); results.Add(result); } return(results); } catch (Exception ex) { _logger.Error(ex, "Error while searching PreDB."); } return(new List <PreDBResult>()); }
public UTorrentResponse ProcessRequest(HttpRequestBuilder requestBuilder, UTorrentSettings settings) { AuthenticateClient(requestBuilder, settings); var request = requestBuilder.Build(); HttpResponse response; try { response = _httpClient.Execute(request); } catch (HttpException ex) { if (ex.Response.StatusCode == HttpStatusCode.BadRequest || ex.Response.StatusCode == HttpStatusCode.Unauthorized) { _logger.Debug("Authentication required, logging in."); AuthenticateClient(requestBuilder, settings, true); request = requestBuilder.Build(); response = _httpClient.Execute(request); } else { throw new DownloadClientException("Unable to connect to uTorrent, please check your settings", ex); } } catch (WebException ex) { if (ex.Status == WebExceptionStatus.TrustFailure) { throw new DownloadClientUnavailableException("Unable to connect to uTorrent, certificate validation failed.", ex); } throw new DownloadClientException("Unable to connect to uTorrent, please check your settings", ex); } return(Json.Deserialize <UTorrentResponse>(response.Content)); }
private IEnumerable <IndexerRequest> GetRequest(string term, int[] categories, string imdbId = null, int?tmdbId = null, int?tvdbId = null) { var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl) .Resource("/pubapi_v2.php") .Accept(HttpAccept.Json); if (Settings.CaptchaToken.IsNotNullOrWhiteSpace()) { requestBuilder.UseSimplifiedUserAgent = true; requestBuilder.SetCookie("cf_clearance", Settings.CaptchaToken); } requestBuilder.AddQueryParam("mode", "search"); if (imdbId.IsNotNullOrWhiteSpace()) { requestBuilder.AddQueryParam("search_imdb", imdbId); } else if (tmdbId.HasValue && tmdbId > 0) { requestBuilder.AddQueryParam("search_themoviedb", tmdbId); } else if (tvdbId.HasValue && tmdbId > 0) { requestBuilder.AddQueryParam("search_tvdb", tvdbId); } if (term.IsNotNullOrWhiteSpace()) { requestBuilder.AddQueryParam("search_string", $"{term}"); } if (!Settings.RankedOnly) { requestBuilder.AddQueryParam("ranked", "0"); } var cats = Categories.MapTorznabCapsToTrackers(categories); if (cats != null && cats.Count > 0) { var categoryParam = string.Join(";", cats.Distinct()); requestBuilder.AddQueryParam("category", categoryParam); } requestBuilder.AddQueryParam("limit", "100"); requestBuilder.AddQueryParam("token", _tokenProvider.GetToken(Settings, Settings.BaseUrl)); requestBuilder.AddQueryParam("format", "json_extended"); requestBuilder.AddQueryParam("app_id", BuildInfo.AppName); yield return(new IndexerRequest(requestBuilder.Build())); }