private List <ReleaseInfo> ParseApiResults(string json) { var releases = new List <ReleaseInfo>(); foreach (dynamic r in JArray.Parse(json)) { var baseRelease = new ReleaseInfo { Title = composeTitle(r), BannerUrl = new Uri(Configuration.StaticLink.Value + r.poster.url), Comments = new Uri(SiteLink + "/release/" + r.code + ".html"), DownloadVolumeFactor = 0, UploadVolumeFactor = 1, Category = new [] { TorznabCatType.TVAnime.ID } }; foreach (var t in r.torrents.list) { var release = (ReleaseInfo)baseRelease.Clone(); release.Title += " [" + t.quality["string"] + "] - " + t.series["string"]; release.Size = t.total_size; release.Seeders = t.seeders; release.Peers = t.leechers + t.seeders; release.Grabs = t.downloads; release.Link = new Uri(SiteLink + t.url); release.Guid = new Uri(SiteLink + t.url); release.PublishDate = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Convert.ToDouble(t.uploaded_timestamp)).ToLocalTime(); releases.Add(release); } } return(releases); }
private async Task <List <ReleaseInfo> > FetchShowReleases(string url) { var releases = new List <ReleaseInfo>(); var uri = new Uri(url); //Some URLs in search are broken if (url.StartsWith("//")) { url = "https:" + url; } var result = await RequestWithCookiesAndRetryAsync(url); try { var parser = new HtmlParser(); var document = await parser.ParseDocumentAsync(result.ContentString); var baseRelease = new ReleaseInfo { Title = composeBaseTitle(document), Poster = new Uri(document.QuerySelector("div.widget__post-info__poster > a").Attributes["href"].Value), Details = uri, DownloadVolumeFactor = 0, UploadVolumeFactor = 1, Category = new[] { TorznabCatType.TVAnime.ID } }; foreach (var t in document.QuerySelectorAll("ul.media__tabs__nav > li > a")) { var release = (ReleaseInfo)baseRelease.Clone(); var tr_id = t.Attributes["href"].Value; var tr = document.QuerySelector("div" + tr_id); if (tr.Text().Contains("TORRENT READ ERROR")) { logger.Warn($"{DisplayName} The page at {uri.ToString()} has a TORRENT READ ERROR alert. Unable to retrieve this torrent's details."); continue; } release.Title += " - " + composeTitleAdditionalInfo(t, tr); release.Link = new Uri(tr.QuerySelector("div.download_tracker > a.btn__green").Attributes["href"].Value); release.MagnetUri = new Uri(tr.QuerySelector("div.download_tracker > a.btn__d-gray").Attributes["href"].Value); release.Seeders = long.Parse(tr.QuerySelector("div.circle_green_text_top").Text()); release.Peers = release.Seeders + long.Parse(tr.QuerySelector("div.circle_red_text_top").Text()); release.Grabs = long.Parse(tr.QuerySelector("div.circle_grey_text_top").Text()); release.PublishDate = getReleaseDate(tr); release.Size = getReleaseSize(tr); release.Guid = new Uri(uri.ToString() + tr_id); releases.Add(release); } } catch (Exception ex) { OnParseError(result.ContentString, ex); } return(releases); }
private async Task <List <ReleaseInfo> > FetchShowReleases(string url) { var releases = new List <ReleaseInfo>(); var uri = new Uri(url); var result = await RequestWithCookiesAndRetryAsync(url); try { var parser = new HtmlParser(); var document = await parser.ParseDocumentAsync(result.ContentString); var r = document.QuerySelector("div.release > div.wrapper-release"); var baseRelease = new ReleaseInfo() { Title = composeBaseTitle(r), BannerUrl = new Uri(SiteLink + r.QuerySelector("a[data-fancybox]").Attributes["href"].Value), Comments = uri, DownloadVolumeFactor = 0, UploadVolumeFactor = 1, Category = new int[] { TorznabCatType.TVAnime.ID }, }; foreach (var t in r.QuerySelectorAll("a[data-toggle]")) { var release = (ReleaseInfo)baseRelease.Clone(); release.Title += " " + t.Text().Trim(); var tr_id = t.Attributes["href"].Value; var tr = r.QuerySelector("div" + tr_id); release.Link = new Uri(tr.QuerySelector("a.button--success").Attributes["href"].Value); release.Seeders = long.Parse(tr.QuerySelector("div.torrent-counter > div:nth-of-type(1)").Text().Trim().Split(' ')[0]); release.Peers = release.Seeders + long.Parse(tr.QuerySelector("div.torrent-counter > div:nth-of-type(2)").Text().Trim().Split(' ')[0]); release.Grabs = long.Parse(tr.QuerySelector("div.torrent-counter > div:nth-of-type(3)").Text().Trim().Split(' ')[0]); release.PublishDate = DateTime.Parse(tr.QuerySelector("time.torrent-time").Text()); release.Size = getReleaseSize(tr); release.Guid = new Uri(uri.ToString() + tr_id); logger.Info(release.Guid); releases.Add(release); } } catch (Exception ex) { OnParseError(result.ContentString, ex); } return(releases); }
protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { var releases = new List <ReleaseInfo>(); var searchString = GetSearchTerm(query); var searchUrl = APIUrl; var queryCollection = new NameValueCollection { { "action", "browse" }, //{"group_results", "0"}, # results won't include all information { "order_by", "time" }, { "order_way", "desc" } }; if (!string.IsNullOrWhiteSpace(query.ImdbID)) { if (imdbInTags) { queryCollection.Add("taglist", query.ImdbID); } else { queryCollection.Add("cataloguenumber", query.ImdbID); } } else if (!string.IsNullOrWhiteSpace(searchString)) { queryCollection.Add("searchstr", searchString); } if (query.Artist != null) { queryCollection.Add("artistname", query.Artist); } if (query.Label != null) { queryCollection.Add("recordlabel", query.Label); } if (query.Year != null) { queryCollection.Add("year", query.Year.ToString()); } if (query.Album != null) { queryCollection.Add("groupname", query.Album); } foreach (var cat in MapTorznabCapsToTrackers(query)) { queryCollection.Add("filter_cat[" + cat + "]", "1"); } searchUrl += "?" + queryCollection.GetQueryString(); var apiKey = configData.ApiKey; var headers = apiKey != null ? new Dictionary <string, string> { ["Authorization"] = String.Format(AuthorizationFormat, apiKey.Value) } : null; var response = await RequestWithCookiesAndRetryAsync(searchUrl, headers : headers); // we get a redirect in html pages and an error message in json response (api) if (response.IsRedirect || (response.ContentString != null && response.ContentString.Contains("\"bad credentials\""))) { // re-login await ApplyConfiguration(null); response = await RequestWithCookiesAndRetryAsync(searchUrl); } try { var json = JObject.Parse(response.ContentString); foreach (JObject r in json["response"]["results"]) { var groupTime = DateTimeUtil.UnixTimestampToDateTime(long.Parse((string)r["groupTime"])); var groupName = WebUtility.HtmlDecode((string)r["groupName"]); var artist = WebUtility.HtmlDecode((string)r["artist"]); var cover = (string)r["cover"]; var tags = r["tags"].ToList(); var groupYear = (string)r["groupYear"]; var releaseType = (string)r["releaseType"]; var title = new StringBuilder(); if (!string.IsNullOrEmpty(artist)) { title.Append(artist + " - "); } title.Append(groupName); if (!string.IsNullOrEmpty(groupYear) && groupYear != "0") { title.Append(" [" + groupYear + "]"); } if (!string.IsNullOrEmpty(releaseType) && releaseType != "Unknown") { title.Append(" [" + releaseType + "]"); } var description = tags?.Any() == true && !string.IsNullOrEmpty(tags[0].ToString()) ? "Tags: " + string.Join(", ", tags) + "\n" : null; Uri poster = null; if (!string.IsNullOrEmpty(cover)) { poster = new Uri(cover); } var release = new ReleaseInfo { PublishDate = groupTime, Title = title.ToString(), Description = description, Poster = poster }; if (imdbInTags) { release.Imdb = tags .Select(tag => ParseUtil.GetImdbID((string)tag)) .Where(tag => tag != null).FirstIfSingleOrDefault(); } if (r["torrents"] is JArray) { foreach (JObject torrent in r["torrents"]) { var release2 = (ReleaseInfo)release.Clone(); FillReleaseInfoFromJson(release2, torrent); if (ReleaseInfoPostParse(release2, torrent, r)) { releases.Add(release2); } } } else { FillReleaseInfoFromJson(release, r); if (ReleaseInfoPostParse(release, r, r)) { releases.Add(release); } } } } catch (Exception ex) { OnParseError(response.ContentString, ex); } return(releases); }
protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { var releases = new List <ReleaseInfo>(); var searchString = GetSearchTerm(query); var searchUrl = APIUrl; var queryCollection = new NameValueCollection(); queryCollection.Add("action", "browse"); //queryCollection.Add("group_results", "0"); # results won't include all information queryCollection.Add("order_by", "time"); queryCollection.Add("order_way", "desc"); if (!string.IsNullOrWhiteSpace(query.ImdbID)) { queryCollection.Add("cataloguenumber", query.ImdbID); } else if (!string.IsNullOrWhiteSpace(searchString)) { queryCollection.Add("searchstr", searchString); } if (query.Artist != null) { queryCollection.Add("artistname", query.Artist); } if (query.Label != null) { queryCollection.Add("recordlabel", query.Label); } if (query.Year != null) { queryCollection.Add("year", query.Year.ToString()); } if (query.Album != null) { queryCollection.Add("groupname", query.Album); } foreach (var cat in MapTorznabCapsToTrackers(query)) { queryCollection.Add("filter_cat[" + cat + "]", "1"); } searchUrl += "?" + queryCollection.GetQueryString(); var response = await RequestStringWithCookiesAndRetry(searchUrl); if (response.IsRedirect || query.IsTest) { // re-login await ApplyConfiguration(null); response = await RequestStringWithCookiesAndRetry(searchUrl); } try { var json = JObject.Parse(response.Content); foreach (JObject r in json["response"]["results"]) { var groupTime = DateTimeUtil.UnixTimestampToDateTime(long.Parse((string)r["groupTime"])); var groupName = WebUtility.HtmlDecode((string)r["groupName"]); var artist = WebUtility.HtmlDecode((string)r["artist"]); var cover = (string)r["cover"]; var tags = r["tags"].ToList(); var groupYear = (string)r["groupYear"]; var releaseType = (string)r["releaseType"]; var release = new ReleaseInfo(); release.PublishDate = groupTime; if (!string.IsNullOrEmpty(cover)) { release.BannerUrl = new Uri(cover); } release.Title = ""; if (!string.IsNullOrEmpty(artist)) { release.Title += artist + " - "; } release.Title += groupName; if (!string.IsNullOrEmpty(groupYear) && groupYear != "0") { release.Title += " [" + groupYear + "]"; } if (!string.IsNullOrEmpty(releaseType) && releaseType != "Unknown") { release.Title += " [" + releaseType + "]"; } release.Description = ""; if (tags != null && tags.Count > 0 && (string)tags[0] != "") { release.Description += "Tags: " + string.Join(", ", tags) + "\n"; } if (r["torrents"] is JArray) { foreach (JObject torrent in r["torrents"]) { ReleaseInfo release2 = (ReleaseInfo)release.Clone(); FillReleaseInfoFromJson(release2, torrent); if (ReleaseInfoPostParse(release2, torrent, r)) { releases.Add(release2); } } } else { FillReleaseInfoFromJson(release, r); if (ReleaseInfoPostParse(release, r, r)) { releases.Add(release); } } } } catch (Exception ex) { OnParseError(response.Content, ex); } return(releases); }
protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { var releasesQuery = new { operationName = "fetchReleases", variables = new { first = 50, //Number of fetched releases (required parameter) TODO: consider adding pagination query = query.SearchTerm }, query = @" query fetchReleases($first: Int, $query: String) { releases(first: $first, query: $query) { edges { node { name originalName alternativeNames publishedAt slug posters { preview: resize(width: 360, height: 500) { url } } torrents { downloaded seeders leechers size magnetUri updatedAt file { url } videoQualities } } } } }" }; var headers = new Dictionary <string, string> { { "Content-Type", "application/json; charset=utf-8" }, }; var response = await RequestWithCookiesAndRetryAsync(GraphqlEndpointUrl, method : RequestType.POST, rawbody : Newtonsoft.Json.JsonConvert.SerializeObject(releasesQuery), headers : headers); var j = JsonConvert.DeserializeObject <ReleasesResponse>(response.ContentString); var releases = new List <ReleaseInfo>(); foreach (var e in j.Data.Releases.Edges) { var n = e.Node; var baseRelease = new ReleaseInfo { Title = composeTitle(n), Poster = n.Posters[0].Preview.Url, Details = new Uri(SiteLink + "releases/" + n.Slug), DownloadVolumeFactor = 0, UploadVolumeFactor = 1, Category = new[] { TorznabCatType.TVAnime.ID } }; foreach (var t in n.Torrents) { var release = (ReleaseInfo)baseRelease.Clone(); release.Title += getTitleQualities(t); release.Size = t.Size; release.Seeders = t.Seeders; release.Peers = t.Leechers + t.Seeders; release.Grabs = t.Downloaded; release.Link = t.File.Url; release.Guid = t.File.Url; release.MagnetUri = t.MagnetUri; release.PublishDate = getActualPublishDate(n, t); releases.Add(release); } } return(releases); }