diff --git a/src/Jackett/Indexers/ShowRSS.cs b/src/Jackett/Indexers/ShowRSS.cs new file mode 100644 index 000000000..50518f893 --- /dev/null +++ b/src/Jackett/Indexers/ShowRSS.cs @@ -0,0 +1,176 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using System.Xml; + +namespace Jackett.Indexers +{ + public class ShowRSS : IndexerInterface + { + public event Action OnSaveConfigurationRequested; + + public event Action OnResultParsingError; + + public string DisplayName + { + get { return "ShowRSS"; } + } + + public string DisplayDescription + { + get { return "showRSS is a service that allows you to keep track of your favorite TV shows"; } + } + + public Uri SiteLink + { + get { return new Uri(DefaultUrl); } + } + + const string DefaultUrl = "http://showrss.info"; + const string searchAllUrl = DefaultUrl + "/feeds/all.rss"; + string BaseUrl; + 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; + + public bool IsConfigured + { + get; + private set; + } + + public ShowRSS() + { + IsConfigured = false; + cookies = new CookieContainer(); + handler = new HttpClientHandler + { + CookieContainer = cookies, + AllowAutoRedirect = true, + UseCookies = true, + }; + client = new HttpClient(handler); + } + + public Task GetConfigurationForSetup() + { + var config = new ConfigurationDataUrl(DefaultUrl); + return Task.FromResult(config); + } + + public async Task ApplyConfiguration(Newtonsoft.Json.Linq.JToken configJson) + { + var config = new ConfigurationDataUrl(DefaultUrl); + config.LoadValuesFromJson(configJson); + + var formattedUrl = config.GetFormattedHostUrl(); + var releases = await PerformQuery(new TorznabQuery(), formattedUrl); + if (releases.Length == 0) + throw new Exception("Could not find releases from this URL"); + + BaseUrl = formattedUrl; + + var configSaveData = new JObject(); + configSaveData["base_url"] = BaseUrl; + + if (OnSaveConfigurationRequested != null) + OnSaveConfigurationRequested(this, configSaveData); + + IsConfigured = true; + } + + public void LoadFromSavedConfiguration(Newtonsoft.Json.Linq.JToken jsonConfig) + { + BaseUrl = (string)jsonConfig["base_url"]; + IsConfigured = true; + } + + public async Task PerformQuery(TorznabQuery query) + { + return await PerformQuery(query, BaseUrl); + } + + public Task Download(Uri link) + { + throw new NotImplementedException(); + } + + private WebClient getWebClient() + { + WebClient wc = new WebClient(); + WebHeaderCollection headers = new WebHeaderCollection(); + headers.Add("User-Agent", chromeUserAgent); + wc.Headers = headers; + return wc; + } + + async Task PerformQuery(TorznabQuery query, string baseUrl) + { + List releases = new List(); + + foreach (var title in query.ShowTitles ?? new string[] { string.Empty }) + { + var searchString = title + " " + query.GetEpisodeSearchString(); + var episodeSearchUrl = string.Format(searchAllUrl); + + XmlDocument xmlDoc = new XmlDocument(); + string xml = string.Empty; + WebClient wc = getWebClient(); + + try + { + using (wc) + { + xml = wc.DownloadString(episodeSearchUrl); + xmlDoc.LoadXml(xml); + } + + ReleaseInfo release; + TorrentzHelper td; + string serie_title; + + foreach (XmlNode node in xmlDoc.GetElementsByTagName("item")) + { + release = new ReleaseInfo(); + + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + + serie_title = node.SelectSingleNode("title").InnerText; + release.Title = serie_title; + + release.Comments = new Uri(node.SelectSingleNode("link").InnerText); + release.Category = node.SelectSingleNode("title").InnerText; + var test = node.SelectSingleNode("enclosure"); + release.Guid = new Uri(test.Attributes["url"].Value); + release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture); + + release.Description = node.SelectSingleNode("description").InnerText; + release.InfoHash = node.SelectSingleNode("description").InnerText; + release.Size = 0; + release.Seeders = 1; + release.Peers = 1; + release.MagnetUri = new Uri(node.SelectSingleNode("link").InnerText); + releases.Add(release); + } + } + catch (Exception ex) + { + OnResultParsingError(this, xml, ex); + throw ex; + } + } + + return releases.ToArray(); + } + } +} diff --git a/src/Jackett/Indexers/Torrentz.cs b/src/Jackett/Indexers/Torrentz.cs index c9109055a..78b60edf1 100644 --- a/src/Jackett/Indexers/Torrentz.cs +++ b/src/Jackett/Indexers/Torrentz.cs @@ -122,7 +122,8 @@ namespace Jackett.Indexers } ReleaseInfo release; - TorrentzDescription td; + TorrentzHelper td; + string serie_title; foreach (XmlNode node in xmlDoc.GetElementsByTagName("item")) { @@ -130,20 +131,21 @@ namespace Jackett.Indexers release.MinimumRatio = 1; release.MinimumSeedTime = 172800; - release.Title = node.SelectSingleNode("title").InnerText; + serie_title = node.SelectSingleNode("title").InnerText; + release.Title = serie_title; release.Comments = new Uri(node.SelectSingleNode("link").InnerText); release.Category = node.SelectSingleNode("category").InnerText; release.Guid = new Uri(node.SelectSingleNode("guid").InnerText); release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture); - td = new TorrentzDescription(node.SelectSingleNode("description").InnerText); + td = new TorrentzHelper(node.SelectSingleNode("description").InnerText); release.Description = td.Description; release.InfoHash = td.hash; release.Size = td.Size; release.Seeders = td.Seeders; release.Peers = td.Peers; - release.MagnetUri = new Uri("https://torrage.com/torrent/" + td.hash.ToUpper() + ".torrent"); + release.MagnetUri = TorrentzHelper.createMagnetLink(td.hash, serie_title); releases.Add(release); } } @@ -176,9 +178,9 @@ namespace Jackett.Indexers } - public class TorrentzDescription + public class TorrentzHelper { - public TorrentzDescription(string description) + public TorrentzHelper(string description) { this.Description = description; if (null == description) @@ -193,6 +195,15 @@ namespace Jackett.Indexers FillProperties(); } + public static Uri createMagnetLink(string hash, string title) + { + string MagnetLink = "magnet:?xt=urn:btih:{0}&dn={1}&tr={2}"; + string Trackers = WebUtility.UrlEncode("udp://tracker.publicbt.com:80&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.ccc.de:80&tr=udp://tracker.istole.it:80"); + title = WebUtility.UrlEncode(title); + + return new Uri(string.Format(MagnetLink, hash, title, Trackers)); + } + private void FillProperties() { string description = this.Description; diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 2c895d48b..da08c5216 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -98,6 +98,7 @@ + @@ -150,6 +151,7 @@ PreserveNewest + PreserveNewest diff --git a/src/Jackett/WebContent/logos/showrss.png b/src/Jackett/WebContent/logos/showrss.png new file mode 100644 index 000000000..4549816c6 Binary files /dev/null and b/src/Jackett/WebContent/logos/showrss.png differ