mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-04-24 13:57:11 -04:00
Fixed: (GGn) Improve title, timezone, MST, min/max size filters
Hiding torrents of type link And some minor refactoring around the passkey fetching and parsing.
This commit is contained in:
parent
bf47380f7b
commit
f9c9d4a0e0
2 changed files with 205 additions and 112 deletions
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
|
@ -21,10 +22,10 @@ namespace NzbDrone.Core.Test.IndexerTests.GazelleGamesTests
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Subject.Definition = new IndexerDefinition()
|
||||
Subject.Definition = new IndexerDefinition
|
||||
{
|
||||
Name = "GazelleGames",
|
||||
Settings = new GazelleGamesSettings() { Apikey = "somekey" }
|
||||
Settings = new GazelleGamesSettings { Apikey = "somekey" }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -37,20 +38,20 @@ namespace NzbDrone.Core.Test.IndexerTests.GazelleGamesTests
|
|||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader { { "Content-Type", "application/json" } }, new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new BasicSearchCriteria { Categories = new int[] { 2000 } })).Releases;
|
||||
var releases = (await Subject.Fetch(new BasicSearchCriteria { Categories = new[] { 2000 } })).Releases;
|
||||
|
||||
releases.Should().HaveCount(1464);
|
||||
releases.Should().HaveCount(1463);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
var torrentInfo = releases.First() as TorrentInfo;
|
||||
|
||||
torrentInfo.Title.Should().Be("Microsoft_Flight_Simulator-HOODLUM");
|
||||
torrentInfo.Title.Should().Be("Microsoft_Flight_Simulator-HOODLUM (2020) [Windows / Multi-Language / Full ISO]");
|
||||
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||
torrentInfo.DownloadUrl.Should().Be("https://gazellegames.net/torrents.php?action=download&id=303216&authkey=prowlarr&torrent_pass=");
|
||||
torrentInfo.InfoUrl.Should().Be("https://gazellegames.net/torrents.php?id=84781&torrentid=303216");
|
||||
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
|
||||
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2022-07-25 6:39:11").ToUniversalTime());
|
||||
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2022-07-25 06:39:11", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal));
|
||||
torrentInfo.Size.Should().Be(80077617780);
|
||||
torrentInfo.InfoHash.Should().Be(null);
|
||||
torrentInfo.MagnetUrl.Should().Be(null);
|
||||
|
@ -74,7 +75,7 @@ namespace NzbDrone.Core.Test.IndexerTests.GazelleGamesTests
|
|||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader { { "Content-Type", "application/json" } }, new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new BasicSearchCriteria { Categories = new int[] { 2000 } })).Releases;
|
||||
var releases = (await Subject.Fetch(new BasicSearchCriteria { Categories = new[] { 2000 } })).Releases;
|
||||
|
||||
releases.Should().HaveCount(0);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Annotations;
|
||||
|
@ -16,6 +19,7 @@ using NzbDrone.Core.Indexers.Exceptions;
|
|||
using NzbDrone.Core.Indexers.Settings;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
|
@ -24,7 +28,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
public class GazelleGames : TorrentIndexerBase<GazelleGamesSettings>
|
||||
{
|
||||
public override string Name => "GazelleGames";
|
||||
public override string[] IndexerUrls => new string[] { "https://gazellegames.net/" };
|
||||
public override string[] IndexerUrls => new[] { "https://gazellegames.net/" };
|
||||
public override string Description => "GazelleGames (GGn) is a Private Torrent Tracker for GAMES";
|
||||
public override string Language => "en-US";
|
||||
public override Encoding Encoding => Encoding.UTF8;
|
||||
|
@ -38,7 +42,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
|
||||
public override IIndexerRequestGenerator GetRequestGenerator()
|
||||
{
|
||||
return new GazelleGamesRequestGenerator() { Settings = Settings, Capabilities = Capabilities, HttpClient = _httpClient };
|
||||
return new GazelleGamesRequestGenerator(Settings, Capabilities);
|
||||
}
|
||||
|
||||
public override IParseIndexerResponse GetParser()
|
||||
|
@ -48,14 +52,13 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
|
||||
private IndexerCapabilities SetCapabilities()
|
||||
{
|
||||
var caps = new IndexerCapabilities
|
||||
{
|
||||
};
|
||||
var caps = new IndexerCapabilities();
|
||||
|
||||
// Apple
|
||||
caps.Categories.AddCategoryMapping("Mac", NewznabStandardCategory.ConsoleOther, "Mac");
|
||||
caps.Categories.AddCategoryMapping("iOS", NewznabStandardCategory.PCMobileiOS, "iOS");
|
||||
caps.Categories.AddCategoryMapping("Apple Bandai Pippin", NewznabStandardCategory.ConsoleOther, "Apple Bandai Pippin");
|
||||
caps.Categories.AddCategoryMapping("Apple II", NewznabStandardCategory.ConsoleOther, "Apple II");
|
||||
|
||||
// Google
|
||||
caps.Categories.AddCategoryMapping("Android", NewznabStandardCategory.PCMobileAndroid, "Android");
|
||||
|
@ -78,6 +81,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
caps.Categories.AddCategoryMapping("Nintendo GameCube", NewznabStandardCategory.ConsoleOther, "Nintendo GameCube");
|
||||
caps.Categories.AddCategoryMapping("Pokemon Mini", NewznabStandardCategory.ConsoleOther, "Pokemon Mini");
|
||||
caps.Categories.AddCategoryMapping("SNES", NewznabStandardCategory.ConsoleOther, "SNES");
|
||||
caps.Categories.AddCategoryMapping("Switch", NewznabStandardCategory.ConsoleOther, "Switch");
|
||||
caps.Categories.AddCategoryMapping("Virtual Boy", NewznabStandardCategory.ConsoleOther, "Virtual Boy");
|
||||
caps.Categories.AddCategoryMapping("Wii", NewznabStandardCategory.ConsoleWii, "Wii");
|
||||
caps.Categories.AddCategoryMapping("Wii U", NewznabStandardCategory.ConsoleWiiU, "Wii U");
|
||||
|
@ -178,31 +182,62 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
caps.Categories.AddCategoryMapping("Retro - Other", NewznabStandardCategory.ConsoleOther, "Retro - Other");
|
||||
|
||||
// special categories (real categories/not platforms)
|
||||
caps.Categories.AddCategoryMapping("OST", NewznabStandardCategory.AudioOther, "OST");
|
||||
caps.Categories.AddCategoryMapping("Applications", NewznabStandardCategory.PC0day, "Applications");
|
||||
caps.Categories.AddCategoryMapping("E-Books", NewznabStandardCategory.BooksEBook, "E-Books");
|
||||
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.PCGames, "Games");
|
||||
caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.PC0day, "Applications");
|
||||
caps.Categories.AddCategoryMapping(3, NewznabStandardCategory.BooksEBook, "E-Books");
|
||||
caps.Categories.AddCategoryMapping(4, NewznabStandardCategory.AudioOther, "OST");
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
protected override async Task Test(List<ValidationFailure> failures)
|
||||
{
|
||||
((GazelleGamesRequestGenerator)GetRequestGenerator()).FetchPasskey();
|
||||
await base.Test(failures);
|
||||
await FetchPasskey().ConfigureAwait(false);
|
||||
|
||||
await base.Test(failures).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task FetchPasskey()
|
||||
{
|
||||
var request = new HttpRequestBuilder($"{Settings.BaseUrl.Trim().TrimEnd('/')}/api.php")
|
||||
.Accept(HttpAccept.Json)
|
||||
.SetHeader("X-API-Key", Settings.Apikey)
|
||||
.AddQueryParam("request", "quick_user")
|
||||
.Build();
|
||||
|
||||
var indexResponse = await _httpClient.ExecuteAsync(request).ConfigureAwait(false);
|
||||
|
||||
var index = Json.Deserialize<GazelleGamesUserResponse>(indexResponse.Content);
|
||||
|
||||
if (index == null ||
|
||||
string.IsNullOrWhiteSpace(index.Status) ||
|
||||
index.Status != "success" ||
|
||||
string.IsNullOrWhiteSpace(index.Response.PassKey))
|
||||
{
|
||||
throw new IndexerAuthException("Failed to authenticate with GazelleGames.");
|
||||
}
|
||||
|
||||
// Set passkey on settings so it can be used to generate the download URL
|
||||
Settings.Passkey = index.Response.PassKey;
|
||||
}
|
||||
}
|
||||
|
||||
public class GazelleGamesRequestGenerator : IIndexerRequestGenerator
|
||||
{
|
||||
public GazelleGamesSettings Settings { get; set; }
|
||||
public IndexerCapabilities Capabilities { get; set; }
|
||||
public IIndexerHttpClient HttpClient { get; set; }
|
||||
private readonly GazelleGamesSettings _settings;
|
||||
private readonly IndexerCapabilities _capabilities;
|
||||
|
||||
public GazelleGamesRequestGenerator(GazelleGamesSettings settings, IndexerCapabilities capabilities)
|
||||
{
|
||||
_settings = settings;
|
||||
_capabilities = capabilities;
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)));
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria)));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
@ -211,7 +246,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)));
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria)));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
@ -220,7 +255,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)));
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria)));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
@ -229,7 +264,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)));
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria)));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
@ -238,61 +273,72 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)));
|
||||
pageableRequests.Add(GetRequest(GetBasicSearchParameters(searchCriteria.SanitizedSearchTerm, searchCriteria)));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public void FetchPasskey()
|
||||
private IEnumerable<IndexerRequest> GetRequest(List<KeyValuePair<string, string>> parameters)
|
||||
{
|
||||
// GET on index for the passkey
|
||||
var request = RequestBuilder().Resource("api.php?request=quick_user").Build();
|
||||
var indexResponse = HttpClient.Execute(request);
|
||||
var index = Json.Deserialize<GazelleGamesUserResponse>(indexResponse.Content);
|
||||
if (index == null ||
|
||||
string.IsNullOrWhiteSpace(index.Status) ||
|
||||
index.Status != "success" ||
|
||||
string.IsNullOrWhiteSpace(index.Response.PassKey))
|
||||
{
|
||||
throw new Exception("Failed to authenticate with GazelleGames.");
|
||||
}
|
||||
|
||||
// Set passkey on settings so it can be used to generate the download URL
|
||||
Settings.Passkey = index.Response.PassKey;
|
||||
}
|
||||
|
||||
private IEnumerable<IndexerRequest> GetRequest(string parameters)
|
||||
{
|
||||
var req = RequestBuilder()
|
||||
.Resource($"api.php?{parameters}")
|
||||
var request = RequestBuilder()
|
||||
.Resource($"/api.php?{parameters.GetQueryString()}")
|
||||
.Build();
|
||||
|
||||
yield return new IndexerRequest(req);
|
||||
yield return new IndexerRequest(request);
|
||||
}
|
||||
|
||||
private HttpRequestBuilder RequestBuilder()
|
||||
{
|
||||
return new HttpRequestBuilder($"{Settings.BaseUrl.Trim().TrimEnd('/')}")
|
||||
return new HttpRequestBuilder($"{_settings.BaseUrl.Trim().TrimEnd('/')}")
|
||||
.Resource("/api.php")
|
||||
.Accept(HttpAccept.Json)
|
||||
.SetHeader("X-API-Key", Settings.Apikey);
|
||||
.SetHeader("X-API-Key", _settings.Apikey);
|
||||
}
|
||||
|
||||
private string GetBasicSearchParameters(string searchTerm, int[] categories)
|
||||
private List<KeyValuePair<string, string>> GetBasicSearchParameters(string searchTerm, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
var parameters = "request=search&search_type=torrents&empty_groups=filled&order_by=time&order_way=desc";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(searchTerm))
|
||||
var parameters = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
var searchType = Settings.SearchGroupNames ? "groupname" : "searchstr";
|
||||
{ "request", "search" },
|
||||
{ "search_type", "torrents" },
|
||||
{ "empty_groups", "filled" },
|
||||
{ "order_by", "time" },
|
||||
{ "order_way", "desc" }
|
||||
};
|
||||
|
||||
parameters += string.Format("&{1}={0}", searchTerm.Replace(".", " "), searchType);
|
||||
if (searchTerm.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
parameters.Add(
|
||||
_settings.SearchGroupNames ? "groupname" : "searchstr",
|
||||
searchTerm.Replace(".", " "));
|
||||
}
|
||||
|
||||
if (categories != null)
|
||||
if (searchCriteria.Categories != null)
|
||||
{
|
||||
foreach (var cat in Capabilities.Categories.MapTorznabCapsToTrackers(categories))
|
||||
var categoryMappings = _capabilities.Categories
|
||||
.MapTorznabCapsToTrackers(searchCriteria.Categories)
|
||||
.Distinct()
|
||||
.Where(x => !x.IsAllDigits())
|
||||
.ToList();
|
||||
|
||||
categoryMappings.ForEach(category => parameters.Add("artistcheck[]", category));
|
||||
}
|
||||
|
||||
if (searchCriteria.MinSize is > 0)
|
||||
{
|
||||
var minSize = searchCriteria.MinSize.Value / 1024L / 1024L;
|
||||
if (minSize > 0)
|
||||
{
|
||||
parameters += string.Format("&artistcheck[]={0}", cat);
|
||||
parameters.Add("sizesmall", minSize.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (searchCriteria.MaxSize is > 0)
|
||||
{
|
||||
var maxSize = searchCriteria.MaxSize.Value / 1024L / 1024L;
|
||||
if (maxSize > 0)
|
||||
{
|
||||
parameters.Add("sizeslarge", maxSize.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,66 +375,63 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
}
|
||||
|
||||
var jsonResponse = new HttpResponse<GazelleGamesResponse>(indexerResponse.HttpResponse);
|
||||
|
||||
if (jsonResponse.Resource.Status != "success" ||
|
||||
string.IsNullOrWhiteSpace(jsonResponse.Resource.Status) ||
|
||||
jsonResponse.Resource.Response == null)
|
||||
jsonResponse.Resource.Response is not JObject response)
|
||||
{
|
||||
return torrentInfos;
|
||||
}
|
||||
|
||||
Dictionary<string, GazelleGamesGroup> response;
|
||||
var groups = response.ToObject<Dictionary<int, GazelleGamesGroup>>(JsonSerializer.Create(Json.GetSerializerSettings()));
|
||||
|
||||
try
|
||||
foreach (var group in groups)
|
||||
{
|
||||
response = ((JObject)jsonResponse.Resource.Response).ToObject<Dictionary<string, GazelleGamesGroup>>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return torrentInfos;
|
||||
}
|
||||
|
||||
foreach (var result in response)
|
||||
{
|
||||
Dictionary<string, GazelleGamesTorrent> torrents;
|
||||
|
||||
try
|
||||
{
|
||||
torrents = ((JObject)result.Value.Torrents).ToObject<Dictionary<string, GazelleGamesTorrent>>();
|
||||
}
|
||||
catch
|
||||
if (group.Value.Torrents is not JObject groupTorrents)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result.Value.Torrents != null)
|
||||
var torrents = groupTorrents
|
||||
.ToObject<Dictionary<int, GazelleGamesTorrent>>(JsonSerializer.Create(Json.GetSerializerSettings()))
|
||||
.Where(t => t.Value.TorrentType != "Link")
|
||||
.ToList();
|
||||
|
||||
var categories = group.Value.Artists
|
||||
.SelectMany(a => _categories.MapTrackerCatDescToNewznab(a.Name))
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
foreach (var torrent in torrents)
|
||||
{
|
||||
var categories = result.Value.Artists.Select(a => a.Name);
|
||||
var torrentId = torrent.Key;
|
||||
var infoUrl = GetInfoUrl(group.Key, torrentId);
|
||||
|
||||
foreach (var torrent in torrents)
|
||||
if (categories.Length == 0)
|
||||
{
|
||||
var id = int.Parse(torrent.Key);
|
||||
|
||||
var infoUrl = GetInfoUrl(result.Key, id);
|
||||
|
||||
var release = new TorrentInfo()
|
||||
{
|
||||
Guid = infoUrl,
|
||||
Title = torrent.Value.ReleaseTitle,
|
||||
Files = torrent.Value.FileCount,
|
||||
Grabs = torrent.Value.Snatched,
|
||||
Size = long.Parse(torrent.Value.Size),
|
||||
DownloadUrl = GetDownloadUrl(id),
|
||||
InfoUrl = infoUrl,
|
||||
Seeders = torrent.Value.Seeders,
|
||||
Categories = _categories.MapTrackerCatDescToNewznab(categories.FirstOrDefault()),
|
||||
Peers = torrent.Value.Leechers + torrent.Value.Seeders,
|
||||
PublishDate = torrent.Value.Time.ToUniversalTime(),
|
||||
DownloadVolumeFactor = torrent.Value.FreeTorrent == GazelleGamesFreeTorrent.FreeLeech || torrent.Value.FreeTorrent == GazelleGamesFreeTorrent.Neutral || torrent.Value.LowSeedFL ? 0 : 1,
|
||||
UploadVolumeFactor = torrent.Value.FreeTorrent == GazelleGamesFreeTorrent.Neutral ? 0 : 1
|
||||
};
|
||||
|
||||
torrentInfos.Add(release);
|
||||
categories = _categories.MapTrackerCatToNewznab(torrent.Value.CategoryId.ToString()).ToArray();
|
||||
}
|
||||
|
||||
var release = new TorrentInfo
|
||||
{
|
||||
Guid = infoUrl,
|
||||
InfoUrl = infoUrl,
|
||||
DownloadUrl = GetDownloadUrl(torrentId),
|
||||
Title = GetTitle(group.Value, torrent.Value),
|
||||
Categories = categories,
|
||||
Files = torrent.Value.FileCount,
|
||||
Size = long.Parse(torrent.Value.Size),
|
||||
Grabs = torrent.Value.Snatched,
|
||||
Seeders = torrent.Value.Seeders,
|
||||
Peers = torrent.Value.Leechers + torrent.Value.Seeders,
|
||||
PublishDate = torrent.Value.Time.ToUniversalTime(),
|
||||
Scene = torrent.Value.Scene == 1,
|
||||
DownloadVolumeFactor = torrent.Value.FreeTorrent is GazelleGamesFreeTorrent.FreeLeech or GazelleGamesFreeTorrent.Neutral || torrent.Value.LowSeedFL ? 0 : 1,
|
||||
UploadVolumeFactor = torrent.Value.FreeTorrent == GazelleGamesFreeTorrent.Neutral ? 0 : 1,
|
||||
MinimumSeedTime = 288000 // Minimum of 3 days and 8 hours (80 hours in total)
|
||||
};
|
||||
|
||||
torrentInfos.Add(release);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,6 +442,44 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
.ToArray();
|
||||
}
|
||||
|
||||
private static string GetTitle(GazelleGamesGroup group, GazelleGamesTorrent torrent)
|
||||
{
|
||||
var title = WebUtility.HtmlDecode(torrent.ReleaseTitle);
|
||||
|
||||
if (group.Year is > 0 && !title.Contains(group.Year.ToString()))
|
||||
{
|
||||
title += $" ({group.Year})";
|
||||
}
|
||||
|
||||
if (torrent.RemasterTitle.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
title += $" [{$"{torrent.RemasterTitle} {torrent.RemasterYear}".Trim()}]";
|
||||
}
|
||||
|
||||
var flags = new List<string>
|
||||
{
|
||||
$"{torrent.Format} {torrent.Encoding}".Trim()
|
||||
};
|
||||
|
||||
if (group.Artists is { Count: > 0 })
|
||||
{
|
||||
flags.AddIfNotNull(group.Artists.Select(a => a.Name).Join(", "));
|
||||
}
|
||||
|
||||
flags.AddIfNotNull(torrent.Language);
|
||||
flags.AddIfNotNull(torrent.Region);
|
||||
flags.AddIfNotNull(torrent.Miscellaneous);
|
||||
|
||||
flags = flags.Where(x => x.IsNotNullOrWhiteSpace()).ToList();
|
||||
|
||||
if (flags.Any())
|
||||
{
|
||||
title += $" [{string.Join(" / ", flags)}]";
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
private string GetDownloadUrl(int torrentId)
|
||||
{
|
||||
// AuthKey is required but not checked, just pass in a dummy variable
|
||||
|
@ -413,7 +494,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
return url.FullUri;
|
||||
}
|
||||
|
||||
private string GetInfoUrl(string groupId, int torrentId)
|
||||
private string GetInfoUrl(int groupId, int torrentId)
|
||||
{
|
||||
var url = new HttpUri(_settings.BaseUrl)
|
||||
.CombinePath("/torrents.php")
|
||||
|
@ -444,7 +525,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
Passkey = "";
|
||||
}
|
||||
|
||||
[FieldDefinition(2, Label = "API Key", HelpText = "API Key from the Site (Found in Settings => Access Settings), Must have User Permissions", Privacy = PrivacyLevel.ApiKey)]
|
||||
[FieldDefinition(2, Label = "API Key", HelpText = "API Key from the Site (Found in Settings => Access Settings)", HelpTextWarning = "Must have User and Torrents permissions", Privacy = PrivacyLevel.ApiKey)]
|
||||
public string Apikey { get; set; }
|
||||
|
||||
[FieldDefinition(3, Label = "Search Group Names", Type = FieldType.Checkbox, HelpText = "Search Group Names Only")]
|
||||
|
@ -466,8 +547,9 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
|
||||
public class GazelleGamesGroup
|
||||
{
|
||||
public List<GazelleGamesArtist> Artists { get; set; }
|
||||
public ReadOnlyCollection<GazelleGamesArtist> Artists { get; set; }
|
||||
public object Torrents { get; set; }
|
||||
public int? Year { get; set; }
|
||||
}
|
||||
|
||||
public class GazelleGamesArtist
|
||||
|
@ -478,13 +560,23 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
|
||||
public class GazelleGamesTorrent
|
||||
{
|
||||
public int CategoryId { get; set; }
|
||||
public string Format { get; set; }
|
||||
public string Encoding { get; set; }
|
||||
public string Language { get; set; }
|
||||
public string Region { get; set; }
|
||||
public string RemasterYear { get; set; }
|
||||
public string RemasterTitle { get; set; }
|
||||
public string ReleaseTitle { get; set; }
|
||||
public string Miscellaneous { get; set; }
|
||||
public int Scene { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
public string TorrentType { get; set; }
|
||||
public int FileCount { get; set; }
|
||||
public string Size { get; set; }
|
||||
public int? Snatched { get; set; }
|
||||
public int Seeders { get; set; }
|
||||
public int Leechers { get; set; }
|
||||
public string ReleaseTitle { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
public int FileCount { get; set; }
|
||||
public GazelleGamesFreeTorrent FreeTorrent { get; set; }
|
||||
public bool PersonalFL { get; set; }
|
||||
public bool LowSeedFL { get; set; }
|
||||
|
@ -503,9 +595,9 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||
|
||||
public enum GazelleGamesFreeTorrent
|
||||
{
|
||||
Normal,
|
||||
FreeLeech,
|
||||
Neutral,
|
||||
Either
|
||||
Normal = 0,
|
||||
FreeLeech = 1,
|
||||
Neutral = 2,
|
||||
Either = 3
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue