From a3312e765ca906d1b82cadb22c4ba5c7b4bcdf65 Mon Sep 17 00:00:00 2001 From: Kayomani Date: Sun, 23 Aug 2015 21:28:21 +0100 Subject: [PATCH] Implement Avistaz --- README.md | 1 + src/Jackett/Content/logos/avistaz.png | Bin 0 -> 4085 bytes .../Indexers/Abstract/AvistazTracker.cs | 136 ++++++++++++++++++ src/Jackett/Indexers/Avistaz.cs | 35 +++++ src/Jackett/Indexers/PrivateHD.cs | 117 ++------------- src/Jackett/Jackett.csproj | 7 +- .../ManualSearchResult.cs | 2 +- 7 files changed, 187 insertions(+), 111 deletions(-) create mode 100644 src/Jackett/Content/logos/avistaz.png create mode 100644 src/Jackett/Indexers/Abstract/AvistazTracker.cs create mode 100644 src/Jackett/Indexers/Avistaz.cs rename src/Jackett/{Indexers => Models}/ManualSearchResult.cs (91%) diff --git a/README.md b/README.md index 95efd8faa..7941d9a74 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ We were previously focused on TV but are working on extending searches to allow #### Supported Trackers * [AlphaRatio](https://alpharatio.cc/) * [AnimeBytes](https://animebytes.tv/) + * [Avistaz](https://avistaz.to/) * [BakaBT](http://bakabt.me/) * [bB](http://reddit.com/r/baconbits) * [BeyondHD](https://beyondhd.me/) diff --git a/src/Jackett/Content/logos/avistaz.png b/src/Jackett/Content/logos/avistaz.png new file mode 100644 index 0000000000000000000000000000000000000000..4944a926ef10f918dc52c4eaf7893c957a21769b GIT binary patch literal 4085 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 literal 0 HcmV?d00001 diff --git a/src/Jackett/Indexers/Abstract/AvistazTracker.cs b/src/Jackett/Indexers/Abstract/AvistazTracker.cs new file mode 100644 index 000000000..72ef2a29e --- /dev/null +++ b/src/Jackett/Indexers/Abstract/AvistazTracker.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Jackett.Models; +using Newtonsoft.Json.Linq; +using NLog; +using Jackett.Utils; +using System.Net; +using System.Net.Http; +using CsQuery; +using System.Web; +using Jackett.Services; +using Jackett.Utils.Clients; +using System.Text.RegularExpressions; +using Jackett.Models.IndexerConfig; + +namespace Jackett.Indexers +{ + public abstract class AvistazTracker : BaseIndexer + { + private string LoginUrl { get { return SiteLink + "auth/login"; } } + private string SearchUrl { get { return SiteLink + "torrents?in=1&type={0}&search={1}"; } } + + new ConfigurationDataBasicLogin configData + { + get { return (ConfigurationDataBasicLogin)base.configData; } + set { base.configData = value; } + } + + public AvistazTracker(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService, string name, string desc, string link) + : base(name: name, + description: desc, + link: link, + caps: TorznabUtil.CreateDefaultTorznabTVCaps(), + manager: indexerManager, + client: webClient, + logger: logger, + p: protectionService, + configData: new ConfigurationDataBasicLogin()) + { + AddCategoryMapping(1, TorznabCatType.Movies); + AddCategoryMapping(1, TorznabCatType.MoviesForeign); + AddCategoryMapping(1, TorznabCatType.MoviesHD); + AddCategoryMapping(1, TorznabCatType.MoviesSD); + AddCategoryMapping(2, TorznabCatType.TV); + AddCategoryMapping(3, TorznabCatType.Audio); + } + + public async Task ApplyConfiguration(JToken configJson) + { + configData.LoadValuesFromJson(configJson); + var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty); + var token = new Regex("Avz.CSRF_TOKEN = '(.*?)';").Match(loginPage.Content).Groups[1].ToString(); + var pairs = new Dictionary { + { "_token", token }, + { "username_email", configData.Username.Value }, + { "password", configData.Password.Value }, + { "remember", "on" } + }; + + var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null, LoginUrl); + await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("auth/logout"), () => + { + CQ dom = result.Content; + var messageEl = dom[".form-error"]; + var errorMessage = messageEl.Text().Trim(); + throw new ExceptionWithConfigData(errorMessage, configData); + }); + + return IndexerConfigurationStatus.RequiresTesting; + } + + public async Task> PerformQuery(TorznabQuery query) + { + var releases = new List(); + + var categoryMapping = MapTorznabCapsToTrackers(query).Distinct(); + string category = "0"; // Aka all + if (categoryMapping.Count() == 1) + { + category = categoryMapping.First(); + } + + + var episodeSearchUrl = string.Format(SearchUrl, category, HttpUtility.UrlEncode(query.GetQueryString())); + + var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); + + try + { + CQ dom = response.Content; + var rows = dom["table > tbody > tr"]; + foreach (var row in rows) + { + CQ qRow = row.Cq(); + var release = new ReleaseInfo(); + + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + + var qLink = row.ChildElements.ElementAt(1).FirstElementChild.Cq(); + release.Title = qLink.Text().Trim(); + release.Comments = new Uri(qLink.Attr("href")); + release.Guid = release.Comments; + + var qDownload = row.ChildElements.ElementAt(3).FirstElementChild.Cq(); + release.Link = new Uri(qDownload.Attr("href")); + + var dateStr = row.ChildElements.ElementAt(5).Cq().Text().Trim(); + release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr); + + var sizeStr = row.ChildElements.ElementAt(6).Cq().Text(); + release.Size = ReleaseInfo.GetBytes(sizeStr); + + release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text()); + release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(9).Cq().Text()) + release.Seeders; + + var cat = row.Cq().Find("td:eq(0) i").First().Attr("class") + .Replace("gi gi-film", "1") + .Replace("gi gi-tv", "2") + .Replace("gi gi-music", "3") + .Replace("text-pink", string.Empty); + release.Category = MapTrackerCatToNewznab(cat.Trim()); + releases.Add(release); + } + } + catch (Exception ex) + { + OnParseError(response.Content, ex); + } + return releases; + } + } +} \ No newline at end of file diff --git a/src/Jackett/Indexers/Avistaz.cs b/src/Jackett/Indexers/Avistaz.cs new file mode 100644 index 000000000..ea99df3a0 --- /dev/null +++ b/src/Jackett/Indexers/Avistaz.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Jackett.Models; +using Newtonsoft.Json.Linq; +using NLog; +using Jackett.Utils; +using System.Net; +using System.Net.Http; +using CsQuery; +using System.Web; +using Jackett.Services; +using Jackett.Utils.Clients; +using System.Text.RegularExpressions; +using Jackett.Models.IndexerConfig; + +namespace Jackett.Indexers +{ + public class Avistaz : AvistazTracker, IIndexer + { + public Avistaz(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService) + : base(name: "Avistaz", + desc: "Aka AsiaTorrents", + link: "https://avistaz.to/", + indexerManager: indexerManager, + logger: logger, + protectionService: protectionService, + webClient: webClient + ) + { + } + } +} \ No newline at end of file diff --git a/src/Jackett/Indexers/PrivateHD.cs b/src/Jackett/Indexers/PrivateHD.cs index 48393fc65..6bb387ca1 100644 --- a/src/Jackett/Indexers/PrivateHD.cs +++ b/src/Jackett/Indexers/PrivateHD.cs @@ -18,119 +18,18 @@ using Jackett.Models.IndexerConfig; namespace Jackett.Indexers { - public class PrivateHD : BaseIndexer, IIndexer + public class PrivateHD : AvistazTracker, IIndexer { - private string LoginUrl { get { return SiteLink + "auth/login"; } } - private string SearchUrl { get { return SiteLink + "torrents?in=1&type={0}&search={1}"; } } - - new ConfigurationDataBasicLogin configData - { - get { return (ConfigurationDataBasicLogin)base.configData; } - set { base.configData = value; } - } - - public PrivateHD(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps) + public PrivateHD(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService) : base(name: "PrivateHD", - description: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows", + desc: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows", link: "https://privatehd.to/", - caps: TorznabUtil.CreateDefaultTorznabTVCaps(), - manager: i, - client: wc, - logger: l, - p: ps, - configData: new ConfigurationDataBasicLogin()) + indexerManager: indexerManager, + logger: logger, + protectionService: protectionService, + webClient: webClient + ) { - AddCategoryMapping(1, TorznabCatType.Movies); - AddCategoryMapping(1, TorznabCatType.MoviesForeign); - AddCategoryMapping(1, TorznabCatType.MoviesHD); - AddCategoryMapping(1, TorznabCatType.MoviesSD); - AddCategoryMapping(2, TorznabCatType.TV); - AddCategoryMapping(3, TorznabCatType.Audio); - } - - public async Task ApplyConfiguration(JToken configJson) - { - configData.LoadValuesFromJson(configJson); - var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty); - var token = new Regex("Avz.CSRF_TOKEN = '(.*?)';").Match(loginPage.Content).Groups[1].ToString(); - var pairs = new Dictionary { - { "_token", token }, - { "username_email", configData.Username.Value }, - { "password", configData.Password.Value }, - { "remember", "on" } - }; - - var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null, LoginUrl); - await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("auth/logout"), () => - { - CQ dom = result.Content; - var messageEl = dom[".form-error"]; - var errorMessage = messageEl.Text().Trim(); - throw new ExceptionWithConfigData(errorMessage, configData); - }); - - return IndexerConfigurationStatus.RequiresTesting; - } - - public async Task> PerformQuery(TorznabQuery query) - { - var releases = new List(); - - var categoryMapping = MapTorznabCapsToTrackers(query).Distinct(); - string category = "0"; // Aka all - if (categoryMapping.Count() == 1) - { - category = categoryMapping.First(); - } - - - var episodeSearchUrl = string.Format(SearchUrl, category, HttpUtility.UrlEncode(query.GetQueryString())); - - var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); - - try - { - CQ dom = response.Content; - var rows = dom["table > tbody > tr"]; - foreach (var row in rows) - { - CQ qRow = row.Cq(); - var release = new ReleaseInfo(); - - release.MinimumRatio = 1; - release.MinimumSeedTime = 172800; - - var qLink = row.ChildElements.ElementAt(1).FirstElementChild.Cq(); - release.Title = qLink.Text().Trim(); - release.Comments = new Uri(qLink.Attr("href")); - release.Guid = release.Comments; - - var qDownload = row.ChildElements.ElementAt(3).FirstElementChild.Cq(); - release.Link = new Uri(qDownload.Attr("href")); - - var dateStr = row.ChildElements.ElementAt(5).Cq().Text().Trim(); - release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr); - - var sizeStr = row.ChildElements.ElementAt(6).Cq().Text(); - release.Size = ReleaseInfo.GetBytes(sizeStr); - - release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text()); - release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(9).Cq().Text()) + release.Seeders; - - var cat = row.Cq().Find("td:eq(0) i").First().Attr("class") - .Replace("gi gi-film", "1") - .Replace("gi gi-tv", "2") - .Replace("gi gi-music", "3") - .Replace("text-pink", string.Empty); - release.Category = MapTrackerCatToNewznab(cat.Trim()); - releases.Add(release); - } - } - catch (Exception ex) - { - OnParseError(response.Content, ex); - } - return releases; } } } diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 8a78bd149..e5a39b615 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -175,6 +175,7 @@ + @@ -189,7 +190,8 @@ - + + @@ -405,6 +407,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/src/Jackett/Indexers/ManualSearchResult.cs b/src/Jackett/Models/ManualSearchResult.cs similarity index 91% rename from src/Jackett/Indexers/ManualSearchResult.cs rename to src/Jackett/Models/ManualSearchResult.cs index 0831640bf..59e1a35bd 100644 --- a/src/Jackett/Indexers/ManualSearchResult.cs +++ b/src/Jackett/Models/ManualSearchResult.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Jackett.Indexers +namespace Jackett { public class ManualSearchResult {