コード例 #1
0
        public static Uri CreateSearchUri(string search)
        {
            var finalUri = SearchUriBase.AbsoluteUri;

            finalUri += "?sec=buscador&valor=" + WebUtilityHelpers.UrlEncode(search, MEEncoding);
            return(new Uri(finalUri));
        }
コード例 #2
0
 public static string GetQueryString(this ICollection <KeyValuePair <string, string> > collection, Encoding encoding = null)
 {
     if (encoding == null)
     {
         encoding = Encoding.UTF8;
     }
     return(string.Join("&", collection.Select(a => a.Key + "=" + WebUtilityHelpers.UrlEncode(a.Value, encoding))));
 }
コード例 #3
0
 public static Uri InfoHashToPublicMagnet(string infoHash, string title)
 {
     if (string.IsNullOrWhiteSpace(infoHash) || string.IsNullOrWhiteSpace(title))
     {
         return(null);
     }
     return(new Uri($"magnet:?xt=urn:btih:{infoHash}&dn={WebUtilityHelpers.UrlEncode(title, Encoding.UTF8)}&{_TrackersEncoded}"));
 }
コード例 #4
0
 public static string GetQueryString(this NameValueCollection collection, Encoding encoding = null)
 {
     if (encoding == null)
     {
         encoding = Encoding.UTF8;
     }
     return(string.Join("&", collection.AllKeys.Select(a => a + "=" + WebUtilityHelpers.UrlEncode(collection[a], encoding))));
 }
コード例 #5
0
 public void WebUtilityHelpers_UrlDecode_CorrectlyDecodes()
 {
     foreach (var encoding in _codePagesToTest)
     {
         foreach (var testString in _stringsToTest)
         {
             //Check our implementation of Decode in .NET Standard Matches the .NET Framework Version
             var encodedString    = HttpUtility.UrlEncode(testString, encoding);
             var NETString        = HttpUtility.UrlDecode(encodedString, encoding);
             var WebUtilityString = WebUtilityHelpers.UrlDecode(encodedString, encoding);
             Assert.AreEqual(NETString, WebUtilityString, $"{testString} did not match the expected decoded value after encoding with {encoding.EncodingName})");
         }
     }
 }
コード例 #6
0
        public void WebUtilityHelpers_UrlEncode_CorrectlyEncodes()
        {
            foreach (var encoding in _codePagesToTest)
            {
                foreach (var testString in _stringsToTest)
                {
                    //Check our implementation of Decode in .NET Standard Matches the .NET Framework Version
                    var NETString        = HttpUtility.UrlEncode(testString, encoding);
                    var WebUtilityString = WebUtilityHelpers.UrlEncode(testString, encoding);
                    //Of note is that percent encoding gives lowercase values, where NET Native uses upper case this should be okay according to RFC3986 (https://tools.ietf.org/html/rfc3986#section-2.1)
                    var NETDecode        = HttpUtility.UrlDecode(NETString);
                    var WebUtilityDecode = HttpUtility.UrlDecode(WebUtilityString);

                    Assert.AreEqual(NETDecode, WebUtilityDecode, $"{testString} did not match the expected decoded string with {encoding.EncodingName})");
                }
            }
        }
コード例 #7
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var templateUrl = SiteLink;

            if (_language.Equals("castellano"))
            {
                templateUrl += "espana/";
            }
            templateUrl += "{0}"; // placeholder for page

            var maxPages = 2;     // we scrape only 2 pages for recent torrents

            if (!string.IsNullOrWhiteSpace(query.GetQueryString()))
            {
                templateUrl += "?s=" + WebUtilityHelpers.UrlEncode(query.GetQueryString(), Encoding.UTF8);
                maxPages     = MaxSearchPageLimit;
            }

            var lastPublishDate = DateTime.Now;

            for (var page = 1; page <= maxPages; page++)
            {
                var pageParam = page > 1 ? $"page/{page}/" : "";
                var searchUrl = string.Format(templateUrl, pageParam);
                var response  = await RequestWithCookiesAndRetryAsync(searchUrl);

                var pageReleases = ParseReleases(response, query);

                // publish date is not available in the torrent list, but we add a relative date so we can sort
                foreach (var release in pageReleases)
                {
                    release.PublishDate = lastPublishDate;
                    lastPublishDate     = lastPublishDate.AddMinutes(-1);
                }
                releases.AddRange(pageReleases);

                if (pageReleases.Count < MaxItemsPerPage)
                {
                    break; // this is the last page
                }
            }

            return(releases);
        }
コード例 #8
0
        /// <summary>
        /// Build query to process
        /// </summary>
        /// <param name="term">Term to search</param>
        /// <param name="query">Torznab Query for categories mapping</param>
        /// <param name="url">Search url for provider</param>
        /// <param name="page">Page number to request</param>
        /// <returns>URL to query for parsing and processing results</returns>
        private string BuildQuery(string term, TorznabQuery query, string url, int page = 0)
        {
            var    parameters     = new NameValueCollection();
            var    categoriesList = MapTorznabCapsToTrackers(query);
            string searchterm     = term;

            // Building our tracker query
            parameters.Add("incldead", "1");
            parameters.Add("fullsearch", "0");
            parameters.Add("scenerelease", "0");

            // If search term provided
            if (!string.IsNullOrWhiteSpace(query.ImdbID))
            {
                searchterm = "imdbsearch=" + query.ImdbID;
            }
            else if (!string.IsNullOrWhiteSpace(term))
            {
                searchterm = "search=" + WebUtilityHelpers.UrlEncode(term, Encoding.GetEncoding(28591));
            }
            else
            {
                // Showing all torrents (just for output function)
                searchterm = "search=";
                term       = "all";
            }

            var CatQryStr = "";

            foreach (var cat in categoriesList)
            {
                CatQryStr += "&" + cat;
            }

            // Building our query
            url += "?" + searchterm + "&" + parameters.GetQueryString() + "&" + CatQryStr;

            Output("\nBuilded query for \"" + term + "\"... " + url);

            // Return our search url
            return(url);
        }
コード例 #9
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var templateUrl = SiteLink + "{0}";

            var maxPages = 2;

            if (!string.IsNullOrWhiteSpace(query.GetQueryString()))
            {
                templateUrl += "?s=" + WebUtilityHelpers.UrlEncode(query.GetQueryString(), Encoding.UTF8);
                maxPages     = MaxSearchPageLimit;
            }

            var lastPublishDate = DateTime.Now;

            for (var page = 1; page <= maxPages; page++)
            {
                var pageParam = page > 1 ? $"page/{page}" : "";
                var searchUrl = string.Format(templateUrl, pageParam);
                var response  = await RequestWithCookiesAndRetryAsync(searchUrl);

                var pageReleases = await ParseReleases(response, query);

                foreach (var release in pageReleases)
                {
                    release.PublishDate = lastPublishDate;
                    lastPublishDate     = lastPublishDate.AddMinutes(-1);
                }
                releases.AddRange(pageReleases);

                if (pageReleases.Count < MaxItemsPerPage)
                {
                    break;
                }
            }

            return(releases);
        }
コード例 #10
0
        public void WebUtilityHelpers_UrlDecode_BadDecodes()
        {
            var decoded = WebUtilityHelpers.UrlDecode(null, Encoding.UTF8);

            Assert.AreEqual("", decoded);
        }
コード例 #11
0
        protected override async Task <WebResult> Run(WebRequest webRequest)
        {
            ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;

            var cookies = new CookieContainer();

            if (!string.IsNullOrWhiteSpace(webRequest.Cookies))
            {
                // don't include the path, Scheme is needed for mono compatibility
                var requestUri       = new Uri(webRequest.Url);
                var cookieUrl        = new Uri(requestUri.Scheme + "://" + requestUri.Host);
                var cookieDictionary = CookieUtil.CookieHeaderToDictionary(webRequest.Cookies);
                foreach (var kv in cookieDictionary)
                {
                    cookies.Add(cookieUrl, new Cookie(kv.Key, kv.Value));
                }
            }

            var userAgent = webRequest.EmulateBrowser.Value ? BrowserUtil.ChromeUserAgent : "Jackett/" + configService.GetVersion();

            using (var clearanceHandlr = new ClearanceHandler(userAgent))
            {
                clearanceHandlr.MaxTries = 10;
                using (var clientHandlr = new HttpClientHandler
                {
                    CookieContainer = cookies,
                    AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
                    UseCookies = true,
                    Proxy = webProxy,
                    UseProxy = (webProxy != null),
                    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
                })
                {
                    clearanceHandlr.InnerHandler = clientHandlr;
                    using (var client = new HttpClient(clearanceHandlr))
                    {
                        if (webRequest.EmulateBrowser == true)
                        {
                            client.DefaultRequestHeaders.Add("User-Agent", BrowserUtil.ChromeUserAgent);
                        }
                        else
                        {
                            client.DefaultRequestHeaders.Add("User-Agent", "Jackett/" + configService.GetVersion());
                        }

                        HttpResponseMessage response = null;
                        using (var request = new HttpRequestMessage())
                        {
                            request.Headers.ExpectContinue = false;
                            request.RequestUri             = new Uri(webRequest.Url);

                            if (webRequest.Headers != null)
                            {
                                foreach (var header in webRequest.Headers)
                                {
                                    if (header.Key != "Content-Type")
                                    {
                                        request.Headers.TryAddWithoutValidation(header.Key, header.Value);
                                    }
                                }
                            }

                            if (!string.IsNullOrEmpty(webRequest.Referer))
                            {
                                request.Headers.Referrer = new Uri(webRequest.Referer);
                            }

                            if (!string.IsNullOrEmpty(webRequest.RawBody))
                            {
                                var type = webRequest.Headers.Where(h => h.Key == "Content-Type").Cast <KeyValuePair <string, string>?>().FirstOrDefault();
                                if (type.HasValue)
                                {
                                    var str = new StringContent(webRequest.RawBody);
                                    str.Headers.Remove("Content-Type");
                                    str.Headers.Add("Content-Type", type.Value.Value);
                                    request.Content = str;
                                }
                                else
                                {
                                    request.Content = new StringContent(webRequest.RawBody);
                                }
                                request.Method = HttpMethod.Post;
                            }
                            else if (webRequest.Type == RequestType.POST)
                            {
                                if (webRequest.PostData != null)
                                {
                                    request.Content = FormUrlEncodedContentWithEncoding(webRequest.PostData, webRequest.Encoding);
                                }
                                request.Method = HttpMethod.Post;
                            }
                            else
                            {
                                request.Method = HttpMethod.Get;
                            }

                            using (response = await client.SendAsync(request))
                            {
                                var result = new WebResult
                                {
                                    ContentBytes = await response.Content.ReadAsByteArrayAsync()
                                };

                                foreach (var header in response.Headers)
                                {
                                    var value = header.Value;
                                    result.Headers[header.Key.ToLowerInvariant()] = value.ToArray();
                                }

                                // some cloudflare clients are using a refresh header
                                // Pull it out manually
                                if (response.StatusCode == HttpStatusCode.ServiceUnavailable && response.Headers.Contains("Refresh"))
                                {
                                    var refreshHeaders = response.Headers.GetValues("Refresh");
                                    var redirval       = "";
                                    var redirtime      = 0;
                                    if (refreshHeaders != null)
                                    {
                                        foreach (var value in refreshHeaders)
                                        {
                                            var start = value.IndexOf("=");
                                            var end   = value.IndexOf(";");
                                            var len   = value.Length;
                                            if (start > -1)
                                            {
                                                redirval             = value.Substring(start + 1);
                                                result.RedirectingTo = redirval;
                                                // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
                                                // of this cloudflare approach..don't want to alter WebResult.IsRedirect because normally
                                                // it shoudln't include service unavailable..only if we have this redirect header.
                                                response.StatusCode = System.Net.HttpStatusCode.Redirect;
                                                redirtime           = int.Parse(value.Substring(0, end));
                                                System.Threading.Thread.Sleep(redirtime * 1000);
                                            }
                                        }
                                    }
                                }
                                if (response.Headers.Location != null)
                                {
                                    result.RedirectingTo = response.Headers.Location.ToString();
                                }
                                // Mono won't add the baseurl to relative redirects.
                                // e.g. a "Location: /index.php" header will result in the Uri "file:///index.php"
                                // See issue #1200
                                if (result.RedirectingTo != null && result.RedirectingTo.StartsWith("file://"))
                                {
                                    // URL decoding apparently is needed to, without it e.g. Demonoid download is broken
                                    // TODO: is it always needed (not just for relative redirects)?
                                    var newRedirectingTo = WebUtilityHelpers.UrlDecode(result.RedirectingTo, webRequest.Encoding);
                                    if (newRedirectingTo.StartsWith("file:////")) // Location without protocol but with host (only add scheme)
                                    {
                                        newRedirectingTo = newRedirectingTo.Replace("file://", request.RequestUri.Scheme + ":");
                                    }
                                    else
                                    {
                                        newRedirectingTo = newRedirectingTo.Replace("file://", request.RequestUri.Scheme + "://" + request.RequestUri.Host);
                                    }
                                    logger.Debug("[MONO relative redirect bug] Rewriting relative redirect URL from " + result.RedirectingTo + " to " + newRedirectingTo);
                                    result.RedirectingTo = newRedirectingTo;
                                }
                                result.Status = response.StatusCode;

                                // Compatiblity issue between the cookie format and httpclient
                                // Pull it out manually ignoring the expiry date then set it manually
                                // http://stackoverflow.com/questions/14681144/httpclient-not-storing-cookies-in-cookiecontainer
                                var responseCookies = new List <Tuple <string, string> >();

                                if (response.Headers.TryGetValues("set-cookie", out var cookieHeaders))
                                {
                                    foreach (var value in cookieHeaders)
                                    {
                                        var nameSplit = value.IndexOf('=');
                                        if (nameSplit > -1)
                                        {
                                            responseCookies.Add(new Tuple <string, string>(value.Substring(0, nameSplit), value.Substring(0, value.IndexOf(';') == -1 ? value.Length : (value.IndexOf(';'))) + ";"));
                                        }
                                    }

                                    var cookieBuilder = new StringBuilder();
                                    foreach (var cookieGroup in responseCookies.GroupBy(c => c.Item1))
                                    {
                                        cookieBuilder.AppendFormat("{0} ", cookieGroup.Last().Item2);
                                    }
                                    result.Cookies = cookieBuilder.ToString().Trim();
                                }
                                ServerUtil.ResureRedirectIsFullyQualified(webRequest, result);
                                return(result);
                            }
                        }
                    }
                }
            }
        }
