mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-10-03 09:09:42 +02:00
@@ -194,5 +194,21 @@ namespace NzbDrone.Common.Extensions
|
|||||||
var inputBytes = encoding.GetBytes(searchString);
|
var inputBytes = encoding.GetBytes(searchString);
|
||||||
return encoding.GetString(WebUtility.UrlDecodeToBytes(inputBytes, 0, inputBytes.Length));
|
return encoding.GetString(WebUtility.UrlDecodeToBytes(inputBytes, 0, inputBytes.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string CleanFileName(this string name)
|
||||||
|
{
|
||||||
|
string result = name;
|
||||||
|
string[] badCharacters = { "\\", "/", "<", ">", "?", "*", ":", "|", "\"" };
|
||||||
|
string[] goodCharacters = { "+", "+", "", "", "!", "-", "-", "", "" };
|
||||||
|
|
||||||
|
result = result.Replace(": ", " - ");
|
||||||
|
|
||||||
|
for (int i = 0; i < badCharacters.Length; i++)
|
||||||
|
{
|
||||||
|
result = result.Replace(badCharacters[i], goodCharacters[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.TrimStart(' ', '.').TrimEnd(' ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
{
|
||||||
|
public class TorrentBlackhole : TorrentClientBase<TorrentBlackholeSettings>
|
||||||
|
{
|
||||||
|
public override bool PreferTorrentFile => true;
|
||||||
|
|
||||||
|
public TorrentBlackhole(ITorrentFileInfoReader torrentFileInfoReader,
|
||||||
|
IHttpClient httpClient,
|
||||||
|
IConfigService configService,
|
||||||
|
IDiskProvider diskProvider,
|
||||||
|
Logger logger)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Blackhole does not support redirected indexers.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink)
|
||||||
|
{
|
||||||
|
if (!Settings.SaveMagnetFiles)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Blackhole does not support magnet links.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var title = release.Title;
|
||||||
|
|
||||||
|
title = title.CleanFileName();
|
||||||
|
|
||||||
|
var filepath = Path.Combine(Settings.TorrentFolder, $"{title}.{Settings.MagnetFileExtension.Trim('.')}");
|
||||||
|
|
||||||
|
var fileContent = Encoding.UTF8.GetBytes(magnetLink);
|
||||||
|
using (var stream = _diskProvider.OpenWriteStream(filepath))
|
||||||
|
{
|
||||||
|
stream.Write(fileContent, 0, fileContent.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("Saving magnet link succeeded, saved to: {0}", filepath);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent)
|
||||||
|
{
|
||||||
|
var title = release.Title;
|
||||||
|
|
||||||
|
title = title.CleanFileName();
|
||||||
|
|
||||||
|
var filepath = Path.Combine(Settings.TorrentFolder, string.Format("{0}.torrent", title));
|
||||||
|
|
||||||
|
using (var stream = _diskProvider.OpenWriteStream(filepath))
|
||||||
|
{
|
||||||
|
stream.Write(fileContent, 0, fileContent.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("Torrent Download succeeded, saved to: {0}", filepath);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name => "Torrent Blackhole";
|
||||||
|
|
||||||
|
protected override void Test(List<ValidationFailure> failures)
|
||||||
|
{
|
||||||
|
failures.AddIfNotNull(TestFolder(Settings.TorrentFolder, "TorrentFolder"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,46 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using FluentValidation;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.Validation;
|
||||||
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
{
|
||||||
|
public class TorrentBlackholeSettingsValidator : AbstractValidator<TorrentBlackholeSettings>
|
||||||
|
{
|
||||||
|
public TorrentBlackholeSettingsValidator()
|
||||||
|
{
|
||||||
|
//Todo: Validate that the path actually exists
|
||||||
|
RuleFor(c => c.TorrentFolder).IsValidPath();
|
||||||
|
RuleFor(c => c.MagnetFileExtension).NotEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TorrentBlackholeSettings : IProviderConfig
|
||||||
|
{
|
||||||
|
public TorrentBlackholeSettings()
|
||||||
|
{
|
||||||
|
MagnetFileExtension = ".magnet";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly TorrentBlackholeSettingsValidator Validator = new TorrentBlackholeSettingsValidator();
|
||||||
|
|
||||||
|
[FieldDefinition(0, Label = "Torrent Folder", Type = FieldType.Path, HelpText = "Folder in which Prowlarr will store the .torrent file")]
|
||||||
|
public string TorrentFolder { get; set; }
|
||||||
|
|
||||||
|
[DefaultValue(false)]
|
||||||
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||||
|
[FieldDefinition(1, Label = "Save Magnet Files", Type = FieldType.Checkbox, HelpText = "Save a .magnet file with the magnet link if no .torrent file is available (only useful if the download client supports .magnet files)")]
|
||||||
|
public bool SaveMagnetFiles { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(2, Label = "Save Magnet Files", Type = FieldType.Textbox, HelpText = "Extension to use for magnet links, defaults to '.magnet'")]
|
||||||
|
public string MagnetFileExtension { get; set; }
|
||||||
|
|
||||||
|
public NzbDroneValidationResult Validate()
|
||||||
|
{
|
||||||
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
{
|
||||||
|
public class UsenetBlackhole : UsenetClientBase<UsenetBlackholeSettings>
|
||||||
|
{
|
||||||
|
public UsenetBlackhole(IHttpClient httpClient,
|
||||||
|
IConfigService configService,
|
||||||
|
IDiskProvider diskProvider,
|
||||||
|
Logger logger)
|
||||||
|
: base(httpClient, configService, diskProvider, logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromLink(ReleaseInfo release)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Blackhole does not support redirected indexers.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromNzbFile(ReleaseInfo release, string filename, byte[] fileContent)
|
||||||
|
{
|
||||||
|
var title = release.Title;
|
||||||
|
|
||||||
|
title = title.CleanFileName();
|
||||||
|
|
||||||
|
var filepath = Path.Combine(Settings.NzbFolder, title + ".nzb");
|
||||||
|
|
||||||
|
using (var stream = _diskProvider.OpenWriteStream(filepath))
|
||||||
|
{
|
||||||
|
stream.Write(fileContent, 0, fileContent.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("NZB Download succeeded, saved to: {0}", filepath);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name => "Usenet Blackhole";
|
||||||
|
|
||||||
|
protected override void Test(List<ValidationFailure> failures)
|
||||||
|
{
|
||||||
|
failures.AddIfNotNull(TestFolder(Settings.NzbFolder, "NzbFolder"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.Validation;
|
||||||
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
{
|
||||||
|
public class UsenetBlackholeSettingsValidator : AbstractValidator<UsenetBlackholeSettings>
|
||||||
|
{
|
||||||
|
public UsenetBlackholeSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.NzbFolder).IsValidPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UsenetBlackholeSettings : IProviderConfig
|
||||||
|
{
|
||||||
|
private static readonly UsenetBlackholeSettingsValidator Validator = new UsenetBlackholeSettingsValidator();
|
||||||
|
|
||||||
|
[FieldDefinition(0, Label = "Nzb Folder", Type = FieldType.Path, HelpText = "Folder in which Prowlarr will store the .nzb file")]
|
||||||
|
public string NzbFolder { get; set; }
|
||||||
|
|
||||||
|
public NzbDroneValidationResult Validate()
|
||||||
|
{
|
||||||
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user