New: (Myanonamouse) Prevent downloads without FL tokens

Co-authored-by: Kalon Shannon-Innes <mav@hotmail.com.au>
This commit is contained in:
Bogdan
2024-09-02 15:21:34 +03:00
parent e6901506a0
commit d1846fde61
2 changed files with 121 additions and 24 deletions

View File

@@ -0,0 +1,60 @@
using System.Collections.Generic;
using System.Data;
using Dapper;
using FluentMigrator;
using Newtonsoft.Json.Linq;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(042)]
public class myanonamouse_freeleech_wedge_options : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Execute.WithConnection(MigrateIndexersToWedgeOptions);
}
private void MigrateIndexersToWedgeOptions(IDbConnection conn, IDbTransaction tran)
{
var updated = new List<object>();
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tran;
cmd.CommandText = "SELECT \"Id\", \"Settings\" FROM \"Indexers\" WHERE \"Implementation\" = 'MyAnonamouse'";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var id = reader.GetInt32(0);
var settings = Json.Deserialize<JObject>(reader.GetString(1));
if (settings.ContainsKey("freeleech") && settings.Value<JToken>("freeleech").Type == JTokenType.Boolean)
{
var optionValue = settings.Value<bool>("freeleech") switch
{
true => 2, // Required
_ => 0 // Never
};
settings.Remove("freeleech");
settings.Add("useFreeleechWedge", optionValue);
}
updated.Add(new
{
Id = id,
Settings = settings.ToJson()
});
}
}
}
var updateSql = "UPDATE \"Indexers\" SET \"Settings\" = @Settings WHERE \"Id\" = @Id";
conn.Execute(updateSql, updated, transaction: tran);
}
}
}

View File

@@ -16,6 +16,7 @@ using NzbDrone.Common.Http;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Exceptions;
using NzbDrone.Core.Indexers.Exceptions; using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.Indexers.Settings; using NzbDrone.Core.Indexers.Settings;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
@@ -36,8 +37,8 @@ namespace NzbDrone.Core.Indexers.Definitions
public override bool SupportsPagination => true; public override bool SupportsPagination => true;
public override int PageSize => 100; public override int PageSize => 100;
public override IndexerCapabilities Capabilities => SetCapabilities(); public override IndexerCapabilities Capabilities => SetCapabilities();
private readonly ICacheManager _cacheManager; private readonly ICacheManager _cacheManager;
private static readonly Regex TorrentIdRegex = new Regex(@"tor/download.php\?tid=(?<id>\d+)$");
public MyAnonamouse(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger, ICacheManager cacheManager) public MyAnonamouse(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger, ICacheManager cacheManager)
: base(httpClient, eventAggregator, indexerStatusService, configService, logger) : base(httpClient, eventAggregator, indexerStatusService, configService, logger)
@@ -59,39 +60,62 @@ namespace NzbDrone.Core.Indexers.Definitions
{ {
var downloadLink = link.RemoveQueryParam("canUseToken"); var downloadLink = link.RemoveQueryParam("canUseToken");
if (Settings.Freeleech && bool.TryParse(link.GetQueryParam("canUseToken"), out var canUseToken) && canUseToken) if (Settings.UseFreeleechWedge is (int)MyAnonamouseFreeleechWedgeAction.Preferred or (int)MyAnonamouseFreeleechWedgeAction.Required &&
bool.TryParse(link.GetQueryParam("canUseToken"), out var canUseToken) && canUseToken)
{ {
_logger.Debug("Attempting to use freeleech token for {0}", downloadLink.AbsoluteUri); _logger.Debug("Attempting to use freeleech wedge for {0}", downloadLink.AbsoluteUri);
var idMatch = TorrentIdRegex.Match(downloadLink.AbsoluteUri); if (int.TryParse(link.GetQueryParam("tid"), out var torrentId) && torrentId > 0)
if (idMatch.Success)
{ {
var id = int.Parse(idMatch.Groups["id"].Value);
var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
var freeleechUrl = Settings.BaseUrl + $"json/bonusBuy.php/{timestamp}"; var freeleechUrl = Settings.BaseUrl + $"json/bonusBuy.php/{timestamp}";
var freeleechRequest = new HttpRequestBuilder(freeleechUrl) var freeleechRequestBuilder = new HttpRequestBuilder(freeleechUrl)
.Accept(HttpAccept.Json)
.AddQueryParam("spendtype", "personalFL") .AddQueryParam("spendtype", "personalFL")
.AddQueryParam("torrentid", id) .AddQueryParam("torrentid", torrentId)
.AddQueryParam("timestamp", timestamp.ToString()) .AddQueryParam("timestamp", timestamp.ToString());
.Build();
var indexerReq = new IndexerRequest(freeleechRequest); freeleechRequestBuilder.LogResponseContent = true;
var response = await FetchIndexerResponse(indexerReq).ConfigureAwait(false);
var resource = Json.Deserialize<MyAnonamouseBuyPersonalFreeleechResponse>(response.Content); var cookies = GetCookies();
if (cookies != null && cookies.Any())
{
freeleechRequestBuilder.SetCookies(Cookies);
}
var freeleechRequest = freeleechRequestBuilder.Build();
var freeleechResponse = await _httpClient.ExecuteProxiedAsync(freeleechRequest, Definition).ConfigureAwait(false);
var resource = Json.Deserialize<MyAnonamouseBuyPersonalFreeleechResponse>(freeleechResponse.Content);
if (resource.Success) if (resource.Success)
{ {
_logger.Debug("Successfully to used freeleech token for torrentid {0}", id); _logger.Debug("Successfully used freeleech wedge for torrentid {0}.", torrentId);
}
else if (resource.Error.IsNotNullOrWhiteSpace() && resource.Error.ContainsIgnoreCase("This is already a personal freeleech"))
{
_logger.Debug("{0} is already a personal freeleech, continuing downloading: {1}", torrentId, resource.Error);
} }
else else
{ {
_logger.Debug("Failed to use freeleech token: {0}", resource.Error); _logger.Warn("Failed to purchase freeleech wedge for {0}: {1}", torrentId, resource.Error);
if (Settings.UseFreeleechWedge == (int)MyAnonamouseFreeleechWedgeAction.Preferred)
{
_logger.Debug("'Use Freeleech Wedge' option set to preferred, continuing downloading: '{0}'", downloadLink.AbsoluteUri);
}
else
{
throw new ReleaseUnavailableException($"Failed to buy freeleech wedge and 'Use Freeleech Wedge' is set to required, aborting download: '{downloadLink.AbsoluteUri}'");
}
} }
} }
else else
{ {
_logger.Debug("Could not get torrent id from link {0}, skipping freeleech", downloadLink.AbsoluteUri); _logger.Warn("Could not get torrent id from link {0}, skipping use of freeleech wedge.", downloadLink.AbsoluteUri);
} }
} }
@@ -535,7 +559,7 @@ namespace NzbDrone.Core.Indexers.Definitions
.CombinePath("/tor/download.php") .CombinePath("/tor/download.php")
.AddQueryParam("tid", torrentId); .AddQueryParam("tid", torrentId);
if (_settings.Freeleech && canUseToken) if (_settings.UseFreeleechWedge is (int)MyAnonamouseFreeleechWedgeAction.Preferred or (int)MyAnonamouseFreeleechWedgeAction.Required && canUseToken)
{ {
url = url.AddQueryParam("canUseToken", "true"); url = url.AddQueryParam("canUseToken", "true");
} }
@@ -592,6 +616,7 @@ namespace NzbDrone.Core.Indexers.Definitions
SearchInSeries = false; SearchInSeries = false;
SearchInFilenames = false; SearchInFilenames = false;
SearchLanguages = Array.Empty<int>(); SearchLanguages = Array.Empty<int>();
UseFreeleechWedge = (int)MyAnonamouseFreeleechWedgeAction.Never;
} }
[FieldDefinition(2, Type = FieldType.Textbox, Label = "Mam Id", HelpText = "Mam Session Id (Created Under Preferences -> Security)")] [FieldDefinition(2, Type = FieldType.Textbox, Label = "Mam Id", HelpText = "Mam Session Id (Created Under Preferences -> Security)")]
@@ -600,21 +625,21 @@ namespace NzbDrone.Core.Indexers.Definitions
[FieldDefinition(3, Type = FieldType.Select, Label = "Search Type", SelectOptions = typeof(MyAnonamouseSearchType), HelpText = "Specify the desired search type")] [FieldDefinition(3, Type = FieldType.Select, Label = "Search Type", SelectOptions = typeof(MyAnonamouseSearchType), HelpText = "Specify the desired search type")]
public int SearchType { get; set; } public int SearchType { get; set; }
[FieldDefinition(4, Type = FieldType.Checkbox, Label = "Use Freeleech Wedges", HelpText = "Use freeleech wedges to make grabbed torrents personal freeleech")] [FieldDefinition(4, Type = FieldType.Checkbox, Label = "Search in description", HelpText = "Search text in the description")]
public bool Freeleech { get; set; }
[FieldDefinition(5, Type = FieldType.Checkbox, Label = "Search in description", HelpText = "Search text in the description")]
public bool SearchInDescription { get; set; } public bool SearchInDescription { get; set; }
[FieldDefinition(6, Type = FieldType.Checkbox, Label = "Search in series", HelpText = "Search text in the series")] [FieldDefinition(5, Type = FieldType.Checkbox, Label = "Search in series", HelpText = "Search text in the series")]
public bool SearchInSeries { get; set; } public bool SearchInSeries { get; set; }
[FieldDefinition(7, Type = FieldType.Checkbox, Label = "Search in filenames", HelpText = "Search text in the filenames")] [FieldDefinition(6, Type = FieldType.Checkbox, Label = "Search in filenames", HelpText = "Search text in the filenames")]
public bool SearchInFilenames { get; set; } public bool SearchInFilenames { get; set; }
[FieldDefinition(8, Type = FieldType.Select, Label = "Search Languages", SelectOptions = typeof(MyAnonamouseSearchLanguages), HelpText = "Specify the desired languages. If unspecified, all options are used.")] [FieldDefinition(7, Type = FieldType.Select, Label = "Search Languages", SelectOptions = typeof(MyAnonamouseSearchLanguages), HelpText = "Specify the desired languages. If unspecified, all options are used.")]
public IEnumerable<int> SearchLanguages { get; set; } public IEnumerable<int> SearchLanguages { get; set; }
[FieldDefinition(8, Type = FieldType.Select, Label = "Use Freeleech Wedges", SelectOptions = typeof(MyAnonamouseFreeleechWedgeAction), HelpText = "Use freeleech wedges to make grabbed torrents personal freeleech")]
public int UseFreeleechWedge { get; set; }
public override NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
@@ -834,6 +859,18 @@ namespace NzbDrone.Core.Indexers.Definitions
Other = 47, Other = 47,
} }
public enum MyAnonamouseFreeleechWedgeAction
{
[FieldOption(Label = "Never", Hint = "Do not buy as freeleech")]
Never = 0,
[FieldOption(Label = "Preferred", Hint = "Buy and use wedge if possible")]
Preferred = 1,
[FieldOption(Label = "Required", Hint = "Abort download if unable to buy wedge")]
Required = 2,
}
public class MyAnonamouseTorrent public class MyAnonamouseTorrent
{ {
public int Id { get; set; } public int Id { get; set; }