1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-03-05 13:20:20 -05:00

Compare commits

...

10 Commits

Author SHA1 Message Date
Bogdan
70bc26dc19 Disable workflows on forks
ignore-downstream
2024-05-21 17:06:44 -07:00
Bogdan
a2e0002a08 Replace multiple occurrences in branch env variable
ignore-downstream
2024-05-21 17:06:44 -07:00
Bogdan
d7ceb11a64 Fixed: Trimming slashes from UrlBase when using environment variable 2024-05-21 17:06:44 -07:00
Bogdan
cc5b5463f2 Ignore Grabbed with STJson 2024-05-21 17:06:36 -07:00
Bogdan
9b4ff657af Update the wanted section for missing and cutoff unmet 2024-05-21 17:06:36 -07:00
Bogdan
aea50fa47e Bump Npgsql to 7.0.7
ignore-downstream
2024-05-21 17:06:28 -07:00
Mark McDowall
05edd44ed6 New: Include time for episode/season/series history 2024-05-21 17:06:18 -07:00
Bogdan
4440aa3cac New: Root folder exists validation for import lists 2024-05-21 17:06:09 -07:00
Bogdan
084fcc2295 Implement equality checks for providers 2024-05-21 17:05:48 -07:00
Weblate
536ff142c3 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dani Talens <databio@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Ransack6086 <servarr.jubilant150@slmail.me>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Yi Cao <caoyi06@qq.com>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: topnew <sznetim@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-05-21 17:05:34 -07:00
105 changed files with 714 additions and 391 deletions

View File

@@ -48,7 +48,7 @@ jobs:
echo "SDK_PATH=${{ env.DOTNET_ROOT }}/sdk/${DOTNET_VERSION}" >> "$GITHUB_ENV"
echo "SONARR_VERSION=$SONARR_VERSION" >> "$GITHUB_ENV"
echo "BRANCH=${RAW_BRANCH_NAME/\//-}" >> "$GITHUB_ENV"
echo "BRANCH=${RAW_BRANCH_NAME//\//-}" >> "$GITHUB_ENV"
echo "framework=${{ env.FRAMEWORK }}" >> "$GITHUB_OUTPUT"
echo "major_version=${{ env.SONARR_MAJOR_VERSION }}" >> "$GITHUB_OUTPUT"

View File

@@ -8,5 +8,6 @@ jobs:
contents: read
pull-requests: write
runs-on: ubuntu-latest
if: github.repository == 'Sonarr/Sonarr'
steps:
- uses: actions/labeler@v5

View File

@@ -8,6 +8,7 @@ on:
jobs:
lock:
runs-on: ubuntu-latest
if: github.repository == 'Sonarr/Sonarr'
steps:
- uses: dessant/lock-threads@v5
with:

View File

