2017-10-29 06:21:18 +00:00
|
|
|
|
using System;
|
2017-04-15 08:45:10 +00:00
|
|
|
|
using System.Collections.Generic;
|
2018-04-26 17:30:03 +00:00
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
using System.Globalization;
|
2017-04-15 08:45:10 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Threading.Tasks;
|
2018-03-10 08:05:56 +00:00
|
|
|
|
using Jackett.Common.Models;
|
|
|
|
|
using Jackett.Common.Models.IndexerConfig.Bespoke;
|
|
|
|
|
using Jackett.Common.Services.Interfaces;
|
|
|
|
|
using Jackett.Common.Utils;
|
2018-04-26 17:30:03 +00:00
|
|
|
|
using Newtonsoft.Json;
|
2017-10-29 06:21:18 +00:00
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
using NLog;
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-03-10 08:05:56 +00:00
|
|
|
|
namespace Jackett.Common.Indexers
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
2017-07-10 20:58:44 +00:00
|
|
|
|
public class AnimeBytes : BaseCachingWebIndexer
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
2018-04-26 17:30:03 +00:00
|
|
|
|
private string ScrapeUrl { get { return SiteLink + "scrape.php"; } }
|
|
|
|
|
private string TorrentsUrl { get { return SiteLink + "torrents.php"; } }
|
2017-04-15 08:45:10 +00:00
|
|
|
|
public bool AllowRaws { get { return configData.IncludeRaw.Value; } }
|
2017-07-10 20:58:44 +00:00
|
|
|
|
public bool InsertSeason { get { return configData.InsertSeason != null && configData.InsertSeason.Value; } }
|
2017-10-17 09:15:09 +00:00
|
|
|
|
public bool AddSynonyms { get { return configData.AddSynonyms.Value; } }
|
|
|
|
|
public bool FilterSeasonEpisode { get { return configData.FilterSeasonEpisode.Value; } }
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2017-11-06 13:29:46 +00:00
|
|
|
|
string csrfIndex = null;
|
|
|
|
|
string csrfToken = null;
|
|
|
|
|
|
2017-10-29 06:21:18 +00:00
|
|
|
|
private new ConfigurationDataAnimeBytes configData
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
|
|
|
|
get { return (ConfigurationDataAnimeBytes)base.configData; }
|
|
|
|
|
set { base.configData = value; }
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-05 09:42:03 +00:00
|
|
|
|
public AnimeBytes(IIndexerConfigurationService configService, Utils.Clients.WebClient client, Logger l, IProtectionService ps)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
: base(name: "AnimeBytes",
|
|
|
|
|
link: "https://animebytes.tv/",
|
|
|
|
|
description: "Powered by Tentacles",
|
2017-07-10 20:58:44 +00:00
|
|
|
|
configService: configService,
|
2017-04-15 08:45:10 +00:00
|
|
|
|
client: client,
|
|
|
|
|
caps: new TorznabCapabilities(TorznabCatType.TVAnime,
|
|
|
|
|
TorznabCatType.Movies,
|
|
|
|
|
TorznabCatType.BooksComics,
|
|
|
|
|
TorznabCatType.ConsolePSP,
|
|
|
|
|
TorznabCatType.ConsoleOther,
|
|
|
|
|
TorznabCatType.PCGames,
|
|
|
|
|
TorznabCatType.AudioMP3,
|
|
|
|
|
TorznabCatType.AudioLossless,
|
|
|
|
|
TorznabCatType.AudioOther),
|
|
|
|
|
logger: l,
|
|
|
|
|
p: ps,
|
|
|
|
|
configData: new ConfigurationDataAnimeBytes())
|
|
|
|
|
{
|
2017-11-05 09:42:03 +00:00
|
|
|
|
Encoding = Encoding.UTF8;
|
2017-04-15 08:45:10 +00:00
|
|
|
|
Language = "en-us";
|
|
|
|
|
Type = "private";
|
2017-08-11 14:53:49 +00:00
|
|
|
|
|
|
|
|
|
webclient.EmulateBrowser = false; // Animebytes doesn't like fake user agents (issue #1535)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-10 20:58:44 +00:00
|
|
|
|
protected override IEnumerable<ReleaseInfo> FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> input)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
|
|
|
|
// Prevent filtering
|
|
|
|
|
return input;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-06 13:29:46 +00:00
|
|
|
|
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
|
|
|
|
{
|
|
|
|
|
LoadValuesFromJson(configJson);
|
|
|
|
|
|
2018-04-27 14:32:26 +00:00
|
|
|
|
if (configData.Passkey.Value.Length != 32)
|
|
|
|
|
throw new Exception("invalid passkey configured: expected length: 32, got " + configData.Passkey.Value.Length.ToString());
|
2017-10-18 08:46:38 +00:00
|
|
|
|
|
2018-04-27 14:32:26 +00:00
|
|
|
|
var results = await PerformQuery(new TorznabQuery());
|
|
|
|
|
if (results.Count() == 0)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
2018-04-27 14:32:26 +00:00
|
|
|
|
throw new Exception("no results found, please report this bug");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IsConfigured = true;
|
|
|
|
|
SaveConfig();
|
|
|
|
|
return IndexerConfigurationStatus.Completed;
|
2017-04-15 08:45:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string StripEpisodeNumber(string term)
|
|
|
|
|
{
|
|
|
|
|
// Tracer does not support searching with episode number so strip it if we have one
|
|
|
|
|
term = Regex.Replace(term, @"\W(\dx)?\d?\d$", string.Empty);
|
|
|
|
|
term = Regex.Replace(term, @"\W(S\d\d?E)?\d?\d$", string.Empty);
|
|
|
|
|
return term;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-03 05:15:47 +00:00
|
|
|
|
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
|
|
|
|
// The result list
|
|
|
|
|
var releases = new List<ReleaseInfo>();
|
2017-07-10 20:58:44 +00:00
|
|
|
|
|
2017-04-15 08:45:10 +00:00
|
|
|
|
if (ContainsMusicCategories(query.Categories))
|
|
|
|
|
{
|
2018-04-26 17:30:03 +00:00
|
|
|
|
foreach (var result in await GetResults(query, "music", query.SanitizedSearchTerm))
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
|
|
|
|
releases.Add(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
foreach (var result in await GetResults(query, "anime", StripEpisodeNumber(query.SanitizedSearchTerm)))
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
|
|
|
|
releases.Add(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return releases.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool ContainsMusicCategories(int[] categories)
|
|
|
|
|
{
|
|
|
|
|
var music = new[]
|
|
|
|
|
{
|
|
|
|
|
TorznabCatType.Audio.ID,
|
|
|
|
|
TorznabCatType.AudioMP3.ID,
|
|
|
|
|
TorznabCatType.AudioLossless.ID,
|
|
|
|
|
TorznabCatType.AudioOther.ID,
|
|
|
|
|
TorznabCatType.AudioForeign.ID
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return categories.Length == 0 || music.Any(categories.Contains);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
private async Task<IEnumerable<ReleaseInfo>> GetResults(TorznabQuery query, string searchType, string searchTerm)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
|
|
|
|
// The result list
|
|
|
|
|
var releases = new List<ReleaseInfo>();
|
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var queryCollection = new NameValueCollection();
|
|
|
|
|
|
|
|
|
|
var cat = "0";
|
|
|
|
|
var queryCats = MapTorznabCapsToTrackers(query);
|
|
|
|
|
if (queryCats.Count == 1)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
2018-04-26 17:30:03 +00:00
|
|
|
|
cat = queryCats.First().ToString();
|
2017-04-15 08:45:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
queryCollection.Add("torrent_pass", configData.Passkey.Value);
|
|
|
|
|
queryCollection.Add("type", searchType);
|
|
|
|
|
queryCollection.Add("searchstr", searchTerm);
|
|
|
|
|
var queryUrl = ScrapeUrl + "?" + queryCollection.GetQueryString();
|
|
|
|
|
|
2017-04-15 08:45:10 +00:00
|
|
|
|
// Check cache first so we don't query the server for each episode when searching for each episode in a series.
|
|
|
|
|
lock (cache)
|
|
|
|
|
{
|
|
|
|
|
// Remove old cache items
|
|
|
|
|
CleanCache();
|
|
|
|
|
|
|
|
|
|
var cachedResult = cache.Where(i => i.Query == queryUrl).FirstOrDefault();
|
|
|
|
|
if (cachedResult != null)
|
|
|
|
|
return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
|
|
|
|
|
}
|
2017-07-10 20:58:44 +00:00
|
|
|
|
|
2017-04-15 08:45:10 +00:00
|
|
|
|
// Get the content from the tracker
|
|
|
|
|
var response = await RequestStringWithCookiesAndRetry(queryUrl);
|
2018-04-26 17:30:03 +00:00
|
|
|
|
if (!response.Content.StartsWith("{")) // not JSON => error
|
|
|
|
|
throw new ExceptionWithConfigData("unexcepted response (not JSON)", configData);
|
|
|
|
|
dynamic json = JsonConvert.DeserializeObject<dynamic>(response.Content);
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
|
|
|
|
// Parse
|
|
|
|
|
try
|
|
|
|
|
{
|
2018-04-26 17:30:03 +00:00
|
|
|
|
if (json["error"] != null)
|
|
|
|
|
throw new Exception(json["error"].ToString());
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var groups = (JArray)json.Groups;
|
|
|
|
|
|
|
|
|
|
foreach (JObject group in groups)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
|
|
|
|
var synonyms = new List<string>();
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var groupID = (long)group["ID"];
|
2018-04-27 14:32:26 +00:00
|
|
|
|
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 Artists = (string)group["Artists"];
|
|
|
|
|
|
|
|
|
|
var mainTitle = WebUtility.HtmlDecode((string)group["FullName"]);
|
|
|
|
|
if (SeriesName != null)
|
|
|
|
|
mainTitle = SeriesName;
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-27 14:32:26 +00:00
|
|
|
|
synonyms.Add(mainTitle);
|
2018-04-26 17:30:03 +00:00
|
|
|
|
|
2017-04-15 08:45:10 +00:00
|
|
|
|
// If the title contains a comma then we can't use the synonyms as they are comma seperated
|
2017-10-17 09:15:09 +00:00
|
|
|
|
if (!mainTitle.Contains(",") && AddSynonyms)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var symnomnNames = WebUtility.HtmlDecode((string)group["Synonymns"]);
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(symnomnNames))
|
|
|
|
|
{
|
|
|
|
|
foreach (var name in symnomnNames.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
|
|
|
|
|
{
|
|
|
|
|
var theName = name.Trim();
|
|
|
|
|
if (!theName.Contains("&#") && !string.IsNullOrWhiteSpace(theName))
|
|
|
|
|
{
|
|
|
|
|
synonyms.Add(theName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
List<int> Category = null;
|
|
|
|
|
var category = (string)group["CategoryName"];
|
|
|
|
|
|
|
|
|
|
var Description = (string)group["Description"];
|
|
|
|
|
|
|
|
|
|
foreach (JObject torrent in group["Torrents"])
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var releaseInfo = "S01";
|
2017-10-17 09:15:09 +00:00
|
|
|
|
string episode = null;
|
|
|
|
|
int? season = null;
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var EditionTitle = (string)torrent["EditionData"]["EditionTitle"];
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(EditionTitle))
|
|
|
|
|
releaseInfo = WebUtility.HtmlDecode(EditionTitle);
|
|
|
|
|
|
|
|
|
|
Regex SeasonRegEx = new Regex(@"Season (\d+)", RegexOptions.Compiled);
|
|
|
|
|
var SeasonRegExMatch = SeasonRegEx.Match(releaseInfo);
|
|
|
|
|
if (SeasonRegExMatch.Success)
|
|
|
|
|
season = ParseUtil.CoerceInt(SeasonRegExMatch.Groups[1].Value);
|
|
|
|
|
|
|
|
|
|
Regex 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();
|
|
|
|
|
|
|
|
|
|
int test = 0;
|
|
|
|
|
if (InsertSeason && int.TryParse(releaseInfo, out test) && releaseInfo.Length <= 3)
|
2017-04-15 08:45:10 +00:00
|
|
|
|
{
|
2018-04-26 17:30:03 +00:00
|
|
|
|
releaseInfo = "E0" + releaseInfo;
|
|
|
|
|
}
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
if (FilterSeasonEpisode)
|
|
|
|
|
{
|
|
|
|
|
if (query.Season != 0 && season != null && season != query.Season) // skip if season doesn't match
|
|
|
|
|
continue;
|
|
|
|
|
if (query.Episode != null && episode != null && episode != query.Episode) // skip if episode doesn't match
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
var torrentID = (long)torrent["ID"];
|
|
|
|
|
logger.Error(torrentID);
|
|
|
|
|
var Property = (string)torrent["Property"];
|
|
|
|
|
Property = Property.Replace(" | Freeleech", "");
|
|
|
|
|
var Link = (string)torrent["Link"];
|
|
|
|
|
var LinkUri = new Uri(Link);
|
|
|
|
|
var UploadTimeString = (string)torrent["UploadTime"];
|
2018-04-27 14:32:26 +00:00
|
|
|
|
var UploadTime = DateTime.ParseExact(UploadTimeString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var PublushDate = DateTime.SpecifyKind(UploadTime, DateTimeKind.Utc).ToLocalTime();
|
|
|
|
|
var CommentsLink = TorrentsUrl + "?id=" + groupID.ToString() + "&torrentid=" + torrentID.ToString();
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (searchType == "anime")
|
|
|
|
|
{
|
|
|
|
|
if (category == "TV Series")
|
|
|
|
|
Category = new List<int> { TorznabCatType.TVAnime.ID };
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
// Ignore these categories as they'll cause hell with the matcher
|
|
|
|
|
// TV Special, OVA, ONA, DVD Special, BD Special
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
if (category == "Movie")
|
|
|
|
|
Category = new List<int> { TorznabCatType.Movies.ID };
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
if (category == "Manga" || category == "Oneshot" || category == "Anthology" || category == "Manhwa" || category == "Manhua" || category == "Light Novel")
|
|
|
|
|
Category = new List<int> { TorznabCatType.BooksComics.ID };
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
if (category == "Novel" || category == "Artbook")
|
|
|
|
|
Category = new List<int> { TorznabCatType.BooksComics.ID };
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
if (category == "Game" || category == "Visual Novel")
|
|
|
|
|
{
|
|
|
|
|
if (Property.Contains(" PSP "))
|
|
|
|
|
Category = new List<int> { TorznabCatType.ConsolePSP.ID };
|
|
|
|
|
if (Property.Contains("PSX"))
|
|
|
|
|
Category = new List<int> { TorznabCatType.ConsoleOther.ID };
|
|
|
|
|
if (Property.Contains(" NES "))
|
|
|
|
|
Category = new List<int> { TorznabCatType.ConsoleOther.ID };
|
|
|
|
|
if (Property.Contains(" PC "))
|
|
|
|
|
Category = new List<int> { 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 (Property.Contains(" Lossless "))
|
|
|
|
|
Category = new List<int> { TorznabCatType.AudioLossless.ID };
|
|
|
|
|
else if (Property.Contains("MP3"))
|
|
|
|
|
Category = new List<int> { TorznabCatType.AudioMP3.ID };
|
2017-04-15 08:45:10 +00:00
|
|
|
|
else
|
2018-04-26 17:30:03 +00:00
|
|
|
|
Category = new List<int> { TorznabCatType.AudioOther.ID };
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
// We dont actually have a release name >.> so try to create one
|
|
|
|
|
var releaseTags = Property.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
|
|
|
|
|
for (int i = releaseTags.Count - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
releaseTags[i] = releaseTags[i].Trim();
|
|
|
|
|
if (string.IsNullOrWhiteSpace(releaseTags[i]))
|
|
|
|
|
releaseTags.RemoveAt(i);
|
|
|
|
|
}
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var releasegroup = releaseTags.LastOrDefault();
|
|
|
|
|
if (releasegroup != null && releasegroup.Contains("(") && releasegroup.Contains(")"))
|
|
|
|
|
{
|
|
|
|
|
// Skip raws if set
|
|
|
|
|
if (releasegroup.ToLowerInvariant().StartsWith("raw") && !AllowRaws)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var start = releasegroup.IndexOf("(");
|
|
|
|
|
releasegroup = "[" + releasegroup.Substring(start + 1, (releasegroup.IndexOf(")") - 1) - start) + "] ";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
releasegroup = string.Empty;
|
|
|
|
|
}
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var infoString = "";
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
for (int i = 0; i + 1 < releaseTags.Count(); i++)
|
|
|
|
|
{
|
|
|
|
|
if (releaseTags[i] == "Raw" && !AllowRaws)
|
|
|
|
|
continue;
|
|
|
|
|
infoString += "[" + releaseTags[i] + "]";
|
|
|
|
|
}
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
var MinimumSeedTime = 259200;
|
|
|
|
|
// Additional 5 hours per GB
|
|
|
|
|
MinimumSeedTime += (int)((Size / 1000000000) * 18000);
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
2018-04-26 17:30:03 +00:00
|
|
|
|
foreach (var title in synonyms)
|
|
|
|
|
{
|
|
|
|
|
string releaseTitle = null;
|
|
|
|
|
if (category == "Movie")
|
|
|
|
|
{
|
|
|
|
|
var year = 0;
|
|
|
|
|
releaseTitle = string.Format("{0} {1} {2}{3}", title, year, group, infoString);
|
2017-04-15 08:45:10 +00:00
|
|
|
|
}
|
2018-04-26 17:30:03 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
releaseTitle = string.Format("{0}{1} {2} {3}", releasegroup, title, releaseInfo, infoString);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var release = new ReleaseInfo();
|
|
|
|
|
release.MinimumRatio = 1;
|
|
|
|
|
release.MinimumSeedTime = MinimumSeedTime;
|
|
|
|
|
release.Title = releaseTitle;
|
|
|
|
|
release.Comments = CommentsLinkUri;
|
|
|
|
|
release.Guid = new Uri(CommentsLinkUri + "&nh=" + StringUtil.Hash(title)); // Sonarr should dedupe on this url - allow a url per name.
|
|
|
|
|
release.Link = LinkUri;
|
2018-04-27 14:32:26 +00:00
|
|
|
|
release.BannerUrl = ImageUrl;
|
2018-04-26 17:30:03 +00:00
|
|
|
|
release.PublishDate = PublushDate;
|
|
|
|
|
release.Category = Category;
|
|
|
|
|
release.Description = Description;
|
|
|
|
|
release.Size = Size;
|
|
|
|
|
release.Seeders = Seeders;
|
|
|
|
|
release.Peers = Peers;
|
|
|
|
|
release.Grabs = Snatched;
|
|
|
|
|
release.Files = FileCount;
|
|
|
|
|
release.DownloadVolumeFactor = RawDownMultiplier;
|
|
|
|
|
release.UploadVolumeFactor = RawUpMultiplier;
|
|
|
|
|
|
|
|
|
|
releases.Add(release);
|
2017-04-15 08:45:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
OnParseError(response.Content, ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add to the cache
|
|
|
|
|
lock (cache)
|
|
|
|
|
{
|
|
|
|
|
cache.Add(new CachedQueryResult(queryUrl, releases));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return releases.Select(s => (ReleaseInfo)s.Clone());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|