mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
New: Support Indexer Grab Redirects
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,6 +12,7 @@ src/**/[Oo]bj/
|
|||||||
*.sln.docstates
|
*.sln.docstates
|
||||||
.vs/
|
.vs/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
# Build results
|
# Build results
|
||||||
*_i.c
|
*_i.c
|
||||||
|
@@ -63,6 +63,7 @@ class IndexerIndexRow extends Component {
|
|||||||
name,
|
name,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
enable,
|
enable,
|
||||||
|
redirect,
|
||||||
tags,
|
tags,
|
||||||
protocol,
|
protocol,
|
||||||
privacy,
|
privacy,
|
||||||
@@ -114,6 +115,7 @@ class IndexerIndexRow extends Component {
|
|||||||
key={column.name}
|
key={column.name}
|
||||||
className={styles[column.name]}
|
className={styles[column.name]}
|
||||||
enabled={enable}
|
enabled={enable}
|
||||||
|
redirect={redirect}
|
||||||
status={status}
|
status={status}
|
||||||
longDateFormat={longDateFormat}
|
longDateFormat={longDateFormat}
|
||||||
timeFormat={timeFormat}
|
timeFormat={timeFormat}
|
||||||
@@ -258,6 +260,7 @@ IndexerIndexRow.propTypes = {
|
|||||||
priority: PropTypes.number.isRequired,
|
priority: PropTypes.number.isRequired,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
enable: PropTypes.bool.isRequired,
|
enable: PropTypes.bool.isRequired,
|
||||||
|
redirect: PropTypes.bool.isRequired,
|
||||||
status: PropTypes.object,
|
status: PropTypes.object,
|
||||||
capabilities: PropTypes.object.isRequired,
|
capabilities: PropTypes.object.isRequired,
|
||||||
added: PropTypes.string.isRequired,
|
added: PropTypes.string.isRequired,
|
||||||
|
@@ -10,6 +10,7 @@ function IndexerStatusCell(props) {
|
|||||||
const {
|
const {
|
||||||
className,
|
className,
|
||||||
enabled,
|
enabled,
|
||||||
|
redirect,
|
||||||
status,
|
status,
|
||||||
longDateFormat,
|
longDateFormat,
|
||||||
timeFormat,
|
timeFormat,
|
||||||
@@ -17,6 +18,9 @@ function IndexerStatusCell(props) {
|
|||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const enableKind = redirect ? kinds.WARNING : kinds.SUCCESS;
|
||||||
|
const enableTitle = redirect ? 'Indexer is Enabled, Redirect is Enabled' : 'Indexer is Enabled';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Component
|
<Component
|
||||||
className={className}
|
className={className}
|
||||||
@@ -25,9 +29,9 @@ function IndexerStatusCell(props) {
|
|||||||
{
|
{
|
||||||
<Icon
|
<Icon
|
||||||
className={styles.statusIcon}
|
className={styles.statusIcon}
|
||||||
kind={enabled ? kinds.SUCCESS : kinds.DEFAULT}
|
kind={enabled ? enableKind : kinds.DEFAULT}
|
||||||
name={enabled ? icons.CHECK : icons.BLACKLIST}
|
name={enabled ? icons.CHECK : icons.BLACKLIST}
|
||||||
title={enabled ? 'Indexer is Enabled' : 'Indexer is Disabled'}
|
title={enabled ? enableTitle : 'Indexer is Disabled'}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -46,6 +50,7 @@ function IndexerStatusCell(props) {
|
|||||||
IndexerStatusCell.propTypes = {
|
IndexerStatusCell.propTypes = {
|
||||||
className: PropTypes.string.isRequired,
|
className: PropTypes.string.isRequired,
|
||||||
enabled: PropTypes.bool.isRequired,
|
enabled: PropTypes.bool.isRequired,
|
||||||
|
redirect: PropTypes.bool.isRequired,
|
||||||
status: PropTypes.object,
|
status: PropTypes.object,
|
||||||
longDateFormat: PropTypes.string.isRequired,
|
longDateFormat: PropTypes.string.isRequired,
|
||||||
timeFormat: PropTypes.string.isRequired,
|
timeFormat: PropTypes.string.isRequired,
|
||||||
|
@@ -39,7 +39,9 @@ function EditIndexerModalContent(props) {
|
|||||||
implementationName,
|
implementationName,
|
||||||
name,
|
name,
|
||||||
enable,
|
enable,
|
||||||
|
redirect,
|
||||||
supportsRss,
|
supportsRss,
|
||||||
|
supportsRedirect,
|
||||||
fields,
|
fields,
|
||||||
priority
|
priority
|
||||||
} = item;
|
} = item;
|
||||||
@@ -90,6 +92,19 @@ function EditIndexerModalContent(props) {
|
|||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('Redirect')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="redirect"
|
||||||
|
helpText={'Redirect incoming download requests for indexer instead of Proxying using Prowlarr'}
|
||||||
|
isDisabled={!supportsRedirect.value}
|
||||||
|
{...redirect}
|
||||||
|
onChange={onInputChange}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
{
|
{
|
||||||
fields.map((field) => {
|
fields.map((field) => {
|
||||||
return (
|
return (
|
||||||
|
30
src/NzbDrone.Core/Datastore/Migration/003_indexer_props.cs
Normal file
30
src/NzbDrone.Core/Datastore/Migration/003_indexer_props.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(3)]
|
||||||
|
public class IndexerProps : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("Indexers")
|
||||||
|
.AddColumn("Redirect").AsBoolean().NotNullable().WithDefaultValue(false);
|
||||||
|
|
||||||
|
Create.TableForModel("DownloadClients")
|
||||||
|
.WithColumn("Enable").AsBoolean().NotNullable()
|
||||||
|
.WithColumn("Name").AsString().NotNullable()
|
||||||
|
.WithColumn("Implementation").AsString().NotNullable()
|
||||||
|
.WithColumn("Settings").AsString().NotNullable()
|
||||||
|
.WithColumn("ConfigContract").AsString().NotNullable()
|
||||||
|
.WithColumn("Priority").AsInt32().WithDefaultValue(1);
|
||||||
|
|
||||||
|
Create.TableForModel("DownloadClientStatus")
|
||||||
|
.WithColumn("ProviderId").AsInt32().NotNullable().Unique()
|
||||||
|
.WithColumn("InitialFailure").AsDateTime().Nullable()
|
||||||
|
.WithColumn("MostRecentFailure").AsDateTime().Nullable()
|
||||||
|
.WithColumn("EscalationLevel").AsInt32().NotNullable()
|
||||||
|
.WithColumn("DisabledTill").AsDateTime().Nullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -45,6 +45,7 @@ namespace NzbDrone.Core.Datastore
|
|||||||
.Ignore(i => i.Privacy)
|
.Ignore(i => i.Privacy)
|
||||||
.Ignore(i => i.SupportsRss)
|
.Ignore(i => i.SupportsRss)
|
||||||
.Ignore(i => i.SupportsSearch)
|
.Ignore(i => i.SupportsSearch)
|
||||||
|
.Ignore(i => i.SupportsRedirect)
|
||||||
.Ignore(i => i.Capabilities)
|
.Ignore(i => i.Capabilities)
|
||||||
.Ignore(d => d.Tags);
|
.Ignore(d => d.Tags);
|
||||||
|
|
||||||
|
@@ -112,6 +112,8 @@ namespace NzbDrone.Core.History
|
|||||||
|
|
||||||
history.Data.Add("Successful", message.Successful.ToString());
|
history.Data.Add("Successful", message.Successful.ToString());
|
||||||
history.Data.Add("Source", message.Source ?? string.Empty);
|
history.Data.Add("Source", message.Source ?? string.Empty);
|
||||||
|
history.Data.Add("GrabMethod", message.Redirect ? "Proxy" : "Redirect");
|
||||||
|
history.Data.Add("Title", message.Title);
|
||||||
|
|
||||||
_historyRepository.Insert(history);
|
_historyRepository.Insert(history);
|
||||||
}
|
}
|
||||||
|
@@ -78,6 +78,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
Privacy = definition.Type == "private" ? IndexerPrivacy.Private : IndexerPrivacy.Public,
|
Privacy = definition.Type == "private" ? IndexerPrivacy.Private : IndexerPrivacy.Public,
|
||||||
SupportsRss = SupportsRss,
|
SupportsRss = SupportsRss,
|
||||||
SupportsSearch = SupportsSearch,
|
SupportsSearch = SupportsSearch,
|
||||||
|
SupportsRedirect = SupportsRedirect,
|
||||||
Capabilities = new IndexerCapabilities(),
|
Capabilities = new IndexerCapabilities(),
|
||||||
ExtraFields = settings
|
ExtraFields = settings
|
||||||
};
|
};
|
||||||
|
@@ -223,7 +223,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
|
|
||||||
if (setting.Type != "password")
|
if (setting.Type != "password")
|
||||||
{
|
{
|
||||||
_logger.Debug($"{name} got value {value.ToJson()}");
|
_logger.Trace($"{name} got value {value.ToJson()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting.Type == "text" || setting.Type == "password")
|
if (setting.Type == "text" || setting.Type == "password")
|
||||||
@@ -236,7 +236,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
}
|
}
|
||||||
else if (setting.Type == "select")
|
else if (setting.Type == "select")
|
||||||
{
|
{
|
||||||
_logger.Debug($"Setting options: {setting.Options.ToJson()}");
|
_logger.Trace($"Setting options: {setting.Options.ToJson()}");
|
||||||
var sorted = setting.Options.OrderBy(x => x.Key).ToList();
|
var sorted = setting.Options.OrderBy(x => x.Key).ToList();
|
||||||
var selected = sorted[(int)(long)value];
|
var selected = sorted[(int)(long)value];
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
public override string Name => "Newznab";
|
public override string Name => "Newznab";
|
||||||
public override string BaseUrl => GetBaseUrlFromSettings();
|
public override string BaseUrl => GetBaseUrlFromSettings();
|
||||||
public override bool FollowRedirect => true;
|
public override bool FollowRedirect => true;
|
||||||
|
public override bool SupportsRedirect => true;
|
||||||
|
|
||||||
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
|
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
|
||||||
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
|
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
|
||||||
@@ -113,6 +114,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
Privacy = IndexerPrivacy.Private,
|
Privacy = IndexerPrivacy.Private,
|
||||||
SupportsRss = SupportsRss,
|
SupportsRss = SupportsRss,
|
||||||
SupportsSearch = SupportsSearch,
|
SupportsSearch = SupportsSearch,
|
||||||
|
SupportsRedirect = SupportsRedirect,
|
||||||
Capabilities = Capabilities
|
Capabilities = Capabilities
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,8 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
|
|||||||
Settings = settings,
|
Settings = settings,
|
||||||
Protocol = DownloadProtocol.Torrent,
|
Protocol = DownloadProtocol.Torrent,
|
||||||
SupportsRss = SupportsRss,
|
SupportsRss = SupportsRss,
|
||||||
SupportsSearch = SupportsSearch
|
SupportsSearch = SupportsSearch,
|
||||||
|
SupportsRedirect = SupportsRedirect
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -64,6 +64,7 @@ namespace NzbDrone.Core.Indexers.Torznab
|
|||||||
Protocol = DownloadProtocol.Usenet,
|
Protocol = DownloadProtocol.Usenet,
|
||||||
SupportsRss = SupportsRss,
|
SupportsRss = SupportsRss,
|
||||||
SupportsSearch = SupportsSearch,
|
SupportsSearch = SupportsSearch,
|
||||||
|
SupportsRedirect = SupportsRedirect,
|
||||||
Capabilities = new IndexerCapabilities()
|
Capabilities = new IndexerCapabilities()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,8 @@ namespace NzbDrone.Core.Indexers
|
|||||||
{
|
{
|
||||||
public interface IDownloadService
|
public interface IDownloadService
|
||||||
{
|
{
|
||||||
byte[] DownloadReport(string link, int indexerId, string source);
|
byte[] DownloadReport(string link, int indexerId, string source, string title);
|
||||||
|
void RecordRedirect(string link, int indexerId, string source, string title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DownloadService : IDownloadService
|
public class DownloadService : IDownloadService
|
||||||
@@ -36,7 +37,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] DownloadReport(string link, int indexerId, string source)
|
public byte[] DownloadReport(string link, int indexerId, string source, string title)
|
||||||
{
|
{
|
||||||
var url = new HttpUri(link);
|
var url = new HttpUri(link);
|
||||||
|
|
||||||
@@ -59,7 +60,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
catch (ReleaseUnavailableException)
|
catch (ReleaseUnavailableException)
|
||||||
{
|
{
|
||||||
_logger.Trace("Release {0} no longer available on indexer.", link);
|
_logger.Trace("Release {0} no longer available on indexer.", link);
|
||||||
_eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success, source));
|
_eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success, source, title));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (ReleaseDownloadException ex)
|
catch (ReleaseDownloadException ex)
|
||||||
@@ -74,12 +75,17 @@ namespace NzbDrone.Core.Indexers
|
|||||||
_indexerStatusService.RecordFailure(indexerId);
|
_indexerStatusService.RecordFailure(indexerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success, source));
|
_eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success, source, title));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success, source));
|
_eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success, source, title));
|
||||||
return downloadedBytes;
|
return downloadedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RecordRedirect(string link, int indexerId, string source, string title)
|
||||||
|
{
|
||||||
|
_eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, true, source, title, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,12 +7,16 @@ namespace NzbDrone.Core.Indexers.Events
|
|||||||
public int IndexerId { get; set; }
|
public int IndexerId { get; set; }
|
||||||
public bool Successful { get; set; }
|
public bool Successful { get; set; }
|
||||||
public string Source { get; set; }
|
public string Source { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public bool Redirect { get; set; }
|
||||||
|
|
||||||
public IndexerDownloadEvent(int indexerId, bool successful, string source)
|
public IndexerDownloadEvent(int indexerId, bool successful, string source, string title, bool redirect = false)
|
||||||
{
|
{
|
||||||
IndexerId = indexerId;
|
IndexerId = indexerId;
|
||||||
Successful = successful;
|
Successful = successful;
|
||||||
Source = source;
|
Source = source;
|
||||||
|
Title = title;
|
||||||
|
Redirect = redirect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
|
|
||||||
public override bool SupportsRss => true;
|
public override bool SupportsRss => true;
|
||||||
public override bool SupportsSearch => true;
|
public override bool SupportsSearch => true;
|
||||||
|
public override bool SupportsRedirect => false;
|
||||||
|
|
||||||
public override bool FollowRedirect => false;
|
public override bool FollowRedirect => false;
|
||||||
public override IndexerCapabilities Capabilities { get; protected set; }
|
public override IndexerCapabilities Capabilities { get; protected set; }
|
||||||
|
@@ -8,6 +8,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
{
|
{
|
||||||
bool SupportsRss { get; }
|
bool SupportsRss { get; }
|
||||||
bool SupportsSearch { get; }
|
bool SupportsSearch { get; }
|
||||||
|
bool SupportsRedirect { get; }
|
||||||
IndexerCapabilities Capabilities { get; }
|
IndexerCapabilities Capabilities { get; }
|
||||||
|
|
||||||
string BaseUrl { get; }
|
string BaseUrl { get; }
|
||||||
|
@@ -25,9 +25,11 @@ namespace NzbDrone.Core.Indexers
|
|||||||
public abstract DownloadProtocol Protocol { get; }
|
public abstract DownloadProtocol Protocol { get; }
|
||||||
public abstract IndexerPrivacy Privacy { get; }
|
public abstract IndexerPrivacy Privacy { get; }
|
||||||
public int Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
|
public bool Redirect { get; set; }
|
||||||
|
|
||||||
public abstract bool SupportsRss { get; }
|
public abstract bool SupportsRss { get; }
|
||||||
public abstract bool SupportsSearch { get; }
|
public abstract bool SupportsSearch { get; }
|
||||||
|
public abstract bool SupportsRedirect { get; }
|
||||||
public abstract IndexerCapabilities Capabilities { get; protected set; }
|
public abstract IndexerCapabilities Capabilities { get; protected set; }
|
||||||
|
|
||||||
public IndexerBase(IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
|
public IndexerBase(IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
|
||||||
|
@@ -12,8 +12,10 @@ namespace NzbDrone.Core.Indexers
|
|||||||
public IndexerPrivacy Privacy { get; set; }
|
public IndexerPrivacy Privacy { get; set; }
|
||||||
public bool SupportsRss { get; set; }
|
public bool SupportsRss { get; set; }
|
||||||
public bool SupportsSearch { get; set; }
|
public bool SupportsSearch { get; set; }
|
||||||
|
public bool SupportsRedirect { get; set; }
|
||||||
public IndexerCapabilities Capabilities { get; set; }
|
public IndexerCapabilities Capabilities { get; set; }
|
||||||
public int Priority { get; set; } = 25;
|
public int Priority { get; set; } = 25;
|
||||||
|
public bool Redirect { get; set; }
|
||||||
public DateTime Added { get; set; }
|
public DateTime Added { get; set; }
|
||||||
|
|
||||||
public IndexerStatus Status { get; set; }
|
public IndexerStatus Status { get; set; }
|
||||||
|
@@ -156,6 +156,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
definition.Protocol = provider.Protocol;
|
definition.Protocol = provider.Protocol;
|
||||||
definition.SupportsRss = provider.SupportsRss;
|
definition.SupportsRss = provider.SupportsRss;
|
||||||
definition.SupportsSearch = provider.SupportsSearch;
|
definition.SupportsSearch = provider.SupportsSearch;
|
||||||
|
definition.SupportsRedirect = provider.SupportsRedirect;
|
||||||
|
|
||||||
//We want to use the definition Caps and Privacy for Cardigann instead of the provider.
|
//We want to use the definition Caps and Privacy for Cardigann instead of the provider.
|
||||||
if (definition.Implementation != typeof(Cardigann.Cardigann).Name)
|
if (definition.Implementation != typeof(Cardigann.Cardigann).Name)
|
||||||
|
@@ -4,6 +4,7 @@ using System.Net;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.ModelBinding;
|
using Nancy.ModelBinding;
|
||||||
|
using Nancy.Responses;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.IndexerSearch;
|
using NzbDrone.Core.IndexerSearch;
|
||||||
@@ -107,17 +108,26 @@ namespace Prowlarr.Api.V1.Indexers
|
|||||||
throw new BadRequestException("Invalid Prowlarr link");
|
throw new BadRequestException("Invalid Prowlarr link");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file = WebUtility.UrlDecode(file);
|
||||||
|
|
||||||
if (indexer == null)
|
if (indexer == null)
|
||||||
{
|
{
|
||||||
throw new NotFoundException("Indexer Not Found");
|
throw new NotFoundException("Indexer Not Found");
|
||||||
}
|
}
|
||||||
|
|
||||||
var indexerInstance = _indexerFactory.GetInstance(indexer);
|
|
||||||
|
|
||||||
var source = UserAgentParser.ParseSource(Request.Headers.UserAgent);
|
var source = UserAgentParser.ParseSource(Request.Headers.UserAgent);
|
||||||
|
|
||||||
|
var unprotectedlLink = _downloadMappingService.ConvertToNormalLink((string)link.Value);
|
||||||
|
|
||||||
|
// If Indexer is set to download via Redirect then just redirect to the link
|
||||||
|
if (indexer.SupportsRedirect && indexer.Redirect)
|
||||||
|
{
|
||||||
|
_downloadService.RecordRedirect(unprotectedlLink, id, source, file);
|
||||||
|
return Response.AsRedirect(unprotectedlLink, RedirectResponse.RedirectType.Temporary);
|
||||||
|
}
|
||||||
|
|
||||||
var downloadBytes = Array.Empty<byte>();
|
var downloadBytes = Array.Empty<byte>();
|
||||||
downloadBytes = _downloadService.DownloadReport(_downloadMappingService.ConvertToNormalLink(link), id, source);
|
downloadBytes = _downloadService.DownloadReport(unprotectedlLink, id, source, file);
|
||||||
|
|
||||||
// handle magnet URLs
|
// handle magnet URLs
|
||||||
if (downloadBytes.Length >= 7
|
if (downloadBytes.Length >= 7
|
||||||
@@ -130,7 +140,7 @@ namespace Prowlarr.Api.V1.Indexers
|
|||||||
&& downloadBytes[6] == 0x3a)
|
&& downloadBytes[6] == 0x3a)
|
||||||
{
|
{
|
||||||
var magnetUrl = Encoding.UTF8.GetString(downloadBytes);
|
var magnetUrl = Encoding.UTF8.GetString(downloadBytes);
|
||||||
return Response.AsRedirect(magnetUrl);
|
return Response.AsRedirect(magnetUrl, RedirectResponse.RedirectType.Temporary);
|
||||||
}
|
}
|
||||||
|
|
||||||
var contentType = indexer.Protocol == DownloadProtocol.Torrent ? "application/x-bittorrent" : "application/x-nzb";
|
var contentType = indexer.Protocol == DownloadProtocol.Torrent ? "application/x-bittorrent" : "application/x-nzb";
|
||||||
|
@@ -14,8 +14,10 @@ namespace Prowlarr.Api.V1.Indexers
|
|||||||
{
|
{
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
public bool Enable { get; set; }
|
public bool Enable { get; set; }
|
||||||
|
public bool Redirect { get; set; }
|
||||||
public bool SupportsRss { get; set; }
|
public bool SupportsRss { get; set; }
|
||||||
public bool SupportsSearch { get; set; }
|
public bool SupportsSearch { get; set; }
|
||||||
|
public bool SupportsRedirect { get; set; }
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
public IndexerPrivacy Privacy { get; set; }
|
public IndexerPrivacy Privacy { get; set; }
|
||||||
public IndexerCapabilityResource Capabilities { get; set; }
|
public IndexerCapabilityResource Capabilities { get; set; }
|
||||||
@@ -61,8 +63,10 @@ namespace Prowlarr.Api.V1.Indexers
|
|||||||
|
|
||||||
resource.BaseUrl = definition.BaseUrl;
|
resource.BaseUrl = definition.BaseUrl;
|
||||||
resource.Enable = definition.Enable;
|
resource.Enable = definition.Enable;
|
||||||
|
resource.Redirect = definition.Redirect;
|
||||||
resource.SupportsRss = definition.SupportsRss;
|
resource.SupportsRss = definition.SupportsRss;
|
||||||
resource.SupportsSearch = definition.SupportsSearch;
|
resource.SupportsSearch = definition.SupportsSearch;
|
||||||
|
resource.SupportsRedirect = definition.SupportsRedirect;
|
||||||
resource.Capabilities = definition.Capabilities.ToResource();
|
resource.Capabilities = definition.Capabilities.ToResource();
|
||||||
resource.Protocol = definition.Protocol;
|
resource.Protocol = definition.Protocol;
|
||||||
resource.Privacy = definition.Privacy;
|
resource.Privacy = definition.Privacy;
|
||||||
@@ -100,6 +104,7 @@ namespace Prowlarr.Api.V1.Indexers
|
|||||||
}
|
}
|
||||||
|
|
||||||
definition.Enable = resource.Enable;
|
definition.Enable = resource.Enable;
|
||||||
|
definition.Redirect = resource.Redirect;
|
||||||
definition.BaseUrl = resource.BaseUrl;
|
definition.BaseUrl = resource.BaseUrl;
|
||||||
definition.Priority = resource.Priority;
|
definition.Priority = resource.Priority;
|
||||||
definition.Privacy = resource.Privacy;
|
definition.Privacy = resource.Privacy;
|
||||||
|
Reference in New Issue
Block a user