diff --git a/README.md b/README.md index 88a8f370c..2b61847c6 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/ * EuTorrents * FileList * Freshon + * FunFile * Fuzer * Ghost City * HD-Space diff --git a/src/Jackett/Content/logos/funfile.png b/src/Jackett/Content/logos/funfile.png new file mode 100644 index 000000000..a6a595bcd Binary files /dev/null and b/src/Jackett/Content/logos/funfile.png differ diff --git a/src/Jackett/Indexers/FunFile.cs b/src/Jackett/Indexers/FunFile.cs new file mode 100644 index 000000000..f15faec5f --- /dev/null +++ b/src/Jackett/Indexers/FunFile.cs @@ -0,0 +1,142 @@ +using CsQuery; +using Jackett.Models; +using Jackett.Services; +using Jackett.Utils; +using Jackett.Utils.Clients; +using Newtonsoft.Json.Linq; +using NLog; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Jackett.Models.IndexerConfig; +using System.Collections.Specialized; + +namespace Jackett.Indexers +{ + public class FunFile : BaseIndexer, IIndexer + { + private string SearchUrl { get { return SiteLink + "browse.php"; } } + private string LoginUrl { get { return SiteLink + "takelogin.php"; } } + + new ConfigurationDataBasicLoginWithRSSAndDisplay configData + { + get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; } + set { base.configData = value; } + } + + public FunFile(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps) + : base(name: "FunFile", + description: "A general tracker", + link: "https://www.funfile.org/", + caps: new TorznabCapabilities(), + manager: i, + client: w, + logger: l, + p: ps, + configData: new ConfigurationDataBasicLoginWithRSSAndDisplay()) + { + AddCategoryMapping(44, TorznabCatType.TVAnime); // Anime + AddCategoryMapping(22, TorznabCatType.PC); // Applications + AddCategoryMapping(43, TorznabCatType.AudioAudiobook); // Audio Books + AddCategoryMapping(27, TorznabCatType.Books); // Ebook + AddCategoryMapping(4, TorznabCatType.PCGames); // Games + AddCategoryMapping(40, TorznabCatType.OtherMisc); // Miscellaneous + AddCategoryMapping(19, TorznabCatType.Movies); // Movies + AddCategoryMapping(6, TorznabCatType.Audio); // Music + AddCategoryMapping(31, TorznabCatType.PCPhoneOther); // Portable + AddCategoryMapping(7, TorznabCatType.TV); // TV + } + + public async Task ApplyConfiguration(JToken configJson) + { + configData.LoadValuesFromJson(configJson); + var pairs = new Dictionary { + { "username", configData.Username.Value }, + { "password", configData.Password.Value }, + { "login", "Login" }, + }; + + var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl); + await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () => + { + CQ dom = result.Content; + var errorMessage = dom["td.mf_content"].Html(); + throw new ExceptionWithConfigData(errorMessage, configData); + }); + return IndexerConfigurationStatus.RequiresTesting; + } + + public async Task> PerformQuery(TorznabQuery query) + { + List releases = new List(); + + var searchString = query.GetQueryString(); + var searchUrl = SearchUrl; + var queryCollection = new NameValueCollection(); + queryCollection.Add("incldead", "1"); + queryCollection.Add("showspam", "1"); + + if (!string.IsNullOrWhiteSpace(searchString)) + { + queryCollection.Add("search", searchString); + } + + var cats = MapTorznabCapsToTrackers(query); + string cat = "0"; + if (cats.Count == 1) + { + cat = cats[0]; + } + queryCollection.Add("cat", cat); + + searchUrl += "?" + queryCollection.GetQueryString(); + + var results = await RequestStringWithCookiesAndRetry(searchUrl); + try + { + CQ dom = results.Content; + var rows = dom["table[cellpadding=2] > tbody > tr:has(td.row3)"]; + foreach (var row in rows) + { + var release = new ReleaseInfo(); + release.MinimumRatio = 1; + release.MinimumSeedTime = 48 * 60 * 60; + + var qRow = row.Cq(); + var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First(); + var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First(); + var qSeeders = qRow.Find("td:eq(9)"); + var qLeechers = qRow.Find("td:eq(10)"); + var qDownloadLink = qRow.Find("a[href^=download.php]").First(); + var qTimeAgo = qRow.Find("td:eq(5)"); + var qSize = qRow.Find("td:eq(7)"); + + var catStr = qCatLink.Attr("href").Split('=')[1].Split('&')[0]; + release.Category = MapTrackerCatToNewznab(catStr); + + release.Link = new Uri(SiteLink + qDownloadLink.Attr("href")); + release.Title = qDetailsLink.Attr("title").Trim(); + release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href")); + release.Guid = release.Link; + + var sizeStr = qSize.Text(); + release.Size = ReleaseInfo.GetBytes(sizeStr); + + release.Seeders = ParseUtil.CoerceInt(qSeeders.Text()); + release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders; + + var dateStr = qTimeAgo.Text(); + release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr); + + releases.Add(release); + } + } + catch (Exception ex) + { + OnParseError(results.Content, ex); + } + + return releases; + } + } +} diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 7a341ff80..97c76434b 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -157,6 +157,7 @@ + @@ -423,6 +424,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest