diff --git a/src/Jackett.Common/Indexers/AnimeBytes.cs b/src/Jackett.Common/Indexers/AnimeBytes.cs index f9239bc2b..b38925121 100644 --- a/src/Jackett.Common/Indexers/AnimeBytes.cs +++ b/src/Jackett.Common/Indexers/AnimeBytes.cs @@ -15,6 +15,7 @@ using Jackett.Common.Utils; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NLog; +using WebClient = Jackett.Common.Utils.Clients.WebClient; namespace Jackett.Common.Indexers { @@ -22,20 +23,16 @@ namespace Jackett.Common.Indexers public class AnimeBytes : BaseCachingWebIndexer { private string ScrapeUrl => SiteLink + "scrape.php"; - public bool AllowRaws => configData.IncludeRaw.Value; - public bool PadEpisode => configData.PadEpisode != null && configData.PadEpisode.Value; - public bool AddJapaneseTitle => configData.AddJapaneseTitle.Value; - public bool AddRomajiTitle => configData.AddRomajiTitle.Value; - public bool AddAlternativeTitles => configData.AddAlternativeTitles.Value; - public bool FilterSeasonEpisode => configData.FilterSeasonEpisode.Value; + private bool AllowRaws => ConfigData.IncludeRaw.Value; + private bool PadEpisode => ConfigData.PadEpisode != null && ConfigData.PadEpisode.Value; + private bool AddJapaneseTitle => ConfigData.AddJapaneseTitle.Value; + private bool AddRomajiTitle => ConfigData.AddRomajiTitle.Value; + private bool AddAlternativeTitles => ConfigData.AddAlternativeTitles.Value; + private bool FilterSeasonEpisode => ConfigData.FilterSeasonEpisode.Value; - private new ConfigurationDataAnimeBytes configData - { - get => (ConfigurationDataAnimeBytes)base.configData; - set => base.configData = value; - } + private ConfigurationDataAnimeBytes ConfigData => (ConfigurationDataAnimeBytes)configData; - public AnimeBytes(IIndexerConfigurationService configService, Utils.Clients.WebClient client, Logger l, IProtectionService ps) + public AnimeBytes(IIndexerConfigurationService configService, WebClient client, Logger l, IProtectionService ps) : base(id: "animebytes", name: "AnimeBytes", description: "Powered by Tentacles", @@ -86,25 +83,18 @@ namespace Jackett.Common.Indexers AddCategoryMapping("printedtype[manhwa]", TorznabCatType.BooksComics, "Manhwa"); AddCategoryMapping("printedtype[light_novel]", TorznabCatType.BooksComics, "Light Novel"); AddCategoryMapping("printedtype[artbook]", TorznabCatType.BooksComics, "Artbook"); - } - // Prevent filtering - protected override IEnumerable FilterResults(TorznabQuery query, IEnumerable input) => - - input; public override async Task ApplyConfiguration(JToken configJson) { LoadValuesFromJson(configJson); - if (configData.Passkey.Value.Length != 32 && configData.Passkey.Value.Length != 48) - throw new Exception("invalid passkey configured: expected length: 32 or 48, got " + configData.Passkey.Value.Length.ToString()); + if (ConfigData.Passkey.Value.Length != 32 && ConfigData.Passkey.Value.Length != 48) + throw new Exception("invalid passkey configured: expected length: 32 or 48, got " + ConfigData.Passkey.Value.Length); var results = await PerformQuery(new TorznabQuery()); - if (results.Count() == 0) - { + if (!results.Any()) throw new Exception("no results found, please report this bug"); - } IsConfigured = true; SaveConfig(); @@ -122,21 +112,14 @@ namespace Jackett.Common.Indexers protected override async Task> PerformQuery(TorznabQuery query) { - // The result list var releases = new List(); if (ContainsMusicCategories(query.Categories)) - { - foreach (var result in await GetResults(query, "music", query.SanitizedSearchTerm)) - { - releases.Add(result); - } - } + releases.AddRange(await GetResults(query, "music", query.SanitizedSearchTerm)); - foreach (var result in await GetResults(query, "anime", StripEpisodeNumber(query.SanitizedSearchTerm))) - { - releases.Add(result); - } + releases.AddRange( + await GetResults(query, "anime", StripEpisodeNumber(query.SanitizedSearchTerm)) + ); return releases.ToArray(); } @@ -157,24 +140,21 @@ namespace Jackett.Common.Indexers private async Task> GetResults(TorznabQuery query, string searchType, string searchTerm) { - // The result list var releases = new List(); - var queryCollection = new NameValueCollection(); + var queryCollection = new NameValueCollection + { + {"username", ConfigData.Username.Value}, + {"torrent_pass", ConfigData.Passkey.Value}, + {"type", searchType}, + {"searchstr", searchTerm} + }; var queryCats = MapTorznabCapsToTrackers(query); if (queryCats.Count > 0) - { foreach (var cat in queryCats) - { queryCollection.Add(cat, "1"); - } - } - queryCollection.Add("username", configData.Username.Value); - queryCollection.Add("torrent_pass", configData.Passkey.Value); - queryCollection.Add("type", searchType); - queryCollection.Add("searchstr", searchTerm); var queryUrl = ScrapeUrl + "?" + queryCollection.GetQueryString(); // Check cache first so we don't query the server for each episode when searching for each episode in a series. @@ -191,7 +171,7 @@ namespace Jackett.Common.Indexers // Get the content from the tracker var response = await RequestWithCookiesAndRetryAsync(queryUrl); if (!response.ContentString.StartsWith("{")) // not JSON => error - throw new ExceptionWithConfigData("unexcepted response (not JSON)", configData); + throw new ExceptionWithConfigData("Unexpected response (not JSON)", ConfigData); var json = JsonConvert.DeserializeObject(response.ContentString); // Parse @@ -200,24 +180,23 @@ namespace Jackett.Common.Indexers if (json["error"] != null) throw new Exception(json["error"].ToString()); - var Matches = (long)json["Matches"]; + var matches = (long)json["Matches"]; - if (Matches > 0) + if (matches > 0) { var groups = (JArray)json.Groups; - foreach (JObject group in groups) + foreach (var group in groups) { var synonyms = new List(); - var groupID = (long)group["ID"]; - var Image = (string)group["Image"]; - var ImageUrl = (string.IsNullOrWhiteSpace(Image) ? null : new Uri(Image)); - var Year = (int)group["Year"]; - var GroupName = (string)group["GroupName"]; - var SeriesName = (string)group["SeriesName"]; + var image = (string)group["Image"]; + var imageUrl = (string.IsNullOrWhiteSpace(image) ? null : new Uri(image)); + var year = (int)group["Year"]; + var groupName = (string)group["GroupName"]; + var seriesName = (string)group["SeriesName"]; var mainTitle = WebUtility.HtmlDecode((string)group["FullName"]); - if (SeriesName != null) - mainTitle = SeriesName; + if (seriesName != null) + mainTitle = seriesName; synonyms.Add(mainTitle); @@ -247,35 +226,35 @@ namespace Jackett.Common.Indexers } } - List Category = null; - var category = (string)group["CategoryName"]; + List category = null; + var categoryName = (string)group["CategoryName"]; - var Description = (string)group["Description"]; + var description = (string)group["Description"]; - foreach (JObject torrent in group["Torrents"]) + foreach (var torrent in group["Torrents"]) { var releaseInfo = "S01"; string episode = null; int? season = null; - var EditionTitle = (string)torrent["EditionData"]["EditionTitle"]; - if (!string.IsNullOrWhiteSpace(EditionTitle)) - releaseInfo = WebUtility.HtmlDecode(EditionTitle); + var editionTitle = (string)torrent["EditionData"]["EditionTitle"]; + if (!string.IsNullOrWhiteSpace(editionTitle)) + releaseInfo = WebUtility.HtmlDecode(editionTitle); - var SeasonRegEx = new Regex(@"Season (\d+)", RegexOptions.Compiled); - var SeasonRegExMatch = SeasonRegEx.Match(releaseInfo); - if (SeasonRegExMatch.Success) - season = ParseUtil.CoerceInt(SeasonRegExMatch.Groups[1].Value); + var seasonRegEx = new Regex(@"Season (\d+)", RegexOptions.Compiled); + var seasonRegExMatch = seasonRegEx.Match(releaseInfo); + if (seasonRegExMatch.Success) + season = ParseUtil.CoerceInt(seasonRegExMatch.Groups[1].Value); - var EpisodeRegEx = new Regex(@"Episode (\d+)", RegexOptions.Compiled); - var EpisodeRegExMatch = EpisodeRegEx.Match(releaseInfo); - if (EpisodeRegExMatch.Success) - episode = EpisodeRegExMatch.Groups[1].Value; + var episodeRegEx = new Regex(@"Episode (\d+)", RegexOptions.Compiled); + var episodeRegExMatch = episodeRegEx.Match(releaseInfo); + if (episodeRegExMatch.Success) + episode = episodeRegExMatch.Groups[1].Value; releaseInfo = releaseInfo.Replace("Episode ", ""); releaseInfo = releaseInfo.Replace("Season ", "S"); releaseInfo = releaseInfo.Trim(); - if (PadEpisode && int.TryParse(releaseInfo, out var test) && releaseInfo.Length == 1) + if (PadEpisode && int.TryParse(releaseInfo, out _) && releaseInfo.Length == 1) { releaseInfo = "0" + releaseInfo; } @@ -287,74 +266,69 @@ namespace Jackett.Common.Indexers if (query.Episode != null && episode != null && episode != query.Episode) // skip if episode doesn't match continue; } - var torrentID = (long)torrent["ID"]; - var Property = (string)torrent["Property"]; - Property = Property.Replace(" | Freeleech", ""); - var Link = (string)torrent["Link"]; - var LinkUri = new Uri(Link); - var UploadTimeString = (string)torrent["UploadTime"]; - var UploadTime = DateTime.ParseExact(UploadTimeString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); - var PublushDate = DateTime.SpecifyKind(UploadTime, DateTimeKind.Utc).ToLocalTime(); - var CommentsLink = SiteLink + "torrent/" + torrentID.ToString() + "/group"; - var CommentsLinkUri = new Uri(CommentsLink); - var Size = (long)torrent["Size"]; - var Snatched = (long)torrent["Snatched"]; - var Seeders = (int)torrent["Seeders"]; - var Leechers = (int)torrent["Leechers"]; - var FileCount = (long)torrent["FileCount"]; - var Peers = Seeders + Leechers; + var torrentId = (long)torrent["ID"]; + var property = ((string)torrent["Property"]).Replace(" | Freeleech", ""); + var link = (string)torrent["Link"]; + var linkUri = new Uri(link); + var uploadTimeString = (string)torrent["UploadTime"]; + var uploadTime = DateTime.ParseExact(uploadTimeString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); + var publishDate = DateTime.SpecifyKind(uploadTime, DateTimeKind.Utc).ToLocalTime(); + var commentsLink = SiteLink + "torrent/" + torrentId + "/group"; + var commentsLinkUri = new Uri(commentsLink); + var size = (long)torrent["Size"]; + var snatched = (long)torrent["Snatched"]; + var seeders = (int)torrent["Seeders"]; + var leechers = (int)torrent["Leechers"]; + var fileCount = (long)torrent["FileCount"]; + var peers = seeders + leechers; - var RawDownMultiplier = (int?)torrent["RawDownMultiplier"]; - if (RawDownMultiplier == null) - RawDownMultiplier = 0; - var RawUpMultiplier = (int?)torrent["RawUpMultiplier"]; - if (RawUpMultiplier == null) - RawDownMultiplier = 0; + var rawDownMultiplier = (int?)torrent["RawDownMultiplier"] ?? 0; + var rawUpMultiplier = (int?)torrent["RawUpMultiplier"] ?? 0; if (searchType == "anime") { - if (GroupName == "TV Series" || GroupName == "OVA") - Category = new List { TorznabCatType.TVAnime.ID }; + if (groupName == "TV Series" || groupName == "OVA") + category = new List { TorznabCatType.TVAnime.ID }; // Ignore these categories as they'll cause hell with the matcher // TV Special, OVA, ONA, DVD Special, BD Special - if (GroupName == "Movie" || GroupName == "Live Action Movie") - Category = new List { TorznabCatType.Movies.ID }; + if (groupName == "Movie" || groupName == "Live Action Movie") + category = new List { TorznabCatType.Movies.ID }; - if (category == "Manga" || category == "Oneshot" || category == "Anthology" || category == "Manhwa" || category == "Manhua" || category == "Light Novel") - Category = new List { TorznabCatType.BooksComics.ID }; + if (categoryName == "Manga" || categoryName == "Oneshot" || categoryName == "Anthology" || categoryName == "Manhwa" || categoryName == "Manhua" || categoryName == "Light Novel") + category = new List { TorznabCatType.BooksComics.ID }; - if (category == "Novel" || category == "Artbook") - Category = new List { TorznabCatType.BooksComics.ID }; + if (categoryName == "Novel" || categoryName == "Artbook") + category = new List { TorznabCatType.BooksComics.ID }; - if (category == "Game" || category == "Visual Novel") + if (categoryName == "Game" || categoryName == "Visual Novel") { - if (Property.Contains(" PSP ")) - Category = new List { TorznabCatType.ConsolePSP.ID }; - if (Property.Contains("PSX")) - Category = new List { TorznabCatType.ConsoleOther.ID }; - if (Property.Contains(" NES ")) - Category = new List { TorznabCatType.ConsoleOther.ID }; - if (Property.Contains(" PC ")) - Category = new List { TorznabCatType.PCGames.ID }; + if (property.Contains(" PSP ")) + category = new List { TorznabCatType.ConsolePSP.ID }; + if (property.Contains("PSX")) + category = new List { TorznabCatType.ConsoleOther.ID }; + if (property.Contains(" NES ")) + category = new List { TorznabCatType.ConsoleOther.ID }; + if (property.Contains(" PC ")) + category = new List { TorznabCatType.PCGames.ID }; } } else if (searchType == "music") { - if (category == "Single" || category == "EP" || category == "Album" || category == "Compilation" || category == "Soundtrack" || category == "Remix CD" || category == "PV" || category == "Live Album" || category == "Image CD" || category == "Drama CD" || category == "Vocal CD") + if (categoryName == "Single" || categoryName == "EP" || categoryName == "Album" || categoryName == "Compilation" || categoryName == "Soundtrack" || categoryName == "Remix CD" || categoryName == "PV" || categoryName == "Live Album" || categoryName == "Image CD" || categoryName == "Drama CD" || categoryName == "Vocal CD") { - if (Property.Contains(" Lossless ")) - Category = new List { TorznabCatType.AudioLossless.ID }; - else if (Property.Contains("MP3")) - Category = new List { TorznabCatType.AudioMP3.ID }; + if (property.Contains(" Lossless ")) + category = new List { TorznabCatType.AudioLossless.ID }; + else if (property.Contains("MP3")) + category = new List { TorznabCatType.AudioMP3.ID }; else - Category = new List { TorznabCatType.AudioOther.ID }; + category = new List { TorznabCatType.AudioOther.ID }; } } - // We dont actually have a release name >.> so try to create one - var releaseTags = Property.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList(); + // We don't actually have a release name >.> so try to create one + var releaseTags = property.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList(); for (var i = releaseTags.Count - 1; i >= 0; i--) { releaseTags[i] = releaseTags[i].Trim(); @@ -362,62 +336,56 @@ namespace Jackett.Common.Indexers releaseTags.RemoveAt(i); } - var releasegroup = releaseTags.LastOrDefault(); - if (releasegroup != null && releasegroup.Contains("(") && releasegroup.Contains(")")) + var releaseGroup = releaseTags.LastOrDefault(); + if (releaseGroup != null && releaseGroup.Contains("(") && releaseGroup.Contains(")")) { // Skip raws if set - if (releasegroup.ToLowerInvariant().StartsWith("raw") && !AllowRaws) + if (releaseGroup.ToLowerInvariant().StartsWith("raw") && !AllowRaws) { continue; } - var start = releasegroup.IndexOf("("); - releasegroup = "[" + releasegroup.Substring(start + 1, (releasegroup.IndexOf(")") - 1) - start) + "] "; + var start = releaseGroup.IndexOf("(", StringComparison.Ordinal); + releaseGroup = "[" + releaseGroup.Substring(start + 1, (releaseGroup.IndexOf(")", StringComparison.Ordinal) - 1) - start) + "] "; } else { - releasegroup = string.Empty; + releaseGroup = string.Empty; } if (!AllowRaws && releaseTags.Contains("raw", StringComparer.InvariantCultureIgnoreCase)) continue; var infoString = releaseTags.Aggregate("", (prev, cur) => prev + "[" + cur + "]"); - var MinimumSeedTime = 259200; + var minimumSeedTime = 259200; // Additional 5 hours per GB - MinimumSeedTime += (int)((Size / 1000000000) * 18000); + minimumSeedTime += (int)((size / 1000000000) * 18000); foreach (var title in synonyms) { - string releaseTitle = null; - if (GroupName == "Movie") - { - releaseTitle = string.Format("{0} {1} {2}{3}", title, Year, releasegroup, infoString); - } - else - { - releaseTitle = string.Format("{0}{1} {2} {3}", releasegroup, title, releaseInfo, infoString); - } + var releaseTitle = groupName == "Movie" ? + $"{title} {year} {releaseGroup}{infoString}" : + $"{releaseGroup}{title} {releaseInfo} {infoString}"; - var guid = new Uri(CommentsLinkUri + "&nh=" + StringUtil.Hash(title)); + var guid = new Uri(commentsLinkUri + "&nh=" + StringUtil.Hash(title)); var release = new ReleaseInfo { MinimumRatio = 1, - MinimumSeedTime = MinimumSeedTime, + MinimumSeedTime = minimumSeedTime, Title = releaseTitle, - Comments = CommentsLinkUri, - Guid = guid, // Sonarr should dedupe on this url - allow a url per name. - Link = LinkUri, - BannerUrl = ImageUrl, - PublishDate = PublushDate, - Category = Category, - Description = Description, - Size = Size, - Seeders = Seeders, - Peers = Peers, - Grabs = Snatched, - Files = FileCount, - DownloadVolumeFactor = RawDownMultiplier, - UploadVolumeFactor = RawUpMultiplier + Comments = commentsLinkUri, + Guid = guid, + Link = linkUri, + BannerUrl = imageUrl, + PublishDate = publishDate, + Category = category, + Description = description, + Size = size, + Seeders = seeders, + Peers = peers, + Grabs = snatched, + Files = fileCount, + DownloadVolumeFactor = rawDownMultiplier, + UploadVolumeFactor = rawUpMultiplier }; releases.Add(release);