diff --git a/src/Jackett/IndexerInterface.cs b/src/Jackett/IndexerInterface.cs index 5027c9b32..1e4e2e583 100644 --- a/src/Jackett/IndexerInterface.cs +++ b/src/Jackett/IndexerInterface.cs @@ -14,6 +14,8 @@ namespace Jackett // Invoked when the indexer configuration has been applied and verified so the cookie needs to be saved event Action OnSaveConfigurationRequested; + event Action OnResultParsingError; + string DisplayName { get; } string DisplayDescription { get; } Uri SiteLink { get; } diff --git a/src/Jackett/IndexerManager.cs b/src/Jackett/IndexerManager.cs index 174b3e0ee..e5f3d8f62 100644 --- a/src/Jackett/IndexerManager.cs +++ b/src/Jackett/IndexerManager.cs @@ -43,6 +43,7 @@ namespace Jackett IndexerInterface newIndexer = (IndexerInterface)Activator.CreateInstance(indexerType); newIndexer.OnSaveConfigurationRequested += newIndexer_OnSaveConfigurationRequested; + newIndexer.OnResultParsingError += newIndexer_OnResultParsingError; var configFilePath = GetIndexerConfigFilePath(newIndexer); if (File.Exists(configFilePath)) @@ -54,6 +55,14 @@ namespace Jackett Indexers.Add(name, newIndexer); } + void newIndexer_OnResultParsingError(IndexerInterface indexer, string results, Exception ex) + { + var fileName = string.Format("Error on {0} for {1}.txt", DateTime.Now.ToString("yyyyMMddHHmmss"), indexer.DisplayName); + var spacing = string.Join("", Enumerable.Repeat(Environment.NewLine, 5)); + var fileContents = string.Format("{0}{1}{2}", ex, spacing, results); + File.WriteAllText(Path.Combine(Program.AppConfigDirectory, fileName), fileContents); + } + string GetIndexerConfigFilePath(IndexerInterface indexer) { return Path.Combine(IndexerConfigDirectory, indexer.GetType().Name.ToLower() + ".json"); diff --git a/src/Jackett/Indexers/BitHdtv.cs b/src/Jackett/Indexers/BitHdtv.cs index abe52ddb0..20e80cf52 100644 --- a/src/Jackett/Indexers/BitHdtv.cs +++ b/src/Jackett/Indexers/BitHdtv.cs @@ -12,139 +12,160 @@ using System.Web; namespace Jackett.Indexers { - public class BitHdtv : IndexerInterface - { - public string DisplayName { - get { return "BIT-HDTV"; } - } + public class BitHdtv : IndexerInterface + { + public event Action OnResultParsingError; - public string DisplayDescription { - get { return "Home of high definition invites"; } - } + public string DisplayName + { + get { return "BIT-HDTV"; } + } - public Uri SiteLink { - get { return new Uri (BaseUrl); } - } + public string DisplayDescription + { + get { return "Home of high definition invites"; } + } - static string BaseUrl = "https://www.bit-hdtv.com"; - static string LoginUrl = BaseUrl + "/takelogin.php"; - static string SearchUrl = BaseUrl + "/torrents.php?cat=0&search="; - static string DownloadUrl = BaseUrl + "/download.php?/{0}/dl.torrent"; + public Uri SiteLink + { + get { return new Uri(BaseUrl); } + } - CookieContainer cookies; - HttpClientHandler handler; - HttpClient client; + static string BaseUrl = "https://www.bit-hdtv.com"; + static string LoginUrl = BaseUrl + "/takelogin.php"; + static string SearchUrl = BaseUrl + "/torrents.php?cat=0&search="; + static string DownloadUrl = BaseUrl + "/download.php?/{0}/dl.torrent"; - public BitHdtv () - { - IsConfigured = false; - cookies = new CookieContainer (); - handler = new HttpClientHandler { - CookieContainer = cookies, - AllowAutoRedirect = true, - UseCookies = true, - }; - client = new HttpClient (handler); - } + CookieContainer cookies; + HttpClientHandler handler; + HttpClient client; - public Task GetConfigurationForSetup () - { - var config = new ConfigurationDataBasicLogin (); - return Task.FromResult (config); - } + public BitHdtv() + { + IsConfigured = false; + cookies = new CookieContainer(); + handler = new HttpClientHandler + { + CookieContainer = cookies, + AllowAutoRedirect = true, + UseCookies = true, + }; + client = new HttpClient(handler); + } - public async Task ApplyConfiguration (JToken configJson) - { - var config = new ConfigurationDataBasicLogin (); - config.LoadValuesFromJson (configJson); + public Task GetConfigurationForSetup() + { + var config = new ConfigurationDataBasicLogin(); + return Task.FromResult(config); + } - var pairs = new Dictionary { + public async Task ApplyConfiguration(JToken configJson) + { + var config = new ConfigurationDataBasicLogin(); + config.LoadValuesFromJson(configJson); + + var pairs = new Dictionary { { "username", config.Username.Value }, { "password", config.Password.Value } }; - var content = new FormUrlEncodedContent (pairs); + var content = new FormUrlEncodedContent(pairs); - var response = await client.PostAsync (LoginUrl, content); - var responseContent = await response.Content.ReadAsStringAsync (); + var response = await client.PostAsync(LoginUrl, content); + var responseContent = await response.Content.ReadAsStringAsync(); - if (!responseContent.Contains ("logout.php")) { - CQ dom = responseContent; - var messageEl = dom ["table.detail td.text"].Last (); - messageEl.Children ("a").Remove (); - messageEl.Children ("style").Remove (); - var errorMessage = messageEl.Text ().Trim (); - throw new ExceptionWithConfigData (errorMessage, (ConfigurationData)config); - } else { - var configSaveData = new JObject (); - configSaveData ["cookies"] = cookies.ToJson (SiteLink); + if (!responseContent.Contains("logout.php")) + { + CQ dom = responseContent; + var messageEl = dom["table.detail td.text"].Last(); + messageEl.Children("a").Remove(); + messageEl.Children("style").Remove(); + var errorMessage = messageEl.Text().Trim(); + throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config); + } + else + { + var configSaveData = new JObject(); + configSaveData["cookies"] = cookies.ToJson(SiteLink); - if (OnSaveConfigurationRequested != null) - OnSaveConfigurationRequested (this, configSaveData); + if (OnSaveConfigurationRequested != null) + OnSaveConfigurationRequested(this, configSaveData); - IsConfigured = true; - } - } + IsConfigured = true; + } + } - public event Action OnSaveConfigurationRequested; + public event Action OnSaveConfigurationRequested; - public bool IsConfigured { get; private set; } + public bool IsConfigured { get; private set; } - public void LoadFromSavedConfiguration (JToken jsonConfig) - { - cookies.FillFromJson (new Uri (BaseUrl), (JArray)jsonConfig ["cookies"]); - IsConfigured = true; - } + public void LoadFromSavedConfiguration(JToken jsonConfig) + { + cookies.FillFromJson(new Uri(BaseUrl), (JArray)jsonConfig["cookies"]); + IsConfigured = true; + } - public async Task PerformQuery (TorznabQuery query) - { - List releases = new List (); + public async Task PerformQuery(TorznabQuery query) + { + List releases = new List(); - foreach (var title in query.ShowTitles ?? new string[] { string.Empty }) { - var searchString = title + " " + query.GetEpisodeSearchString (); - var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode (searchString); - var results = await client.GetStringAsync (episodeSearchUrl); - CQ dom = results; - dom ["#needseed"].Remove (); - var rows = dom ["table[width='750'] > tbody"].Children (); - foreach (var row in rows.Skip(1)) { + foreach (var title in query.ShowTitles ?? new string[] { string.Empty }) + { + var searchString = title + " " + query.GetEpisodeSearchString(); + var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString); + var results = await client.GetStringAsync(episodeSearchUrl); + try + { + CQ dom = results; + dom["#needseed"].Remove(); + var rows = dom["table[width='750'] > tbody"].Children(); + foreach (var row in rows.Skip(1)) + { - var release = new ReleaseInfo (); + var release = new ReleaseInfo(); - var qRow = row.Cq (); - var qLink = qRow.Children ().ElementAt (2).Cq ().Children ("a").First (); + var qRow = row.Cq(); + var qLink = qRow.Children().ElementAt(2).Cq().Children("a").First(); - release.MinimumRatio = 1; - release.MinimumSeedTime = 172800; - release.Title = qLink.Attr ("title"); - release.Description = release.Title; - release.Guid = new Uri (BaseUrl + qLink.Attr ("href")); - release.Comments = release.Guid; - release.Link = new Uri (string.Format (DownloadUrl, qLink.Attr ("href").Split ('=') [1])); + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + release.Title = qLink.Attr("title"); + release.Description = release.Title; + release.Guid = new Uri(BaseUrl + qLink.Attr("href")); + release.Comments = release.Guid; + release.Link = new Uri(string.Format(DownloadUrl, qLink.Attr("href").Split('=')[1])); - var dateString = qRow.Children ().ElementAt (5).Cq ().Text ().Trim (); - var pubDate = DateTime.ParseExact (dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); - release.PublishDate = pubDate; + var dateString = qRow.Children().ElementAt(5).Cq().Text().Trim(); + var pubDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); + release.PublishDate = pubDate; - var sizeCol = qRow.Children ().ElementAt (6); - var sizeVal = sizeCol.ChildNodes [0].NodeValue; - var sizeUnit = sizeCol.ChildNodes [2].NodeValue; - release.Size = ReleaseInfo.GetBytes (sizeUnit, float.Parse (sizeVal)); + var sizeCol = qRow.Children().ElementAt(6); + var sizeVal = sizeCol.ChildNodes[0].NodeValue; + var sizeUnit = sizeCol.ChildNodes[2].NodeValue; + release.Size = ReleaseInfo.GetBytes(sizeUnit, float.Parse(sizeVal)); - release.Seeders = int.Parse (qRow.Children ().ElementAt (8).Cq ().Text ().Trim ()); - release.Peers = int.Parse (qRow.Children ().ElementAt (9).Cq ().Text ().Trim ()) + release.Seeders; + release.Seeders = int.Parse(qRow.Children().ElementAt(8).Cq().Text().Trim()); + release.Peers = int.Parse(qRow.Children().ElementAt(9).Cq().Text().Trim()) + release.Seeders; - releases.Add (release); - } - } + releases.Add(release); + } + } + catch (Exception ex) + { + OnResultParsingError(this, results, ex); + throw ex; + } + } - return releases.ToArray (); - } + return releases.ToArray(); + } - public Task Download (Uri link) - { - return client.GetByteArrayAsync (link); - } - } + public Task Download(Uri link) + { + return client.GetByteArrayAsync(link); + } + + + } } diff --git a/src/Jackett/Indexers/BitMeTV.cs b/src/Jackett/Indexers/BitMeTV.cs index 4d2fed863..ceba8dbc0 100644 --- a/src/Jackett/Indexers/BitMeTV.cs +++ b/src/Jackett/Indexers/BitMeTV.cs @@ -50,6 +50,7 @@ namespace Jackett HttpClient client; public event Action OnSaveConfigurationRequested; + public event Action OnResultParsingError; public BitMeTV() { @@ -136,46 +137,54 @@ namespace Jackett var searchString = title + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode(searchString)); var results = await client.GetStringAsync(episodeSearchUrl); - CQ dom = results; - - var table = dom["tbody > tr > .latest"].Parent().Parent(); - - foreach (var row in table.Children().Skip(1)) + try { - var release = new ReleaseInfo(); + CQ dom = results; - CQ qDetailsCol = row.ChildElements.ElementAt(1).Cq(); - CQ qLink = qDetailsCol.Children("a").First(); + var table = dom["tbody > tr > .latest"].Parent().Parent(); - release.MinimumRatio = 1; - release.MinimumSeedTime = 172800; - release.Comments = new Uri(BaseUrl + "/" + qLink.Attr("href")); - release.Guid = release.Comments; - release.Title = qLink.Attr("title"); - release.Description = release.Title; + foreach (var row in table.Children().Skip(1)) + { + var release = new ReleaseInfo(); - //"Tuesday, June 11th 2013 at 03:52:53 AM" to... - //"Tuesday June 11 2013 03:52:53 AM" - var timestamp = qDetailsCol.Children("font").Text().Trim() + " "; - var timeParts = new List(timestamp.Replace(" at", "").Replace(",", "").Split(' ')); - timeParts[2] = Regex.Replace(timeParts[2], "[^0-9.]", ""); - var formattedTimeString = string.Join(" ", timeParts.ToArray()).Trim(); - release.PublishDate = DateTime.ParseExact(formattedTimeString, "dddd MMMM d yyyy hh:mm:ss tt", CultureInfo.InvariantCulture); + CQ qDetailsCol = row.ChildElements.ElementAt(1).Cq(); + CQ qLink = qDetailsCol.Children("a").First(); - release.Link = new Uri(BaseUrl + "/" + row.ChildElements.ElementAt(2).Cq().Children("a.index").Attr("href")); + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + release.Comments = new Uri(BaseUrl + "/" + qLink.Attr("href")); + release.Guid = release.Comments; + release.Title = qLink.Attr("title"); + release.Description = release.Title; - var sizeCol = row.ChildElements.ElementAt(6); - var sizeVal = float.Parse(sizeCol.ChildNodes[0].NodeValue); - var sizeUnit = sizeCol.ChildNodes[2].NodeValue; - release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal); + //"Tuesday, June 11th 2013 at 03:52:53 AM" to... + //"Tuesday June 11 2013 03:52:53 AM" + var timestamp = qDetailsCol.Children("font").Text().Trim() + " "; + var timeParts = new List(timestamp.Replace(" at", "").Replace(",", "").Split(' ')); + timeParts[2] = Regex.Replace(timeParts[2], "[^0-9.]", ""); + var formattedTimeString = string.Join(" ", timeParts.ToArray()).Trim(); + release.PublishDate = DateTime.ParseExact(formattedTimeString, "dddd MMMM d yyyy hh:mm:ss tt", CultureInfo.InvariantCulture); - release.Seeders = int.Parse(row.ChildElements.ElementAt(8).Cq().Text()); - release.Peers = int.Parse(row.ChildElements.ElementAt(9).Cq().Text()) + release.Seeders; + release.Link = new Uri(BaseUrl + "/" + row.ChildElements.ElementAt(2).Cq().Children("a.index").Attr("href")); - if (!release.Title.ToLower().Contains(title.ToLower())) - continue; + var sizeCol = row.ChildElements.ElementAt(6); + var sizeVal = float.Parse(sizeCol.ChildNodes[0].NodeValue); + var sizeUnit = sizeCol.ChildNodes[2].NodeValue; + release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal); - releases.Add(release); + release.Seeders = int.Parse(row.ChildElements.ElementAt(8).Cq().Text()); + release.Peers = int.Parse(row.ChildElements.ElementAt(9).Cq().Text()) + release.Seeders; + + if (!release.Title.ToLower().Contains(title.ToLower())) + continue; + + releases.Add(release); + } + } + catch (Exception ex) + { + OnResultParsingError(this, results, ex); + throw ex; } } @@ -187,5 +196,6 @@ namespace Jackett { return client.GetByteArrayAsync(link); } + } } diff --git a/src/Jackett/Indexers/Freshon.cs b/src/Jackett/Indexers/Freshon.cs index ffde50db0..c8a2b46d3 100644 --- a/src/Jackett/Indexers/Freshon.cs +++ b/src/Jackett/Indexers/Freshon.cs @@ -14,168 +14,183 @@ using System.Web.UI.WebControls; namespace Jackett { - public class Freshon : IndexerInterface - { + public class Freshon : IndexerInterface + { + public event Action OnResultParsingError; - static string BaseUrl = "https://freshon.tv"; - static string LoginUrl = BaseUrl + "/login.php"; - static string LoginPostUrl = BaseUrl + "/login.php?action=makelogin"; - static string SearchUrl = BaseUrl + "/browse.php"; + static string BaseUrl = "https://freshon.tv"; + static string LoginUrl = BaseUrl + "/login.php"; + static string LoginPostUrl = BaseUrl + "/login.php?action=makelogin"; + static string SearchUrl = BaseUrl + "/browse.php"; - static string chromeUserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36"; + static string chromeUserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36"; - CookieContainer cookies; - HttpClientHandler handler; - HttpClient client; + CookieContainer cookies; + HttpClientHandler handler; + HttpClient client; - public bool IsConfigured { get; private set; } + public bool IsConfigured { get; private set; } - public string DisplayName { get { return "FreshOnTV"; } } + public string DisplayName { get { return "FreshOnTV"; } } - public string DisplayDescription { get { return "Our goal is to provide the latest stuff in the TV show domain"; } } + public string DisplayDescription { get { return "Our goal is to provide the latest stuff in the TV show domain"; } } - public Uri SiteLink { get { return new Uri (BaseUrl); } } + public Uri SiteLink { get { return new Uri(BaseUrl); } } - public event Action OnSaveConfigurationRequested; + public event Action OnSaveConfigurationRequested; - public Freshon () - { - IsConfigured = false; - cookies = new CookieContainer (); - handler = new HttpClientHandler { - CookieContainer = cookies, - AllowAutoRedirect = true, - UseCookies = true, - }; - client = new HttpClient (handler); - } + public Freshon() + { + IsConfigured = false; + cookies = new CookieContainer(); + handler = new HttpClientHandler + { + CookieContainer = cookies, + AllowAutoRedirect = true, + UseCookies = true, + }; + client = new HttpClient(handler); + } - public async Task GetConfigurationForSetup () - { - var request = CreateHttpRequest (new Uri (LoginUrl)); - var response = await client.SendAsync (request); - await response.Content.ReadAsStreamAsync (); - var config = new ConfigurationDataBasicLogin (); - return config; - } + public async Task GetConfigurationForSetup() + { + var request = CreateHttpRequest(new Uri(LoginUrl)); + var response = await client.SendAsync(request); + await response.Content.ReadAsStreamAsync(); + var config = new ConfigurationDataBasicLogin(); + return config; + } - public async Task ApplyConfiguration (JToken configJson) - { - var config = new ConfigurationDataBasicLogin (); - config.LoadValuesFromJson (configJson); + public async Task ApplyConfiguration(JToken configJson) + { + var config = new ConfigurationDataBasicLogin(); + config.LoadValuesFromJson(configJson); - var pairs = new Dictionary { + var pairs = new Dictionary { { "username", config.Username.Value }, { "password", config.Password.Value } }; - var content = new FormUrlEncodedContent (pairs); - var message = CreateHttpRequest (new Uri (LoginPostUrl)); - message.Method = HttpMethod.Post; - message.Content = content; - message.Headers.Referrer = new Uri (LoginUrl); + var content = new FormUrlEncodedContent(pairs); + var message = CreateHttpRequest(new Uri(LoginPostUrl)); + message.Method = HttpMethod.Post; + message.Content = content; + message.Headers.Referrer = new Uri(LoginUrl); - var response = await client.SendAsync (message); - var responseContent = await response.Content.ReadAsStringAsync (); + var response = await client.SendAsync(message); + var responseContent = await response.Content.ReadAsStringAsync(); - if (!responseContent.Contains ("/logout.php")) { - CQ dom = responseContent; - var messageEl = dom [".error_text"]; - var errorMessage = messageEl.Text ().Trim (); - throw new ExceptionWithConfigData (errorMessage, (ConfigurationData)config); - } else { - var configSaveData = new JObject (); - configSaveData ["cookies"] = cookies.ToJson (SiteLink); + if (!responseContent.Contains("/logout.php")) + { + CQ dom = responseContent; + var messageEl = dom[".error_text"]; + var errorMessage = messageEl.Text().Trim(); + throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config); + } + else + { + var configSaveData = new JObject(); + configSaveData["cookies"] = cookies.ToJson(SiteLink); - if (OnSaveConfigurationRequested != null) - OnSaveConfigurationRequested (this, configSaveData); + if (OnSaveConfigurationRequested != null) + OnSaveConfigurationRequested(this, configSaveData); - IsConfigured = true; - } - } + IsConfigured = true; + } + } - public void LoadFromSavedConfiguration (JToken jsonConfig) - { - cookies.FillFromJson (new Uri (BaseUrl), (JArray)jsonConfig ["cookies"]); - IsConfigured = true; - } + public void LoadFromSavedConfiguration(JToken jsonConfig) + { + cookies.FillFromJson(new Uri(BaseUrl), (JArray)jsonConfig["cookies"]); + IsConfigured = true; + } - HttpRequestMessage CreateHttpRequest (Uri uri) - { - var message = new HttpRequestMessage (); - message.Method = HttpMethod.Get; - message.RequestUri = uri; - message.Headers.UserAgent.ParseAdd (chromeUserAgent); - return message; - } + HttpRequestMessage CreateHttpRequest(Uri uri) + { + var message = new HttpRequestMessage(); + message.Method = HttpMethod.Get; + message.RequestUri = uri; + message.Headers.UserAgent.ParseAdd(chromeUserAgent); + return message; + } - public async Task PerformQuery (TorznabQuery query) - { - List releases = new List (); + public async Task PerformQuery(TorznabQuery query) + { + List releases = new List(); - foreach (var title in query.ShowTitles ?? new string[] { string.Empty }) { - string episodeSearchUrl; + foreach (var title in query.ShowTitles ?? new string[] { string.Empty }) + { + string episodeSearchUrl; - if (string.IsNullOrEmpty (title)) - episodeSearchUrl = SearchUrl; - else { - var searchString = title + " " + query.GetEpisodeSearchString (); - episodeSearchUrl = string.Format ("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode (searchString)); - } + if (string.IsNullOrEmpty(title)) + episodeSearchUrl = SearchUrl; + else + { + var searchString = title + " " + query.GetEpisodeSearchString(); + episodeSearchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode(searchString)); + } - var request = CreateHttpRequest (new Uri (episodeSearchUrl)); - var response = await client.SendAsync (request); - var results = await response.Content.ReadAsStringAsync (); + var request = CreateHttpRequest(new Uri(episodeSearchUrl)); + var response = await client.SendAsync(request); + var results = await response.Content.ReadAsStringAsync(); + try + { + CQ dom = results; - CQ dom = results; + var rows = dom["#highlight > tbody > tr"]; - var rows = dom ["#highlight > tbody > tr"]; + foreach (var row in rows.Skip(1)) + { + var release = new ReleaseInfo(); - foreach (var row in rows.Skip(1)) { - var release = new ReleaseInfo (); + var qRow = row.Cq(); + var qLink = qRow.Find("a.torrent_name_link").First(); - var qRow = row.Cq (); - var qLink = qRow.Find ("a.torrent_name_link").First (); + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + release.Title = qLink.Attr("title"); + release.Description = release.Title; + release.Guid = new Uri(BaseUrl + qLink.Attr("href")); + release.Comments = release.Guid; + release.Link = new Uri(BaseUrl + qRow.Find("td.table_links > a").First().Attr("href")); - release.MinimumRatio = 1; - release.MinimumSeedTime = 172800; - release.Title = qLink.Attr ("title"); - release.Description = release.Title; - release.Guid = new Uri (BaseUrl + qLink.Attr ("href")); - release.Comments = release.Guid; - release.Link = new Uri (BaseUrl + qRow.Find ("td.table_links > a").First ().Attr ("href")); + DateTime pubDate; + var dateString = qRow.Find("td.table_added").Text().Trim(); + if (dateString.StartsWith("Today ")) + pubDate = (DateTime.UtcNow + TimeSpan.Parse(dateString.Split(' ')[1])).ToLocalTime(); + else if (dateString.StartsWith("Yesterday ")) + pubDate = (DateTime.UtcNow + TimeSpan.Parse(dateString.Split(' ')[1]) - TimeSpan.FromDays(1)).ToLocalTime(); + else + pubDate = DateTime.ParseExact(dateString, "d-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime(); + release.PublishDate = pubDate; - DateTime pubDate; - var dateString = qRow.Find ("td.table_added").Text ().Trim (); - if (dateString.StartsWith ("Today ")) - pubDate = (DateTime.UtcNow + TimeSpan.Parse (dateString.Split (' ') [1])).ToLocalTime (); - else if (dateString.StartsWith ("Yesterday ")) - pubDate = (DateTime.UtcNow + TimeSpan.Parse (dateString.Split (' ') [1]) - TimeSpan.FromDays (1)).ToLocalTime (); - else - pubDate = DateTime.ParseExact (dateString, "d-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime (); - release.PublishDate = pubDate; + release.Seeders = int.Parse(qRow.Find("td.table_seeders").Text().Trim()); + release.Peers = int.Parse(qRow.Find("td.table_leechers").Text().Trim()) + release.Seeders; - release.Seeders = int.Parse (qRow.Find ("td.table_seeders").Text ().Trim ()); - release.Peers = int.Parse (qRow.Find ("td.table_leechers").Text ().Trim ()) + release.Seeders; + var sizeCol = qRow.Find("td.table_size")[0]; + var sizeVal = float.Parse(sizeCol.ChildNodes[0].NodeValue.Trim()); + var sizeUnit = sizeCol.ChildNodes[2].NodeValue.Trim(); + release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal); - var sizeCol = qRow.Find ("td.table_size") [0]; - var sizeVal = float.Parse (sizeCol.ChildNodes [0].NodeValue.Trim ()); - var sizeUnit = sizeCol.ChildNodes [2].NodeValue.Trim (); - release.Size = ReleaseInfo.GetBytes (sizeUnit, sizeVal); + releases.Add(release); + } + } + catch (Exception ex) + { + OnResultParsingError(this, results, ex); + throw ex; + } + } - releases.Add (release); - } - } + return releases.ToArray(); + } - return releases.ToArray (); - } - - public async Task Download (Uri link) - { - var request = CreateHttpRequest (link); - var response = await client.SendAsync (request); - var bytes = await response.Content.ReadAsByteArrayAsync (); - return bytes; - } - } + public async Task Download(Uri link) + { + var request = CreateHttpRequest(link); + var response = await client.SendAsync(request); + var bytes = await response.Content.ReadAsByteArrayAsync(); + return bytes; + } + } } diff --git a/src/Jackett/Indexers/IPTorrents.cs b/src/Jackett/Indexers/IPTorrents.cs index 5de4080ee..f1a2f1d2d 100644 --- a/src/Jackett/Indexers/IPTorrents.cs +++ b/src/Jackett/Indexers/IPTorrents.cs @@ -11,181 +11,199 @@ using System.Web; namespace Jackett.Indexers { - public class IPTorrents : IndexerInterface - { + public class IPTorrents : IndexerInterface + { - public event Action OnSaveConfigurationRequested; + public event Action OnSaveConfigurationRequested; + public event Action OnResultParsingError; - public string DisplayName { get { return "IPTorrents"; } } + public string DisplayName { get { return "IPTorrents"; } } - public string DisplayDescription { get { return "Always a step ahead"; } } + public string DisplayDescription { get { return "Always a step ahead"; } } - public Uri SiteLink { get { return new Uri (BaseUrl); } } + public Uri SiteLink { get { return new Uri(BaseUrl); } } - public bool IsConfigured { get; private set; } + public bool IsConfigured { get; private set; } - static string chromeUserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36"; + static string chromeUserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36"; - static string BaseUrl = "https://iptorrents.com"; + static string BaseUrl = "https://iptorrents.com"; - string SearchUrl = BaseUrl + "/t?q="; + string SearchUrl = BaseUrl + "/t?q="; - CookieContainer cookies; - HttpClientHandler handler; - HttpClient client; + CookieContainer cookies; + HttpClientHandler handler; + HttpClient client; - public IPTorrents () - { - IsConfigured = false; - cookies = new CookieContainer (); - handler = new HttpClientHandler { - CookieContainer = cookies, - AllowAutoRedirect = true, - UseCookies = true, - }; - client = new HttpClient (handler); - } + public IPTorrents() + { + IsConfigured = false; + cookies = new CookieContainer(); + handler = new HttpClientHandler + { + CookieContainer = cookies, + AllowAutoRedirect = true, + UseCookies = true, + }; + client = new HttpClient(handler); + } - public async Task GetConfigurationForSetup () - { - await client.GetAsync (new Uri (BaseUrl)); - var config = new ConfigurationDataBasicLogin (); - return (ConfigurationData)config; - } + public async Task GetConfigurationForSetup() + { + await client.GetAsync(new Uri(BaseUrl)); + var config = new ConfigurationDataBasicLogin(); + return (ConfigurationData)config; + } - public async Task ApplyConfiguration (JToken configJson) - { + public async Task ApplyConfiguration(JToken configJson) + { - var config = new ConfigurationDataBasicLogin (); - config.LoadValuesFromJson (configJson); + var config = new ConfigurationDataBasicLogin(); + config.LoadValuesFromJson(configJson); - var pairs = new Dictionary { + var pairs = new Dictionary { { "username", config.Username.Value }, { "password", config.Password.Value } }; - var content = new FormUrlEncodedContent (pairs); - var message = new HttpRequestMessage (); - message.Method = HttpMethod.Post; - message.Content = content; - message.RequestUri = new Uri (BaseUrl); - message.Headers.Referrer = new Uri (BaseUrl); - message.Headers.UserAgent.ParseAdd (chromeUserAgent); + var content = new FormUrlEncodedContent(pairs); + var message = new HttpRequestMessage(); + message.Method = HttpMethod.Post; + message.Content = content; + message.RequestUri = new Uri(BaseUrl); + message.Headers.Referrer = new Uri(BaseUrl); + message.Headers.UserAgent.ParseAdd(chromeUserAgent); - var response = await client.SendAsync (message); - var responseContent = await response.Content.ReadAsStringAsync (); + var response = await client.SendAsync(message); + var responseContent = await response.Content.ReadAsStringAsync(); - if (!responseContent.Contains ("/my.php")) { - CQ dom = responseContent; - var messageEl = dom ["body > div"].First (); - var errorMessage = messageEl.Text ().Trim (); - throw new ExceptionWithConfigData (errorMessage, (ConfigurationData)config); - } else { - var configSaveData = new JObject (); - configSaveData ["cookies"] = cookies.ToJson (SiteLink); + if (!responseContent.Contains("/my.php")) + { + CQ dom = responseContent; + var messageEl = dom["body > div"].First(); + var errorMessage = messageEl.Text().Trim(); + throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config); + } + else + { + var configSaveData = new JObject(); + configSaveData["cookies"] = cookies.ToJson(SiteLink); - if (OnSaveConfigurationRequested != null) - OnSaveConfigurationRequested (this, configSaveData); + if (OnSaveConfigurationRequested != null) + OnSaveConfigurationRequested(this, configSaveData); - IsConfigured = true; - } + IsConfigured = true; + } - } + } - HttpRequestMessage CreateHttpRequest (Uri uri) - { - var message = new HttpRequestMessage (); - message.Method = HttpMethod.Get; - message.RequestUri = uri; - message.Headers.UserAgent.ParseAdd (chromeUserAgent); - return message; - } + HttpRequestMessage CreateHttpRequest(Uri uri) + { + var message = new HttpRequestMessage(); + message.Method = HttpMethod.Get; + message.RequestUri = uri; + message.Headers.UserAgent.ParseAdd(chromeUserAgent); + return message; + } - public void LoadFromSavedConfiguration (Newtonsoft.Json.Linq.JToken jsonConfig) - { - cookies.FillFromJson (new Uri (BaseUrl), (JArray)jsonConfig ["cookies"]); - IsConfigured = true; - } + public void LoadFromSavedConfiguration(Newtonsoft.Json.Linq.JToken jsonConfig) + { + cookies.FillFromJson(new Uri(BaseUrl), (JArray)jsonConfig["cookies"]); + IsConfigured = true; + } - public async Task PerformQuery (TorznabQuery query) - { + public async Task PerformQuery(TorznabQuery query) + { - List releases = new List (); + List releases = new List(); - foreach (var title in query.ShowTitles ?? new string[] { string.Empty }) { + foreach (var title in query.ShowTitles ?? new string[] { string.Empty }) + { - var searchString = title + " " + query.GetEpisodeSearchString (); - var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode (searchString); + var searchString = title + " " + query.GetEpisodeSearchString(); + var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString); - var request = CreateHttpRequest (new Uri (episodeSearchUrl)); - var response = await client.SendAsync (request); - var results = await response.Content.ReadAsStringAsync (); + var request = CreateHttpRequest(new Uri(episodeSearchUrl)); + var response = await client.SendAsync(request); + var results = await response.Content.ReadAsStringAsync(); - CQ dom = results; + try + { + CQ dom = results; - var rows = dom ["table.torrents > tbody > tr"]; - foreach (var row in rows.Skip(1)) { - var release = new ReleaseInfo (); + var rows = dom["table.torrents > tbody > tr"]; + foreach (var row in rows.Skip(1)) + { + var release = new ReleaseInfo(); - var qRow = row.Cq (); + var qRow = row.Cq(); - var qTitleLink = qRow.Find ("a.t_title").First (); - release.Title = qTitleLink.Text ().Trim (); - release.Description = release.Title; - release.Guid = new Uri (BaseUrl + qTitleLink.Attr ("href")); - release.Comments = release.Guid; + var qTitleLink = qRow.Find("a.t_title").First(); + release.Title = qTitleLink.Text().Trim(); + release.Description = release.Title; + release.Guid = new Uri(BaseUrl + qTitleLink.Attr("href")); + release.Comments = release.Guid; - DateTime pubDate; - var descString = qRow.Find (".t_ctime").Text (); - var dateString = descString.Split ('|').Last ().Trim (); - dateString = dateString.Split (new string[] { " by " }, StringSplitOptions.None) [0]; - var dateValue = float.Parse (dateString.Split (' ') [0]); - var dateUnit = dateString.Split (' ') [1]; - if (dateUnit.Contains ("minute")) - pubDate = DateTime.Now - TimeSpan.FromMinutes (dateValue); - else if (dateUnit.Contains ("hour")) - pubDate = DateTime.Now - TimeSpan.FromHours (dateValue); - else if (dateUnit.Contains ("day")) - pubDate = DateTime.Now - TimeSpan.FromDays (dateValue); - else if (dateUnit.Contains ("week")) - pubDate = DateTime.Now - TimeSpan.FromDays (7 * dateValue); - else if (dateUnit.Contains ("month")) - pubDate = DateTime.Now - TimeSpan.FromDays (30 * dateValue); - else if (dateUnit.Contains ("year")) - pubDate = DateTime.Now - TimeSpan.FromDays (365 * dateValue); - else - pubDate = DateTime.MinValue; - release.PublishDate = pubDate; + DateTime pubDate; + var descString = qRow.Find(".t_ctime").Text(); + var dateString = descString.Split('|').Last().Trim(); + dateString = dateString.Split(new string[] { " by " }, StringSplitOptions.None)[0]; + var dateValue = float.Parse(dateString.Split(' ')[0]); + var dateUnit = dateString.Split(' ')[1]; + if (dateUnit.Contains("minute")) + pubDate = DateTime.Now - TimeSpan.FromMinutes(dateValue); + else if (dateUnit.Contains("hour")) + pubDate = DateTime.Now - TimeSpan.FromHours(dateValue); + else if (dateUnit.Contains("day")) + pubDate = DateTime.Now - TimeSpan.FromDays(dateValue); + else if (dateUnit.Contains("week")) + pubDate = DateTime.Now - TimeSpan.FromDays(7 * dateValue); + else if (dateUnit.Contains("month")) + pubDate = DateTime.Now - TimeSpan.FromDays(30 * dateValue); + else if (dateUnit.Contains("year")) + pubDate = DateTime.Now - TimeSpan.FromDays(365 * dateValue); + else + pubDate = DateTime.MinValue; + release.PublishDate = pubDate; - var qLink = row.ChildElements.ElementAt (3).Cq ().Children ("a"); - release.Link = new Uri (BaseUrl + qLink.Attr ("href")); + var qLink = row.ChildElements.ElementAt(3).Cq().Children("a"); + release.Link = new Uri(BaseUrl + qLink.Attr("href")); - var sizeStr = row.ChildElements.ElementAt (5).Cq ().Text ().Trim (); - var sizeVal = float.Parse (sizeStr.Split (' ') [0]); - var sizeUnit = sizeStr.Split (' ') [1]; - release.Size = ReleaseInfo.GetBytes (sizeUnit, sizeVal); + var sizeStr = row.ChildElements.ElementAt(5).Cq().Text().Trim(); + var sizeVal = float.Parse(sizeStr.Split(' ')[0]); + var sizeUnit = sizeStr.Split(' ')[1]; + release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal); - release.Seeders = int.Parse (qRow.Find (".t_seeders").Text ().Trim ()); - release.Peers = int.Parse (qRow.Find (".t_leechers").Text ().Trim ()) + release.Seeders; + release.Seeders = int.Parse(qRow.Find(".t_seeders").Text().Trim()); + release.Peers = int.Parse(qRow.Find(".t_leechers").Text().Trim()) + release.Seeders; - releases.Add (release); - } + releases.Add(release); + } + } + catch (Exception ex) + { + OnResultParsingError(this, results, ex); + throw ex; + } - } + } - return releases.ToArray (); + return releases.ToArray(); - } + } - public async Task Download (Uri link) - { - var request = CreateHttpRequest (link); - var response = await client.SendAsync (request); - var bytes = await response.Content.ReadAsByteArrayAsync (); - return bytes; - } - } + public async Task Download(Uri link) + { + var request = CreateHttpRequest(link); + var response = await client.SendAsync(request); + var bytes = await response.Content.ReadAsByteArrayAsync(); + return bytes; + } + + + + } } diff --git a/src/Jackett/Indexers/MoreThanTV.cs b/src/Jackett/Indexers/MoreThanTV.cs index 51ac1c554..8d61e9d40 100644 --- a/src/Jackett/Indexers/MoreThanTV.cs +++ b/src/Jackett/Indexers/MoreThanTV.cs @@ -30,6 +30,7 @@ namespace Jackett.Indexers public event Action OnSaveConfigurationRequested; + public event Action OnResultParsingError; public bool IsConfigured { get; private set; } @@ -159,36 +160,44 @@ namespace Jackett.Indexers var response = await CurlHelper.GetAsync(episodeSearchUrl, cookieHeader); results = Encoding.UTF8.GetString(response.Content); } - - var json = JObject.Parse(results); - foreach (JObject r in json["response"]["results"]) + try { - var pubDate = UnixTimestampToDateTime(double.Parse((string)r["groupTime"])); - var groupName = (string)r["groupName"]; - - if (r["torrents"] is JArray) + var json = JObject.Parse(results); + foreach (JObject r in json["response"]["results"]) { - foreach (JObject t in r["torrents"]) + + var pubDate = UnixTimestampToDateTime(double.Parse((string)r["groupTime"])); + var groupName = (string)r["groupName"]; + + if (r["torrents"] is JArray) + { + foreach (JObject t in r["torrents"]) + { + var release = new ReleaseInfo(); + release.PublishDate = pubDate; + release.Title = groupName; + release.Description = groupName; + FillReleaseInfoFromJson(release, t); + releases.Add(release); + } + } + else { var release = new ReleaseInfo(); release.PublishDate = pubDate; release.Title = groupName; release.Description = groupName; - FillReleaseInfoFromJson(release, t); + FillReleaseInfoFromJson(release, r); releases.Add(release); } - } - else - { - var release = new ReleaseInfo(); - release.PublishDate = pubDate; - release.Title = groupName; - release.Description = groupName; - FillReleaseInfoFromJson(release, r); - releases.Add(release); - } + } + } + catch (Exception ex) + { + OnResultParsingError(this, results, ex); + throw ex; } } @@ -215,5 +224,6 @@ namespace Jackett.Indexers } } + } } diff --git a/src/Jackett/Indexers/Strike.cs b/src/Jackett/Indexers/Strike.cs index ffda89d0e..24a141e4d 100644 --- a/src/Jackett/Indexers/Strike.cs +++ b/src/Jackett/Indexers/Strike.cs @@ -31,6 +31,7 @@ namespace Jackett.Indexers public event Action OnSaveConfigurationRequested; + public event Action OnResultParsingError; public string DisplayName { @@ -116,32 +117,40 @@ namespace Jackett.Indexers var searchString = title + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = baseUrl + string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim())); var results = await client.GetStringAsync(episodeSearchUrl); - var jResults = JObject.Parse(results); - foreach (JObject result in (JArray)jResults["torrents"]) + try { - var release = new ReleaseInfo(); + var jResults = JObject.Parse(results); + foreach (JObject result in (JArray)jResults["torrents"]) + { + var release = new ReleaseInfo(); - release.MinimumRatio = 1; - release.MinimumSeedTime = 172800; + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; - release.Title = (string)result["torrent_title"]; - release.Description = release.Title; - release.Seeders = (int)result["seeds"]; - release.Peers = (int)result["leeches"] + release.Seeders; - release.Size = (long)result["size"]; + release.Title = (string)result["torrent_title"]; + release.Description = release.Title; + release.Seeders = (int)result["seeds"]; + release.Peers = (int)result["leeches"] + release.Seeders; + release.Size = (long)result["size"]; - // "Apr 2, 2015", "Apr 12, 2015" (note the spacing) - var dateString = string.Join(" ", ((string)result["upload_date"]).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); - release.PublishDate = DateTime.ParseExact(dateString, "MMM d, yyyy", CultureInfo.InvariantCulture); + // "Apr 2, 2015", "Apr 12, 2015" (note the spacing) + var dateString = string.Join(" ", ((string)result["upload_date"]).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); + release.PublishDate = DateTime.ParseExact(dateString, "MMM d, yyyy", CultureInfo.InvariantCulture); - release.Guid = new Uri((string)result["page"]); - release.Comments = release.Guid; + release.Guid = new Uri((string)result["page"]); + release.Comments = release.Guid; - release.InfoHash = (string)result["torrent_hash"]; - release.MagnetUri = new Uri((string)result["magnet_uri"]); - release.Link = new Uri(string.Format("{0}{1}{2}", baseUrl, DownloadUrl, release.InfoHash)); + release.InfoHash = (string)result["torrent_hash"]; + release.MagnetUri = new Uri((string)result["magnet_uri"]); + release.Link = new Uri(string.Format("{0}{1}{2}", baseUrl, DownloadUrl, release.InfoHash)); - releases.Add(release); + releases.Add(release); + } + } + catch (Exception ex) + { + OnResultParsingError(this, results, ex); + throw ex; } } @@ -157,5 +166,7 @@ namespace Jackett.Indexers { throw new NotImplementedException(); } + + } } diff --git a/src/Jackett/Indexers/ThePirateBay.cs b/src/Jackett/Indexers/ThePirateBay.cs index f7c55191d..6bf9a6cd1 100644 --- a/src/Jackett/Indexers/ThePirateBay.cs +++ b/src/Jackett/Indexers/ThePirateBay.cs @@ -31,7 +31,9 @@ namespace Jackett.Indexers } } - public event Action OnSaveConfigurationRequested; + public event Action OnSaveConfigurationRequested; + + public event Action OnResultParsingError; public string DisplayName { get { return "The Pirate Bay"; } } @@ -133,54 +135,61 @@ namespace Jackett.Indexers var response = await CurlHelper.GetAsync(baseUrl + SwitchSingleViewUrl, null, episodeSearchUrl); results = Encoding.UTF8.GetString(response.Content); } - - CQ dom = results; - - var rows = dom["#searchResult > tbody > tr"]; - foreach (var row in rows) + try { - var release = new ReleaseInfo(); + CQ dom = results; - CQ qLink = row.ChildElements.ElementAt(1).Cq().Children("a").First(); - - release.MinimumRatio = 1; - release.MinimumSeedTime = 172800; - release.Title = qLink.Text().Trim(); - release.Description = release.Title; - release.Comments = new Uri(baseUrl + qLink.Attr("href").TrimStart('/')); - release.Guid = release.Comments; - - var timeString = row.ChildElements.ElementAt(2).Cq().Text(); - if (timeString.Contains("mins ago")) - release.PublishDate = (DateTime.Now - TimeSpan.FromMinutes(int.Parse(timeString.Split(' ')[0]))); - else if (timeString.Contains("Today")) - release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(2) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime(); - else if (timeString.Contains("Y-day")) - release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(26) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime(); - else if (timeString.Contains(':')) + var rows = dom["#searchResult > tbody > tr"]; + foreach (var row in rows) { - var utc = DateTime.ParseExact(timeString, "MM-dd HH:mm", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2); - release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime(); + var release = new ReleaseInfo(); + + CQ qLink = row.ChildElements.ElementAt(1).Cq().Children("a").First(); + + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + release.Title = qLink.Text().Trim(); + release.Description = release.Title; + release.Comments = new Uri(baseUrl + qLink.Attr("href").TrimStart('/')); + release.Guid = release.Comments; + + var timeString = row.ChildElements.ElementAt(2).Cq().Text(); + if (timeString.Contains("mins ago")) + release.PublishDate = (DateTime.Now - TimeSpan.FromMinutes(int.Parse(timeString.Split(' ')[0]))); + else if (timeString.Contains("Today")) + release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(2) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime(); + else if (timeString.Contains("Y-day")) + release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(26) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime(); + else if (timeString.Contains(':')) + { + var utc = DateTime.ParseExact(timeString, "MM-dd HH:mm", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2); + release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime(); + } + else + { + var utc = DateTime.ParseExact(timeString, "MM-dd yyyy", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2); + release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime(); + } + + var downloadCol = row.ChildElements.ElementAt(3).Cq().Find("a"); + release.MagnetUri = new Uri(downloadCol.Attr("href")); + release.InfoHash = release.MagnetUri.ToString().Split(':')[3].Split('&')[0]; + + var sizeString = row.ChildElements.ElementAt(4).Cq().Text().Split(' '); + var sizeVal = float.Parse(sizeString[0]); + var sizeUnit = sizeString[1]; + release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal); + + release.Seeders = int.Parse(row.ChildElements.ElementAt(5).Cq().Text()); + release.Peers = int.Parse(row.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders; + + releases.Add(release); } - else - { - var utc = DateTime.ParseExact(timeString, "MM-dd yyyy", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2); - release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime(); - } - - var downloadCol = row.ChildElements.ElementAt(3).Cq().Find("a"); - release.MagnetUri = new Uri(downloadCol.Attr("href")); - release.InfoHash = release.MagnetUri.ToString().Split(':')[3].Split('&')[0]; - - var sizeString = row.ChildElements.ElementAt(4).Cq().Text().Split(' '); - var sizeVal = float.Parse(sizeString[0]); - var sizeUnit = sizeString[1]; - release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal); - - release.Seeders = int.Parse(row.ChildElements.ElementAt(5).Cq().Text()); - release.Peers = int.Parse(row.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders; - - releases.Add(release); + } + catch (Exception ex) + { + OnResultParsingError(this, results, ex); + throw ex; } } return releases.ToArray(); @@ -192,5 +201,7 @@ namespace Jackett.Indexers { throw new NotImplementedException(); } + + } } diff --git a/src/Jackett/Indexers/TorrentLeech.cs b/src/Jackett/Indexers/TorrentLeech.cs index 4ae42dd1a..617666fa4 100644 --- a/src/Jackett/Indexers/TorrentLeech.cs +++ b/src/Jackett/Indexers/TorrentLeech.cs @@ -14,6 +14,7 @@ namespace Jackett.Indexers { public class TorrentLeech : IndexerInterface { + public event Action OnResultParsingError; public event Action OnSaveConfigurationRequested; @@ -114,45 +115,55 @@ namespace Jackett.Indexers var searchString = title + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var results = await client.GetStringAsync(episodeSearchUrl); - CQ dom = results; - - CQ qRows = dom["#torrenttable > tbody > tr"]; - - foreach (var row in qRows) + try { - var release = new ReleaseInfo(); + CQ dom = results; - var qRow = row.Cq(); + CQ qRows = dom["#torrenttable > tbody > tr"]; - var debug = qRow.Html(); + foreach (var row in qRows) + { + var release = new ReleaseInfo(); - release.MinimumRatio = 1; - release.MinimumSeedTime = 172800; + var qRow = row.Cq(); - CQ qLink = qRow.Find(".title > a").First(); - release.Guid = new Uri(BaseUrl + qLink.Attr("href")); - release.Comments = release.Guid; - release.Title = qLink.Text(); - release.Description = release.Title; + var debug = qRow.Html(); - release.Link = new Uri(BaseUrl + qRow.Find(".quickdownload > a").Attr("href")); + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; - var dateString = qRow.Find(".name").First()[0].ChildNodes[4].NodeValue.Replace(" on", "").Trim(); - //"2015-04-25 23:38:12" - //"yyyy-MMM-dd hh:mm:ss" - release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); + CQ qLink = qRow.Find(".title > a").First(); + release.Guid = new Uri(BaseUrl + qLink.Attr("href")); + release.Comments = release.Guid; + release.Title = qLink.Text(); + release.Description = release.Title; - var sizeStringParts = qRow.Children().ElementAt(4).InnerText.Split(' '); - release.Size = ReleaseInfo.GetBytes(sizeStringParts[1], float.Parse(sizeStringParts[0])); + release.Link = new Uri(BaseUrl + qRow.Find(".quickdownload > a").Attr("href")); - release.Seeders = int.Parse(qRow.Find(".seeders").Text()); - release.Peers = int.Parse(qRow.Find(".leechers").Text()); + var dateString = qRow.Find(".name").First()[0].ChildNodes[4].NodeValue.Replace(" on", "").Trim(); + //"2015-04-25 23:38:12" + //"yyyy-MMM-dd hh:mm:ss" + release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); - releases.Add(release); + var sizeStringParts = qRow.Children().ElementAt(4).InnerText.Split(' '); + release.Size = ReleaseInfo.GetBytes(sizeStringParts[1], float.Parse(sizeStringParts[0])); + + release.Seeders = int.Parse(qRow.Find(".seeders").Text()); + release.Peers = int.Parse(qRow.Find(".leechers").Text()); + + releases.Add(release); + } + } + + catch (Exception ex) + { + OnResultParsingError(this, results, ex); + throw ex; } } + return releases.ToArray(); } @@ -160,5 +171,8 @@ namespace Jackett.Indexers { return client.GetByteArrayAsync(link); } + + + } }