mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
New: (Myanonamouse) Prevent downloads without FL tokens
Co-authored-by: Kalon Shannon-Innes <mav@hotmail.com.au>
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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; }
|
||||||
|
Reference in New Issue
Block a user