New: Add aro.lol

pull/1365/head
Bogdan 2 years ago
parent 5f7bc82eb5
commit 077e4727f2

@ -112,9 +112,9 @@ public class AlphaRatioRequestGenerator : GazelleRequestGenerator
public class AlphaRatioSettings : GazelleSettings public class AlphaRatioSettings : GazelleSettings
{ {
[FieldDefinition(5, Label = "Freeleech Only", Type = FieldType.Checkbox, HelpText = "Search freeleech torrents only")] [FieldDefinition(6, Label = "Freeleech Only", Type = FieldType.Checkbox, HelpText = "Search freeleech torrents only")]
public bool FreeleechOnly { get; set; } public bool FreeleechOnly { get; set; }
[FieldDefinition(6, Label = "Exclude Scene", Type = FieldType.Checkbox, HelpText = "Exclude Scene torrents from results")] [FieldDefinition(7, Label = "Exclude Scene", Type = FieldType.Checkbox, HelpText = "Exclude Scene torrents from results")]
public bool ExcludeScene { get; set; } public bool ExcludeScene { get; set; }
} }

@ -0,0 +1,81 @@
using System.Collections.Generic;
using AngleSharp.Html.Parser;
using NLog;
using NzbDrone.Common.Http;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Indexers.Definitions.Gazelle;
using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.Indexers.Definitions;
public class AroLol : GazelleBase<AroLolSettings>
{
public override string Name => "aro.lol";
public override string[] IndexerUrls => new[] { "https://aro.lol/" };
public override string Description => "aro.lol is a SERBIAN/ENGLISH Private Torrent Tracker for ANIME";
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
public AroLol(IIndexerHttpClient httpClient,
IEventAggregator eventAggregator,
IIndexerStatusService indexerStatusService,
IConfigService configService,
Logger logger)
: base(httpClient, eventAggregator, indexerStatusService, configService, logger)
{
}
protected override HttpRequestBuilder AuthLoginRequestBuilder()
{
return base.AuthLoginRequestBuilder()
.AddFormParameter("twofa", Settings.TwoFactorAuthCode.Trim());
}
protected override bool CheckForLoginError(HttpResponse response)
{
if (response.Content.Contains("loginform"))
{
var parser = new HtmlParser();
var dom = parser.ParseDocument(response.Content);
var errorMessage = dom.QuerySelector("#loginform > .warning")?.TextContent.Trim();
throw new IndexerAuthException(errorMessage ?? "Unknown error message, please report.");
}
return true;
}
protected override IndexerCapabilities SetCapabilities()
{
var caps = new IndexerCapabilities
{
TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q
},
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q
},
BookSearchParams = new List<BookSearchParam>
{
BookSearchParam.Q
}
};
caps.Categories.AddCategoryMapping("1", NewznabStandardCategory.Movies, "Movies");
caps.Categories.AddCategoryMapping("2", NewznabStandardCategory.TVAnime, "Anime");
caps.Categories.AddCategoryMapping("3", NewznabStandardCategory.Books, "Manga");
caps.Categories.AddCategoryMapping("4", NewznabStandardCategory.Console, "Games");
caps.Categories.AddCategoryMapping("5", NewznabStandardCategory.Other, "Other");
return caps;
}
}
public class AroLolSettings : GazelleSettings
{
[FieldDefinition(4, Label = "2FA code", Type = FieldType.Textbox, HelpText = "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the aro.lol Web Site. Otherwise just leave it empty.")]
public string TwoFactorAuthCode { get; set; }
}

@ -1,4 +1,5 @@
using System; using System;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using NLog; using NLog;
@ -40,12 +41,27 @@ public abstract class GazelleBase<TSettings> : TorrentIndexerBase<TSettings>
protected virtual IndexerCapabilities SetCapabilities() protected virtual IndexerCapabilities SetCapabilities()
{ {
var caps = new IndexerCapabilities(); return new IndexerCapabilities();
return caps;
} }
protected override async Task DoLogin() protected override async Task DoLogin()
{
var cookies = Cookies;
Cookies = null;
var authLoginRequestBuilder = AuthLoginRequestBuilder();
var response = await ExecuteAuth(authLoginRequestBuilder.Build());
CheckForLoginError(response);
cookies = response.GetCookies();
UpdateCookies(cookies, DateTime.Now + TimeSpan.FromDays(30));
_logger.Debug("Gazelle authentication succeeded.");
}
protected virtual HttpRequestBuilder AuthLoginRequestBuilder()
{ {
var requestBuilder = new HttpRequestBuilder(LoginUrl) var requestBuilder = new HttpRequestBuilder(LoginUrl)
{ {
@ -54,26 +70,19 @@ public abstract class GazelleBase<TSettings> : TorrentIndexerBase<TSettings>
}; };
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15); requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
var cookies = Cookies; var authLoginRequestBuilder = requestBuilder
Cookies = null;
var authLoginRequest = requestBuilder
.AddFormParameter("username", Settings.Username) .AddFormParameter("username", Settings.Username)
.AddFormParameter("password", Settings.Password) .AddFormParameter("password", Settings.Password)
.AddFormParameter("keeplogged", "1") .AddFormParameter("keeplogged", "1")
.SetHeader("Content-Type", "application/x-www-form-urlencoded") .SetHeader("Content-Type", "application/x-www-form-urlencoded")
.Accept(HttpAccept.Json) .SetHeader("Referer", LoginUrl)
.Build(); .Accept(HttpAccept.Json);
var response = await ExecuteAuth(authLoginRequest);
cookies = response.GetCookies();
UpdateCookies(cookies, DateTime.Now + TimeSpan.FromDays(30));
_logger.Debug("Gazelle authentication succeeded."); return authLoginRequestBuilder;
} }
protected virtual bool CheckForLoginError(HttpResponse response) => true;
public override async Task<byte[]> Download(Uri link) public override async Task<byte[]> Download(Uri link)
{ {
var response = await base.Download(link); var response = await base.Download(link);
@ -100,6 +109,8 @@ public abstract class GazelleBase<TSettings> : TorrentIndexerBase<TSettings>
protected override bool CheckIfLoginNeeded(HttpResponse response) protected override bool CheckIfLoginNeeded(HttpResponse response)
{ {
return response.HasHttpRedirect || (response.Content != null && response.Content.Contains("\"bad credentials\"")); var invalidResponses = new[] { "\"bad credentials\"", "\"groupName\":\"wrong-creds\"" };
return response.HasHttpRedirect || (response.Content != null && invalidResponses.Any(response.Content.Contains));
} }
} }

@ -15,7 +15,7 @@ public class GazelleSettings : UserPassTorrentBaseSettings
public string AuthKey { get; set; } public string AuthKey { get; set; }
public string PassKey { get; set; } public string PassKey { get; set; }
[FieldDefinition(4, Type = FieldType.Checkbox, Label = "Use Freeleech Token", HelpText = "Use freeleech tokens when available")] [FieldDefinition(5, Type = FieldType.Checkbox, Label = "Use Freeleech Token", HelpText = "Use freeleech tokens when available")]
public bool UseFreeleechToken { get; set; } public bool UseFreeleechToken { get; set; }
public override NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()

@ -217,7 +217,7 @@ public class GreatPosterWallParser : GazelleParser
public class GreatPosterWallSettings : GazelleSettings public class GreatPosterWallSettings : GazelleSettings
{ {
[FieldDefinition(5, Label = "Freeleech Only", Type = FieldType.Checkbox, HelpText = "Search freeleech torrents only")] [FieldDefinition(6, Label = "Freeleech Only", Type = FieldType.Checkbox, HelpText = "Search freeleech torrents only")]
public bool FreeleechOnly { get; set; } public bool FreeleechOnly { get; set; }
} }

Loading…
Cancel
Save