コード例 #12
0
        private async Task <IEnumerable <ReleaseInfo> > performRegularQuery(TorznabQuery query, string hebName = null)
        {
            var releases        = new List <ReleaseInfo>();
            var searchurls      = new List <string>();
            var searchUrl       = SearchUrl;
            var queryCollection = new NameValueCollection();
            var searchString    = query.GetQueryString();

            if (query.IsImdbQuery)
            {
                searchString = query.ImdbID;
            }

            if (hebName != null)
            {
                searchString = hebName + " - עונה " + query.Season + " פרק " + query.Episode;
            }
            searchUrl += "?";
            if (!string.IsNullOrWhiteSpace(searchString))
            {
                var strEncoded = WebUtilityHelpers.UrlEncode(searchString, Encoding);
                searchUrl += "&query=" + strEncoded + "&matchquery=any";
            }

            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                searchUrl += "&c[]=" + cat;
            }

            var data = await RequestStringWithCookiesAndRetry(searchUrl);

            try
            {
                CQ  dom  = data.Content;
                var rows = dom["tr.box_torrent"];
                foreach (var row in rows)
                {
                    CQ qRow = row.Cq();

                    var release         = new ReleaseInfo();
                    var main_title_link = qRow.Find("div.main_title > a");
                    release.Title = main_title_link.Attr("longtitle");
                    if (release.Title.IsNullOrEmptyOrWhitespace())
                    {
                        release.Title = main_title_link.Text();
                    }

                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;

                    int seeders, peers;
                    if (ParseUtil.TryCoerceInt(qRow.Find("td:nth-child(7) > div").Text(), out seeders))
                    {
                        release.Seeders = seeders;
                        if (ParseUtil.TryCoerceInt(qRow.Find("td:nth-child(8) > div").Text(), out peers))
                        {
                            release.Peers = peers + release.Seeders;
                        }
                    }
                    release.Grabs   = ParseUtil.CoerceLong(qRow.Find("td:nth-child(5)").Text().Replace(",", ""));
                    release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:nth-child(6)").Text().Replace(",", ""));
                    release.Peers   = ParseUtil.CoerceInt(qRow.Find("td:nth-child(7)").Text().Replace(",", "")) + release.Seeders;
                    string fullSize = qRow.Find("td:nth-child(4)").Text();
                    release.Size = ReleaseInfo.GetBytes(fullSize);

                    release.Comments = new Uri(SiteLink + qRow.Find("a.threadlink[href]").Attr("href"));
                    release.Link     = new Uri(SiteLink + qRow.Find("a:has(div.dlimg)").Attr("href"));
                    release.Guid     = release.Comments;
                    try
                    {
                        release.BannerUrl = new Uri(qRow.Find("a[imgsrc]").Attr("imgsrc"));
                    }
                    catch (Exception)
                    {
                        // do nothing, some releases have invalid banner URLs, ignore the banners in this case
                    }

                    var    dateStringAll = qRow.Find("div.up_info2")[0].ChildNodes.Last().ToString();
                    var    dateParts     = dateStringAll.Split(' ');
                    string dateString    = dateParts[dateParts.Length - 2] + " " + dateParts[dateParts.Length - 1];
                    release.PublishDate = DateTime.ParseExact(dateString, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture);

                    string categoryLink = qRow.Find("a[href^=\"/browse.php?cat=\"]").Attr("href");
                    var    catid        = ParseUtil.GetArgumentFromQueryString(categoryLink, "cat");
                    release.Category = MapTrackerCatToNewznab(catid);

                    if (qRow.Find("a[href^=\"?freeleech=1\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

                    var sub_title = qRow.Find("div.sub_title");
                    var imdb_link = sub_title.Find("span.imdb-inline > a");
                    release.Imdb = ParseUtil.GetLongFromString(imdb_link.Attr("href"));
                    sub_title.Find("span.imdb-inline").Remove();
                    release.Description = sub_title.Text();

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(data.Content, ex);
            }

            return(releases);
        }
コード例 #13
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();
            var searchUrl    = SearchUrl;

            if (!string.IsNullOrWhiteSpace(searchString))
            {
                searchUrl += "&action=advanced&searchsubmit=1&filelist=" + WebUtilityHelpers.UrlEncode(searchString, Encoding);
            }
            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count > 0)
            {
                searchUrl = cats.Aggregate(searchUrl, (url, cat) => $"{url}&filter_cat[{cat}]=1");
            }
            var response = await RequestWithCookiesAsync(searchUrl);

            try
            {
                var parser = new HtmlParser();
                var dom    = parser.ParseDocument(response.ContentString);
                var rows   = dom.QuerySelectorAll("table#torrent_table > tbody > tr.torrent");
                foreach (var row in rows)
                {
                    var release = new ReleaseInfo
                    {
                        MinimumRatio    = 1.0,
                        MinimumSeedTime = 604800 // 168 hours
                    };
                    var qCat   = row.QuerySelector("div[class*=\"cats_\"]");
                    var catStr = qCat.GetAttribute("class").Split('_')[1];
                    release.Category = catStr switch
                    {
                        "movies" => MapTrackerCatToNewznab("1"),
                        "tv" => MapTrackerCatToNewznab("2"),
                        "theater" => MapTrackerCatToNewznab("3"),
                        "software" => MapTrackerCatToNewznab("4"),
                        "games" => MapTrackerCatToNewznab("5"),
                        "music" => MapTrackerCatToNewznab("6"),
                        "books" => MapTrackerCatToNewznab("7"),
                        "moviespacks" => MapTrackerCatToNewznab("8"),
                        "porno" => MapTrackerCatToNewznab("9"),
                        "other" => MapTrackerCatToNewznab("10"),
                        _ => throw new Exception("Error parsing category! Unknown cat=" + catStr),
                    };
                    var qTitle = row.QuerySelector("div.torrent_info");
                    release.Title = qTitle.TextContent.Trim();
                    var qDetailsLink = row.QuerySelector("a.torrent_name");
                    // I don't understand, I correctly build the poster as
                    // https://hebits.net/images/oRbJr/3776T8DeNsKbyUM3tsV0LBY_v_JfdfmkhShh_LguTP.jpg
                    // yet the dashboard shows a broken icon symbol! No idea why this does not work.
                    //if (!string.IsNullOrEmpty(qDetailsLink.GetAttribute("data-cover")))
                    //{
                    //    release.Poster = new Uri(SiteLink.TrimEnd('/') + qDetailsLink.GetAttribute("data-cover"));
                    //    logger.Debug("poster=" + release.Poster);
                    //}
                    release.Details = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
                    release.Link    = new Uri(SiteLink + row.QuerySelector("a[href^=\"torrents.php?action=download&id=\"]").GetAttribute("href"));
                    release.Guid    = release.Link;
                    var qDate = row.QuerySelector("span.time").GetAttribute("title");
                    release.PublishDate = DateTime.ParseExact(qDate, "dd/MM/yyyy, HH:mm", CultureInfo.InvariantCulture);
                    var qSize = row.QuerySelector("td:nth-last-child(4)").TextContent.Trim();
                    release.Size    = ReleaseInfo.GetBytes(qSize);
                    release.Seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(2)").TextContent.Trim());
                    release.Peers   = release.Seeders + ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(1)").TextContent.Trim());
                    release.Files   = ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(6)").TextContent.Trim());
                    release.Grabs   = ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(3)").TextContent.Trim());
                    release.DownloadVolumeFactor = release.Title.Contains("פריליץ")
                        ? 0
                        : release.Title.Contains("חצי פריליץ")
                            ? 0.5
                            : release.Title.Contains("75% פריליץ")
                                ? 0.25
                                : 1;
                    release.UploadVolumeFactor = release.Title.Contains("העלאה משולשת")
                        ? 3
                        : release.Title.Contains("העלאה כפולה")
                            ? 2
                            : 1;
                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.ContentString, ex);
            }

            return(releases);
        }
コード例 #14
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();
            var queryUrl     = SearchUrl;

            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count == 0)
            {
                cats = GetAllTrackerCategories();
            }

            var catStr = string.Join(";", cats);

            queryUrl += "?" + catStr;

            if (!string.IsNullOrWhiteSpace(query.ImdbID))
            {
                queryUrl += ";q=" + query.ImdbID;
            }
            else
            {
                queryUrl += ";q=" + WebUtilityHelpers.UrlEncode(searchString, Encoding);
            }

            var results = await RequestStringWithCookiesAndRetry(queryUrl);

            // Check for being logged out
            if (results.IsRedirect)
            {
                if (results.RedirectingTo.Contains("login.php"))
                {
                    throw new ExceptionWithConfigData("Login failed, please reconfigure the tracker to update the cookies", configData);
                }
                else
                {
                    throw new ExceptionWithConfigData(string.Format("Got a redirect to {0}, please adjust your the alternative link", results.RedirectingTo), configData);
                }
            }

            try
            {
                dynamic json = JsonConvert.DeserializeObject <dynamic>(results.Content);

                foreach (var torrent in json)
                {
                    var release = new ReleaseInfo();

                    release.Title = torrent.name;
                    if ((query.ImdbID == null || !TorznabCaps.SupportsImdbMovieSearch) && !query.MatchQueryStringAND(release.Title))
                    {
                        continue;
                    }

                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800; // 48 hours
                    release.Category        = MapTrackerCatToNewznab(torrent.c.ToString());

                    var torrentID = (long)torrent.t;
                    release.Comments    = new Uri(SiteLink + "details.php?id=" + torrentID);
                    release.Guid        = release.Comments;
                    release.Link        = new Uri(SiteLink + "download.php/" + torrentID + "/" + torrentID + ".torrent");
                    release.PublishDate = DateTimeUtil.UnixTimestampToDateTime((long)torrent.ctime).ToLocalTime();

                    release.Size    = (long)torrent.size;
                    release.Seeders = (int)torrent.seeders;
                    release.Peers   = release.Seeders + (int)torrent.leechers;
                    release.Files   = (long)torrent.files;
                    release.Grabs   = (long)torrent.completed;
                    var imdbId = (string)torrent["imdb-id"];
                    release.Imdb = ParseUtil.GetImdbID(imdbId);
                    var downloadMultiplier = (double?)torrent["download-multiplier"];
                    release.DownloadVolumeFactor = downloadMultiplier ?? 1;
                    release.UploadVolumeFactor   = 1;

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }
            return(releases);
        }
コード例 #15
0
ファイル: Hebits.cs プロジェクト: tide4cw/Jackett
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();
            var searchUrl    = SearchUrl;

            if (!string.IsNullOrWhiteSpace(searchString))
            {
                searchUrl += "&search=" + WebUtilityHelpers.UrlEncode(searchString, Encoding);
            }
            string.Format(SearchUrl, WebUtilityHelpers.UrlEncode(searchString, Encoding));

            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count > 0)
            {
                foreach (var cat in cats)
                {
                    searchUrl += "&c" + cat + "=1";
                }
            }

            var response = await RequestStringWithCookies(searchUrl);

            try
            {
                CQ dom = response.Content;

                var qRows = dom[".browse > div > div"];

                foreach (var row in qRows)
                {
                    var release = new ReleaseInfo();

                    var qRow = row.Cq();

                    var debug = qRow.Html();

                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800; // 48 hours

                    var qTitle     = qRow.Find(".bTitle");
                    var titleParts = qTitle.Text().Split('/');
                    if (titleParts.Length >= 2)
                    {
                        release.Title = titleParts[1].Trim();
                    }
                    else
                    {
                        release.Title = titleParts[0].Trim();
                    }

                    var qDetailsLink = qTitle.Find("a[href^=\"details.php\"]");
                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
                    release.Link     = new Uri(SiteLink + qRow.Find("a[href^=\"download.php\"]").Attr("href"));
                    release.Guid     = release.Link;

                    var dateString = qRow.Find("div:last-child").Text().Trim();
                    var pattern    = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}";
                    var match      = Regex.Match(dateString, pattern);
                    if (match.Success)
                    {
                        release.PublishDate = DateTime.ParseExact(match.Value, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                    }

                    var sizeStr = qRow.Find(".bSize").Text();
                    release.Size    = ReleaseInfo.GetBytes(sizeStr);
                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".bUping").Text().Trim());
                    release.Peers   = release.Seeders + ParseUtil.CoerceInt(qRow.Find(".bDowning").Text().Trim());

                    var files = qRow.Find("div.bFiles").Get(0).LastChild.ToString();
                    release.Files = ParseUtil.CoerceInt(files);

                    var grabs = qRow.Find("div.bFinish").Get(0).LastChild.ToString();
                    release.Grabs = ParseUtil.CoerceInt(grabs);

                    if (qRow.Find("img[src=\"/pic/free.jpg\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    if (qRow.Find("img[src=\"/pic/triple.jpg\"]").Length >= 1)
                    {
                        release.UploadVolumeFactor = 3;
                    }
                    else if (qRow.Find("img[src=\"/pic/double.jpg\"]").Length >= 1)
                    {
                        release.UploadVolumeFactor = 2;
                    }
                    else
                    {
                        release.UploadVolumeFactor = 1;
                    }

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.Content, ex);
            }

            return(releases);
        }
コード例 #16
0
ファイル: Hebits.cs プロジェクト: xfouloux/Jackett
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();
            var searchUrl    = SearchUrl;

            if (!string.IsNullOrWhiteSpace(searchString))
            {
                searchUrl += "&search=" + WebUtilityHelpers.UrlEncode(searchString, Encoding);
            }
            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count > 0)
            {
                searchUrl = cats.Aggregate(searchUrl, (url, cat) => $"{url}&c{cat}=1");
            }
            var response = await RequestWithCookiesAsync(searchUrl);

            try
            {
                var parser = new HtmlParser();
                var dom    = parser.ParseDocument(response.ContentString);
                var rows   = dom.QuerySelectorAll(".browse > div > div");
                foreach (var row in rows)
                {
                    var release = new ReleaseInfo();
                    release.MinimumRatio    = 0.8;
                    release.MinimumSeedTime = 259200; // 72 hours
                    var qCatLink = row.QuerySelector("a[href^=\"browse.php?cat=\"]");
                    var catStr   = qCatLink.GetAttribute("href").Split('=')[1];
                    release.Category = MapTrackerCatToNewznab(catStr);
                    var qTitle     = row.QuerySelector(".bTitle");
                    var titleParts = qTitle.TextContent.Split('/');
                    release.Title = titleParts.Length >= 2 ? titleParts[1].Trim() : titleParts[0].Trim();
                    var qDetailsLink = qTitle.QuerySelector("a[href^=\"details.php\"]");
                    release.Details = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
                    release.Link    = new Uri(SiteLink + row.QuerySelector("a[href^=\"download.php\"]").GetAttribute("href"));
                    release.Guid    = release.Link;
                    var dateString = row.QuerySelector("div:last-child").TextContent.Trim();
                    var match      = Regex.Match(dateString, @"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}");
                    if (match.Success)
                    {
                        release.PublishDate = DateTime.ParseExact(match.Value, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                    }
                    var sizeStr = row.QuerySelector(".bSize").TextContent.Trim();
                    release.Size    = ReleaseInfo.GetBytes(sizeStr);
                    release.Seeders = ParseUtil.CoerceInt(row.QuerySelector(".bUping").TextContent.Trim());
                    release.Peers   = release.Seeders + ParseUtil.CoerceInt(row.QuerySelector(".bDowning").TextContent.Trim());
                    var files = row.QuerySelector("div.bFiles").ChildNodes.Last().TextContent.Trim();
                    release.Files = ParseUtil.CoerceInt(files);
                    var grabs = row.QuerySelector("div.bFinish").ChildNodes.Last().TextContent.Trim();
                    release.Grabs = ParseUtil.CoerceInt(grabs);
                    release.DownloadVolumeFactor = row.QuerySelector("img[src=\"/pic/free.jpg\"]") != null ? 0 : 1;
                    if (row.QuerySelector("img[src=\"/pic/triple.jpg\"]") != null)
                    {
                        release.UploadVolumeFactor = 3;
                    }
                    else if (row.QuerySelector("img[src=\"/pic/double.jpg\"]") != null)
                    {
                        release.UploadVolumeFactor = 2;
                    }
                    else
                    {
                        release.UploadVolumeFactor = 1;
                    }
                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.ContentString, ex);
            }

            return(releases);
        }
コード例 #17
0
ファイル: SpeedCD.cs プロジェクト: henryzulux/Jackett
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            // the order of the params is important!
            var qc = new List <string>();

            var catList = MapTorznabCapsToTrackers(query);

            foreach (var cat in catList)
            {
                qc.Add(cat);
            }

            if (query.IsImdbQuery)
            {
                qc.Add("deep");
                qc.Add("q");
                qc.Add(query.ImdbID);
            }
            else
            {
                qc.Add("q");
                qc.Add(WebUtilityHelpers.UrlEncode(query.GetQueryString(), Encoding));
            }

            var searchUrl = SearchUrl + string.Join("/", qc);
            var response  = await RequestWithCookiesAndRetryAsync(searchUrl);

            if (!response.ContentString.Contains("/logout.php")) // re-login
            {
                await DoLogin();

                response = await RequestWithCookiesAndRetryAsync(searchUrl);
            }

            try
            {
                var parser = new HtmlParser();
                var dom    = parser.ParseDocument(response.ContentString);
                var rows   = dom.QuerySelectorAll("div.boxContent > table > tbody > tr");

                foreach (var row in rows)
                {
                    var cells = row.QuerySelectorAll("td");

                    var title    = row.QuerySelector("td[class='lft'] > div > a").TextContent.Trim();
                    var link     = new Uri(SiteLink + row.QuerySelector("img[title='Download']").ParentElement.GetAttribute("href").TrimStart('/'));
                    var comments = new Uri(SiteLink + row.QuerySelector("td[class='lft'] > div > a").GetAttribute("href").TrimStart('/'));
                    var size     = ReleaseInfo.GetBytes(cells[5].TextContent);
                    var grabs    = ParseUtil.CoerceInt(cells[6].TextContent);
                    var seeders  = ParseUtil.CoerceInt(cells[7].TextContent);
                    var leechers = ParseUtil.CoerceInt(cells[8].TextContent);

                    var pubDateStr  = row.QuerySelector("span[class^='elapsedDate']").GetAttribute("title").Replace(" at", "");
                    var publishDate = DateTime.ParseExact(pubDateStr, "dddd, MMMM d, yyyy h:mmtt", CultureInfo.InvariantCulture);

                    var cat = row.QuerySelector("a").GetAttribute("href").Split('/').Last();
                    var downloadVolumeFactor = row.QuerySelector("span:contains(\"[Freeleech]\")") != null ? 0 : 1;

                    var release = new ReleaseInfo
                    {
                        Title                = title,
                        Link                 = link,
                        Guid                 = link,
                        Comments             = comments,
                        PublishDate          = publishDate,
                        Category             = MapTrackerCatToNewznab(cat),
                        Size                 = size,
                        Grabs                = grabs,
                        Seeders              = seeders,
                        Peers                = seeders + leechers,
                        MinimumRatio         = 1,
                        MinimumSeedTime      = 172800, // 48 hours
                        DownloadVolumeFactor = downloadVolumeFactor,
                        UploadVolumeFactor   = 1
                    };

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.ContentString, ex);
            }
            return(releases);
        }
コード例 #18
0
ファイル: TorrentDay.cs プロジェクト: spirkaa/Jackett
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count == 0)
            {
                cats = GetAllTrackerCategories();
            }
            var catStr    = string.Join(";", cats);
            var searchUrl = SearchUrl + "?" + catStr;

            if (query.IsImdbQuery)
            {
                searchUrl += ";q=" + query.ImdbID;
            }
            else
            {
                searchUrl += ";q=" + WebUtilityHelpers.UrlEncode(query.GetQueryString(), Encoding);
            }

            if (((BoolConfigurationItem)configData.GetDynamic("freeleech")).Value)
            {
                searchUrl += ";free=on";
            }

            var results = await RequestWithCookiesAndRetryAsync(searchUrl);

            // Check for being logged out
            if (results.IsRedirect)
            {
                if (results.RedirectingTo.Contains("login.php"))
                {
                    throw new Exception("The user is not logged in. It is possible that the cookie has expired or you made a mistake when copying it. Please check the settings.");
                }
                else
                {
                    throw new Exception($"Got a redirect to {results.RedirectingTo}, please adjust your the alternative link");
                }
            }

            try
            {
                var rows = JsonConvert.DeserializeObject <dynamic>(results.ContentString);

                foreach (var row in rows)
                {
                    var title = (string)row.name;
                    if ((!query.IsImdbQuery || !TorznabCaps.MovieSearchImdbAvailable) && !query.MatchQueryStringAND(title))
                    {
                        continue;
                    }
                    var torrentId          = (long)row.t;
                    var details            = new Uri(SiteLink + "details.php?id=" + torrentId);
                    var seeders            = (int)row.seeders;
                    var imdbId             = (string)row["imdb-id"];
                    var downloadMultiplier = (double?)row["download-multiplier"] ?? 1;
                    var link        = new Uri(SiteLink + "download.php/" + torrentId + "/" + torrentId + ".torrent");
                    var publishDate = DateTimeUtil.UnixTimestampToDateTime((long)row.ctime).ToLocalTime();
                    var imdb        = ParseUtil.GetImdbID(imdbId);

                    var release = new ReleaseInfo
                    {
                        Title                = title,
                        Details              = details,
                        Guid                 = details,
                        Link                 = link,
                        PublishDate          = publishDate,
                        Category             = MapTrackerCatToNewznab(row.c.ToString()),
                        Size                 = (long)row.size,
                        Files                = (long)row.files,
                        Grabs                = (long)row.completed,
                        Seeders              = seeders,
                        Peers                = seeders + (int)row.leechers,
                        Imdb                 = imdb,
                        DownloadVolumeFactor = downloadMultiplier,
                        UploadVolumeFactor   = 1,
                        MinimumRatio         = 1,
                        MinimumSeedTime      = 172800 // 48 hours
                    };

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.ContentString, ex);
            }
            return(releases);
        }
コード例 #19
0
ファイル: Fuzer.cs プロジェクト: awesome-archive/Jackett
        private async Task <IEnumerable <ReleaseInfo> > PerformRegularQueryAsync(TorznabQuery query, string hebName = null)
        {
            var releases     = new List <ReleaseInfo>();
            var searchUrl    = SearchUrl;
            var searchString = query.GetQueryString();

            if (query.IsImdbQuery)
            {
                searchString = query.ImdbID;
            }
            if (hebName != null)
            {
                searchString = hebName + " - עונה " + query.Season + " פרק " + query.Episode;
            }
            searchUrl += "?";
            if (!string.IsNullOrWhiteSpace(searchString))
            {
                var strEncoded = WebUtilityHelpers.UrlEncode(searchString, Encoding);
                searchUrl += "&query=" + strEncoded + "&matchquery=any";
            }

            searchUrl = MapTorznabCapsToTrackers(query).Aggregate(searchUrl, (current, cat) => $"{current}&c[]={cat}");
            var data = await RequestWithCookiesAndRetryAsync(searchUrl);

            try
            {
                var parser = new HtmlParser();
                var dom    = parser.ParseDocument(data.ContentString);
                var rows   = dom.QuerySelectorAll("tr.box_torrent");
                foreach (var row in rows)
                {
                    var release       = new ReleaseInfo();
                    var mainTitleLink = row.QuerySelector("div.main_title > a");
                    release.Title = mainTitleLink.GetAttribute("longtitle");
                    if (string.IsNullOrWhiteSpace(release.Title))
                    {
                        release.Title = mainTitleLink.TextContent;
                    }
                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800; // 48 hours
                    release.Grabs           = ParseUtil.CoerceLong(row.QuerySelector("td:nth-child(5)").TextContent.Replace(",", ""));
                    release.Seeders         = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(6)").TextContent.Replace(",", ""));
                    release.Peers           = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(7)").TextContent.Replace(",", "")) +
                                              release.Seeders;
                    var fullSize = row.QuerySelector("td:nth-child(4)").TextContent;
                    release.Size     = ReleaseInfo.GetBytes(fullSize);
                    release.Comments = new Uri(SiteLink + row.QuerySelector("a.threadlink[href]").GetAttribute("href"));
                    release.Link     = new Uri(SiteLink + row.QuerySelector("a:has(div.dlimg)").GetAttribute("href"));
                    release.Guid     = release.Comments;
                    //some releases have invalid banner URLs, ignore the banners in this case
                    if (Uri.TryCreate(row.QuerySelector("a[imgsrc]").GetAttribute("imgsrc"),
                                      UriKind.Absolute, out var banner))
                    {
                        release.BannerUrl = banner;
                    }
                    var dateStringAll = row.QuerySelector("div.up_info2").ChildNodes.Last().TextContent;
                    var dateParts     = dateStringAll.Split(' ');
                    var dateString    = dateParts[dateParts.Length - 2] + " " + dateParts[dateParts.Length - 1];
                    release.PublishDate = DateTime.ParseExact(dateString, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture);
                    var categoryLink = row.QuerySelector("a[href^=\"/browse.php?cat=\"]").GetAttribute("href");
                    var catid        = ParseUtil.GetArgumentFromQueryString(categoryLink, "cat");
                    release.Category = MapTrackerCatToNewznab(catid);
                    if (row.QuerySelector("a[href^=\"?freeleech=1\"]") != null)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }
                    release.UploadVolumeFactor = 1;
                    var subTitle = row.QuerySelector("div.sub_title");
                    var imdbLink = subTitle.QuerySelector("span.imdb-inline > a");
                    if (imdbLink != null)
                    {
                        release.Imdb = ParseUtil.GetLongFromString(imdbLink.GetAttribute("href"));
                    }
                    release.Description = subTitle.FirstChild.TextContent;
                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(data.ContentString, ex);
            }

            return(releases);
        }
コード例 #20
0
        override protected async Task <WebClientByteResult> Run(WebRequest webRequest)
        {
            HttpResponseMessage response = null;
            var request = new HttpRequestMessage();

            request.Headers.ExpectContinue = false;
            request.RequestUri             = new Uri(webRequest.Url);

            if (webRequest.EmulateBrowser == true)
            {
                request.Headers.UserAgent.ParseAdd(BrowserUtil.ChromeUserAgent);
            }
            else
            {
                request.Headers.UserAgent.ParseAdd("Jackett/" + configService.GetVersion());
            }

            // clear cookies from cookiecontainer
            var oldCookies = cookies.GetCookies(request.RequestUri);

            foreach (Cookie oldCookie in oldCookies)
            {
                oldCookie.Expired = true;
            }

            if (!string.IsNullOrEmpty(webRequest.Cookies))
            {
                // add cookies to cookiecontainer
                var cookieUrl = new Uri(request.RequestUri.Scheme + "://" + request.RequestUri.Host); // don't include the path, Scheme is needed for mono compatibility
                foreach (var ccookiestr in webRequest.Cookies.Split(';'))
                {
                    var cookiestrparts = ccookiestr.Split('=');
                    var name           = cookiestrparts[0].Trim();
                    if (string.IsNullOrWhiteSpace(name))
                    {
                        continue;
                    }
                    var value = "";
                    if (cookiestrparts.Length >= 2)
                    {
                        value = cookiestrparts[1].Trim();
                    }
                    var cookie = new Cookie(name, value);
                    cookies.Add(cookieUrl, cookie);
                }
            }

            if (webRequest.Headers != null)
            {
                foreach (var header in webRequest.Headers)
                {
                    if (header.Key != "Content-Type")
                    {
                        request.Headers.TryAddWithoutValidation(header.Key, header.Value);
                    }
                }
            }

            if (!string.IsNullOrEmpty(webRequest.Referer))
            {
                request.Headers.Referrer = new Uri(webRequest.Referer);
            }

            if (!string.IsNullOrEmpty(webRequest.RawBody))
            {
                var type = webRequest.Headers.Where(h => h.Key == "Content-Type").Cast <KeyValuePair <string, string>?>().FirstOrDefault();
                if (type.HasValue)
                {
                    var str = new StringContent(webRequest.RawBody);
                    str.Headers.Remove("Content-Type");
                    str.Headers.Add("Content-Type", type.Value.Value);
                    request.Content = str;
                }
                else
                {
                    request.Content = new StringContent(webRequest.RawBody);
                }
                request.Method = HttpMethod.Post;
            }
            else if (webRequest.Type == RequestType.POST)
            {
                if (webRequest.PostData != null)
                {
                    request.Content = new FormUrlEncodedContent(webRequest.PostData);
                }
                request.Method = HttpMethod.Post;
            }
            else
            {
                request.Method = HttpMethod.Get;
            }

            response = await client.SendAsync(request);

            var result = new WebClientByteResult();

            result.Content = await response.Content.ReadAsByteArrayAsync();

            foreach (var header in response.Headers)
            {
                IEnumerable <string> value = header.Value;
                result.Headers[header.Key.ToLowerInvariant()] = value.ToArray();
            }

            // some cloudflare clients are using a refresh header
            // Pull it out manually
            if (response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && response.Headers.Contains("Refresh"))
            {
                var refreshHeaders = response.Headers.GetValues("Refresh");
                var redirval       = "";
                var redirtime      = 0;
                if (refreshHeaders != null)
                {
                    foreach (var value in refreshHeaders)
                    {
                        var start = value.IndexOf("=");
                        var end   = value.IndexOf(";");
                        var len   = value.Length;
                        if (start > -1)
                        {
                            redirval             = value.Substring(start + 1);
                            result.RedirectingTo = redirval;
                            // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
                            // of this cloudflare approach..don't want to alter BaseWebResult.IsRedirect because normally
                            // it shoudln't include service unavailable..only if we have this redirect header.
                            response.StatusCode = System.Net.HttpStatusCode.Redirect;
                            redirtime           = Int32.Parse(value.Substring(0, end));
                            System.Threading.Thread.Sleep(redirtime * 1000);
                        }
                    }
                }
            }
            if (response.Headers.Location != null)
            {
                result.RedirectingTo = response.Headers.Location.ToString();
            }
            // Mono won't add the baseurl to relative redirects.
            // e.g. a "Location: /index.php" header will result in the Uri "file:///index.php"
            // See issue #1200
            if (result.RedirectingTo != null && result.RedirectingTo.StartsWith("file://"))
            {
                // URL decoding apparently is needed to, without it e.g. Demonoid download is broken
                // TODO: is it always needed (not just for relative redirects)?
                var newRedirectingTo = WebUtilityHelpers.UrlDecode(result.RedirectingTo, webRequest.Encoding);
                newRedirectingTo = newRedirectingTo.Replace("file://", request.RequestUri.Scheme + "://" + request.RequestUri.Host);
                logger.Debug("[MONO relative redirect bug] Rewriting relative redirect URL from " + result.RedirectingTo + " to " + newRedirectingTo);
                result.RedirectingTo = newRedirectingTo;
            }
            result.Status = response.StatusCode;

            // Compatiblity issue between the cookie format and httpclient
            // Pull it out manually ignoring the expiry date then set it manually
            // http://stackoverflow.com/questions/14681144/httpclient-not-storing-cookies-in-cookiecontainer
            IEnumerable <string> cookieHeaders;
            var responseCookies = new List <Tuple <string, string> >();

            if (response.Headers.TryGetValues("set-cookie", out cookieHeaders))
            {
                foreach (var value in cookieHeaders)
                {
                    logger.Debug(value);
                    var nameSplit = value.IndexOf('=');
                    if (nameSplit > -1)
                    {
                        responseCookies.Add(new Tuple <string, string>(value.Substring(0, nameSplit), value.Substring(0, value.IndexOf(';') == -1 ? value.Length : (value.IndexOf(';'))) + ";"));
                    }
                }

                var cookieBuilder = new StringBuilder();
                foreach (var cookieGroup in responseCookies.GroupBy(c => c.Item1))
                {
                    cookieBuilder.AppendFormat("{0} ", cookieGroup.Last().Item2);
                }
                result.Cookies = cookieBuilder.ToString().Trim();
            }
            ServerUtil.ResureRedirectIsFullyQualified(webRequest, result);
            return(result);
        }
