Compare commits

...

21 Commits

Author SHA1 Message Date
Mark McDowall
9312f17041 New: Use 307 redirect for requests missing URL Base
(cherry picked from commit 39074b0b1d040969f86d787c2346d5ed5a9f72dc)
2024-10-08 02:20:37 +03:00
Bogdan
8192c22910 Bump macOS runner version to 13 2024-10-06 16:30:37 +03:00
ManiMatter
0b1d6b677a Add '.temp*' to .gitignore (#3778) 2024-10-02 22:53:34 +03:00
Bogdan
d666df0189 Bump version to 0.4.1 2024-09-29 08:19:59 +03:00
Bogdan
10d8f345c1 Display naming example errors when all fields are empty
(cherry picked from commit 768af433d1655c587a9eee9b100f306ba4345f88)
2024-09-28 05:18:41 +03:00
Robin Dadswell
fb720b8714 Fixed: Telegram log message including token
(cherry picked from commit a7cb264cc8013d9a56aee7d5e41acfd76cde5f96)
2024-09-28 05:18:29 +03:00
Servarr
e8131b5791 Automated API Docs update 2024-09-25 10:34:30 +03:00
Bogdan
4f793f6b93 Remove $ from Discord delete notifications 2024-09-25 10:28:00 +03:00
Bogdan
4215c21c94 Add package needed for RemoveDiacritics 2024-09-23 05:46:26 +03:00
Paul DiLoreto
6913789adc New: Use instance name in forms authentication cookie name (#3761)
(cherry picked from commit 97ebaf279650082c6baee9563ef179921c5ed25a)
(cherry picked from commit faf9173b3b4a298e3afa9a186e66ba6764ac055e)
(cherry picked from commit 75fae9262c6ca003d24df9fcf035d75b1e90f994)

---------

Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2024-09-23 05:45:01 +03:00
Mark McDowall
09e0c40792 Fixed: Limit redirects after login to local paths
(cherry picked from commit 14005d8d1054eafaba808337a109d5812f3e79e6)
2024-09-23 05:41:21 +03:00
Mark McDowall
baff805551 New: Return downloading magnets from Transmission
(cherry picked from commit 11a9dcb3890eaf99602900f37e64007f2fbf9b8e)
2024-09-23 05:40:25 +03:00
Bogdan
c885fe43cd Fix disabled style for monitor toggle button
(cherry picked from commit dde28cbd7e16b85f78d38c8dde7cf6bbb6119bb3)
2024-09-23 05:39:36 +03:00
Treycos
464a777722 Updated code action fixall value for VSCode
(cherry picked from commit 8af4246ff9baee4c291550102769a1186f65dc29)
2024-09-23 05:39:19 +03:00
momo
89e5999c85 Fix description for API key as query parameter
(cherry picked from commit 30c36fdc3baa686102ff124833c7963fc786f251)
2024-09-23 05:36:05 +03:00
Bogdan
b6fa332550 Ignore metadata tests temporarily once again 2024-09-23 05:35:27 +03:00
Bogdan
05f262dc0a Don't persist value for SslCertHash when checking for existence
(cherry picked from commit 98c4cbdd13dc49ad30e91343897b8bd006002489)
2024-09-07 16:26:28 -05:00
Bogdan
699b765ee9 Remove provider status on provider deletion
(cherry picked from commit f45713bff815b2a49a5cdad4afe62a53bbdf6a6e)
2024-09-07 16:26:11 -05:00
Mark McDowall
84beba2383 Don't hash files in development builds
(cherry picked from commit bc7799139e52b92956eb595fb87f44d7dda9a320)
2024-09-07 13:46:26 -05:00
Mark McDowall
62eceb9148 New: Default file log level changed to debug
(cherry picked from commit 9b528eb82914a05cfc3b67d4d6146ce51e86f68d)
2024-09-07 13:45:57 -05:00
Servarr
f46070d4b0 Translations update from Servarr Weblate (#3578)
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Ano10 <arnaudthommeray+github@ik.me>
Co-authored-by: Dream <seth.gecko.rr@gmail.com>
Co-authored-by: Gabriel Markowski <gmarkowski62@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Jason54 <jason54700.jg@gmail.com>
Co-authored-by: Kerk en IT <info@kerkenit.nl>
Co-authored-by: MattiaPell <mattiapellegrini16@gmail.com>
Co-authored-by: Nota Inutilis <hugo@notainutilis.fr>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: iMohmmedSA <i.mohmmed.i+1@gmail.com>
2024-09-07 13:44:59 -05:00
41 changed files with 278 additions and 180 deletions

1
.gitignore vendored
View File

@@ -120,6 +120,7 @@ _artifacts
_rawPackage/
_dotTrace*
_tests/
_temp*
*.Result.xml
coverage*.xml
coverage*.json

View File

@@ -9,7 +9,7 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '0.4.0'
majorVersion: '0.4.1'
minorVersion: $[counter('minorVersion', 1)]
readarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(readarrVersion)'
@@ -20,7 +20,7 @@ variables:
innoVersion: '6.2.0'
windowsImage: 'windows-2022'
linuxImage: 'ubuntu-20.04'
macImage: 'macOS-12'
macImage: 'macOS-13'
trigger:
branches:

View File

@@ -9,7 +9,7 @@
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll": true
"source.fixAll": "explicit"
},
"typescript.preferences.quoteStyle": "single",

View File

@@ -67,7 +67,7 @@ module.exports = (env) => {
output: {
path: distFolder,
publicPath: '/',
filename: '[name]-[contenthash].js',
filename: isProduction ? '[name]-[contenthash].js' : '[name].js',
sourceMapFilename: '[file].map'
},
@@ -92,7 +92,7 @@ module.exports = (env) => {
new MiniCssExtractPlugin({
filename: 'Content/styles.css',
chunkFilename: 'Content/[id]-[chunkhash].css'
chunkFilename: isProduction ? 'Content/[id]-[chunkhash].css' : 'Content/[id].css'
}),
new HtmlWebpackPlugin({
@@ -202,7 +202,7 @@ module.exports = (env) => {
options: {
importLoaders: 1,
modules: {
localIdentName: '[name]/[local]/[hash:base64:5]'
localIdentName: isProduction ? '[name]/[local]/[hash:base64:5]' : '[name]/[local]'
}
}
},

View File

@@ -3,9 +3,9 @@
padding: 0;
font-size: inherit;
}
.isDisabled {
color: var(--disabledColor);
cursor: not-allowed;
&.isDisabled {
color: var(--disabledColor);
cursor: not-allowed;
}
}

View File

@@ -1,4 +1,3 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -15,11 +14,11 @@ function createMapStateToProps() {
(state) => state.settings.advancedSettings,
(state) => state.settings.namingExamples,
createSettingsSectionSelector(SECTION),
(advancedSettings, examples, sectionSettings) => {
(advancedSettings, namingExamples, sectionSettings) => {
return {
advancedSettings,
examples: examples.item,
examplesPopulated: !_.isEmpty(examples.item),
examples: namingExamples.item,
examplesPopulated: namingExamples.isPopulated,
...sectionSettings
};
}

View File

@@ -4,6 +4,7 @@
<PackageVersion Include="AutoFixture" Version="4.17.0" />
<PackageVersion Include="coverlet.collector" Version="3.0.4-preview.27.ge7cb7c3b40" PrivateAssets="all" />
<PackageVersion Include="Dapper" Version="2.0.151" />
<PackageVersion Include="Diacritical.Net" Version="1.0.4" />
<PackageVersion Include="DryIoc.dll" Version="5.4.3" />
<PackageVersion Include="DryIoc.Microsoft.DependencyInjection" Version="6.2.0" />
<PackageVersion Include="Equ" Version="2.3.0" />
@@ -65,4 +66,4 @@
<PackageVersion Include="System.ValueTuple" Version="4.5.0" />
<PackageVersion Include="TagLibSharp-Lidarr" Version="2.2.0.19" />
</ItemGroup>
</Project>
</Project>

View File

@@ -89,6 +89,10 @@ namespace NzbDrone.Common.Test.InstrumentationTests
[TestCase(@"https://discord.com/api/webhooks/mySecret")]
[TestCase(@"https://discord.com/api/webhooks/mySecret/01233210")]
// Telegram
[TestCase(@"https://api.telegram.org/bot1234567890:mySecret/sendmessage: chat_id=123456&parse_mode=HTML&text=<text>")]
[TestCase(@"https://api.telegram.org/bot1234567890:mySecret/")]
public void should_clean_message(string message)
{
var cleansedMessage = CleanseLogMessage.Cleanse(message);

View File

@@ -54,7 +54,10 @@ namespace NzbDrone.Common.Instrumentation
new (@"api/v[0-9]/notification/readarr/(?<secret>[\w-]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Discord
new (@"discord.com/api/webhooks/((?<secret>[\w-]+)/)?(?<secret>[\w-]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase)
new (@"discord.com/api/webhooks/((?<secret>[\w-]+)/)?(?<secret>[\w-]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Telegram
new (@"api.telegram.org/bot(?<id>[\d]+):(?<secret>[\w-]+)/", RegexOptions.Compiled | RegexOptions.IgnoreCase)
};
private static readonly Regex CleanseRemoteIPRegex = new (@"(?:Auth-\w+(?<!Failure|Unauthorized) ip|from) (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", RegexOptions.Compiled);

View File

@@ -49,10 +49,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
}
[Test]
public void magnet_download_should_not_return_the_item()
public void magnet_download_should_be_returned_as_queued()
{
PrepareClientToReturnMagnetItem();
Subject.GetItems().Count().Should().Be(0);
var item = Subject.GetItems().Single();
item.Status.Should().Be(DownloadItemStatus.Queued);
}
[Test]

View File

@@ -60,7 +60,10 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
public void magnet_download_should_not_return_the_item()
{
PrepareClientToReturnMagnetItem();
Subject.GetItems().Count().Should().Be(0);
var item = Subject.GetItems().Single();
item.Status.Should().Be(DownloadItemStatus.Queued);
}
[Test]

View File

@@ -13,7 +13,7 @@ using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.MetadataSource.Goodreads
{
[TestFixture]
[Ignore("Waiting for metadata to be back again", Until = "2024-08-15 00:00:00Z")]
[Ignore("Waiting for metadata to be back again", Until = "2024-12-15 00:00:00Z")]
public class BookInfoProxyFixture : CoreTest<BookInfoProxy>
{
private MetadataProfile _metadataProfile;

View File

@@ -15,7 +15,7 @@ using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.MetadataSource.Goodreads
{
[TestFixture]
[Ignore("Waiting for metadata to be back again", Until = "2024-08-15 00:00:00Z")]
[Ignore("Waiting for metadata to be back again", Until = "2024-12-15 00:00:00Z")]
public class BookInfoProxySearchFixture : CoreTest<BookInfoProxy>
{
[SetUp]

View File

@@ -219,7 +219,7 @@ namespace NzbDrone.Core.Configuration
// TODO: Change back to "master" for the first stable release
public string Branch => _updateOptions.Branch ?? GetValue("Branch", "develop").ToLowerInvariant();
public string LogLevel => _logOptions.Level ?? GetValue("LogLevel", "info").ToLowerInvariant();
public string LogLevel => _logOptions.Level ?? GetValue("LogLevel", "debug").ToLowerInvariant();
public string ConsoleLogLevel => _logOptions.ConsoleLevel ?? GetValue("ConsoleLogLevel", string.Empty, persist: false);
public string PostgresHost => _postgresOptions?.Host ?? GetValue("PostgresHost", string.Empty, persist: false);
@@ -357,7 +357,7 @@ namespace NzbDrone.Core.Configuration
}
// If SSL is enabled and a cert hash is still in the config file or cert path is empty disable SSL
if (EnableSsl && (GetValue("SslCertHash", null).IsNotNullOrWhiteSpace() || SslCertPath.IsNullOrWhiteSpace()))
if (EnableSsl && (GetValue("SslCertHash", string.Empty, false).IsNotNullOrWhiteSpace() || SslCertPath.IsNullOrWhiteSpace()))
{
SetValue("EnableSsl", false);
}

View File

@@ -41,12 +41,6 @@ namespace NzbDrone.Core.Download.Clients.Transmission
foreach (var torrent in torrents)
{
// If totalsize == 0 the torrent is a magnet downloading metadata
if (torrent.TotalSize == 0)
{
continue;
}
var outputPath = new OsPath(torrent.DownloadDir);
if (Settings.TvDirectory.IsNotNullOrWhiteSpace())
@@ -97,6 +91,10 @@ namespace NzbDrone.Core.Download.Clients.Transmission
item.Status = DownloadItemStatus.Warning;
item.Message = torrent.ErrorString;
}
else if (torrent.TotalSize == 0)
{
item.Status = DownloadItemStatus.Queued;
}
else if (torrent.LeftUntilDone == 0 && (torrent.Status == TransmissionTorrentStatus.Stopped ||
torrent.Status == TransmissionTorrentStatus.Seeding ||
torrent.Status == TransmissionTorrentStatus.SeedingWait))

View File

@@ -615,7 +615,7 @@
"NotificationStatusSingleClientHealthCheckMessage": "القوائم غير متاحة بسبب الإخفاقات: {0}",
"SomeResultsAreHiddenByTheAppliedFilter": "بعض النتائج مخفية بواسطة عامل التصفية المطبق",
"ConnectionLost": "انقطع الاتصال",
"ConnectionLostReconnect": "سيحاول Radarr الاتصال تلقائيًا ، أو يمكنك النقر فوق إعادة التحميل أدناه.",
"ConnectionLostReconnect": "سيحاول {appName} الاتصال تلقائيًا ، أو يمكنك النقر فوق إعادة التحميل أدناه.",
"LastDuration": "المدة الماضية",
"Large": "كبير",
"WhatsNew": "ما هو الجديد؟",

View File

@@ -699,5 +699,19 @@
"ChangeCategory": "Změnit kategorii",
"BlocklistMultipleOnlyHint": "Blokovat a nehledat náhradu",
"CustomFormatsSettingsTriggerInfo": "Vlastní formát se použije na vydání nebo soubor, pokud odpovídá alespoň jednomu z různých typů zvolených podmínek.",
"ConnectionSettingsUrlBaseHelpText": "Přidá předponu do {connectionName} url, jako např. {url}"
"ConnectionSettingsUrlBaseHelpText": "Přidá předponu do {connectionName} url, jako např. {url}",
"AuthBasic": "Základní (vyskakovací okno prohlížeče)",
"AuthenticationMethod": "Metoda ověřování",
"AuthenticationMethodHelpTextWarning": "Prosím vyberte platnou metodu ověřování",
"AuthenticationRequired": "Vyžadované ověření",
"AuthenticationRequiredHelpText": "Změnit, pro které požadavky je vyžadováno ověření. Pokud nerozumíte rizikům, neměňte je.",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Potvrďte nové heslo",
"AuthenticationRequiredPasswordHelpTextWarning": "Vložte nové heslo",
"AuthenticationRequiredUsernameHelpTextWarning": "Vložte nové uživatelské jméno",
"AuthenticationRequiredWarning": "Aby se zabránilo vzdálenému přístupu bez ověření, vyžaduje nyní {appName} povolení ověření. Ověřování z místních adres můžete volitelně zakázat.",
"BlocklistOnlyHint": "Blokovat a nehledat náhradu",
"Enabled": "Povoleno",
"ApiKey": "Klíč API",
"AuthForm": "Formuláře (přihlašovací stránka)",
"DisabledForLocalAddresses": "Zakázáno pro místní adresy"
}

View File

@@ -896,7 +896,7 @@
"DataListMonitorNone": "No monitorizar autores o libros",
"Iso639-3": "Códigos de idioma ISO 639-3, o 'nulo', separados por coma",
"MinPopularityHelpText": "Popularidad es la media de valoraciones * número de votos",
"DeleteSelected": "Eliminar seleccionados",
"DeleteSelected": "Borrar seleccionados",
"IsExpandedShowFileInfo": "Mostrar información de archivo",
"MassBookSearchWarning": "¿Estás seguro que quieres llevar a cabo una búsqueda masiva para {0} libros?",
"MonitorNewItemsHelpText": "Qué nuevos libros deberían ser monitorizados",

View File

@@ -551,7 +551,7 @@
"OnBookFileDeleteForUpgradeHelpText": "Lors de la suppression du fichier d'un livre pour la mise à niveau",
"OnBookFileDeleteHelpText": "Lors de la suppression du fichier d'un livre",
"OnGrab": "Lors de la saisie",
"OnHealthIssue": "Sur la question de la santé",
"OnHealthIssue": "Lors de problème de santé",
"OnRename": "Au renommage",
"ProxyCheckBadRequestMessage": "Échec du test du proxy. StatusCode: {0}",
"ProxyCheckFailedToTestMessage": "Échec du test du proxy : {0}",
@@ -679,7 +679,7 @@
"CopyToClipboard": "Copier dans le presse-papier",
"CustomFormat": "Format personnalisé",
"CustomFormatSettings": "Réglages Formats Personnalisés",
"CustomFormats": "Formats perso.",
"CustomFormats": "Formats personnalisés",
"DeleteCustomFormat": "Supprimer le format personnalisé",
"DeleteCustomFormatMessageText": "Voulez-vous vraiment supprimer le format personnalisé « {name} » ?",
"DeleteFormatMessageText": "Êtes-vous sûr de vouloir supprimer le tag « {0} » ?",
@@ -766,7 +766,7 @@
"ConnectionLostToBackend": "{appName} a perdu sa connexion au backend et devra être rechargé pour fonctionner à nouveau.",
"RecentChanges": "Changements récents",
"System": "Système",
"WhatsNew": "Quoi de neuf ?",
"WhatsNew": "Quoi de neuf ?",
"AllResultsAreHiddenByTheAppliedFilter": "Tous les résultats sont masqués par le filtre appliqué",
"Location": "Emplacement",
"NoResultsFound": "Aucun résultat trouvé",
@@ -923,7 +923,7 @@
"ExtraFileExtensionsHelpText": "Liste de fichiers supplémentaires séparés par des virgules à importer (.nfo sera importé en tant que .nfo-orig)",
"ExtraFileExtensionsHelpTextsExamples": "Exemples : '.sub, .nfo' ou 'sub,nfo'",
"UseSSL": "Utiliser SSL",
"DeleteSelected": "Supprimer sélectionnée",
"DeleteSelected": "Supprimer la sélection",
"InvalidUILanguage": "Votre interface utilisateur est définie sur une langue non valide, corrigez-la et enregistrez vos paramètres",
"DownloadClientQbittorrentSettingsContentLayout": "Disposition du contenu",
"DownloadClientQbittorrentSettingsContentLayoutHelpText": "Utiliser la disposition du contenu configurée par qBittorrent, la disposition originale du torrent ou toujours créer un sous-dossier (qBittorrent 4.3.2+)",
@@ -990,9 +990,9 @@
"InteractiveSearchModalHeader": "Recherche interactive",
"FailedLoadingSearchResults": "Échec du chargement des résultats de recherche, veuillez réessayer.",
"MonitoredAuthorIsMonitored": "Artiste non surveillé",
"IndexerSettingsSeedRatio": "Ratio d'envoie",
"IndexerSettingsSeedRatio": "Ratio d'envoi",
"IndexerSettingsSeedRatioHelpText": "Le ratio qu'un torrent doit atteindre avant de s'arrêter, vide utilise la valeur par défaut du client de téléchargement. Le ratio doit être d'au moins 1.0 et suivre les règles des indexeurs",
"IndexerSettingsSeedTime": "Temps d'envoie",
"IndexerSettingsSeedTime": "Temps d'envoi",
"IndexerSettingsSeedTimeHelpText": "Durée pendant laquelle un torrent doit être envoyé avant de s'arrêter, vide utilise la valeur par défaut du client de téléchargement",
"WhySearchesCouldBeFailing": "Cliquez ici pour savoir pourquoi les recherches pourraient échouer",
"ApiKey": "Clé API",
@@ -1099,5 +1099,7 @@
"WriteTagsAll": "Tous les fichiers ; importation initiale uniquement",
"WriteTagsSync": "Tous les fichiers ; rester synchronisé avec Goodreads",
"Iso639-3": "Codes de langage ISO 639-3, ou 'null', séparés par des virgules",
"SpecificBook": "Livre spécifique"
"SpecificBook": "Livre spécifique",
"SkipSecondarySeriesBooks": "Sauter les livres de séries secondaires",
"SkipPartBooksAndSets": "Livres et coffrets \"Skip part\""
}

View File

@@ -80,7 +80,7 @@
"DelayingDownloadUntilInterp": "Ritardare il download fino al {0} a {1}",
"Delete": "Cancella",
"DeleteBackup": "Cancella Backup",
"DeleteBackupMessageText": "Sei sicuro di voler cancellare il backup '{name}'?",
"DeleteBackupMessageText": "Sei sicuro di voler eliminare il backup '{name}'?",
"DeleteDelayProfile": "Elimina Profilo di Ritardo",
"DeleteDelayProfileMessageText": "Sei sicuro di volere eliminare questo profilo di ritardo?",
"DeleteDownloadClient": "Cancella Client di Download",
@@ -89,9 +89,9 @@
"DeleteEmptyFoldersHelpText": "Cancellare le cartelle vuote dei film durante la scansione del disco e quando i file di film vengono cancellati",
"DeleteImportListExclusion": "Rimuovi Esclusione dalla Lista Importazioni",
"DeleteImportListExclusionMessageText": "Sei sicuro di voler cancellare questa lista di esclusioni delle importazioni?",
"DeleteImportListMessageText": "Sei sicuro di volere eliminare la lista '{name}'?",
"DeleteImportListMessageText": "Sei sicuro di voler eliminare la lista '{name}'?",
"DeleteIndexer": "Cancella Indicizzatore",
"DeleteIndexerMessageText": "Sicuro di voler eliminare l'indicizzatore '{name}'?",
"DeleteIndexerMessageText": "Sei sicuro di voler eliminare l'indicizzatore '{name}'?",
"DeleteMetadataProfileMessageText": "Sicuro di voler cancellare il profilo di qualità '{name}'?",
"DeleteNotification": "Cancella Notifica",
"DeleteNotificationMessageText": "Sei sicuro di voler eliminare la notifica '{name}'?",
@@ -677,7 +677,7 @@
"RemoveSelectedItem": "Rimuovi elemento selezionato",
"ApplyTagsHelpTextReplace": "Sostituire: Sostituisce le etichette con quelle inserite (non inserire nessuna etichette per eliminarle tutte)",
"ApplyTagsHelpTextHowToApplyAuthors": "Come applicare etichette agli indicizzatori selezionati",
"CountIndexersSelected": "{selectedCount} indicizzatore(i) selezionato(i)",
"CountIndexersSelected": "{selectedCount} indicizzatori selezionati",
"No": "No",
"NoChange": "Nessun Cambio",
"RemoveCompleted": "Rimuovi completati",
@@ -898,5 +898,7 @@
"ShouldMonitorExisting": "Monitora Libri Esistenti",
"UseSSL": "Usa SSL",
"Fixed": "Fissato",
"MusicBrainzTrackID": "ID Libro MusicBrainz"
"MusicBrainzTrackID": "ID Libro MusicBrainz",
"CountImportListsSelected": "{selectedCount} autore/i selezionato/i",
"DownloadClientDelugeSettingsDirectory": "Cartella Download"
}

View File

@@ -739,5 +739,20 @@
"AuthenticationRequiredWarning": "Om toegang zonder authenticatie te voorkomen vereist {appName} nu verificatie. Je kan dit optioneel uitschakelen voor lokale adressen.",
"DisabledForLocalAddresses": "Uitgeschakeld voor lokale adressen",
"Enabled": "Ingeschakeld",
"ApiKey": "API-sleutel"
"ApiKey": "API-sleutel",
"ClickToChangeIndexerFlags": "Klik om indexeringsvlaggen te wijzigen",
"CustomFormatsSpecificationFlag": "Vlag",
"CustomFormatsSpecificationRegularExpression": "Reguliere expressie",
"BlocklistOnlyHint": "Blokkeer lijst zonder te zoeken naar een vervanger",
"BlocklistAndSearch": "Blokkeerlijst en zoeken",
"BlocklistAndSearchHint": "Een vervanger zoeken na het blokkeren",
"BlocklistAndSearchMultipleHint": "Zoekopdrachten voor vervangers starten na het blokkeren van de lijst",
"CustomFormatsSettingsTriggerInfo": "Een Aangepast Formaat wordt toegepast op een uitgave of bestand als het overeenkomt met ten minste één van de verschillende condities die zijn gekozen.",
"ConnectionSettingsUrlBaseHelpText": "Voegt een voorvoegsel toe aan de {connectionName} url, zoals {url}",
"BlocklistMultipleOnlyHint": "Blocklist zonder te zoeken naar vervangers",
"BlocklistOnly": "Alleen bloklijst",
"ChangeCategoryHint": "Verandert download naar de 'Post-Import Categorie' van Downloadclient",
"Clone": "Kloon",
"CustomFormatsSpecificationRegularExpressionHelpText": "Aangepaste opmaak RegEx is hoofdletterongevoelig",
"ChangeCategoryMultipleHint": "Wijzigt downloads naar de 'Post-Import Categorie' van Downloadclient"
}

View File

@@ -44,7 +44,7 @@
"AddingTag": "Dodawanie tagu",
"RemoveTagExistingTag": "Istniejący tag",
"RemoveTagRemovingTag": "Usuwanie tagu",
"AgeWhenGrabbed": "Wiek (po złapaniu)",
"AgeWhenGrabbed": "Wiek (przy złapaniu)",
"ShowRelativeDates": "Pokaż daty względne",
"AlreadyInYourLibrary": "Już w Twojej bibliotece",
"AlternateTitles": "Alternatywny tytuł",
@@ -71,7 +71,7 @@
"BackupRetentionHelpText": "Automatyczne kopie zapasowe starsze niż okres przechowywania zostaną automatycznie wyczyszczone",
"Backups": "Kopie zapasowe",
"BindAddress": "Adres powiązania",
"BindAddressHelpText": "Prawidłowy adres IPv4 lub „*” dla wszystkich interfejsów",
"BindAddressHelpText": "Prawidłowy adres IP, localhost lub '*' dla wszystkich interfejsów",
"BindAddressHelpTextWarning": "Wymaga ponownego uruchomienia, aby odniosło skutek",
"BookIsDownloading": "Film jest pobierany",
"BookIsDownloadingInterp": "Film jest pobierany - {0}% {1}",
@@ -111,18 +111,18 @@
"DelayingDownloadUntilInterp": "Opóźnianie pobierania do {0} o {1}",
"Delete": "Usunąć",
"DeleteBackup": "Usuń kopię zapasową",
"DeleteBackupMessageText": "Czy na pewno chcesz usunąć kopię zapasową „{0}”?",
"DeleteBackupMessageText": "Czy na pewno chcesz usunąć kopię zapasową „{name}”?",
"DeleteDelayProfile": "Usuń profil opóźnienia",
"DeleteDelayProfileMessageText": "Czy na pewno chcesz usunąć ten profil opóźnienia?",
"DeleteDownloadClient": "Usuń klienta pobierania",
"DeleteDownloadClientMessageText": "Czy na pewno chcesz usunąć klienta pobierania „{0}”?",
"DeleteDownloadClientMessageText": "Czy na pewno chcesz usunąć klienta pobierania „{name}”?",
"DeleteEmptyFolders": "Usuń puste foldery",
"DeleteEmptyFoldersHelpText": "Usuń puste foldery z filmami podczas skanowania dysku i po usunięciu plików filmowych",
"DeleteImportListExclusion": "Usuń wykluczenie listy importu",
"DeleteImportListExclusionMessageText": "Czy na pewno chcesz usunąć to wykluczenie listy importu?",
"DeleteImportListMessageText": "Czy na pewno chcesz usunąć listę „{0}”?",
"DeleteIndexer": "Usuń indeksator",
"DeleteIndexerMessageText": "Czy na pewno chcesz usunąć indeksator „{0}”?",
"DeleteIndexerMessageText": "Czy na pewno chcesz usunąć indeksator „{name}”?",
"DeleteMetadataProfileMessageText": "Czy na pewno usunąć informacje dodatkowe '{0name}'?",
"DeleteNotification": "Usuń powiadomienie",
"DeleteNotificationMessageText": "Czy na pewno chcesz usunąć powiadomienie „{0}”?",
@@ -287,7 +287,7 @@
"RemoveCompletedDownloadsHelpText": "Usuń zaimportowane pliki do pobrania z historii klienta pobierania",
"RemoveFailedDownloadsHelpText": "Usuń nieudane pobieranie z historii klienta pobierania",
"RemoveFilter": "Usuń filtr",
"RemoveFromDownloadClient": "Usuń z klienta pobierania",
"RemoveFromDownloadClient": "Usuń z Klienta Pobierania",
"RemoveFromQueue": "Usuń z kolejki",
"RemoveHelpTextWarning": "Usunięcie spowoduje usunięcie pobierania i plików z klienta pobierania.",
"RemoveSelected": "Usuń zaznaczone",
@@ -352,7 +352,7 @@
"SslPortHelpTextWarning": "Wymaga ponownego uruchomienia, aby odniosło skutek",
"StandardBookFormat": "Standardowy format filmu",
"StartTypingOrSelectAPathBelow": "Zacznij pisać lub wybierz ścieżkę poniżej",
"StartupDirectory": "Katalog startowy",
"StartupDirectory": "Katalog Startowy",
"Status": "Status",
"StatusEndedEnded": "Zakończone",
"Style": "Styl",
@@ -691,5 +691,11 @@
"AuthForm": "Formularze (strona logowania)",
"DisabledForLocalAddresses": "Wyłączone dla adresów lokalnych",
"Enabled": "Włączone",
"ApiKey": "Klucz API"
"ApiKey": "Klucz API",
"ASIN": "ASIN",
"AppUpdatedVersion": "{appName} został zaktualizowany do wersji `{version}`, by uzyskać nowe zmiany należy przeładować {appName}",
"AppUpdated": "{appName} Zaktualizowany",
"AuthenticationMethod": "Metoda Autoryzacji",
"AuthenticationMethodHelpTextWarning": "Wybierz prawidłową metodę autoryzacji",
"AuthenticationRequired": "Wymagana Autoryzacja"
}

View File

@@ -113,7 +113,7 @@
"DownloadFailedInterp": "Неудачное скачивание: {0}",
"DownloadPropersAndRepacksHelpTexts1": "Следует ли автоматически обновляться до Propers / Repacks",
"DownloadWarningCheckDownloadClientForMoreDetails": "Предупреждения по скачиванию: подробности в программе для скачивания",
"Edit": "Редактирование",
"Edit": "Изменить",
"Edition": "Издание",
"Enable": "Включить",
"EnableAutomaticAdd": "Включить автоматическое добавление",
@@ -245,7 +245,7 @@
"PortHelpTextWarning": "Для вступления в силу требуется перезапуск",
"PortNumber": "Номер порта",
"PosterSize": "Размер постера",
"PreviewRename": "Предварительный просмотр переименования",
"PreviewRename": "Предпросмотр\nпереименования",
"Profiles": "Профили",
"Proper": "Пропер (Proper)",
"PropersAndRepacks": "Проперы и репаки",
@@ -491,7 +491,7 @@
"IndexersSettingsSummary": "Ограничения для индексаторов и релизов",
"IndexerStatusCheckAllClientMessage": "Все индексаторы недоступны из-за ошибок",
"IndexerStatusCheckSingleClientMessage": "Индексаторы недоступны из-за ошибок: {0}",
"MaintenanceRelease": "Техническая версия: исправлены ошибки и другие улучшения. Дополнительную информацию см. в истории коммитов Github.",
"MaintenanceRelease": "Техническая версия: исправлены ошибки и другие улучшения. Дополнительную информацию см. в истории коммитов Github",
"Monitor": "Монитор",
"OnBookFileDeleteForUpgradeHelpText": "При удалении файла фильма для обновления",
"OnGrab": "При захвате",
@@ -499,7 +499,7 @@
"OnUpgrade": "При обновлении",
"Queued": "В очереди",
"ReadarrSupportsAnyDownloadClient": "Radarr поддерживает многие популярные торрент и usenet-клиенты для скачивания.",
"RefreshAndScan": "Обновить и сканировать",
"RefreshAndScan": "Обновить",
"RemotePathMappingCheckDownloadPermissions": "Radarr видит загруженный фильм {0}, но не может получить доступ к нему. Возможно, ошибка в правах доступа.",
"RemotePathMappingCheckFileRemoved": "Файл {0} был удален в процессе обработки.",
"RemotePathMappingCheckFilesBadDockerPath": "Вы используете docker; клиент загрузки {0} сообщил о файлах в {1}, но это не корректный путь {2}. Проверьте правильность указанного пути и настройки клиента загрузки.",
@@ -567,7 +567,7 @@
"AllAuthorBooks": "Все книги автора",
"AllowAuthorChangeClickToChangeAuthor": "Нажмите, чтобы изменить автора",
"AllExpandedExpandAll": "Развернуть Все",
"RestartRequiredHelpTextWarning": "Для вступления в силу требуется перезапуск",
"RestartRequiredHelpTextWarning": "Для применения изменений, требуется перезапуск",
"Label": "Метка",
"AddList": "Добавить список",
"Publisher": "Издатель",
@@ -822,12 +822,35 @@
"ShowBanners": "Показывать баннеры",
"SetIndexerFlags": "Установить флаги индексатора",
"SelectIndexerFlags": "Выбор флагов индексатора",
"SearchMonitored": "Искать отслеживаемое",
"SearchMonitored": "Искать сериал",
"CustomFormatsSettingsTriggerInfo": "Пользовательский формат будет применен к релизу или файлу, если он соответствует хотя бы одному из каждого из выбранных типов условий.",
"CustomFormatsSpecificationRegularExpressionHelpText": "RegEx пользовательского формата не чувствителен к регистру",
"DownloadClientQbittorrentSettingsContentLayoutHelpText": "Использовать ли настроенный макет контента qBittorrent, исходный макет из торрента или всегда создавать подпапку (qBittorrent 4.3.2+)",
"MetadataSource": "Источник метаданных",
"NotificationsSettingsUpdateMapPathsFromHelpText": "Путь {appName}, используемый для изменения путей к сериалам, когда {serviceName} видит путь к библиотеке иначе, чем {appName} (требуется 'Обновить библиотеку')",
"NotificationsSettingsUpdateMapPathsToHelpText": "Путь {serviceName}, используемый для изменения путей к сериям, когда {serviceName} видит путь к библиотеке иначе, чем {appName} (требуется 'Обновить библиотеку')",
"PasswordConfirmation": "Подтверждение пароля"
"PasswordConfirmation": "Подтверждение пароля",
"DashOrSpaceDashDependingOnName": "Тире или пробел в зависимости от имени",
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Клиент загрузки {downloadClientName} настроен на удаление завершенных загрузок. Это может привести к удалению загрузок из вашего клиента до того, как {appName} сможет их импортировать.",
"NoMissingItems": "Нет отсутствующих элементов",
"ShowBannersHelpText": "Показывать баннеры вместо заголовков",
"RootFolderPathHelpText": "Элементы списка корневых папок будут добавлены в",
"MetadataSettingsSummary": "Создавать файлы метаданных при импорте эпизодов или обновлении сериалов",
"DataMissingBooks": "Отслеживать эпизоды, у которых нет файлов или которые еще не вышли в эфир",
"MetadataProfileIdHelpText": "Элементы списка профиля качества будут добавлены с помощью",
"ReadarrSupportsMultipleListsForImportingBooksAndAuthorsIntoTheDatabase": "{appName} поддерживает несколько списков для импорта сериалов в базу данных.",
"IndexerIdHelpText": "Укажите, к какому индексатору применяется профиль",
"ContinuingAllBooksDownloaded": "Продолжается (все эпизоды скачаны)",
"DeleteBookFileMessageText": "Вы уверены, что хотите удалить '{path}'?",
"QualityProfileIdHelpText": "Элементы списка профиля качества будут добавлены с помощью",
"UseSSL": "Использовать SSL",
"EndedAllBooksDownloaded": "Завершено (Все эпизоды скачаны)",
"SearchForAllCutoffUnmetBooks": "Искать все эпизоды не достигшие указанного качества",
"StatusEndedContinuing": "Продолжается",
"Author": "Автор",
"IsShowingMonitoredUnmonitorSelected": "Неотслеживаемые выбраны",
"EnabledHelpText": "Установите флажок, чтобы включить профиль релиза",
"Authors": "Автор",
"IsShowingMonitoredMonitorSelected": "Отслеживание выбрано",
"SearchForAllMissingBooks": "Искать все недостающие эпизоды"
}

View File

@@ -823,5 +823,6 @@
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Yeni şifreyi onayla",
"AuthenticationRequiredPasswordHelpTextWarning": "Yeni şifre girin",
"AuthenticationRequiredUsernameHelpTextWarning": "Yeni kullanıcı adınızı girin",
"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."
"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.",
"DeleteSelected": "Seçileni Sil"
}

View File

@@ -740,5 +740,10 @@
"BlocklistAndSearchMultipleHint": "Розпочати пошук замін після додавання до чорного списку",
"ChangeCategoryMultipleHint": "Змінює завантаження на «Категорію після імпорту» з клієнта завантажувача",
"CloneCondition": "Клонування умови",
"AutoRedownloadFailedFromInteractiveSearchHelpText": "Автоматично шукати та намагатися завантажити інший реліз, якщо обраний реліз не вдалось завантажити з інтерактивного пошуку."
"AutoRedownloadFailedFromInteractiveSearchHelpText": "Автоматично шукати та намагатися завантажити інший реліз, якщо обраний реліз не вдалось завантажити з інтерактивного пошуку.",
"BypassIfAboveCustomFormatScoreHelpText": "Увімкнути обхід, якщо реліз має оцінку вищу за встановлений мінімальний бал користувацького формату",
"CountDownloadClientsSelected": "Вибрано {count} клієнтів завантажувача",
"ReleaseProfiles": "профіль релізу",
"MinimumCustomFormatScoreHelpText": "Мінімальна оцінка користувацького формату, необхідна для обходу затримки для обраного протоколу",
"BypassIfAboveCustomFormatScore": "Пропустити, якщо перевищено оцінку користувацького формату"
}

View File

@@ -25,15 +25,15 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnGrab(GrabMessage message)
{
var embeds = new List<Embed>
{
new Embed
{
Description = message.Message,
Title = message.Author.Name,
Text = message.Message,
Color = (int)DiscordColors.Warning
}
};
{
new ()
{
Description = message.Message,
Title = message.Author.Name,
Text = message.Message,
Color = (int)DiscordColors.Warning
}
};
var payload = CreatePayload($"Grabbed: {message.Message}", embeds);
_proxy.SendPayload(payload, Settings);
@@ -43,7 +43,7 @@ namespace NzbDrone.Core.Notifications.Discord
{
var attachments = new List<Embed>
{
new Embed
new ()
{
Description = message.Message,
Title = message.Author.Name,
@@ -59,12 +59,12 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnRename(Author author, List<RenamedBookFile> renamedFiles)
{
var attachments = new List<Embed>
{
new Embed
{
Title = author.Name,
}
};
{
new ()
{
Title = author.Name,
}
};
var payload = CreatePayload("Renamed", attachments);
@@ -74,21 +74,21 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnAuthorAdded(Author author)
{
var attachments = new List<Embed>
{
new Embed
{
Title = author.Name,
Fields = new List<DiscordField>()
{
new DiscordField()
{
Name = "Links",
Value = string.Join(" / ", author.Metadata.Value.Links.Select(link => $"[{link.Name}]({link.Url})"))
}
},
}
};
var payload = CreatePayload($"Author Added", attachments);
{
new ()
{
Title = author.Name,
Fields = new List<DiscordField>()
{
new ()
{
Name = "Links",
Value = string.Join(" / ", author.Metadata.Value.Links.Select(link => $"[{link.Name}]({link.Url})"))
}
},
}
};
var payload = CreatePayload("Author Added", attachments);
_proxy.SendPayload(payload, Settings);
}
@@ -96,13 +96,13 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnAuthorDelete(AuthorDeleteMessage deleteMessage)
{
var attachments = new List<Embed>
{
new Embed
{
Title = deleteMessage.Author.Name,
Description = deleteMessage.DeletedFilesMessage
}
};
{
new ()
{
Title = deleteMessage.Author.Name,
Description = deleteMessage.DeletedFilesMessage
}
};
var payload = CreatePayload("Author Deleted", attachments);
@@ -112,13 +112,13 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnBookDelete(BookDeleteMessage deleteMessage)
{
var attachments = new List<Embed>
{
new Embed
{
Title = $"${deleteMessage.Book.Author.Value.Name} - ${deleteMessage.Book.Title}",
Description = deleteMessage.DeletedFilesMessage
}
};
{
new ()
{
Title = $"{deleteMessage.Book.Author.Value.Name} - ${deleteMessage.Book.Title}",
Description = deleteMessage.DeletedFilesMessage
}
};
var payload = CreatePayload("Book Deleted", attachments);
@@ -128,13 +128,13 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnBookFileDelete(BookFileDeleteMessage deleteMessage)
{
var attachments = new List<Embed>
{
new Embed
{
Title = $"${deleteMessage.Book.Author.Value.Name} - ${deleteMessage.Book.Title} - file deleted",
Description = deleteMessage.BookFile.Path
}
};
{
new ()
{
Title = $"{deleteMessage.Book.Author.Value.Name} - ${deleteMessage.Book.Title} - file deleted",
Description = deleteMessage.BookFile.Path
}
};
var payload = CreatePayload("Book File Deleted", attachments);
@@ -144,14 +144,14 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
{
var attachments = new List<Embed>
{
new Embed
{
Title = healthCheck.Source.Name,
Text = healthCheck.Message,
Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? (int)DiscordColors.Warning : (int)DiscordColors.Danger
}
};
{
new ()
{
Title = healthCheck.Source.Name,
Text = healthCheck.Message,
Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? (int)DiscordColors.Warning : (int)DiscordColors.Danger
}
};
var payload = CreatePayload("Health Issue", attachments);
@@ -161,13 +161,13 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnBookRetag(BookRetagMessage message)
{
var attachments = new List<Embed>
{
new Embed
{
Title = BOOK_RETAGGED_TITLE,
Text = message.Message
}
};
{
new ()
{
Title = BOOK_RETAGGED_TITLE,
Text = message.Message
}
};
var payload = CreatePayload($"Track file tags updated: {message.Message}", attachments);
@@ -178,7 +178,7 @@ namespace NzbDrone.Core.Notifications.Discord
{
var attachments = new List<Embed>
{
new Embed
new ()
{
Description = message.Message,
Title = message.SourceTitle,
@@ -195,7 +195,7 @@ namespace NzbDrone.Core.Notifications.Discord
{
var attachments = new List<Embed>
{
new Embed
new ()
{
Description = message.Message,
Title = message.Book?.Title ?? message.Message,
@@ -211,32 +211,32 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{
var attachments = new List<Embed>
{
new Embed
{
Author = new DiscordAuthor
{
Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author,
IconUrl = "https://raw.githubusercontent.com/Readarr/Readarr/develop/Logo/256.png"
},
Title = APPLICATION_UPDATE_TITLE,
Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
Color = (int)DiscordColors.Standard,
Fields = new List<DiscordField>()
{
new DiscordField()
{
Name = "Previous Version",
Value = updateMessage.PreviousVersion.ToString()
},
new DiscordField()
{
Name = "New Version",
Value = updateMessage.NewVersion.ToString()
}
},
}
};
{
new ()
{
Author = new DiscordAuthor
{
Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author,
IconUrl = "https://raw.githubusercontent.com/Readarr/Readarr/develop/Logo/256.png"
},
Title = APPLICATION_UPDATE_TITLE,
Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
Color = (int)DiscordColors.Standard,
Fields = new List<DiscordField>()
{
new ()
{
Name = "Previous Version",
Value = updateMessage.PreviousVersion.ToString()
},
new ()
{
Name = "New Version",
Value = updateMessage.NewVersion.ToString()
}
},
}
};
var payload = CreatePayload(null, attachments);

View File

@@ -4,6 +4,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" />
<PackageReference Include="Diacritical.Net" />
<PackageReference Include="LazyCache" />
<PackageReference Include="Polly" />
<PackageReference Include="System.Text.Json" />

View File

@@ -8,6 +8,7 @@ namespace NzbDrone.Core.ThingiProvider.Status
where TModel : ProviderStatusBase, new()
{
TModel FindByProviderId(int providerId);
void DeleteByProviderId(int providerId);
}
public class ProviderStatusRepository<TModel> : BasicRepository<TModel>, IProviderStatusRepository<TModel>
@@ -22,5 +23,10 @@ namespace NzbDrone.Core.ThingiProvider.Status
{
return Query(c => c.ProviderId == providerId).SingleOrDefault();
}
public void DeleteByProviderId(int providerId)
{
Delete(c => c.ProviderId == providerId);
}
}
}

View File

@@ -151,12 +151,7 @@ namespace NzbDrone.Core.ThingiProvider.Status
public virtual void HandleAsync(ProviderDeletedEvent<TProvider> message)
{
var providerStatus = _providerStatusRepository.FindByProviderId(message.ProviderId);
if (providerStatus != null)
{
_providerStatusRepository.Delete(providerStatus);
}
_providerStatusRepository.DeleteByProviderId(message.ProviderId);
}
}
}

View File

@@ -135,7 +135,7 @@ namespace NzbDrone.Host
Name = "apikey",
Type = SecuritySchemeType.ApiKey,
Scheme = "apiKey",
Description = "Apikey passed as header",
Description = "Apikey passed as query parameter",
In = ParameterLocation.Query,
Reference = new OpenApiReference
{

View File

@@ -7,7 +7,7 @@ using Readarr.Api.V1.Author;
namespace NzbDrone.Integration.Test.ApiTests
{
[TestFixture]
[Ignore("Waiting for metadata to be back again", Until = "2024-08-15 00:00:00Z")]
[Ignore("Waiting for metadata to be back again", Until = "2024-12-15 00:00:00Z")]
public class AuthorEditorFixture : IntegrationTest
{
private void GivenExistingAuthor()

View File

@@ -7,7 +7,7 @@ using NUnit.Framework;
namespace NzbDrone.Integration.Test.ApiTests
{
[TestFixture]
[Ignore("Waiting for metadata to be back again", Until = "2024-08-15 00:00:00Z")]
[Ignore("Waiting for metadata to be back again", Until = "2024-12-15 00:00:00Z")]
public class AuthorFixture : IntegrationTest
{
[Test]

View File

@@ -4,7 +4,7 @@ using NUnit.Framework;
namespace NzbDrone.Integration.Test.ApiTests
{
[TestFixture]
[Ignore("Waiting for metadata to be back again", Until = "2024-08-15 00:00:00Z")]
[Ignore("Waiting for metadata to be back again", Until = "2024-12-15 00:00:00Z")]
public class AuthorLookupFixture : IntegrationTest
{
[TestCase("Robert Harris", "Robert Harris")]

View File

@@ -6,7 +6,7 @@ using Readarr.Api.V1.Blocklist;
namespace NzbDrone.Integration.Test.ApiTests
{
[TestFixture]
[Ignore("Waiting for metadata to be back again", Until = "2024-08-15 00:00:00Z")]
[Ignore("Waiting for metadata to be back again", Until = "2024-12-15 00:00:00Z")]
public class BlocklistFixture : IntegrationTest
{
private AuthorResource _author;

View File

@@ -9,7 +9,7 @@ using Readarr.Api.V1.Books;
namespace NzbDrone.Integration.Test.ApiTests
{
[TestFixture]
[Ignore("Waiting for metadata to be back again", Until = "2024-08-15 00:00:00Z")]
[Ignore("Waiting for metadata to be back again", Until = "2024-12-15 00:00:00Z")]
public class CalendarFixture : IntegrationTest
{
public ClientBase<BookResource> Calendar;

View File

@@ -8,7 +8,7 @@ using Readarr.Api.V1.RootFolders;
namespace NzbDrone.Integration.Test.ApiTests.WantedTests
{
[TestFixture]
[Ignore("Waiting for metadata to be back again", Until = "2024-08-15 00:00:00Z")]
[Ignore("Waiting for metadata to be back again", Until = "2024-12-15 00:00:00Z")]
public class CutoffUnmetFixture : IntegrationTest
{
[SetUp]

View File

@@ -7,7 +7,7 @@ using Readarr.Api.V1.RootFolders;
namespace NzbDrone.Integration.Test.ApiTests.WantedTests
{
[TestFixture]
[Ignore("Waiting for metadata to be back again", Until = "2024-08-15 00:00:00Z")]
[Ignore("Waiting for metadata to be back again", Until = "2024-12-15 00:00:00Z")]
public class MissingFixture : IntegrationTest
{
[SetUp]

View File

@@ -13815,7 +13815,7 @@
},
"apikey": {
"type": "apiKey",
"description": "Apikey passed as header",
"description": "Apikey passed as query parameter",
"name": "apikey",
"in": "query"
}

View File

@@ -1,12 +1,18 @@
using System;
using System.Text.RegularExpressions;
using Diacritical;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.DependencyInjection;
using NzbDrone.Core.Authentication;
using NzbDrone.Core.Configuration;
namespace Readarr.Http.Authentication
{
public static class AuthenticationBuilderExtensions
{
private static readonly Regex CookieNameRegex = new Regex(@"[^a-z0-9]+", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static AuthenticationBuilder AddApiKey(this AuthenticationBuilder authenticationBuilder, string name, Action<ApiKeyAuthenticationOptions> options)
{
return authenticationBuilder.AddScheme<ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>(name, options);
@@ -29,19 +35,27 @@ namespace Readarr.Http.Authentication
public static AuthenticationBuilder AddAppAuthentication(this IServiceCollection services)
{
return services.AddAuthentication()
.AddNone(AuthenticationType.None.ToString())
.AddExternal(AuthenticationType.External.ToString())
.AddBasic(AuthenticationType.Basic.ToString())
.AddCookie(AuthenticationType.Forms.ToString(), options =>
services.AddOptions<CookieAuthenticationOptions>(AuthenticationType.Forms.ToString())
.Configure<IConfigFileProvider>((options, configFileProvider) =>
{
options.Cookie.Name = "ReadarrAuth";
// Replace diacritics and replace non-word characters to ensure cookie name doesn't contain any valid URL characters not allowed in cookie names
var instanceName = configFileProvider.InstanceName;
instanceName = instanceName.RemoveDiacritics();
instanceName = CookieNameRegex.Replace(instanceName, string.Empty);
options.Cookie.Name = $"{instanceName}Auth";
options.AccessDeniedPath = "/login?loginFailed=true";
options.LoginPath = "/login";
options.ExpireTimeSpan = TimeSpan.FromDays(7);
options.SlidingExpiration = true;
options.ReturnUrlParameter = "returnUrl";
})
});
return services.AddAuthentication()
.AddNone(AuthenticationType.None.ToString())
.AddExternal(AuthenticationType.External.ToString())
.AddBasic(AuthenticationType.Basic.ToString())
.AddCookie(AuthenticationType.Forms.ToString())
.AddApiKey("API", options =>
{
options.HeaderName = "X-Api-Key";

View File

@@ -47,7 +47,7 @@ namespace Readarr.Http.Authentication
await HttpContext.SignInAsync(AuthenticationType.Forms.ToString(), new ClaimsPrincipal(new ClaimsIdentity(claims, "Cookies", "user", "identifier")), authProperties);
if (returnUrl.IsNullOrWhiteSpace())
if (returnUrl.IsNullOrWhiteSpace() || !Url.IsLocalUrl(returnUrl))
{
return Redirect(_configFileProvider.UrlBase + "/");
}

View File

@@ -20,6 +20,8 @@ namespace Readarr.Http.Middleware
if (_urlBase.IsNotNullOrWhiteSpace() && context.Request.PathBase.Value.IsNullOrWhiteSpace())
{
context.Response.Redirect($"{_urlBase}{context.Request.Path}{context.Request.QueryString}");
context.Response.StatusCode = 307;
return;
}