@@ -244,7 +244,7 @@ class SignalRConnector extends Component {
handleWantedCutoff = (body) => {
if (body.action === 'updated') {
this.props.dispatchUpdateItem({
section: 'cutoffUnmet',
section: 'wanted.cutoffUnmet',
updateOnly: true,
...body.resource
});
@@ -254,7 +254,7 @@ class SignalRConnector extends Component {
handleWantedMissing = (body) => {
if (body.action === 'updated') {
this.props.dispatchUpdateItem({
section: 'missing',
section: 'wanted.missing',
updateOnly: true,
...body.resource
});

View File

@@ -15,6 +15,7 @@ class RelativeDateCell extends PureComponent {
className,
date,
includeSeconds,
includeTime,
showRelativeDates,
shortDateFormat,
longDateFormat,
@@ -39,7 +40,7 @@ class RelativeDateCell extends PureComponent {
title={formatDateTime(date, longDateFormat, timeFormat, { includeSeconds, includeRelativeDay: !showRelativeDates })}
{...otherProps}
>
{getRelativeDate(date, shortDateFormat, showRelativeDates, { timeFormat, includeSeconds, timeForToday: true })}
{getRelativeDate(date, shortDateFormat, showRelativeDates, { timeFormat, includeSeconds, includeTime, timeForToday: true })}
</Component>
);
}
@@ -49,6 +50,7 @@ RelativeDateCell.propTypes = {
className: PropTypes.string.isRequired,
date: PropTypes.string,
includeSeconds: PropTypes.bool.isRequired,
includeTime: PropTypes.bool.isRequired,
showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired,
longDateFormat: PropTypes.string.isRequired,
@@ -60,6 +62,7 @@ RelativeDateCell.propTypes = {
RelativeDateCell.defaultProps = {
className: styles.cell,
includeSeconds: false,
includeTime: false,
component: TableRowCell
};

View File

@@ -111,6 +111,8 @@ class EpisodeHistoryRow extends Component {
<RelativeDateCellConnector
date={date}
includeSeconds={true}
includeTime={true}
/>
<TableRowCell className={styles.actions}>

View File

@@ -14,7 +14,7 @@ function SeriesHistoryModal(props) {
return (
<Modal
isOpen={isOpen}
size={sizes.EXTRA_LARGE}
size={sizes.EXTRA_EXTRA_LARGE}
onModalClose={onModalClose}
>
<SeriesHistoryModalContentConnector

View File

@@ -135,6 +135,8 @@ class SeriesHistoryRow extends Component {
<RelativeDateCellConnector
date={date}
includeSeconds={true}
includeTime={true}
/>
<TableRowCell className={styles.actions}>

View File

@@ -5,16 +5,18 @@ import isToday from 'Utilities/Date/isToday';
import isTomorrow from 'Utilities/Date/isTomorrow';
import isYesterday from 'Utilities/Date/isYesterday';
import translate from 'Utilities/String/translate';
import formatDateTime from './formatDateTime';
function getRelativeDate(date, shortDateFormat, showRelativeDates, { timeFormat, includeSeconds = false, timeForToday = false } = {}) {
function getRelativeDate(date, shortDateFormat, showRelativeDates, { timeFormat, includeSeconds = false, timeForToday = false, includeTime = false } = {}) {
if (!date) {
return null;
}
const isTodayDate = isToday(date);
const time = formatTime(date, timeFormat, { includeMinuteZero: true, includeSeconds });
if (isTodayDate && timeForToday && timeFormat) {
return formatTime(date, timeFormat, { includeMinuteZero: true, includeSeconds });
return time;
}
if (!showRelativeDates) {
@@ -22,22 +24,26 @@ function getRelativeDate(date, shortDateFormat, showRelativeDates, { timeFormat,
}
if (isYesterday(date)) {
return translate('Yesterday');
return includeTime ? translate('YesterdayAt', { time } ): translate('Yesterday');
}
if (isTodayDate) {
return translate('Today');
return includeTime ? translate('TodayAt', { time } ): translate('Today');
}
if (isTomorrow(date)) {
return translate('Tomorrow');
return includeTime ? translate('TomorrowAt', { time } ): translate('Tomorrow');
}
if (isInNextWeek(date)) {
return moment(date).format('dddd');
const day = moment(date).format('dddd');
return includeTime ? translate('DayOfWeekAt', { day, time }) : day;
}
return moment(date).format(shortDateFormat);
return includeTime ?
formatDateTime(date, shortDateFormat, timeFormat, { includeSeconds }) :
moment(date).format(shortDateFormat);
}
export default getRelativeDate;

View File

@@ -5,7 +5,6 @@ using FluentValidation.Results;
using NUnit.Framework;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Notifications;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Validation;
using NzbDrone.Test.Common;
@@ -15,9 +14,9 @@ namespace NzbDrone.Core.Test.NotificationTests
[TestFixture]
public class NotificationBaseFixture : TestBase
{
private class TestSetting : IProviderConfig
private class TestSetting : NotificationSettingsBase<TestSetting>
{
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult();
}

View File

@@ -242,7 +242,7 @@ namespace NzbDrone.Core.Configuration
{
get
{
var urlBase = _serverOptions.UrlBase ?? GetValue("UrlBase", "").Trim('/');
var urlBase = (_serverOptions.UrlBase ?? GetValue("UrlBase", "")).Trim('/');
if (urlBase.IsNullOrWhiteSpace())
{

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Aria2
@@ -13,9 +12,9 @@ namespace NzbDrone.Core.Download.Clients.Aria2
}
}
public class Aria2Settings : IProviderConfig
public class Aria2Settings : DownloadClientSettingsBase<Aria2Settings>
{
private static readonly Aria2SettingsValidator Validator = new Aria2SettingsValidator();
private static readonly Aria2SettingsValidator Validator = new ();
public Aria2Settings()
{
@@ -44,7 +43,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2
[FieldDefinition(5, Label = "Directory", Type = FieldType.Textbox, HelpText = "DownloadClientAriaSettingsDirectoryHelpText")]
public string Directory { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -2,7 +2,6 @@ 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;
@@ -18,7 +17,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
}
}
public class TorrentBlackholeSettings : IProviderConfig
public class TorrentBlackholeSettings : DownloadClientSettingsBase<TorrentBlackholeSettings>
{
public TorrentBlackholeSettings()
{
@@ -26,7 +25,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
ReadOnly = true;
}
private static readonly TorrentBlackholeSettingsValidator Validator = new TorrentBlackholeSettingsValidator();
private static readonly TorrentBlackholeSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "TorrentBlackholeTorrentFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")]
[FieldToken(TokenField.HelpText, "TorrentBlackholeTorrentFolder", "extension", ".torrent")]
@@ -48,7 +47,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
[FieldDefinition(4, Label = "TorrentBlackholeSaveMagnetFilesReadOnly", Type = FieldType.Checkbox, HelpText = "TorrentBlackholeSaveMagnetFilesReadOnlyHelpText")]
public bool ReadOnly { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths;
@@ -15,9 +14,9 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
}
}
public class UsenetBlackholeSettings : IProviderConfig
public class UsenetBlackholeSettings : DownloadClientSettingsBase<UsenetBlackholeSettings>
{
private static readonly UsenetBlackholeSettingsValidator Validator = new UsenetBlackholeSettingsValidator();
private static readonly UsenetBlackholeSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "UsenetBlackholeNzbFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")]
[FieldToken(TokenField.HelpText, "UsenetBlackholeNzbFolder", "extension", ".nzb")]
@@ -26,7 +25,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
[FieldDefinition(1, Label = "BlackholeWatchFolder", Type = FieldType.Path, HelpText = "BlackholeWatchFolderHelpText")]
public string WatchFolder { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Deluge
@@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
}
}
public class DelugeSettings : IProviderConfig
public class DelugeSettings : DownloadClientSettingsBase<DelugeSettings>
{
private static readonly DelugeSettingsValidator Validator = new DelugeSettingsValidator();
private static readonly DelugeSettingsValidator Validator = new ();
public DelugeSettings()
{
@@ -67,7 +66,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
[FieldDefinition(11, Label = "DownloadClientDelugeSettingsDirectoryCompleted", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientDelugeSettingsDirectoryCompletedHelpText")]
public string CompletedDirectory { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -0,0 +1,30 @@
using System;
using Equ;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients
{
public abstract class DownloadClientSettingsBase<TSettings> : IProviderConfig, IEquatable<TSettings>
where TSettings : DownloadClientSettingsBase<TSettings>
{
private static readonly MemberwiseEqualityComparer<TSettings> Comparer = MemberwiseEqualityComparer<TSettings>.ByProperties;
public abstract NzbDroneValidationResult Validate();
public bool Equals(TSettings other)
{
return Comparer.Equals(this as TSettings, other);
}
public override bool Equals(object obj)
{
return Equals(obj as TSettings);
}
public override int GetHashCode()
{
return Comparer.GetHashCode(this as TSettings);
}
}
}

View File

@@ -1,8 +1,7 @@
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.DownloadStation
@@ -26,9 +25,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
}
}
public class DownloadStationSettings : IProviderConfig
public class DownloadStationSettings : DownloadClientSettingsBase<DownloadStationSettings>
{
private static readonly DownloadStationSettingsValidator Validator = new DownloadStationSettingsValidator();
private static readonly DownloadStationSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
public string Host { get; set; }
@@ -58,7 +57,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
this.Port = 5000;
}
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -3,7 +3,6 @@ using System.Linq;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Download.Clients.Flood.Models;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Flood
@@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.Flood
}
}
public class FloodSettings : IProviderConfig
public class FloodSettings : DownloadClientSettingsBase<FloodSettings>
{
private static readonly FloodSettingsValidator Validator = new FloodSettingsValidator();
private static readonly FloodSettingsValidator Validator = new ();
public FloodSettings()
{
@@ -69,7 +68,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
[FieldDefinition(10, Label = "DownloadClientFloodSettingsStartOnAdd", Type = FieldType.Checkbox)]
public bool StartOnAdd { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -2,7 +2,6 @@ using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths;
@@ -34,9 +33,9 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
}
}
public class FreeboxDownloadSettings : IProviderConfig
public class FreeboxDownloadSettings : DownloadClientSettingsBase<FreeboxDownloadSettings>
{
private static readonly FreeboxDownloadSettingsValidator Validator = new FreeboxDownloadSettingsValidator();
private static readonly FreeboxDownloadSettingsValidator Validator = new ();
public FreeboxDownloadSettings()
{
@@ -84,7 +83,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
[FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)]
public bool AddPaused { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using FluentValidation;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Hadouken
@@ -22,9 +21,9 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
}
}
public class HadoukenSettings : IProviderConfig
public class HadoukenSettings : DownloadClientSettingsBase<HadoukenSettings>
{
private static readonly HadoukenSettingsValidator Validator = new HadoukenSettingsValidator();
private static readonly HadoukenSettingsValidator Validator = new ();
public HadoukenSettings()
{
@@ -57,7 +56,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
public string Category { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using FluentValidation;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.NzbVortex
@@ -23,9 +22,9 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
}
}
public class NzbVortexSettings : IProviderConfig
public class NzbVortexSettings : DownloadClientSettingsBase<NzbVortexSettings>
{
private static readonly NzbVortexSettingsValidator Validator = new NzbVortexSettingsValidator();
private static readonly NzbVortexSettingsValidator Validator = new ();
public NzbVortexSettings()
{
@@ -59,7 +58,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
[FieldDefinition(6, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(NzbVortexPriority), HelpText = "DownloadClientSettingsOlderPriorityEpisodeHelpText")]
public int OlderTvPriority { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Nzbget
@@ -21,9 +20,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
}
}
public class NzbgetSettings : IProviderConfig
public class NzbgetSettings : DownloadClientSettingsBase<NzbgetSettings>
{
private static readonly NzbgetSettingsValidator Validator = new NzbgetSettingsValidator();
private static readonly NzbgetSettingsValidator Validator = new ();
public NzbgetSettings()
{
@@ -67,7 +66,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
[FieldDefinition(9, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox, HelpText = "DownloadClientNzbgetSettingsAddPausedHelpText")]
public bool AddPaused { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths;
@@ -15,9 +14,9 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
}
}
public class PneumaticSettings : IProviderConfig
public class PneumaticSettings : DownloadClientSettingsBase<PneumaticSettings>
{
private static readonly PneumaticSettingsValidator Validator = new PneumaticSettingsValidator();
private static readonly PneumaticSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "DownloadClientPneumaticSettingsNzbFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsNzbFolderHelpText")]
public string NzbFolder { get; set; }
@@ -25,7 +24,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
[FieldDefinition(1, Label = "DownloadClientPneumaticSettingsStrmFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsStrmFolderHelpText")]
public string StrmFolder { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.QBittorrent
@@ -19,9 +18,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
}
}
public class QBittorrentSettings : IProviderConfig
public class QBittorrentSettings : DownloadClientSettingsBase<QBittorrentSettings>
{
private static readonly QBittorrentSettingsValidator Validator = new QBittorrentSettingsValidator();
private static readonly QBittorrentSettingsValidator Validator = new ();
public QBittorrentSettings()
{
@@ -74,7 +73,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
[FieldDefinition(13, Label = "DownloadClientQbittorrentSettingsContentLayout", Type = FieldType.Select, SelectOptions = typeof(QBittorrentContentLayout), HelpText = "DownloadClientQbittorrentSettingsContentLayoutHelpText")]
public int ContentLayout { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using FluentValidation;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Sabnzbd
@@ -32,9 +31,9 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
}
}
public class SabnzbdSettings : IProviderConfig
public class SabnzbdSettings : DownloadClientSettingsBase<SabnzbdSettings>
{
private static readonly SabnzbdSettingsValidator Validator = new SabnzbdSettingsValidator();
private static readonly SabnzbdSettingsValidator Validator = new ();
public SabnzbdSettings()
{
@@ -78,7 +77,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
[FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(SabnzbdPriority), HelpText = "DownloadClientSettingsOlderPriorityEpisodeHelpText")]
public int OlderTvPriority { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,10 +1,10 @@
using System;
using System;
namespace NzbDrone.Core.Download.Clients
{
public class TorrentSeedConfiguration
{
public static TorrentSeedConfiguration DefaultConfiguration = new TorrentSeedConfiguration();
public static TorrentSeedConfiguration DefaultConfiguration = new ();
public double? Ratio { get; set; }
public TimeSpan? SeedTime { get; set; }

View File

@@ -2,7 +2,6 @@ using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Transmission
@@ -24,9 +23,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
}
}
public class TransmissionSettings : IProviderConfig
public class TransmissionSettings : DownloadClientSettingsBase<TransmissionSettings>
{
private static readonly TransmissionSettingsValidator Validator = new TransmissionSettingsValidator();
private static readonly TransmissionSettingsValidator Validator = new ();
public TransmissionSettings()
{
@@ -72,7 +71,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
[FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)]
public bool AddPaused { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.RTorrent
@@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
}
}
public class RTorrentSettings : IProviderConfig
public class RTorrentSettings : DownloadClientSettingsBase<RTorrentSettings>
{
private static readonly RTorrentSettingsValidator Validator = new RTorrentSettingsValidator();
private static readonly RTorrentSettingsValidator Validator = new ();
public RTorrentSettings()
{
@@ -70,7 +69,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
[FieldDefinition(11, Label = "DownloadClientRTorrentSettingsAddStopped", Type = FieldType.Checkbox, HelpText = "DownloadClientRTorrentSettingsAddStoppedHelpText")]
public bool AddStopped { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.UTorrent
@@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
}
}
public class UTorrentSettings : IProviderConfig
public class UTorrentSettings : DownloadClientSettingsBase<UTorrentSettings>
{
private static readonly UTorrentSettingsValidator Validator = new UTorrentSettingsValidator();
private static readonly UTorrentSettingsValidator Validator = new ();
public UTorrentSettings()
{
@@ -65,7 +64,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
[FieldToken(TokenField.HelpText, "DownloadClientSettingsInitialState", "clientName", "uTorrent")]
public int IntialState { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,14 +1,35 @@
using NzbDrone.Core.Indexers;
using System;
using Equ;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Download
{
public class DownloadClientDefinition : ProviderDefinition
public class DownloadClientDefinition : ProviderDefinition, IEquatable<DownloadClientDefinition>
{
private static readonly MemberwiseEqualityComparer<DownloadClientDefinition> Comparer = MemberwiseEqualityComparer<DownloadClientDefinition>.ByProperties;
[MemberwiseEqualityIgnore]
public DownloadProtocol Protocol { get; set; }
public int Priority { get; set; } = 1;
public bool RemoveCompletedDownloads { get; set; } = true;
public bool RemoveFailedDownloads { get; set; } = true;
public bool Equals(DownloadClientDefinition other)
{
return Comparer.Equals(this, other);
}
public override bool Equals(object obj)
{
return Equals(obj as DownloadClientDefinition);
}
public override int GetHashCode()
{
return Comparer.GetHashCode(this);
}
}
}

View File

@@ -29,18 +29,17 @@ namespace NzbDrone.Core.ImportLists.AniList
}
}
public class AniListSettingsBase<TSettings> : IImportListSettings
public class AniListSettingsBase<TSettings> : ImportListSettingsBase<TSettings>
where TSettings : AniListSettingsBase<TSettings>
{
protected virtual AbstractValidator<TSettings> Validator => new AniListSettingsBaseValidator<TSettings>();
private static readonly AniListSettingsBaseValidator<TSettings> Validator = new ();
public AniListSettingsBase()
{
BaseUrl = "https://graphql.anilist.co";
SignIn = "startOAuth";
}
public string BaseUrl { get; set; }
public override string BaseUrl { get; set; } = "https://graphql.anilist.co";
[FieldDefinition(0, Label = "ImportListsSettingsAccessToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)]
public string AccessToken { get; set; }
@@ -54,7 +53,7 @@ namespace NzbDrone.Core.ImportLists.AniList
[FieldDefinition(99, Label = "ImportListsAniListSettingsAuthenticateWithAniList", Type = FieldType.OAuth)]
public string SignIn { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate((TSettings)this));
}

View File

@@ -1,12 +1,12 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.AniList.List
{
public class AniListSettingsValidator : AniListSettingsBaseValidator<AniListSettings>
{
public AniListSettingsValidator()
: base()
{
RuleFor(c => c.Username).NotEmpty();
@@ -18,10 +18,11 @@ namespace NzbDrone.Core.ImportLists.AniList.List
public class AniListSettings : AniListSettingsBase<AniListSettings>
{
public const string sectionImport = "Import List Status";
public const string SectionImport = "Import List Status";
private static readonly AniListSettingsValidator Validator = new ();
public AniListSettings()
: base()
{
ImportCurrent = true;
ImportPlanning = true;
@@ -29,42 +30,45 @@ namespace NzbDrone.Core.ImportLists.AniList.List
ImportFinished = true;
}
protected override AbstractValidator<AniListSettings> Validator => new AniListSettingsValidator();
[FieldDefinition(1, Label = "Username", HelpText = "ImportListsAniListSettingsUsernameHelpText")]
public string Username { get; set; }
[FieldDefinition(2, Label = "ImportListsAniListSettingsImportWatching", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportWatchingHelpText")]
[FieldDefinition(2, Label = "ImportListsAniListSettingsImportWatching", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportWatchingHelpText")]
public bool ImportCurrent { get; set; }
[FieldDefinition(3, Label = "ImportListsAniListSettingsImportPlanning", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportPlanningHelpText")]
[FieldDefinition(3, Label = "ImportListsAniListSettingsImportPlanning", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportPlanningHelpText")]
public bool ImportPlanning { get; set; }
[FieldDefinition(4, Label = "ImportListsAniListSettingsImportCompleted", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportCompletedHelpText")]
[FieldDefinition(4, Label = "ImportListsAniListSettingsImportCompleted", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportCompletedHelpText")]
public bool ImportCompleted { get; set; }
[FieldDefinition(5, Label = "ImportListsAniListSettingsImportDropped", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportDroppedHelpText")]
[FieldDefinition(5, Label = "ImportListsAniListSettingsImportDropped", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportDroppedHelpText")]
public bool ImportDropped { get; set; }
[FieldDefinition(6, Label = "ImportListsAniListSettingsImportPaused", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportPausedHelpText")]
[FieldDefinition(6, Label = "ImportListsAniListSettingsImportPaused", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportPausedHelpText")]
public bool ImportPaused { get; set; }
[FieldDefinition(7, Label = "ImportListsAniListSettingsImportRepeating", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportRepeatingHelpText")]
[FieldDefinition(7, Label = "ImportListsAniListSettingsImportRepeating", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportRepeatingHelpText")]
public bool ImportRepeating { get; set; }
[FieldDefinition(8, Label = "ImportListsAniListSettingsImportFinished", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportFinishedHelpText")]
[FieldDefinition(8, Label = "ImportListsAniListSettingsImportFinished", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportFinishedHelpText")]
public bool ImportFinished { get; set; }
[FieldDefinition(9, Label = "ImportListsAniListSettingsImportReleasing", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportReleasingHelpText")]
[FieldDefinition(9, Label = "ImportListsAniListSettingsImportReleasing", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportReleasingHelpText")]
public bool ImportReleasing { get; set; }
[FieldDefinition(10, Label = "ImportListsAniListSettingsImportNotYetReleased", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportNotYetReleasedHelpText")]
[FieldDefinition(10, Label = "ImportListsAniListSettingsImportNotYetReleased", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportNotYetReleasedHelpText")]
public bool ImportUnreleased { get; set; }
[FieldDefinition(11, Label = "ImportListsAniListSettingsImportCancelled", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportCancelledHelpText")]
[FieldDefinition(11, Label = "ImportListsAniListSettingsImportCancelled", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportCancelledHelpText")]
public bool ImportCancelled { get; set; }
[FieldDefinition(12, Label = "ImportListsAniListSettingsImportHiatus", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportHiatusHelpText")]
[FieldDefinition(12, Label = "ImportListsAniListSettingsImportHiatus", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportHiatusHelpText")]
public bool ImportHiatus { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

View File

@@ -13,19 +13,14 @@ namespace NzbDrone.Core.ImportLists.Custom
}
}
public class CustomSettings : IImportListSettings
public class CustomSettings : ImportListSettingsBase<CustomSettings>
{
private static readonly CustomSettingsValidator Validator = new CustomSettingsValidator();
public CustomSettings()
{
BaseUrl = "";
}
private static readonly CustomSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "ImportListsCustomListSettingsUrl", HelpText = "ImportListsCustomListSettingsUrlHelpText")]
public string BaseUrl { get; set; }
public override string BaseUrl { get; set; } = string.Empty;
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -14,16 +14,16 @@ namespace NzbDrone.Core.ImportLists.Imdb
}
}
public class ImdbListSettings : IImportListSettings
public class ImdbListSettings : ImportListSettingsBase<ImdbListSettings>
{
private static readonly ImdbSettingsValidator Validator = new ImdbSettingsValidator();
private static readonly ImdbSettingsValidator Validator = new ();
public string BaseUrl { get; set; }
public override string BaseUrl { get; set; }
[FieldDefinition(1, Label = "ImportListsImdbSettingsListId", HelpText = "ImportListsImdbSettingsListIdHelpText")]
public string ListId { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,11 +1,14 @@
using System;
using Equ;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.ImportLists
{
public class ImportListDefinition : ProviderDefinition
public class ImportListDefinition : ProviderDefinition, IEquatable<ImportListDefinition>
{
private static readonly MemberwiseEqualityComparer<ImportListDefinition> Comparer = MemberwiseEqualityComparer<ImportListDefinition>.ByProperties;
public bool EnableAutomaticAdd { get; set; }
public bool SearchForMissingEpisodes { get; set; }
public MonitorTypes ShouldMonitor { get; set; }
@@ -15,10 +18,31 @@ namespace NzbDrone.Core.ImportLists
public bool SeasonFolder { get; set; }
public string RootFolderPath { get; set; }
[MemberwiseEqualityIgnore]
public override bool Enable => EnableAutomaticAdd;
[MemberwiseEqualityIgnore]
public ImportListStatus Status { get; set; }
[MemberwiseEqualityIgnore]
public ImportListType ListType { get; set; }
[MemberwiseEqualityIgnore]
public TimeSpan MinRefreshInterval { get; set; }
public bool Equals(ImportListDefinition other)
{
return Comparer.Equals(this, other);
}
public override bool Equals(object obj)
{
return Equals(obj as ImportListDefinition);
}
public override int GetHashCode()
{
return Comparer.GetHashCode(this);
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using Equ;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists
{
public abstract class ImportListSettingsBase<TSettings> : IImportListSettings, IEquatable<TSettings>
where TSettings : ImportListSettingsBase<TSettings>
{
private static readonly MemberwiseEqualityComparer<TSettings> Comparer = MemberwiseEqualityComparer<TSettings>.ByProperties;
public abstract string BaseUrl { get; set; }
public abstract NzbDroneValidationResult Validate();
public bool Equals(TSettings other)
{
return Comparer.Equals(this as TSettings, other);
}
public override bool Equals(object obj)
{
return Equals(obj as TSettings);
}
public override int GetHashCode()
{
return Comparer.GetHashCode(this as TSettings);
}
}
}

View File

@@ -24,16 +24,11 @@ namespace NzbDrone.Core.ImportLists.MyAnimeList
}
}
public class MyAnimeListSettings : IImportListSettings
public class MyAnimeListSettings : ImportListSettingsBase<MyAnimeListSettings>
{
public string BaseUrl { get; set; }
private static readonly MalSettingsValidator Validator = new ();
protected AbstractValidator<MyAnimeListSettings> Validator => new MalSettingsValidator();
public MyAnimeListSettings()
{
BaseUrl = "https://api.myanimelist.net/v2";
}
public override string BaseUrl { get; set; } = "https://api.myanimelist.net/v2";
[FieldDefinition(0, Label = "ImportListsMyAnimeListSettingsListStatus", Type = FieldType.Select, SelectOptions = typeof(MyAnimeListStatus), HelpText = "ImportListsMyAnimeListSettingsListStatusHelpText")]
public int ListStatus { get; set; }
@@ -50,7 +45,7 @@ namespace NzbDrone.Core.ImportLists.MyAnimeList
[FieldDefinition(99, Label = "ImportListsMyAnimeListSettingsAuthenticateWithMyAnimeList", Type = FieldType.OAuth)]
public string SignIn { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -14,9 +14,9 @@ namespace NzbDrone.Core.ImportLists.Plex
}
}
public class PlexListSettings : IImportListSettings
public class PlexListSettings : ImportListSettingsBase<PlexListSettings>
{
protected virtual PlexListSettingsValidator Validator => new PlexListSettingsValidator();
private static readonly PlexListSettingsValidator Validator = new ();
public PlexListSettings()
{
@@ -25,7 +25,7 @@ namespace NzbDrone.Core.ImportLists.Plex
public virtual string Scope => "";
public string BaseUrl { get; set; }
public override string BaseUrl { get; set; }
[FieldDefinition(0, Label = "ImportListsSettingsAccessToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)]
public string AccessToken { get; set; }
@@ -33,7 +33,7 @@ namespace NzbDrone.Core.ImportLists.Plex
[FieldDefinition(99, Label = "ImportListsPlexSettingsAuthenticateWithPlex", Type = FieldType.OAuth)]
public string SignIn { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -12,9 +12,9 @@ namespace NzbDrone.Core.ImportLists.Rss.Plex
}
}
public class PlexRssImportSettings : RssImportBaseSettings
public class PlexRssImportSettings : RssImportBaseSettings<PlexRssImportSettings>
{
private PlexRssImportSettingsValidator Validator => new ();
private static readonly PlexRssImportSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "ImportListsSettingsRssUrl", Type = FieldType.Textbox, HelpLink = "https://app.plex.tv/desktop/#!/settings/watchlist")]
public override string Url { get; set; }

View File

@@ -8,7 +8,7 @@ using NzbDrone.Core.Parser;
namespace NzbDrone.Core.ImportLists.Rss
{
public class RssImportBase<TSettings> : HttpImportListBase<TSettings>
where TSettings : RssImportBaseSettings, new()
where TSettings : RssImportBaseSettings<TSettings>, new()
{
public override string Name => "RSS List Base";
public override ImportListType ListType => ImportListType.Advanced;
@@ -36,7 +36,7 @@ namespace NzbDrone.Core.ImportLists.Rss
public override IImportListRequestGenerator GetRequestGenerator()
{
return new RssImportRequestGenerator
return new RssImportRequestGenerator<TSettings>
{
Settings = Settings
};

View File

@@ -4,7 +4,8 @@ using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Rss
{
public class RssImportSettingsValidator : AbstractValidator<RssImportBaseSettings>
public class RssImportSettingsValidator<TSettings> : AbstractValidator<TSettings>
where TSettings : RssImportBaseSettings<TSettings>
{
public RssImportSettingsValidator()
{
@@ -12,18 +13,19 @@ namespace NzbDrone.Core.ImportLists.Rss
}
}
public class RssImportBaseSettings : IImportListSettings
public class RssImportBaseSettings<TSettings> : ImportListSettingsBase<TSettings>
where TSettings : RssImportBaseSettings<TSettings>
{
private RssImportSettingsValidator Validator => new ();
private static readonly RssImportSettingsValidator<TSettings> Validator = new ();
public string BaseUrl { get; set; }
public override string BaseUrl { get; set; }
[FieldDefinition(0, Label = "ImportListsSettingsRssUrl", Type = FieldType.Textbox)]
public virtual string Url { get; set; }
public virtual NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
return new NzbDroneValidationResult(Validator.Validate(this as TSettings));
}
}
}

View File

@@ -3,9 +3,10 @@ using NzbDrone.Common.Http;
namespace NzbDrone.Core.ImportLists.Rss
{
public class RssImportRequestGenerator : IImportListRequestGenerator
public class RssImportRequestGenerator<TSettings> : IImportListRequestGenerator
where TSettings : RssImportBaseSettings<TSettings>, new()
{
public RssImportBaseSettings Settings { get; set; }
public RssImportBaseSettings<TSettings> Settings { get; set; }
public virtual ImportListPageableRequestChain GetListItems()
{
@@ -18,9 +19,7 @@ namespace NzbDrone.Core.ImportLists.Rss
private IEnumerable<ImportListRequest> GetSeriesRequest()
{
var request = new ImportListRequest(Settings.Url, HttpAccept.Rss);
yield return request;
yield return new ImportListRequest(Settings.Url, HttpAccept.Rss);
}
}
}

View File

@@ -24,18 +24,17 @@ namespace NzbDrone.Core.ImportLists.Simkl
}
}
public class SimklSettingsBase<TSettings> : IImportListSettings
public class SimklSettingsBase<TSettings> : ImportListSettingsBase<TSettings>
where TSettings : SimklSettingsBase<TSettings>
{
protected virtual AbstractValidator<TSettings> Validator => new SimklSettingsBaseValidator<TSettings>();
private static readonly SimklSettingsBaseValidator<TSettings> Validator = new ();
public SimklSettingsBase()
{
BaseUrl = "https://api.simkl.com";
SignIn = "startOAuth";
}
public string BaseUrl { get; set; }
public override string BaseUrl { get; set; } = "https://api.simkl.com";
[FieldDefinition(0, Label = "ImportListsSettingsAccessToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)]
public string AccessToken { get; set; }
@@ -52,7 +51,7 @@ namespace NzbDrone.Core.ImportLists.Simkl
[FieldDefinition(99, Label = "ImportListsSimklSettingsAuthenticatewithSimkl", Type = FieldType.OAuth)]
public string SignIn { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate((TSettings)this));
}

View File

@@ -1,12 +1,12 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Simkl.User
{
public class SimklUserSettingsValidator : SimklSettingsBaseValidator<SimklUserSettings>
{
public SimklUserSettingsValidator()
: base()
{
RuleFor(c => c.ListType).NotNull();
}
@@ -14,7 +14,7 @@ namespace NzbDrone.Core.ImportLists.Simkl.User
public class SimklUserSettings : SimklSettingsBase<SimklUserSettings>
{
protected override AbstractValidator<SimklUserSettings> Validator => new SimklUserSettingsValidator();
private static readonly SimklUserSettingsValidator Validator = new ();
public SimklUserSettings()
{
@@ -27,5 +27,10 @@ namespace NzbDrone.Core.ImportLists.Simkl.User
[FieldDefinition(1, Label = "ImportListsSimklSettingsShowType", Type = FieldType.Select, SelectOptions = typeof(SimklUserShowType), HelpText = "ImportListsSimklSettingsShowTypeHelpText")]
public int ShowType { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

View File

@@ -15,13 +15,12 @@ namespace NzbDrone.Core.ImportLists.Sonarr
}
}
public class SonarrSettings : IImportListSettings
public class SonarrSettings : ImportListSettingsBase<SonarrSettings>
{
private static readonly SonarrSettingsValidator Validator = new SonarrSettingsValidator();
private static readonly SonarrSettingsValidator Validator = new ();
public SonarrSettings()
{
BaseUrl = "";
ApiKey = "";
ProfileIds = Array.Empty<int>();
LanguageProfileIds = Array.Empty<int>();
@@ -30,7 +29,7 @@ namespace NzbDrone.Core.ImportLists.Sonarr
}
[FieldDefinition(0, Label = "ImportListsSonarrSettingsFullUrl", HelpText = "ImportListsSonarrSettingsFullUrlHelpText")]
public string BaseUrl { get; set; }
public override string BaseUrl { get; set; } = string.Empty;
[FieldDefinition(1, Label = "ApiKey", HelpText = "ImportListsSonarrSettingsApiKeyHelpText")]
public string ApiKey { get; set; }
@@ -51,7 +50,7 @@ namespace NzbDrone.Core.ImportLists.Sonarr
[FieldDefinition(6, Type = FieldType.Select, SelectOptionsProviderAction = "getLanguageProfiles", Label = "Language Profiles", HelpText = "Language Profiles from the source instance to import from")]
public IEnumerable<int> LanguageProfileIds { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,12 +1,12 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Trakt.List
{
public class TraktListSettingsValidator : TraktSettingsBaseValidator<TraktListSettings>
{
public TraktListSettingsValidator()
: base()
{
RuleFor(c => c.Username).NotEmpty();
RuleFor(c => c.Listname).NotEmpty();
@@ -15,12 +15,17 @@ namespace NzbDrone.Core.ImportLists.Trakt.List
public class TraktListSettings : TraktSettingsBase<TraktListSettings>
{
protected override AbstractValidator<TraktListSettings> Validator => new TraktListSettingsValidator();
private static readonly TraktListSettingsValidator Validator = new ();
[FieldDefinition(1, Label = "Username", HelpText = "ImportListsTraktSettingsUsernameHelpText")]
public string Username { get; set; }
[FieldDefinition(2, Label = "ImportListsTraktSettingsListName", HelpText = "ImportListsTraktSettingsListNameHelpText")]
public string Listname { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

View File

@@ -2,13 +2,13 @@ using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Trakt.Popular
{
public class TraktPopularSettingsValidator : TraktSettingsBaseValidator<TraktPopularSettings>
{
public TraktPopularSettingsValidator()
: base()
{
RuleFor(c => c.TraktListType).NotNull();
@@ -28,7 +28,7 @@ namespace NzbDrone.Core.ImportLists.Trakt.Popular
public class TraktPopularSettings : TraktSettingsBase<TraktPopularSettings>
{
protected override AbstractValidator<TraktPopularSettings> Validator => new TraktPopularSettingsValidator();
private static readonly TraktPopularSettingsValidator Validator = new ();
public TraktPopularSettings()
{
@@ -46,5 +46,10 @@ namespace NzbDrone.Core.ImportLists.Trakt.Popular
[FieldDefinition(5, Label = "ImportListsTraktSettingsYears", HelpText = "ImportListsTraktSettingsYearsHelpText")]
public string Years { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

View File

@@ -34,19 +34,18 @@ namespace NzbDrone.Core.ImportLists.Trakt
}
}
public class TraktSettingsBase<TSettings> : IImportListSettings
public class TraktSettingsBase<TSettings> : ImportListSettingsBase<TSettings>
where TSettings : TraktSettingsBase<TSettings>
{
protected virtual AbstractValidator<TSettings> Validator => new TraktSettingsBaseValidator<TSettings>();
private static readonly TraktSettingsBaseValidator<TSettings> Validator = new ();
public TraktSettingsBase()
{
BaseUrl = "https://api.trakt.tv";
SignIn = "startOAuth";
Limit = 100;
}
public string BaseUrl { get; set; }
public override string BaseUrl { get; set; } = "https://api.trakt.tv";
[FieldDefinition(0, Label = "ImportListsSettingsAccessToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)]
public string AccessToken { get; set; }
@@ -69,7 +68,7 @@ namespace NzbDrone.Core.ImportLists.Trakt
[FieldDefinition(99, Label = "ImportListsTraktSettingsAuthenticateWithTrakt", Type = FieldType.OAuth)]
public string SignIn { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate((TSettings)this));
}

View File

@@ -1,12 +1,12 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Trakt.User
{
public class TraktUserSettingsValidator : TraktSettingsBaseValidator<TraktUserSettings>
{
public TraktUserSettingsValidator()
: base()
{
RuleFor(c => c.TraktListType).NotNull();
RuleFor(c => c.TraktWatchedListType).NotNull();
@@ -16,7 +16,7 @@ namespace NzbDrone.Core.ImportLists.Trakt.User
public class TraktUserSettings : TraktSettingsBase<TraktUserSettings>
{
protected override AbstractValidator<TraktUserSettings> Validator => new TraktUserSettingsValidator();
private static readonly TraktUserSettingsValidator Validator = new ();
public TraktUserSettings()
{
@@ -36,6 +36,11 @@ namespace NzbDrone.Core.ImportLists.Trakt.User
[FieldDefinition(4, Label = "Username", HelpText = "ImportListsTraktSettingsUserListUsernameHelpText")]
public string Username { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
public enum TraktUserWatchSorting

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages;
@@ -18,7 +19,7 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet
}
}
public class BroadcastheNetSettings : ITorrentIndexerSettings
public class BroadcastheNetSettings : PropertywiseEquatable<BroadcastheNetSettings>, ITorrentIndexerSettings
{
private static readonly BroadcastheNetSettingsValidator Validator = new ();

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages;
@@ -15,9 +16,9 @@ namespace NzbDrone.Core.Indexers.Fanzub
}
}
public class FanzubSettings : IIndexerSettings
public class FanzubSettings : PropertywiseEquatable<FanzubSettings>, IIndexerSettings
{
private static readonly FanzubSettingsValidator Validator = new FanzubSettingsValidator();
private static readonly FanzubSettingsValidator Validator = new ();
public FanzubSettings()
{

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages;
@@ -19,9 +20,9 @@ namespace NzbDrone.Core.Indexers.FileList
}
}
public class FileListSettings : ITorrentIndexerSettings
public class FileListSettings : PropertywiseEquatable<FileListSettings>, ITorrentIndexerSettings
{
private static readonly FileListSettingsValidator Validator = new FileListSettingsValidator();
private static readonly FileListSettingsValidator Validator = new ();
public FileListSettings()
{
@@ -61,7 +62,7 @@ namespace NzbDrone.Core.Indexers.FileList
public int MinimumSeeders { get; set; }
[FieldDefinition(7)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
public SeedCriteriaSettings SeedCriteria { get; set; } = new ();
[FieldDefinition(8, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages;
@@ -18,7 +19,7 @@ namespace NzbDrone.Core.Indexers.HDBits
}
}
public class HDBitsSettings : ITorrentIndexerSettings
public class HDBitsSettings : PropertywiseEquatable<HDBitsSettings>, ITorrentIndexerSettings
{
private static readonly HDBitsSettingsValidator Validator = new ();

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Equ;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
@@ -25,9 +26,9 @@ namespace NzbDrone.Core.Indexers.IPTorrents
}
}
public class IPTorrentsSettings : ITorrentIndexerSettings
public class IPTorrentsSettings : PropertywiseEquatable<IPTorrentsSettings>, ITorrentIndexerSettings
{
private static readonly IPTorrentsSettingsValidator Validator = new IPTorrentsSettingsValidator();
private static readonly IPTorrentsSettingsValidator Validator = new ();
public IPTorrentsSettings()
{
@@ -42,7 +43,7 @@ namespace NzbDrone.Core.Indexers.IPTorrents
public int MinimumSeeders { get; set; }
[FieldDefinition(2)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
public SeedCriteriaSettings SeedCriteria { get; set; } = new ();
[FieldDefinition(3, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

View File

@@ -1,9 +1,13 @@
using System;
using Equ;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers
{
public class IndexerDefinition : ProviderDefinition
public class IndexerDefinition : ProviderDefinition, IEquatable<IndexerDefinition>
{
private static readonly MemberwiseEqualityComparer<IndexerDefinition> Comparer = MemberwiseEqualityComparer<IndexerDefinition>.ByProperties;
public const int DefaultPriority = 25;
public IndexerDefinition()
@@ -11,18 +15,41 @@ namespace NzbDrone.Core.Indexers
Priority = DefaultPriority;
}
[MemberwiseEqualityIgnore]
public DownloadProtocol Protocol { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsRss { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsSearch { get; set; }
public bool EnableRss { get; set; }
public bool EnableAutomaticSearch { get; set; }
public bool EnableInteractiveSearch { get; set; }
public int DownloadClientId { get; set; }
public DownloadProtocol Protocol { get; set; }
public bool SupportsRss { get; set; }
public bool SupportsSearch { get; set; }
public int Priority { get; set; }
public int SeasonSearchMaximumSingleEpisodeAge { get; set; }
[MemberwiseEqualityIgnore]
public override bool Enable => EnableRss || EnableAutomaticSearch || EnableInteractiveSearch;
[MemberwiseEqualityIgnore]
public IndexerStatus Status { get; set; }
public bool Equals(IndexerDefinition other)
{
return Comparer.Equals(this, other);
}
public override bool Equals(object obj)
{
return Equals(obj as IndexerDefinition);
}
public override int GetHashCode()
{
return Comparer.GetHashCode(this);
}
}
}

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Equ;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
@@ -28,7 +29,7 @@ namespace NzbDrone.Core.Indexers.Newznab
return settings.BaseUrl != null && ApiKeyWhiteList.Any(c => settings.BaseUrl.ToLowerInvariant().Contains(c));
}
private static readonly Regex AdditionalParametersRegex = new Regex(@"(&.+?\=.+?)+", RegexOptions.Compiled);
private static readonly Regex AdditionalParametersRegex = new (@"(&.+?\=.+?)+", RegexOptions.Compiled);
public NewznabSettingsValidator()
{
@@ -48,9 +49,9 @@ namespace NzbDrone.Core.Indexers.Newznab
}
}
public class NewznabSettings : IIndexerSettings
public class NewznabSettings : PropertywiseEquatable<NewznabSettings>, IIndexerSettings
{
private static readonly NewznabSettingsValidator Validator = new NewznabSettingsValidator();
private static readonly NewznabSettingsValidator Validator = new ();
public NewznabSettings()
{

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages;
@@ -19,9 +20,9 @@ namespace NzbDrone.Core.Indexers.Nyaa
}
}
public class NyaaSettings : ITorrentIndexerSettings
public class NyaaSettings : PropertywiseEquatable<NyaaSettings>, ITorrentIndexerSettings
{
private static readonly NyaaSettingsValidator Validator = new NyaaSettingsValidator();
private static readonly NyaaSettingsValidator Validator = new ();
public NyaaSettings()
{
@@ -44,7 +45,7 @@ namespace NzbDrone.Core.Indexers.Nyaa
public int MinimumSeeders { get; set; }
[FieldDefinition(4)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
public SeedCriteriaSettings SeedCriteria { get; set; } = new ();
[FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

View File

@@ -1,3 +1,4 @@
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
@@ -46,7 +47,7 @@ namespace NzbDrone.Core.Indexers
}
}
public class SeedCriteriaSettings
public class SeedCriteriaSettings : PropertywiseEquatable<SeedCriteriaSettings>
{
[FieldDefinition(0, Type = FieldType.Number, Label = "IndexerSettingsSeedRatio", HelpText = "IndexerSettingsSeedRatioHelpText")]
public double? SeedRatio { get; set; }

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages;
@@ -17,9 +18,9 @@ namespace NzbDrone.Core.Indexers.TorrentRss
}
}
public class TorrentRssIndexerSettings : ITorrentIndexerSettings
public class TorrentRssIndexerSettings : PropertywiseEquatable<TorrentRssIndexerSettings>, ITorrentIndexerSettings
{
private static readonly TorrentRssIndexerSettingsValidator Validator = new TorrentRssIndexerSettingsValidator();
private static readonly TorrentRssIndexerSettingsValidator Validator = new ();
public TorrentRssIndexerSettings()
{
@@ -42,7 +43,7 @@ namespace NzbDrone.Core.Indexers.TorrentRss
public int MinimumSeeders { get; set; }
[FieldDefinition(4)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
public SeedCriteriaSettings SeedCriteria { get; set; } = new ();
[FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages;
@@ -18,9 +19,9 @@ namespace NzbDrone.Core.Indexers.Torrentleech
}
}
public class TorrentleechSettings : ITorrentIndexerSettings
public class TorrentleechSettings : PropertywiseEquatable<TorrentleechSettings>, ITorrentIndexerSettings
{
private static readonly TorrentleechSettingsValidator Validator = new TorrentleechSettingsValidator();
private static readonly TorrentleechSettingsValidator Validator = new ();
public TorrentleechSettings()
{
@@ -39,7 +40,7 @@ namespace NzbDrone.Core.Indexers.Torrentleech
public int MinimumSeeders { get; set; }
[FieldDefinition(3)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
public SeedCriteriaSettings SeedCriteria { get; set; } = new ();
[FieldDefinition(4, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

View File

@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
using Equ;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
@@ -18,7 +19,7 @@ namespace NzbDrone.Core.Indexers.Torznab
return settings.BaseUrl != null && ApiKeyWhiteList.Any(c => settings.BaseUrl.ToLowerInvariant().Contains(c));
}
private static readonly Regex AdditionalParametersRegex = new Regex(@"(&.+?\=.+?)+", RegexOptions.Compiled);
private static readonly Regex AdditionalParametersRegex = new (@"(&.+?\=.+?)+", RegexOptions.Compiled);
public TorznabSettingsValidator()
{
@@ -40,9 +41,11 @@ namespace NzbDrone.Core.Indexers.Torznab
}
}
public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings
public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings, IEquatable<TorznabSettings>
{
private static readonly TorznabSettingsValidator Validator = new TorznabSettingsValidator();
private static readonly TorznabSettingsValidator Validator = new ();
private static readonly MemberwiseEqualityComparer<TorznabSettings> Comparer = MemberwiseEqualityComparer<TorznabSettings>.ByProperties;
public TorznabSettings()
{
@@ -53,7 +56,7 @@ namespace NzbDrone.Core.Indexers.Torznab
public int MinimumSeeders { get; set; }
[FieldDefinition(9)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
public SeedCriteriaSettings SeedCriteria { get; set; } = new ();
[FieldDefinition(10, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
@@ -62,5 +65,20 @@ namespace NzbDrone.Core.Indexers.Torznab
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
public bool Equals(TorznabSettings other)
{
return Comparer.Equals(this, other);
}
public override bool Equals(object obj)
{
return Equals(obj as TorznabSettings);
}
public override int GetHashCode()
{
return Comparer.GetHashCode(this);
}
}
}

View File

@@ -743,5 +743,14 @@
"IndexerHDBitsSettingsMediums": "Mitjans",
"UpdateStartupTranslocationHealthCheckMessage": "No es pot instal·lar l'actualització perquè la carpeta d'inici '{startupFolder}' es troba en una carpeta de translocació d'aplicacions.",
"UpdateStartupNotWritableHealthCheckMessage": "No es pot instal·lar l'actualització perquè l'usuari '{userName}' no té permisos d'escriptura de la carpeta d'inici '{startupFolder}'.",
"DownloadClientTransmissionSettingsDirectoryHelpText": "Ubicació opcional per a les baixades, deixeu-lo en blanc per utilitzar la ubicació predeterminada de Transmission"
"DownloadClientTransmissionSettingsDirectoryHelpText": "Ubicació opcional per a les baixades, deixeu-lo en blanc per utilitzar la ubicació predeterminada de Transmission",
"Mixed": "Combinat",
"Proxy": "Servidor intermediari",
"Mapping": "Mapejat",
"More": "Més",
"MultiLanguages": "Multi-idioma",
"Organize": "Organitza",
"Search": "Cerca",
"SelectDropdown": "Seleccioneu...",
"Shutdown": "Apaga"
}

View File

@@ -308,6 +308,7 @@
"Date": "Date",
"Dates": "Dates",
"Day": "Day",
"DayOfWeekAt": "{day} at {time}",
"Debug": "Debug",
"Default": "Default",
"DefaultCase": "Default Case",
@@ -1949,10 +1950,12 @@
"Title": "Title",
"Titles": "Titles",
"Today": "Today",
"TodayAt": "Today at {time}",
"ToggleMonitoredSeriesUnmonitored ": "Cannot toggle monitored state when series is unmonitored",
"ToggleMonitoredToUnmonitored": "Monitored, click to unmonitor",
"ToggleUnmonitoredToMonitored": "Unmonitored, click to monitor",
"Tomorrow": "Tomorrow",
"TomorrowAt": "Tomorrow at {time}",
"TorrentBlackhole": "Torrent Blackhole",
"TorrentBlackholeSaveMagnetFiles": "Save Magnet Files",
"TorrentBlackholeSaveMagnetFilesExtension": "Save Magnet Files Extension",
@@ -2074,5 +2077,6 @@
"Year": "Year",
"Yes": "Yes",
"YesCancel": "Yes, Cancel",
"Yesterday": "Yesterday"
"Yesterday": "Yesterday",
"YesterdayAt": "Yesterday at {time}"
}

View File

@@ -57,7 +57,7 @@
"Condition": "Condición",
"Component": "Componente",
"Custom": "Personalizado",
"Cutoff": "Umbral",
"Cutoff": "Límite",
"Dates": "Fechas",
"Debug": "Debug",
"Date": "Fecha",
@@ -181,7 +181,7 @@
"AddNewSeriesError": "Falló al cargar los resultados de la búsqueda, inténtelo de nuevo.",
"AddNewSeriesHelpText": "Es fácil añadir una nueva serie, empiece escribiendo el nombre de la serie que desea añadir.",
"AddNewSeriesRootFolderHelpText": "La subcarpeta '{folder}' será creada automáticamente",
"AddNewSeriesSearchForCutoffUnmetEpisodes": "Empezar la búsqueda de episodios con umbrales no alcanzados",
"AddNewSeriesSearchForCutoffUnmetEpisodes": "Empezar la búsqueda de episodios con límites no alcanzados",
"AddNewSeriesSearchForMissingEpisodes": "Empezar búsqueda de episodios faltantes",
"AddQualityProfile": "Añadir Perfil de Calidad",
"AddQualityProfileError": "No se pudo añadir un nuevo perfil de calidad, inténtelo de nuevo.",
@@ -272,7 +272,7 @@
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirma la nueva contraseña",
"MonitorPilotEpisode": "Episodio Piloto",
"MonitorRecentEpisodesDescription": "Monitorizar episodios emitidos en los últimos 90 días y los episodios futuros",
"MonitorSelected": "Monitorizar Seleccionados",
"MonitorSelected": "Monitorizar seleccionados",
"MonitorSeries": "Monitorizar Series",
"NoHistory": "Sin historial",
"NoHistoryFound": "No se encontró historial",
@@ -436,7 +436,7 @@
"CustomFormatsLoadError": "No se pudo cargar Formatos Personalizados",
"CustomFormatsSettings": "Configuración de formatos personalizados",
"CustomFormatsSettingsSummary": "Formatos y configuraciones personalizados",
"CutoffUnmet": "Umbrales no alcanzados",
"CutoffUnmet": "Límite no alcanzado",
"DailyEpisodeFormat": "Formato de episodio diario",
"Database": "Base de datos",
"DelayMinutes": "{delay} minutos",
@@ -463,14 +463,14 @@
"InteractiveImportLoadError": "No se pueden cargar elementos de la importación manual",
"InteractiveImportNoFilesFound": "No se han encontrado archivos de vídeo en la carpeta seleccionada",
"InteractiveImportNoQuality": "La calidad debe elegirse para cada archivo seleccionado",
"InteractiveSearchModalHeader": "Búsqueda Interactiva",
"InteractiveSearchModalHeader": "Búsqueda interactiva",
"InvalidUILanguage": "Su interfaz de usuario está configurada en un idioma no válido, corríjalo y guarde la configuración",
"ChownGroup": "chown grupo",
"DelayProfileProtocol": "Protocolo: {preferredProtocol}",
"DelayProfilesLoadError": "Incapaz de cargar Perfiles de Retardo",
"ContinuingSeriesDescription": "Se esperan más episodios u otra temporada",
"CutoffUnmetLoadError": "Error cargando elementos con umbrales no alcanzados",
"CutoffUnmetNoItems": "No hay elementos con umbrales no alcanzados",
"CutoffUnmetLoadError": "Error cargando elementos con límites no alcanzados",
"CutoffUnmetNoItems": "Ningún elemento con límites no alcanzados",
"DelayProfile": "Perfil de retardo",
"Delete": "Eliminar",
"DeleteDelayProfile": "Eliminar Perfil de Retardo",
@@ -530,7 +530,7 @@
"DeleteEpisodesFilesHelpText": "Eliminar archivos de episodios y directorio de series",
"DoNotPrefer": "No preferir",
"DoNotUpgradeAutomatically": "No actualizar automáticamente",
"IndexerSettingsSeedRatioHelpText": "El ratio que un torrent debería alcanzar antes de detenerse, vacío usa el predeterminado del cliente de descarga. El ratio debería ser al menos 1.0 y seguir las reglas de los indexadores",
"IndexerSettingsSeedRatioHelpText": "El ratio que un torrent debería alcanzar antes de parar, vacío usa el predeterminado del cliente de descarga. El ratio debería ser al menos 1.0 y seguir las reglas de los indexadores",
"Download": "Descargar",
"Donate": "Donar",
"DownloadClientDelugeValidationLabelPluginFailure": "La configuración de etiqueta falló",
@@ -816,7 +816,7 @@
"FirstDayOfWeek": "Primer día de la semana",
"Forums": "Foros",
"FreeSpace": "Espacio libre",
"MissingNoItems": "No hay elementos faltantes",
"MissingNoItems": "Ningún elemento faltante",
"ImportListRootFolderMissingRootHealthCheckMessage": "Carpeta raíz faltante para importar lista(s): {rootFolderInfo}",
"MissingLoadError": "Error cargando elementos faltantes",
"RemoveSelectedBlocklistMessageText": "¿Estás seguro que quieres eliminar los elementos seleccionados de la lista de bloqueos?",
@@ -890,8 +890,8 @@
"ImportListSettings": "Importar ajustes de lista",
"ImportListsSettingsSummary": "Importar desde otra instancia de {appName} o listas de Trakt y gestionar exclusiones de lista",
"IncludeCustomFormatWhenRenamingHelpText": "Incluir en formato de renombrado {Custom Formats}",
"QualityCutoffNotMet": "Calidad del umbral que no ha sido alcanzado",
"SearchForCutoffUnmetEpisodesConfirmationCount": "¿Estás seguro que quieres buscar los {totalRecords} episodios en Umbrales no alcanzados?",
"QualityCutoffNotMet": "No se ha alcanzado el límite de calidad",
"SearchForCutoffUnmetEpisodesConfirmationCount": "¿Estás seguro que quieres buscar los {totalRecords} episodios con límites no alcanzados?",
"IndexerOptionsLoadError": "No se pudieron cargar las opciones del indexador",
"IndexerIPTorrentsSettingsFeedUrl": "URL del canal",
"ICalFeed": "Canal de iCal",
@@ -991,7 +991,7 @@
"ImportScriptPathHelpText": "La ruta al script a usar para importar",
"ImportUsingScriptHelpText": "Copiar archivos para importar usando un script (p. ej. para transcodificación)",
"Importing": "Importando",
"IncludeUnmonitored": "Incluir sin monitorizar",
"IncludeUnmonitored": "Incluir no monitorizadas",
"IndexerLongTermStatusAllUnavailableHealthCheckMessage": "Ningún indexador está disponible debido a errores durante más de 6 horas",
"IRC": "IRC",
"ICalShowAsAllDayEvents": "Mostrar como eventos para todo el día",
@@ -1041,7 +1041,7 @@
"ImportedTo": "Importar a",
"IncludeCustomFormatWhenRenaming": "Incluir formato personalizado cuando se renombra",
"CleanLibraryLevel": "Limpiar el nivel de la librería",
"SearchForCutoffUnmetEpisodes": "Buscar todos los episodios en Umbrales no alcanzados",
"SearchForCutoffUnmetEpisodes": "Buscar todos los episodios con límites no alcanzados",
"IconForSpecials": "Icono para Especiales",
"ImportListExclusions": "Importar lista de exclusiones",
"ImportListStatusAllPossiblePartialFetchHealthCheckMessage": "Todas las listas requieren interacción manual debido a posibles búsquedas parciales",
@@ -1057,8 +1057,8 @@
"HourShorthand": "h",
"ICalFeedHelpText": "Copia esta URL a tu(s) cliente(s) o pulsa para suscribirse si tu navegador soporta Webcal",
"ICalTagsSeriesHelpText": "El canal solo contendrá series con al menos una etiqueta coincidente",
"IconForCutoffUnmet": "Icono para Umbrales no alcanzados",
"IconForCutoffUnmetHelpText": "Mostrar icono para archivos cuando el umbral no haya sido alcanzado",
"IconForCutoffUnmet": "Icono de límite no alcanzado",
"IconForCutoffUnmetHelpText": "Muestra un icono para archivos cuando el límite no haya sido alcanzado",
"EpisodeCount": "Recuento de episodios",
"IndexerSettings": "Opciones del indexador",
"AddDelayProfileError": "No se pudo añadir un nuevo perfil de retraso, por favor inténtalo de nuevo.",
@@ -1102,7 +1102,7 @@
"IndexerSettingsRssUrlHelpText": "Introduzca la URL de un canal RSS compatible con {indexer}",
"IndexerStatusUnavailableHealthCheckMessage": "Indexadores no disponibles debido a errores: {indexerNames}",
"IndexerHDBitsSettingsMediums": "Medios",
"IndexerSettingsSeedTimeHelpText": "El tiempo que un torrent debería ser compartido antes de detenerse, vac usa el predeterminado del cliente de descarga",
"IndexerSettingsSeedTimeHelpText": "El tiempo que un torrent debería ser sembrado antes de parar, vacío usa el predeterminado del cliente de descarga",
"IndexerValidationCloudFlareCaptchaRequired": "Sitio protegido por CloudFlare CAPTCHA. Se requiere un token CAPTCHA válido.",
"NotificationsEmailSettingsUseEncryption": "Usar Cifrado",
"LastDuration": "Última Duración",
@@ -1226,7 +1226,7 @@
"MetadataSourceSettings": "Opciones de fuente de metadatos",
"MetadataSettingsSeriesSummary": "Crea archivos de metadatos cuando los episodios son importados o las series son refrescadas",
"Metadata": "Metadatos",
"MassSearchCancelWarning": "Esto no puede ser cancelado una vez empiece sin reiniciar {appName} o deshabilitar todos tus indexadores.",
"MassSearchCancelWarning": "No puede ser cancelado una vez comience sin reiniciar {appName} o deshabilitar todos tus indexadores.",
"MaximumSingleEpisodeAgeHelpText": "Durante una búsqueda completa de temporada, solo serán permitidos los paquetes de temporada cuando el último episodio de temporada sea más antiguo que esta configuración. Solo series estándar. Usa 0 para deshabilitar.",
"MaximumSize": "Tamaño máximo",
"IndexerValidationNoResultsInConfiguredCategories": "Petición con éxito, pero no se devolvió ningún resultado en las categorías configuradas de tu indexador. Esto puede ser un problema con el indexador o tus ajustes de categoría de tu indexador.",
@@ -1710,7 +1710,7 @@
"SeriesIndexFooterEnded": "FInalizado (Todos los episodios descargados)",
"ShowDateAdded": "Mostrar fecha de adición",
"UnmonitorDeletedEpisodesHelpText": "Los episodios borrados del disco son dejados de monitorizar automáticamente en {appName}",
"UnmonitorSelected": "Dejar de monitorizar seleccionados",
"UnmonitorSelected": "No monitorizar seleccionados",
"UpdateSelected": "Actualizar seleccionados",
"UpdateUiNotWritableHealthCheckMessage": "No se puede instalar la actualización porque la carpeta de interfaz '{uiFolder}' no es modificable por el usuario '{userName}'.",
"UpgradeUntil": "Actualizar hasta",
@@ -2073,6 +2073,6 @@
"IndexerSettingsMultiLanguageRelease": "Múltiples idiomas",
"IndexerSettingsMultiLanguageReleaseHelpText": "¿Qué idiomas están normalmente en un lanzamiento múltiple en este indexador?",
"DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent está reportando archivos faltantes",
"BlocklistFilterHasNoItems": "El filtro de lista de bloqueo seleccionado no contiene ningún elemento",
"BlocklistFilterHasNoItems": "El filtro de lista de bloqueo seleccionado no contiene elementos",
"HasUnmonitoredSeason": "Tiene temporada sin monitorizar"
}

View File

@@ -1884,7 +1884,7 @@
"CustomFormatsSpecificationSource": "Source",
"ImportListsAniListSettingsAuthenticateWithAniList": "S'authentifier avec AniList",
"ImportListsAniListSettingsImportCancelled": "Importation annulée",
"ImportListsAniListSettingsImportCancelledHelpText": "Médias : La série est annulée",
"ImportListsAniListSettingsImportCancelledHelpText": "Médias : Série annulée",
"ImportListsAniListSettingsImportCompleted": "Importation terminée",
"ImportListsAniListSettingsImportFinished": "Importation terminée",
"ImportListsAniListSettingsUsernameHelpText": "Nom d'utilisateur pour la liste à importer",

View File

@@ -186,5 +186,28 @@
"AutomaticSearch": "Pesquisa automática",
"AutoTaggingRequiredHelpText": "Esta condição de {implementationName} deve corresponder para que a regra de marcação automática seja aplicada. Caso contrário, uma única correspondência de {implementationName} é suficiente.",
"Backup": "Backup",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirmar nova senha"
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirmar nova senha",
"Conditions": "Condições",
"ClickToChangeIndexerFlags": "Clique para alterar os sinalizadores do indexador",
"CustomFormatsSpecificationRegularExpression": "Expressão regular (regex)",
"Dash": "Traço",
"ConnectionSettingsUrlBaseHelpText": "Adiciona um prefixo ao URL {connectionName}, como {url}",
"CustomFormatsSpecificationFlag": "Sinalizar",
"CustomFormatsSpecificationRegularExpressionHelpText": "O regex do formato personalizado não diferencia maiúsculas e minúsculas",
"AutoTaggingSpecificationTag": "Etiqueta",
"ClearBlocklist": "Limpar lista de bloqueio",
"ClearBlocklistMessageText": "Tem a certeza de que deseja limpar todos os itens da lista de bloqueio?",
"CustomFormatsSettingsTriggerInfo": "Um formato personalizado será aplicado a uma versão ou ficheiro quando corresponder a pelo menos um dos diferentes tipos de condição escolhidos.",
"BlocklistOnly": "Apenas adicionar à lista de bloqueio",
"BlocklistAndSearch": "Adicionar à lista de bloqueio e pesquisar",
"BlocklistAndSearchHint": "Iniciar uma pesquisa por um substituto após adicionar à lista de bloqueio",
"BlocklistAndSearchMultipleHint": "Iniciar pesquisas por substitutos após adicionar à lista de bloqueio",
"BlocklistMultipleOnlyHint": "Adicionar à lista de bloqueio sem procurar por substitutos",
"BlocklistOnlyHint": "Adicionar à lista de bloqueio sem procurar por um substituto",
"ChangeCategory": "Alterar categoria",
"ChangeCategoryHint": "Altera o download para a \"Categoria pós-importação\" do cliente de download",
"ChangeCategoryMultipleHint": "Altera os downloads para a \"Categoria pós-importação' do cliente de download",
"ChownGroup": "Fazer chown em grupo",
"Clone": "Clonar",
"ContinuingOnly": "Continuando apenas"
}

View File

@@ -465,7 +465,7 @@
"ChmodFolder": "chmod Pasta",
"ChmodFolderHelpText": "Octal, aplicado durante a importação/renomeação de pastas e arquivos de mídia (sem bits de execução)",
"ChmodFolderHelpTextWarning": "Isso só funciona se o usuário que executa {appName} for o proprietário do arquivo. É melhor garantir que o cliente de download defina as permissões corretamente.",
"ChownGroup": "chown Grupo",
"ChownGroup": "Fazer chown em grupo",
"ChownGroupHelpText": "Nome do grupo ou gid. Use gid para sistemas de arquivos remotos.",
"ChownGroupHelpTextWarning": "Isso só funciona se o usuário que executa {appName} for o proprietário do arquivo. É melhor garantir que o cliente de download use o mesmo grupo que {appName}.",
"ClientPriority": "Prioridade do Cliente",
@@ -683,7 +683,7 @@
"OnApplicationUpdate": "Na Atualização do Aplicativo",
"OnEpisodeFileDelete": "Ao Excluir o Arquivo do Episódio",
"OnEpisodeFileDeleteForUpgrade": "No Arquivo do Episódio Excluir para Atualização",
"OnGrab": "Ao Baixar",
"OnGrab": "Ao obter",
"OnHealthIssue": "Ao Problema de Saúde",
"OnHealthRestored": "Com a Saúde Restaurada",
"OnImport": "Ao Importar",
@@ -1447,12 +1447,12 @@
"MissingLoadError": "Erro ao carregar itens ausentes",
"MissingNoItems": "Nenhum item ausente",
"SearchAll": "Pesquisar Todos",
"UnmonitorSelected": "Não Monitorar Selecionado",
"CutoffUnmetNoItems": "Nenhum item com limite não atendido",
"MonitorSelected": "Monitorar selecionados",
"UnmonitorSelected": "Não Monitorar os Selecionados",
"CutoffUnmetNoItems": "Nenhum item com corte não atingido",
"MonitorSelected": "Monitorar Selecionados",
"SearchForAllMissingEpisodesConfirmationCount": "Tem certeza de que deseja pesquisar todos os episódios ausentes de {totalRecords}?",
"SearchSelected": "Pesquisar Selecionado",
"CutoffUnmetLoadError": "Erro ao carregar itens de limite não atendido",
"CutoffUnmetLoadError": "Erro ao carregar itens de corte não atingidos",
"MassSearchCancelWarning": "Isso não pode ser cancelado depois de iniciado sem reiniciar {appName} ou desabilitar todos os seus indexadores.",
"SearchForAllMissingEpisodes": "Pesquisar por todos os episódios ausentes",
"SearchForCutoffUnmetEpisodes": "Pesquise todos os episódios que o corte não foi atingido",
@@ -1503,11 +1503,11 @@
"NzbgetHistoryItemMessage": "Status PAR: {parStatus} - Status de descompactação: {unpackStatus} - Status de movimentação: {moveStatus} - Status do script: {scriptStatus} - Status de exclusão: {deleteStatus} - Status de marcação: {markStatus}",
"PostImportCategory": "Categoria Pós-Importação",
"SecretToken": "Token Secreto",
"TorrentBlackhole": "Torrent Blackhole",
"TorrentBlackhole": "Blackhole para torrent",
"TorrentBlackholeSaveMagnetFiles": "Salvar Arquivos Magnets",
"TorrentBlackholeSaveMagnetFilesHelpText": "Salve o link magnet se nenhum arquivo .torrent estiver disponível (útil apenas se o cliente de download suportar magnets salvos em um arquivo)",
"UnknownDownloadState": "Estado de download desconhecido: {state}",
"UsenetBlackhole": "Usenet Blackhole",
"UsenetBlackhole": "Blackhole para Usenet",
"DownloadClientQbittorrentSettingsInitialStateHelpText": "Estado inicial para torrents adicionados ao qBittorrent. Observe que os Torrents Forçados não obedecem às restrições de semeação",
"DownloadClientQbittorrentTorrentStatePathError": "Não foi possível importar. O caminho corresponde ao diretório de download da base do cliente, é possível que 'Manter pasta de nível superior' esteja desabilitado para este torrent ou 'Layout de conteúdo de torrent' NÃO esteja definido como 'Original' ou 'Criar subpasta'?",
"DownloadClientQbittorrentValidationCategoryUnsupportedDetail": "As categorias não são suportadas até a versão 3.3.0 do qBittorrent. Atualize ou tente novamente com uma categoria vazia.",
@@ -1645,8 +1645,8 @@
"IndexerSettingsPasskey": "Passkey",
"IndexerSettingsRssUrl": "URL do RSS",
"IndexerSettingsSeasonPackSeedTime": "Tempo de Seed de Pack de Temporada",
"IndexerSettingsSeedRatio": "Proporção de Semeação",
"IndexerSettingsSeedTime": "Tempo de Semeação",
"IndexerSettingsSeedRatio": "Proporção de semeação",
"IndexerSettingsSeedTime": "Tempo de semeação",
"IndexerSettingsSeedTimeHelpText": "O tempo que um torrent deve ser semeado antes de parar, vazio usa o padrão do cliente de download",
"IndexerSettingsWebsiteUrl": "URL do Website",
"IndexerValidationCloudFlareCaptchaExpired": "O token CloudFlare CAPTCHA expirou, atualize-o.",
@@ -1892,8 +1892,8 @@
"CustomFormatsSpecificationMaximumSizeHelpText": "O lançamento deve ser menor ou igual a este tamanho",
"CustomFormatsSpecificationMinimumSize": "Tamanho Mínimo",
"CustomFormatsSpecificationMinimumSizeHelpText": "O lançamento deve ser maior que esse tamanho",
"CustomFormatsSpecificationRegularExpression": "Expressão Regular",
"CustomFormatsSpecificationRegularExpressionHelpText": "RegEx do Formato Personalizado Não Diferencia Maiúsculas de Minúsculas",
"CustomFormatsSpecificationRegularExpression": "Expressão regular (regex)",
"CustomFormatsSpecificationRegularExpressionHelpText": "O regex do formato personalizado não diferencia maiúsculas e minúsculas",
"CustomFormatsSpecificationReleaseGroup": "Grupo do Lançamento",
"CustomFormatsSpecificationResolution": "Resolução",
"CustomFormatsSpecificationSource": "Fonte",
@@ -2010,24 +2010,24 @@
"IgnoreDownloadsHint": "Impede que {appName} processe ainda mais esses downloads",
"RemoveFromDownloadClientHint": "Remove download e arquivo(s) do cliente de download",
"RemoveQueueItemRemovalMethodHelpTextWarning": "'Remover do cliente de download' removerá o download e os arquivos do cliente de download.",
"BlocklistMultipleOnlyHint": "Adiciona a Lista de bloqueio sem procurar substitutos",
"BlocklistOnly": "Apenas Adicionar a Lista de Bloqueio",
"BlocklistAndSearchMultipleHint": "Iniciar pesquisas por substitutos após adicionar a lista de bloqueio",
"BlocklistMultipleOnlyHint": "Adicionar à lista de bloqueio sem procurar por substitutos",
"BlocklistOnly": "Apenas adicionar à lista de bloqueio",
"BlocklistAndSearchMultipleHint": "Iniciar pesquisas por substitutos após adicionar à lista de bloqueio",
"BlocklistReleaseHelpText": "Impede que esta versão seja baixada novamente por {appName} via RSS ou Pesquisa Automática",
"ChangeCategoryHint": "Altera o download para a 'Categoria Pós-Importação' do Cliente de Download",
"ChangeCategoryMultipleHint": "Altera os downloads para a 'Categoria Pós-Importação' do Cliente de Download",
"ChangeCategoryHint": "Altera o download para a \"Categoria pós-importação\" do cliente de download",
"ChangeCategoryMultipleHint": "Altera os downloads para a \"Categoria pós-importação' do cliente de download",
"DatabaseMigration": "Migração de Banco de Dados",
"DoNotBlocklistHint": "Remover sem colocar na lista de bloqueio",
"ChangeCategory": "Alterar Categoria",
"ChangeCategory": "Alterar categoria",
"DoNotBlocklist": "Não coloque na lista de bloqueio",
"IgnoreDownloads": "Ignorar Downloads",
"IgnoreDownloadHint": "Impede que {appName} processe ainda mais este download",
"RemoveMultipleFromDownloadClientHint": "Remove downloads e arquivos do cliente de download",
"RemoveQueueItemRemovalMethod": "Método de Remoção",
"RemoveQueueItemsRemovalMethodHelpTextWarning": "'Remover do Cliente de Download' removerá os downloads e os arquivos do cliente de download.",
"BlocklistAndSearch": "Lista de Bloqueio e Pesquisa",
"BlocklistAndSearchHint": "Inicie uma busca por um substituto após adicionar a lista de bloqueio",
"BlocklistOnlyHint": "Adiciona a Lista de bloqueio sem procurar um substituto",
"BlocklistAndSearch": "Adicionar à lista de bloqueio e pesquisar",
"BlocklistAndSearchHint": "Iniciar uma pesquisa por um substituto após adicionar à lista de bloqueio",
"BlocklistOnlyHint": "Adicionar à lista de bloqueio sem procurar por um substituto",
"IgnoreDownload": "Ignorar Download",
"ImportListStatusAllPossiblePartialFetchHealthCheckMessage": "Todas as listas requerem interação manual devido a possíveis buscas parciais",
"KeepAndTagSeries": "Manter e Etiquetar Séries",
@@ -2038,10 +2038,10 @@
"LogOnly": "Só Registro",
"CleanLibraryLevel": "Limpar Nível da Biblioteca",
"AddDelayProfileError": "Não foi possível adicionar um novo perfil de atraso. Tente novamente.",
"ClickToChangeIndexerFlags": "Clique para alterar sinalizadores do indexador",
"ClickToChangeIndexerFlags": "Clique para alterar os sinalizadores do indexador",
"SelectIndexerFlags": "Selecionar Sinalizadores do Indexador",
"SetIndexerFlagsModalTitle": "{modalTitle} - Definir Sinalizadores do Indexador",
"CustomFormatsSpecificationFlag": "Sinalizador",
"CustomFormatsSpecificationFlag": "Sinalizar",
"IndexerFlags": "Sinalizadores do Indexador",
"SetIndexerFlags": "Definir Sinalizadores de Indexador",
"ImportListsSonarrSettingsSyncSeasonMonitoring": "Sincronização do Monitoramento da Temporada",
@@ -2050,7 +2050,7 @@
"Filters": "Filtros",
"Label": "Rótulo",
"LabelIsRequired": "Rótulo é requerido",
"ConnectionSettingsUrlBaseHelpText": "Adiciona um prefixo a URL {connectionName}, como {url}",
"ConnectionSettingsUrlBaseHelpText": "Adiciona um prefixo ao URL {connectionName}, como {url}",
"ReleaseType": "Tipo de Lançamento",
"DownloadClientDelugeSettingsDirectory": "Diretório de Download",
"DownloadClientDelugeSettingsDirectoryCompleted": "Mover para o Diretório Quando Concluído",
@@ -2061,7 +2061,7 @@
"ImportListsMyAnimeListSettingsAuthenticateWithMyAnimeList": "Autenticar com MyAnimeList",
"ImportListsMyAnimeListSettingsListStatus": "Status da Lista",
"ImportListsMyAnimeListSettingsListStatusHelpText": "Tipo de lista da qual você deseja importar, defina como 'Todas' para todas as listas",
"CustomFormatsSettingsTriggerInfo": "Um formato personalizado será aplicado a um lançamento ou arquivo quando corresponder a pelo menos um de cada um dos diferentes tipos de condição escolhidos.",
"CustomFormatsSettingsTriggerInfo": "Um formato personalizado será aplicado a um lançamento ou arquivo quando corresponder a pelo menos um dos diferentes tipos de condição escolhidos.",
"EpisodeTitleFootNote": "Opcionalmente, controle o truncamento para um número máximo de bytes, incluindo reticências (`...`). Truncar do final (por exemplo, `{Episode Title:30}`) ou do início (por exemplo, `{Episode Title:-30}`) é suportado. Os títulos dos episódios serão automaticamente truncados de acordo com as limitações do sistema de arquivos, se necessário.",
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Opcionalmente, prefixe o título da mensagem com {appName} para diferenciar notificações de diferentes aplicativos",
"ReleaseGroupFootNote": "Opcionalmente, controle o truncamento para um número máximo de bytes, incluindo reticências (`...`). Truncar do final (por exemplo, `{Release Group:30}`) ou do início (por exemplo, `{Release Group:-30}`) é suportado.`).",
@@ -2073,5 +2073,5 @@
"AutoTaggingSpecificationTag": "Etiqueta",
"IndexerSettingsMultiLanguageRelease": "Multi Idiomas",
"DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent está relatando arquivos perdidos",
"BlocklistFilterHasNoItems": "O filtro da lista de bloqueio selecionado não contém itens"
"BlocklistFilterHasNoItems": "O filtro selecionado para a lista de bloqueio não contém itens"
}

View File

@@ -60,7 +60,7 @@
"AddDownloadClientError": "Yeni bir indirme istemcisi eklenemiyor, lütfen tekrar deneyin.",
"AddCustomFilter": "Özel Filtre Ekleyin",
"AddDownloadClientImplementation": "İndirme İstemcisi Ekle - {implementationName}",
"AddExclusion": "Hariç Tutma Ekleme",
"AddExclusion": "Dışlananlara Ekle",
"AddList": "Liste Ekleyin",
"AddListError": "Yeni bir liste eklenemiyor, lütfen tekrar deneyin.",
"AddNew": "Yeni Ekle",
@@ -134,11 +134,11 @@
"AutoRedownloadFailedFromInteractiveSearchHelpText": "Başarısız indirmeler, etkileşimli aramada bulunduğunda otomatik olarak farklı bir versiyonu arayın ve indirmeyi deneyin",
"ApplyTagsHelpTextReplace": "Değiştir: Etiketleri girilen etiketlerle değiştirin (tüm etiketleri kaldırmak için etiket girmeyin)",
"AuthenticationMethod": "Kimlik Doğrulama Yöntemi",
"AuthenticationRequired": "Kimlik Doğrulama Gerekli",
"AuthenticationRequired": "Kimlik Doğrulama",
"AuthenticationRequiredWarning": "Kimlik doğrulaması olmadan uzaktan erişimi engellemek için, {appName}'da artık kimlik doğrulamanın etkinleştirilmesini gerektiriyor. İsteğe bağlı olarak yerel adresler için kimlik doğrulamayı devre dışı bırakabilirsiniz.",
"ApiKeyValidationHealthCheckMessage": "Lütfen API anahtarınızı en az {length} karakter sayısı kadar güncelleyiniz. Bunu ayarlar veya yapılandırma dosyası üzerinden yapabilirsiniz",
"ClearBlocklistMessageText": "Engellenenler listesindeki tüm öğeleri temizlemek istediğinizden emin misiniz?",
"AutomaticUpdatesDisabledDocker": "Docker güncelleme mekanizması kullanıldığında otomatik güncellemeler doğrudan desteklenmez. Kapsayıcı görüntüsünü {appName} dışında güncellemeniz veya bir komut dosyası kullanmanız gerekecek",
"AutomaticUpdatesDisabledDocker": "Docker güncelleme mekanizması kullanıldığında otomatik güncellemeler doğrudan desteklenmez. Konteyner görüntüsünü {appName} dışında güncellemeniz veya bir komut dosyası kullanmanız gerekecek",
"ConnectionLostReconnect": "{appName} otomatik bağlanmayı deneyecek veya aşağıda yeniden yükle seçeneğini işaretleyebilirsiniz.",
"BlackholeWatchFolderHelpText": "{appName} uygulamasının tamamlanmış indirmeleri içe aktaracağı klasör",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Yeni şifreyi onayla",
@@ -196,7 +196,7 @@
"DownloadClientDownloadStationValidationSharedFolderMissing": "Paylaşılan klasör mevcut değil",
"DeleteImportList": "İçe Aktarma Listesini Sil",
"IndexerPriorityHelpText": "Dizinleyici Önceliği (En Yüksek) 1'den (En Düşük) 50'ye kadar. Varsayılan: 25'dir. Eşit olmayan yayınlar için eşitlik bozucu olarak yayınlar alınırken kullanılan {appName}, RSS Senkronizasyonu ve Arama için etkinleştirilmiş tüm dizin oluşturucuları kullanmaya devam edecek",
"DisabledForLocalAddresses": "Yerel Adresler için Devre Dışı Bırakıldı",
"DisabledForLocalAddresses": "Yerel Adreslerde Devre Dışı Bırak",
"DownloadClientDelugeValidationLabelPluginInactive": "Etiket eklentisi etkinleştirilmedi",
"DownloadClientDelugeValidationLabelPluginInactiveDetail": "Kategorileri kullanmak için {clientName} uygulamasında Etiket eklentisini etkinleştirmiş olmanız gerekir.",
"DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Diskstation'ınızda {username} olarak oturum açmalı ve BT/HTTP/FTP/NZB -> Konum altında DownloadStation ayarlarında manuel olarak ayarlamalısınız.",
@@ -383,7 +383,7 @@
"NotificationsKodiSettingAlwaysUpdate": "Daima Güncelle",
"NotificationsKodiSettingsCleanLibrary": "Kütüphaneyi Temizle",
"NotificationsKodiSettingsCleanLibraryHelpText": "Güncellemeden sonra kitaplığı temizle",
"Unmonitored": "İzlenmeyen",
"Unmonitored": "Takip Edilmiyor",
"FormatAgeHour": "saat",
"FormatAgeHours": "saat",
"NoHistory": "Geçmiş yok",
@@ -549,7 +549,7 @@
"VideoDynamicRange": "Video Dinamik Aralığı",
"WouldYouLikeToRestoreBackup": "'{name}' yedeğini geri yüklemek ister misiniz?",
"NotificationsTwitterSettingsDirectMessage": "Direk mesaj",
"PasswordConfirmation": "Şifre onayı",
"PasswordConfirmation": "Şifre Tekrarı",
"OrganizeRenamingDisabled": "Yeniden adlandırma devre dışı bırakıldı, yeniden adlandırılacak bir şey yok",
"ResetQualityDefinitionsMessageText": "Kalite tanımlarını sıfırlamak istediğinizden emin misiniz?",
"SelectFolderModalTitle": "{modalTitle} - Klasör seç",
@@ -689,7 +689,7 @@
"NotificationsValidationUnableToConnectToService": "{serviceName} hizmetine bağlanılamıyor",
"OrganizeLoadError": "Önizlemeler yüklenirken hata oluştu",
"ParseModalHelpTextDetails": "{appName}, başlığı ayrıştırmaya ve size konuyla ilgili ayrıntıları göstermeye çalışacak",
"NegateHelpText": "İşaretlenirse, bu {implementationName} koşulu eşleşirse özel format uygulanmayacaktır.",
"NegateHelpText": "İşaretlenirse, {implementationName} koşulu eşleşirse özel format uygulanmayacaktır.",
"ParseModalHelpText": "Yukarıdaki girişe bir yayın başlığı girin",
"Period": "Periyot",
"NotificationsPushoverSettingsSound": "Ses",
@@ -802,5 +802,40 @@
"MustContain": "İçermeli",
"MustNotContain": "İçermemeli",
"RssSyncIntervalHelpTextWarning": "Bu, tüm dizinleyiciler için geçerli olacaktır, lütfen onlar tarafından belirlenen kurallara uyun",
"DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent eksik dosya raporluyor"
"DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent eksik dosya raporluyor",
"ImportListExclusions": "İçe Aktarma Listesinden Hariç Bırakılan(lar)",
"UiLanguage": "Arayüz Dili",
"IndexerSettingsSeedTimeHelpText": "Bir torrentin durmadan önce seed edilmesi gereken süre. Boş bırakılırsa indirme istemcisinin varsayılan ayarını kullanır",
"IndexerSettingsSeedRatioHelpText": "Bir torrentin durmadan önce ulaşması gereken oran. Boş bırakılırsa indirme istemcisinin varsayılan değerini kullanır. Oran en az 1,0 olmalı ve indeksleyici kurallarına uygun olmalıdır",
"EditImportListExclusion": "Hariç Tutulanlar Listesini Düzenle",
"UiLanguageHelpText": "{appName}'ın arayüz için kullanacağı dil",
"IndexerSettingsSeedTime": "Seed Süresi",
"BlocklistFilterHasNoItems": "Seçilen engelleme listesi filtresi hiçbir öğe içermiyor",
"IndexerSettingsSeedRatio": "Seed Oranı",
"Password": "Şifre",
"CutoffUnmetNoItems": "Karşılanmayan son öğe yok",
"MissingLoadError": "Eksik öğeler yüklenirken hata oluştu",
"MissingNoItems": "Eksik öğe yok",
"CutoffUnmet": "Kesinti Karşılanmayan",
"Monitor": "Takip",
"CutoffUnmetLoadError": "Karşılanmamış kesinti öğeleri yüklenirken hata oluştu",
"Monitored": "Takip Ediliyor",
"MonitoredOnly": "Sadece Takip Edilen",
"External": "Harici",
"MassSearchCancelWarning": "Bu işlem, {appName} yeniden başlatılmadan veya tüm dizin oluşturucularınız devre dışı bırakılmadan başlatılır ise iptal edilemez.",
"IncludeUnmonitored": "Takip Edilmeyenleri Dahil Et",
"MonitorSelected": "Takip Edilen Seçildi",
"MonitoredStatus": "Takip Edilen/Durum",
"UnmonitorSelected": "Seçili Takipleri Kaldır",
"ShowMonitored": "Takip Edilenleri Göster",
"ShowMonitoredHelpText": "Posterin altında takip durumu göster",
"Ui": "Arayüz",
"Mechanism": "İşleyiş",
"UiSettings": "Arayüz Ayarları",
"Script": "Hazır Metin",
"UiSettingsLoadError": "Arayüz ayarları yüklenemiyor",
"UpdateAutomaticallyHelpText": "Güncelleştirmeleri otomatik olarak indirip yükleyin. Sistem: Güncellemeler'den yükleme yapmaya devam edebileceksiniz",
"Wanted": "Arananlar",
"Cutoff": "Kesinti",
"Required": "Gerekli"
}

View File

@@ -518,7 +518,7 @@
"AnEpisodeIsDownloading": "集正在下载",
"AuthenticationRequiredWarning": "为了防止未经身份验证的远程访问,{appName} 现在需要启用身份验证。您可以禁用本地地址的身份验证。",
"AutomaticSearch": "自动搜索",
"BackupFolderHelpText": "相对路径将在{appName}AppData目录下",
"BackupFolderHelpText": "相对路径将在 {appName}AppData 目录下",
"BindAddress": "绑定地址",
"BindAddressHelpText": "有效的 IP 地址、localhost、或以'*'代表所有接口",
"BlocklistLoadError": "无法加载黑名单",
@@ -1827,5 +1827,8 @@
"CustomFormatsSpecificationMaximumSizeHelpText": "必须小于或等于该尺寸时才会发布",
"AutoTaggingSpecificationGenre": "类型",
"AutoTaggingSpecificationSeriesType": "系列类型",
"AutoTaggingSpecificationStatus": "状态"
"AutoTaggingSpecificationStatus": "状态",
"ClickToChangeIndexerFlags": "点击修改索引器标志",
"ConnectionSettingsUrlBaseHelpText": "向 {clientName} url 添加前缀,例如 {url}",
"BlocklistFilterHasNoItems": "所选的黑名单过滤器没有项目"
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Apprise
@@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Apprise
}
}
public class AppriseSettings : IProviderConfig
public class AppriseSettings : NotificationSettingsBase<AppriseSettings>
{
private static readonly AppriseSettingsValidator Validator = new ();
@@ -66,7 +65,7 @@ namespace NzbDrone.Core.Notifications.Apprise
[FieldDefinition(7, Label = "Password", Type = FieldType.Password, HelpText = "NotificationsAppriseSettingsPasswordHelpText", Privacy = PrivacyLevel.Password)]
public string AuthPassword { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths;
@@ -16,9 +15,9 @@ namespace NzbDrone.Core.Notifications.CustomScript
}
}
public class CustomScriptSettings : IProviderConfig
public class CustomScriptSettings : NotificationSettingsBase<CustomScriptSettings>
{
private static readonly CustomScriptSettingsValidator Validator = new CustomScriptSettingsValidator();
private static readonly CustomScriptSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "Path", Type = FieldType.FilePath)]
public string Path { get; set; }
@@ -26,7 +25,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
[FieldDefinition(1, Label = "NotificationsCustomScriptSettingsArguments", HelpText = "NotificationsCustomScriptSettingsArgumentsHelpText", Hidden = HiddenType.HiddenIfNotSet)]
public string Arguments { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Discord
@@ -14,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Discord
}
}
public class DiscordSettings : IProviderConfig
public class DiscordSettings : NotificationSettingsBase<DiscordSettings>
{
public DiscordSettings()
{
@@ -89,7 +88,7 @@ namespace NzbDrone.Core.Notifications.Discord
[FieldDefinition(6, Label = "NotificationsDiscordSettingsOnManualInteractionFields", Advanced = true, SelectOptions = typeof(DiscordManualInteractionFieldType), HelpText = "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText", Type = FieldType.Select)]
public IEnumerable<int> ManualInteractionFields { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Email
@@ -26,9 +25,9 @@ namespace NzbDrone.Core.Notifications.Email
}
}
public class EmailSettings : IProviderConfig
public class EmailSettings : NotificationSettingsBase<EmailSettings>
{
private static readonly EmailSettingsValidator Validator = new EmailSettingsValidator();
private static readonly EmailSettingsValidator Validator = new ();
public EmailSettings()
{
@@ -66,7 +65,7 @@ namespace NzbDrone.Core.Notifications.Email
[FieldDefinition(8, Label = "NotificationsEmailSettingsBccAddress", HelpText = "NotificationsEmailSettingsBccAddressHelpText", Advanced = true)]
public IEnumerable<string> Bcc { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Gotify
@@ -14,9 +13,9 @@ namespace NzbDrone.Core.Notifications.Gotify
}
}
public class GotifySettings : IProviderConfig
public class GotifySettings : NotificationSettingsBase<GotifySettings>
{
private static readonly GotifySettingsValidator Validator = new GotifySettingsValidator();
private static readonly GotifySettingsValidator Validator = new ();
public GotifySettings()
{
@@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Gotify
[FieldDefinition(3, Label = "NotificationsGotifySettingIncludeSeriesPoster", Type = FieldType.Checkbox, HelpText = "NotificationsGotifySettingIncludeSeriesPosterHelpText")]
public bool IncludeSeriesPoster { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Join
@@ -14,15 +13,15 @@ namespace NzbDrone.Core.Notifications.Join
}
}
public class JoinSettings : IProviderConfig
public class JoinSettings : NotificationSettingsBase<JoinSettings>
{
private static readonly JoinSettingsValidator Validator = new ();
public JoinSettings()
{
Priority = (int)JoinPriority.Normal;
}
private static readonly JoinSettingsValidator Validator = new JoinSettingsValidator();
[FieldDefinition(0, Label = "ApiKey", HelpText = "NotificationsJoinSettingsApiKeyHelpText", HelpLink = "https://joinjoaomgcd.appspot.com/")]
public string ApiKey { get; set; }
@@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Join
[FieldDefinition(3, Label = "NotificationsJoinSettingsNotificationPriority", Type = FieldType.Select, SelectOptions = typeof(JoinPriority))]
public int Priority { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Mailgun
@@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Mailgun
}
}
public class MailgunSettings : IProviderConfig
public class MailgunSettings : NotificationSettingsBase<MailgunSettings>
{
private static readonly MailGunSettingsValidator Validator = new MailGunSettingsValidator();
private static readonly MailGunSettingsValidator Validator = new ();
public MailgunSettings()
{
@@ -41,7 +40,7 @@ namespace NzbDrone.Core.Notifications.Mailgun
[FieldDefinition(4, Label = "NotificationsEmailSettingsRecipientAddress", Type = FieldType.Tag)]
public IEnumerable<string> Recipients { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -2,7 +2,6 @@ using FluentValidation;
using Newtonsoft.Json;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Emby
@@ -19,9 +18,9 @@ namespace NzbDrone.Core.Notifications.Emby
}
}
public class MediaBrowserSettings : IProviderConfig
public class MediaBrowserSettings : NotificationSettingsBase<MediaBrowserSettings>
{
private static readonly MediaBrowserSettingsValidator Validator = new MediaBrowserSettingsValidator();
private static readonly MediaBrowserSettingsValidator Validator = new ();
public MediaBrowserSettings()
{
@@ -65,7 +64,7 @@ namespace NzbDrone.Core.Notifications.Emby
public bool IsValid => !string.IsNullOrWhiteSpace(Host) && Port > 0;
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Notifiarr
@@ -13,14 +12,14 @@ namespace NzbDrone.Core.Notifications.Notifiarr
}
}
public class NotifiarrSettings : IProviderConfig
public class NotifiarrSettings : NotificationSettingsBase<NotifiarrSettings>
{
private static readonly NotifiarrSettingsValidator Validator = new NotifiarrSettingsValidator();
private static readonly NotifiarrSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsNotifiarrSettingsApiKeyHelpText", HelpLink = "https://notifiarr.com")]
public string ApiKey { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -8,7 +8,7 @@ using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Notifications
{
public abstract class NotificationBase<TSettings> : INotification
where TSettings : IProviderConfig, new()
where TSettings : NotificationSettingsBase<TSettings>, new()
{
protected const string EPISODE_GRABBED_TITLE = "Episode Grabbed";
protected const string EPISODE_DOWNLOADED_TITLE = "Episode Downloaded";

View File

@@ -1,9 +1,13 @@
using System;
using Equ;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Notifications
{
public class NotificationDefinition : ProviderDefinition
public class NotificationDefinition : ProviderDefinition, IEquatable<NotificationDefinition>
{
private static readonly MemberwiseEqualityComparer<NotificationDefinition> Comparer = MemberwiseEqualityComparer<NotificationDefinition>.ByProperties;
public bool OnGrab { get; set; }
public bool OnDownload { get; set; }
public bool OnUpgrade { get; set; }
@@ -13,23 +17,63 @@ namespace NzbDrone.Core.Notifications
public bool OnEpisodeFileDelete { get; set; }
public bool OnEpisodeFileDeleteForUpgrade { get; set; }
public bool OnHealthIssue { get; set; }
public bool IncludeHealthWarnings { get; set; }
public bool OnHealthRestored { get; set; }
public bool OnApplicationUpdate { get; set; }
public bool OnManualInteractionRequired { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnGrab { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnDownload { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnUpgrade { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnRename { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnSeriesAdd { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnSeriesDelete { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnEpisodeFileDelete { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnEpisodeFileDeleteForUpgrade { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnHealthIssue { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnHealthRestored { get; set; }
public bool IncludeHealthWarnings { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnApplicationUpdate { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnManualInteractionRequired { get; set; }
[MemberwiseEqualityIgnore]
public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || OnRename || OnSeriesAdd || OnSeriesDelete || OnEpisodeFileDelete || (OnEpisodeFileDelete && OnEpisodeFileDeleteForUpgrade) || OnHealthIssue || OnHealthRestored || OnApplicationUpdate || OnManualInteractionRequired;
public bool Equals(NotificationDefinition other)
{
return Comparer.Equals(this, other);
}
public override bool Equals(object obj)
{
return Equals(obj as NotificationDefinition);
}
public override int GetHashCode()
{
return Comparer.GetHashCode(this);
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
using Equ;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications
{
public abstract class NotificationSettingsBase<TSettings> : IProviderConfig, IEquatable<TSettings>
where TSettings : NotificationSettingsBase<TSettings>
{
private static readonly MemberwiseEqualityComparer<TSettings> Comparer = MemberwiseEqualityComparer<TSettings>.ByProperties;
public abstract NzbDroneValidationResult Validate();
public bool Equals(TSettings other)
{
return Comparer.Equals(this as TSettings, other);
}
public override bool Equals(object obj)
{
return Equals(obj as TSettings);
}
public override int GetHashCode()
{
return Comparer.GetHashCode(this as TSettings);
}
}
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Ntfy
@@ -21,12 +20,12 @@ namespace NzbDrone.Core.Notifications.Ntfy
RuleForEach(c => c.Topics).NotEmpty().Matches("[a-zA-Z0-9_-]+").Must(c => !InvalidTopics.Contains(c)).WithMessage("Invalid topic");
}
private static List<string> InvalidTopics => new List<string> { "announcements", "app", "docs", "settings", "stats", "mytopic-rw", "mytopic-ro", "mytopic-wo" };
private static List<string> InvalidTopics => new () { "announcements", "app", "docs", "settings", "stats", "mytopic-rw", "mytopic-ro", "mytopic-wo" };
}
public class NtfySettings : IProviderConfig
public class NtfySettings : NotificationSettingsBase<NtfySettings>
{
private static readonly NtfySettingsValidator Validator = new NtfySettingsValidator();
private static readonly NtfySettingsValidator Validator = new ();
public NtfySettings()
{
@@ -59,7 +58,7 @@ namespace NzbDrone.Core.Notifications.Ntfy
[FieldDefinition(7, Label = "NotificationsNtfySettingsClickUrl", Type = FieldType.Url, HelpText = "NotificationsNtfySettingsClickUrlHelpText")]
public string ClickUrl { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Plex.Server
@@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Plex.Server
}
}
public class PlexServerSettings : IProviderConfig
public class PlexServerSettings : NotificationSettingsBase<PlexServerSettings>
{
private static readonly PlexServerSettingsValidator Validator = new PlexServerSettingsValidator();
private static readonly PlexServerSettingsValidator Validator = new ();
public PlexServerSettings()
{
@@ -62,7 +61,7 @@ namespace NzbDrone.Core.Notifications.Plex.Server
public bool IsValid => !string.IsNullOrWhiteSpace(Host);
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Prowl
@@ -13,9 +12,9 @@ namespace NzbDrone.Core.Notifications.Prowl
}
}
public class ProwlSettings : IProviderConfig
public class ProwlSettings : NotificationSettingsBase<ProwlSettings>
{
private static readonly ProwlSettingsValidator Validator = new ProwlSettingsValidator();
private static readonly ProwlSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://www.prowlapp.com/api_settings.php")]
public string ApiKey { get; set; }
@@ -25,7 +24,7 @@ namespace NzbDrone.Core.Notifications.Prowl
public bool IsValid => !string.IsNullOrWhiteSpace(ApiKey) && Priority >= -2 && Priority <= 2;
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.PushBullet
@@ -15,9 +14,9 @@ namespace NzbDrone.Core.Notifications.PushBullet
}
}
public class PushBulletSettings : IProviderConfig
public class PushBulletSettings : NotificationSettingsBase<PushBulletSettings>
{
private static readonly PushBulletSettingsValidator Validator = new PushBulletSettingsValidator();
private static readonly PushBulletSettingsValidator Validator = new ();
public PushBulletSettings()
{
@@ -37,7 +36,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
[FieldDefinition(3, Label = "NotificationsPushBulletSettingSenderId", HelpText = "NotificationsPushBulletSettingSenderIdHelpText")]
public string SenderId { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Pushcut
@@ -14,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
}
}
public class PushcutSettings : IProviderConfig
public class PushcutSettings : NotificationSettingsBase<PushcutSettings>
{
private static readonly PushcutSettingsValidator Validator = new ();
@@ -27,7 +26,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
[FieldDefinition(2, Label = "NotificationsPushcutSettingsTimeSensitive", Type = FieldType.Checkbox, HelpText = "NotificationsPushcutSettingsTimeSensitiveHelpText")]
public bool TimeSensitive { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Pushover
@@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Pushover
}
}
public class PushoverSettings : IProviderConfig
public class PushoverSettings : NotificationSettingsBase<PushoverSettings>
{
private static readonly PushoverSettingsValidator Validator = new PushoverSettingsValidator();
private static readonly PushoverSettingsValidator Validator = new ();
public PushoverSettings()
{
@@ -51,7 +50,7 @@ namespace NzbDrone.Core.Notifications.Pushover
public bool IsValid => !string.IsNullOrWhiteSpace(UserKey) && Priority >= -1 && Priority <= 2;
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,8 +1,7 @@
using System;
using System;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.SendGrid
@@ -18,9 +17,9 @@ namespace NzbDrone.Core.Notifications.SendGrid
}
}
public class SendGridSettings : IProviderConfig
public class SendGridSettings : NotificationSettingsBase<SendGridSettings>
{
private static readonly SendGridSettingsValidator Validator = new SendGridSettingsValidator();
private static readonly SendGridSettingsValidator Validator = new ();
public SendGridSettings()
{
@@ -39,7 +38,7 @@ namespace NzbDrone.Core.Notifications.SendGrid
[FieldDefinition(3, Label = "NotificationsEmailSettingsRecipientAddress", Type = FieldType.Tag)]
public IEnumerable<string> Recipients { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Signal
@@ -16,7 +15,7 @@ namespace NzbDrone.Core.Notifications.Signal
}
}
public class SignalSettings : IProviderConfig
public class SignalSettings : NotificationSettingsBase<SignalSettings>
{
private static readonly SignalSettingsValidator Validator = new ();
@@ -42,7 +41,7 @@ namespace NzbDrone.Core.Notifications.Signal
[FieldDefinition(6, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password, HelpText = "NotificationsSignalSettingsPasswordHelpText")]
public string AuthPassword { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Simplepush
@@ -13,9 +12,9 @@ namespace NzbDrone.Core.Notifications.Simplepush
}
}
public class SimplepushSettings : IProviderConfig
public class SimplepushSettings : NotificationSettingsBase<SimplepushSettings>
{
private static readonly SimplepushSettingsValidator Validator = new SimplepushSettingsValidator();
private static readonly SimplepushSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "NotificationsSimplepushSettingsKey", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://simplepush.io/features")]
public string Key { get; set; }
@@ -25,7 +24,7 @@ namespace NzbDrone.Core.Notifications.Simplepush
public bool IsValid => !string.IsNullOrWhiteSpace(Key);
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Slack
@@ -14,9 +13,9 @@ namespace NzbDrone.Core.Notifications.Slack
}
}
public class SlackSettings : IProviderConfig
public class SlackSettings : NotificationSettingsBase<SlackSettings>
{
private static readonly SlackSettingsValidator Validator = new SlackSettingsValidator();
private static readonly SlackSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "NotificationsSettingsWebhookUrl", HelpText = "NotificationsSlackSettingsWebhookUrlHelpText", Type = FieldType.Url, HelpLink = "https://my.slack.com/services/new/incoming-webhook/")]
public string WebHookUrl { get; set; }
@@ -30,7 +29,7 @@ namespace NzbDrone.Core.Notifications.Slack
[FieldDefinition(3, Label = "NotificationsSlackSettingsChannel", HelpText = "NotificationsSlackSettingsChannelHelpText", Type = FieldType.Textbox)]
public string Channel { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Synology
@@ -9,9 +8,9 @@ namespace NzbDrone.Core.Notifications.Synology
{
}
public class SynologyIndexerSettings : IProviderConfig
public class SynologyIndexerSettings : NotificationSettingsBase<SynologyIndexerSettings>
{
private static readonly SynologyIndexerSettingsValidator Validator = new SynologyIndexerSettingsValidator();
private static readonly SynologyIndexerSettingsValidator Validator = new ();
public SynologyIndexerSettings()
{
@@ -21,7 +20,7 @@ namespace NzbDrone.Core.Notifications.Synology
[FieldDefinition(0, Label = "NotificationsSettingsUpdateLibrary", Type = FieldType.Checkbox, HelpText = "NotificationsSynologySettingsUpdateLibraryHelpText")]
public bool UpdateLibrary { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Telegram
@@ -16,9 +15,9 @@ namespace NzbDrone.Core.Notifications.Telegram
}
}
public class TelegramSettings : IProviderConfig
public class TelegramSettings : NotificationSettingsBase<TelegramSettings>
{
private static readonly TelegramSettingsValidator Validator = new TelegramSettingsValidator();
private static readonly TelegramSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "NotificationsTelegramSettingsBotToken", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://core.telegram.org/bots")]
public string BotToken { get; set; }
@@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Telegram
[FieldDefinition(4, Label = "NotificationsTelegramSettingsIncludeAppName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeAppNameHelpText")]
public bool IncludeAppNameInTitle { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using System;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Trakt
@@ -16,9 +15,9 @@ namespace NzbDrone.Core.Notifications.Trakt
}
}
public class TraktSettings : IProviderConfig
public class TraktSettings : NotificationSettingsBase<TraktSettings>
{
private static readonly TraktSettingsValidator Validator = new TraktSettingsValidator();
private static readonly TraktSettingsValidator Validator = new ();
public TraktSettings()
{
@@ -40,7 +39,7 @@ namespace NzbDrone.Core.Notifications.Trakt
[FieldDefinition(4, Label = "NotificationsTraktSettingsAuthenticateWithTrakt", Type = FieldType.OAuth)]
public string SignIn { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,7 +1,6 @@
using FluentValidation;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Twitter
@@ -28,9 +27,9 @@ namespace NzbDrone.Core.Notifications.Twitter
}
}
public class TwitterSettings : IProviderConfig
public class TwitterSettings : NotificationSettingsBase<TwitterSettings>
{
private static readonly TwitterSettingsValidator Validator = new TwitterSettingsValidator();
private static readonly TwitterSettingsValidator Validator = new ();
public TwitterSettings()
{
@@ -59,7 +58,7 @@ namespace NzbDrone.Core.Notifications.Twitter
[FieldDefinition(6, Label = "NotificationsTwitterSettingsConnectToTwitter", Type = FieldType.OAuth)]
public string AuthorizeNotification { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -6,13 +6,12 @@ using NzbDrone.Core.Configuration;
using NzbDrone.Core.Localization;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Tags;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Notifications.Webhook
{
public abstract class WebhookBase<TSettings> : NotificationBase<TSettings>
where TSettings : IProviderConfig, new()
where TSettings : NotificationSettingsBase<TSettings>, new()
{
private readonly IConfigFileProvider _configFileProvider;
private readonly IConfigService _configService;

View File

@@ -1,7 +1,6 @@
using System;
using System;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Webhook
@@ -14,9 +13,9 @@ namespace NzbDrone.Core.Notifications.Webhook
}
}
public class WebhookSettings : IProviderConfig
public class WebhookSettings : NotificationSettingsBase<WebhookSettings>
{
private static readonly WebhookSettingsValidator Validator = new WebhookSettingsValidator();
private static readonly WebhookSettingsValidator Validator = new ();
public WebhookSettings()
{
@@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Webhook
[FieldDefinition(3, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
public string Password { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -3,7 +3,6 @@ using FluentValidation;
using Newtonsoft.Json;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Xbmc
@@ -18,7 +17,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
}
}
public class XbmcSettings : IProviderConfig
public class XbmcSettings : NotificationSettingsBase<XbmcSettings>
{
private static readonly XbmcSettingsValidator Validator = new ();
@@ -69,7 +68,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
[JsonIgnore]
public string Address => $"{Host.ToUrlHost()}:{Port}{UrlBase}";
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

View File

@@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.123" />
<PackageReference Include="Diacritical.Net" Version="1.0.4" />
<PackageReference Include="Equ" Version="2.3.0" />
<PackageReference Include="MailKit" Version="3.6.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.21" />
<PackageReference Include="Polly" Version="8.3.1" />
@@ -24,7 +25,7 @@
<PackageReference Include="MonoTorrent" Version="2.0.7" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="System.Text.Json" Version="6.0.9" />
<PackageReference Include="Npgsql" Version="7.0.4" />
<PackageReference Include="Npgsql" Version="7.0.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\Sonarr.Common.csproj" />

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Equ;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.ThingiProvider
@@ -16,20 +17,22 @@ namespace NzbDrone.Core.ThingiProvider
public string Name { get; set; }
[JsonIgnore]
[MemberwiseEqualityIgnore]
public string ImplementationName { get; set; }
public string Implementation { get; set; }
public string ConfigContract { get; set; }
public virtual bool Enable { get; set; }
[MemberwiseEqualityIgnore]
public ProviderMessage Message { get; set; }
public HashSet<int> Tags { get; set; }
[MemberwiseEqualityIgnore]
public IProviderConfig Settings
{
get
{
return _settings;
}
get => _settings;
set
{
_settings = value;

Some files were not shown because too many files have changed in this diff Show More