コード例 #21
0
 public static string GetQueryString(this NameValueCollection collection, Encoding encoding = null) =>
 string.Join("&", collection.AllKeys.Select(a =>
                                            $"{a}={WebUtilityHelpers.UrlEncode(collection[a], encoding ?? Encoding.UTF8)}"));
コード例 #22
0
ファイル: Nordicbits.cs プロジェクト: spoopadoop/jackett
        /// <summary>
        /// Build query to process
        /// </summary>
        /// <param name="term">Term to search</param>
        /// <param name="query">Torznab Query for categories mapping</param>
        /// <param name="url">Search url for provider</param>
        /// <param name="page">Page number to request</param>
        /// <returns>URL to query for parsing and processing results</returns>
        private string BuildQuery(string term, TorznabQuery query, string url, int page = 0)
        {
            var    parameters     = new NameValueCollection();
            var    categoriesList = MapTorznabCapsToTrackers(query);
            string searchterm     = term;

            // Building our tracker query
            parameters.Add("searchin", "title");
            parameters.Add("incldead", "0");

            // If search term provided
            if (!string.IsNullOrWhiteSpace(query.ImdbID))
            {
                searchterm = "imdbsearch=" + query.ImdbID;
            }
            else if (!string.IsNullOrWhiteSpace(term))
            {
                searchterm = "search=" + WebUtilityHelpers.UrlEncode(term, Encoding.GetEncoding(28591));
            }
            else
            {
                // Showing all torrents (just for output function)
                searchterm = "search=";
                term       = "all";
            }

            // Loop on categories and change the catagories for search purposes
            for (int i = 0; i < categoriesList.Count; i++)
            {
                // APPS
                if (new[] { "63", "17", "12", "62", "64" }.Any(c => categoriesList[i].Contains(categoriesList[i])))
                {
                    categoriesList[i] = categoriesList[i].Replace("cat=", "cats5[]=");
                }
                // Books
                if (new[] { "54", "9" }.Any(c => categoriesList[i].Contains(categoriesList[i])))
                {
                    categoriesList[i] = categoriesList[i].Replace("cat=", "cats6[]=");
                }
                // Games
                if (new[] { "24", "53", "49", "51" }.Any(c => categoriesList[i].Contains(categoriesList[i])))
                {
                    categoriesList[i] = categoriesList[i].Replace("cat=", "cats3[]=");
                }
                // Movies
                if (new[] { "35", "42", "47", "15", "58", "16", "6", "21", "19", "22", "20", "25", "10", "23", "65" }.Any(c => categoriesList[i].Contains(categoriesList[i])))
                {
                    categoriesList[i] = categoriesList[i].Replace("cat=", "cats1[]=");
                }
                // Music
                if (new[] { "28", "60", "4", "59", "61", "1" }.Any(c => categoriesList[i].Contains(categoriesList[i])))
                {
                    categoriesList[i] = categoriesList[i].Replace("cat=", "cats4[]=");
                }
                // Series
                if (new[] { "48", "57", "11", "7", "31", "30", "32", "5", "66" }.Any(c => categoriesList[i].Contains(categoriesList[i])))
                {
                    categoriesList[i] = categoriesList[i].Replace("cat=", "cats2[]=");
                }
            }

            // Build category search string
            var CatQryStr = "";

            foreach (var cat in categoriesList)
            {
                CatQryStr += cat + "&";
            }

            // Building our query
            url += "?" + CatQryStr + searchterm + "&" + parameters.GetQueryString();

            Output("\nBuilded query for \"" + term + "\"... " + url);

            // Return our search url
            return(url);
        }
コード例 #23
0
 public static string GetQueryString(this ICollection <KeyValuePair <string, string> > collection, Encoding encoding = null) =>
 string.Join("&", collection.Select(a =>
                                    $"{a.Key}={WebUtilityHelpers.UrlEncode(a.Value, encoding ?? Encoding.UTF8)}"));
コード例 #24
0
 public static string GetQueryString(this IEnumerable <KeyValuePair <string, string> > collection,
                                     Encoding encoding = null, string separator = "&") =>
 string.Join(separator,
             collection.Select(a => $"{a.Key}={WebUtilityHelpers.UrlEncode(a.Value, encoding ?? Encoding.UTF8)}"));