1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-16 21:15:28 -04:00

Compare commits

...

9 Commits

Author SHA1 Message Date
Weblate
cf3d51bab2 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Casselluu <jack10193@163.com>
Co-authored-by: Gianmarco Novelli <rinogaetano94@live.it>
Co-authored-by: Jason54 <jason54700.jg@gmail.com>
Co-authored-by: MadaxDeLuXe <madaxdeluxe@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: infoaitek24 <info@aitekph.com>
Co-authored-by: reloxx <reloxx@interia.pl>
Co-authored-by: shimmyx <shimmygodx@gmail.com>
Co-authored-by: vfaergestad <vgf@hotmail.no>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-03-21 21:21:30 -07:00
Mark McDowall
dec3fc6889 Fixed: Don't add series from import list with no matched TVDB ID 2024-03-22 00:21:04 -04:00
Mark McDowall
40bac23698 New: Support parsing season number from season folder when importing
Closes #903
2024-03-21 21:20:49 -07:00
Mark McDowall
88de927435 Fixed: Plex Watchlist import list 2024-03-21 21:20:27 -07:00
Mark McDowall
29204c93a3 New: Parsing multi-episode file with two and three digit episode numbers
Closes #6631
2024-03-21 21:20:13 -07:00
Mark McDowall
c641733781 Fixed: Task progress messages in the UI
Closes #6632
2024-03-21 21:20:08 -07:00
Weblate
58de0310fd Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Gianmarco Novelli <rinogaetano94@live.it>
Co-authored-by: Jason54 <jason54700.jg@gmail.com>
Co-authored-by: MadaxDeLuXe <madaxdeluxe@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: infoaitek24 <info@aitekph.com>
Co-authored-by: reloxx <reloxx@interia.pl>
Co-authored-by: vfaergestad <vgf@hotmail.no>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/nb_NO/
Translation: Servarr/Sonarr
2024-03-21 21:20:01 -07:00
Bogdan
172b1a82d1 Sort series by title in task name 2024-03-21 21:19:23 -07:00
Bogdan
e14568adef Ensure not allowed cursor is shown for disabled select inputs 2024-03-21 21:19:23 -07:00
23 changed files with 164 additions and 43 deletions

View File

@@ -19,7 +19,7 @@
.isDisabled {
opacity: 0.7;
cursor: not-allowed;
cursor: not-allowed !important;
}
.dropdownArrowContainer {

View File

@@ -23,13 +23,16 @@ export default function QueuedTaskRowNameCell(
}
const series = useSelector(createMultiSeriesSelector(seriesIds));
const sortedSeries = series.sort((a, b) =>
a.sortTitle.localeCompare(b.sortTitle)
);
return (
<TableRowCell>
<span className={styles.commandName}>
{commandName}
{series.length ? (
<span> - {series.map((s) => s.title).join(', ')}</span>
{sortedSeries.length ? (
<span> - {sortedSeries.map((s) => s.title).join(', ')}</span>
) : null}
{body.seasonNumber ? (
<span>

View File

@@ -120,6 +120,17 @@ namespace NzbDrone.Core.Test.ImportListTests
private void WithImdbId()
{
_list1Series.First().ImdbId = "tt0496424";
Mocker.GetMock<ISearchForNewSeries>()
.Setup(s => s.SearchForNewSeriesByImdbId(_list1Series.First().ImdbId))
.Returns(
Builder<Series>
.CreateListOfSize(1)
.All()
.With(s => s.Title = "Breaking Bad")
.With(s => s.TvdbId = 81189)
.Build()
.ToList());
}
private void WithExistingSeries()
@@ -342,6 +353,7 @@ namespace NzbDrone.Core.Test.ImportListTests
public void should_add_new_series_from_single_list_to_library()
{
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
WithTvdbId();
WithList(1, true);
WithCleanLevel(ListSyncLevelType.Disabled);
@@ -358,6 +370,7 @@ namespace NzbDrone.Core.Test.ImportListTests
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
_importListFetch.Series.AddRange(_list2Series);
WithTvdbId();
WithList(1, true);
WithList(2, true);
@@ -376,6 +389,7 @@ namespace NzbDrone.Core.Test.ImportListTests
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
_importListFetch.Series.AddRange(_list2Series);
WithTvdbId();
WithList(1, true);
WithList(2, false);
@@ -422,12 +436,17 @@ namespace NzbDrone.Core.Test.ImportListTests
public void should_search_by_imdb_if_series_title_and_series_imdb()
{
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
WithList(1, true);
WithImdbId();
Subject.Execute(_commandAll);
Mocker.GetMock<ISearchForNewSeries>()
.Verify(v => v.SearchForNewSeriesByImdbId(It.IsAny<string>()), Times.Once());
Mocker.GetMock<IAddSeriesService>()
.Verify(v => v.AddSeries(It.Is<List<Series>>(t => t.Count == 1), It.IsAny<bool>()));
}
[Test]
@@ -498,5 +517,18 @@ namespace NzbDrone.Core.Test.ImportListTests
Mocker.GetMock<IImportListExclusionService>()
.Verify(v => v.All(), Times.Never);
}
[Test]
public void should_not_add_if_tvdbid_is_0()
{
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
WithList(1, true);
WithExcludedSeries();
Subject.Execute(_commandAll);
Mocker.GetMock<IAddSeriesService>()
.Verify(v => v.AddSeries(It.Is<List<Series>>(t => t.Count == 0), It.IsAny<bool>()));
}
}
}

View File

@@ -77,6 +77,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Series Title (S15E06-08) City Sushi", "Series Title", 15, new[] { 6, 7, 8 })]
[TestCase("Босх: Спадок (S2E1-4) / Series: Legacy (S2E1-4) (2023) WEB-DL 1080p Ukr/Eng | sub Eng", "Series: Legacy", 2, new[] { 1, 2, 3, 4 })]
[TestCase("Босх: Спадок / Series: Legacy / S2E1-4 of 10 (2023) WEB-DL 1080p Ukr/Eng | sub Eng", "Series: Legacy", 2, new[] { 1, 2, 3, 4 })]
[TestCase("Series Title - S26E96-97-98-99-100 - Episode 5931 + Episode 5932 + Episode 5933 + Episode 5934 + Episode 5935", "Series Title", 26, new[] { 96, 97, 98, 99, 100 })]
// [TestCase("", "", , new [] { })]
public void should_parse_multiple_episodes(string postTitle, string title, int season, int[] episodes)

View File

@@ -29,6 +29,8 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase(@"C:\Test\Series\Season 01\1 Pilot (1080p HD).mkv", 1, 1)]
[TestCase(@"C:\Test\Series\Season 1\02 Honor Thy Father (1080p HD).m4v", 1, 2)]
[TestCase(@"C:\Test\Series\Season 1\2 Honor Thy Developer (1080p HD).m4v", 1, 2)]
[TestCase(@"C:\Test\Series\Season 2 - Total Series Action\01. Total Series Action - Episode 1 - Monster Cash.mkv", 2, 1)]
[TestCase(@"C:\Test\Series\Season 2\01. Total Series Action - Episode 1 - Monster Cash.mkv", 2, 1)]
// [TestCase(@"C:\series.state.S02E04.720p.WEB-DL.DD5.1.H.264\73696S02-04.mkv", 2, 4)] //Gets treated as S01E04 (because it gets parsed as anime); 2020-01 broken test case: Expected result.EpisodeNumbers to contain 1 item(s), but found 0
public void should_parse_from_path(string path, int season, int episode)
@@ -45,6 +47,7 @@ namespace NzbDrone.Core.Test.ParserTests
}
[TestCase("01-03\\The Series Title (2010) - 1x01-02-03 - Episode Title HDTV-720p Proper", "The Series Title (2010)", 1, new[] { 1, 2, 3 })]
[TestCase("Season 2\\E05-06 - Episode Title HDTV-720p Proper", "", 2, new[] { 5, 6 })]
public void should_parse_multi_episode_from_path(string path, string title, int season, int[] episodes)
{
var result = Parser.Parser.ParsePath(path.AsOsAgnostic());

View File

@@ -190,6 +190,12 @@ namespace NzbDrone.Core.ImportLists
item.Title = mappedSeries.Title;
}
if (item.TvdbId == 0)
{
_logger.Debug("[{0}] Rejected, unable to find TVDB ID", item.Title);
continue;
}
// Check to see if series excluded
var excludedSeries = listExclusions.Where(s => s.TvdbId == item.TvdbId).SingleOrDefault();
@@ -202,7 +208,7 @@ namespace NzbDrone.Core.ImportLists
// Break if Series Exists in DB
if (existingTvdbIds.Any(x => x == item.TvdbId))
{
_logger.Debug("{0} [{1}] Rejected, Series Exists in DB", item.TvdbId, item.Title);
_logger.Debug("{0} [{1}] Rejected, series exists in database", item.TvdbId, item.Title);
continue;
}

View File

@@ -522,7 +522,7 @@ namespace NzbDrone.Core.IndexerSearch
var reports = batch.SelectMany(x => x).ToList();
_logger.Debug("Total of {0} reports were found for {1} from {2} indexers", reports.Count, criteriaBase, indexers.Count);
_logger.ProgressDebug("Total of {0} reports were found for {1} from {2} indexers", reports.Count, criteriaBase, indexers.Count);
// Update the last search time for all episodes if at least 1 indexer was searched.
if (indexers.Any())

View File

@@ -5,7 +5,6 @@ namespace NzbDrone.Core.Indexers
public class RssSyncCommand : Command
{
public override bool SendUpdatesToClient => true;
public override bool IsLongRunning => true;
}
}

View File

@@ -665,5 +665,13 @@
"NotificationsPushoverSettingsRetry": "Torna-ho a provar",
"NotificationsSettingsWebhookMethod": "Mètode",
"Other": "Altres",
"Monitor": "Monitora"
"Monitor": "Monitora",
"AutoTaggingSpecificationOriginalLanguage": "Llenguatge",
"AutoTaggingSpecificationQualityProfile": "Perfil de Qualitat",
"AutoTaggingSpecificationRootFolder": "Carpeta arrel",
"AddDelayProfileError": "No s'ha pogut afegir un perfil realentit, torna-ho a probar",
"AutoTaggingSpecificationSeriesType": "Tipus de Sèries",
"AutoTaggingSpecificationStatus": "Estat",
"BlocklistAndSearch": "Llista de bloqueig i cerca",
"BlocklistAndSearchHint": "Comença una cerca per reemplaçar després d'haver bloquejat"
}

View File

@@ -41,7 +41,7 @@
"SkipFreeSpaceCheck": "Prüfung des freien Speichers überspringen",
"AbsoluteEpisodeNumber": "Exakte Folgennummer",
"AddConnection": "Verbindung hinzufügen",
"AddAutoTagError": "Der neue automatische Tag konnte nicht hinzugefügt werden, bitte versuche es erneut.",
"AddAutoTagError": "Auto-Tag konnte nicht hinzugefügt werden. Bitte erneut versuchen.",
"AddConditionError": "Neue Bedingung konnte nicht hinzugefügt werden, bitte erneut versuchen.",
"AddCustomFormat": "Eigenes Format hinzufügen",
"AddCustomFormatError": "Neues eigenes Format kann nicht hinzugefügt werden, bitte versuchen Sie es erneut.",
@@ -146,7 +146,7 @@
"AuthenticationRequiredHelpText": "Ändern, welche anfragen Authentifizierung benötigen. Ändere nichts wenn du dir nicht des Risikos bewusst bist.",
"AnalyseVideoFilesHelpText": "Videoinformationen wie Auflösung, Laufzeit und Codec-Informationen aus Dateien extrahieren. Dies erfordert, dass {appName} Teile der Datei liest, was bei Scans zu hoher Festplatten- oder Netzwerkaktivität führen kann.",
"AnalyticsEnabledHelpText": "Senden Sie anonyme Nutzungs- und Fehlerinformationen an die Server von {appName}. Dazu gehören Informationen zu Ihrem Browser, welche {appName}-WebUI-Seiten Sie verwenden, Fehlerberichte sowie Betriebssystem- und Laufzeitversion. Wir werden diese Informationen verwenden, um Funktionen und Fehlerbehebungen zu priorisieren.",
"AutoTaggingNegateHelpText": "Wenn diese Option aktiviert ist, wird die automatische Tagging-Regel nicht angewendet, wenn diese {implementationName}-Bedingung zutrifft.",
"AutoTaggingNegateHelpText": "Falls aktiviert wird das eigene Format nicht angewendet solange diese {0} Bedingung zutrifft.",
"CopyUsingHardlinksSeriesHelpText": "Mithilfe von Hardlinks kann {appName} Seeding-Torrents in den Serienordner importieren, ohne zusätzlichen Speicherplatz zu beanspruchen oder den gesamten Inhalt der Datei zu kopieren. Hardlinks funktionieren nur, wenn sich Quelle und Ziel auf demselben Volume befinden",
"DailyEpisodeTypeFormat": "Datum ({format})",
"DefaultDelayProfileSeries": "Dies ist das Standardprofil. Es gilt für alle Serien, die kein explizites Profil haben.",
@@ -171,7 +171,7 @@
"BackupIntervalHelpText": "Intervall zwischen automatischen Sicherungen",
"BuiltIn": "Eingebaut",
"ChangeFileDate": "Ändern Sie das Dateidatum",
"CustomFormatsLoadError": "Benutzerdefinierte Formate können nicht geladen werden",
"CustomFormatsLoadError": "Eigene Formate konnten nicht geladen werden",
"DeleteQualityProfileMessageText": "Sind Sie sicher, dass Sie das Qualitätsprofil „{name}“ löschen möchten?",
"DeletedReasonUpgrade": "Die Datei wurde gelöscht, um ein Upgrade zu importieren",
"DeleteEpisodesFiles": "{episodeFileCount} Episodendateien löschen",
@@ -205,7 +205,7 @@
"AuthenticationMethodHelpText": "Für den Zugriff auf {appName} sind Benutzername und Passwort erforderlich",
"Automatic": "Automatisch",
"AutomaticSearch": "Automatische Suche",
"AutoTaggingRequiredHelpText": "Diese {implementationName}-Bedingung muss zutreffen, damit die automatische Tagging-Regel angewendet wird. Andernfalls reicht eine einzelne {implementationName}-Übereinstimmung aus.",
"AutoTaggingRequiredHelpText": "Diese {0} Bedingungen müssen erfüllt sein, damit das eigene Format zutrifft. Ansonsten reicht ein einzelner {1} Treffer.",
"BackupRetentionHelpText": "Automatische Backups, die älter als der Aufbewahrungszeitraum sind, werden automatisch bereinigt",
"BindAddressHelpText": "Gültige IP-Adresse, localhost oder „*“ für alle Schnittstellen",
"BackupsLoadError": "Sicherrungen können nicht geladen werden",
@@ -280,8 +280,8 @@
"Custom": "Benutzerdefiniert",
"CustomFilters": "Benutzerdefinierte Filter",
"CustomFormat": "Benutzerdefiniertes Format",
"CustomFormats": "Benutzerdefinierte Formate",
"CustomFormatsSettingsSummary": "Benutzerdefinierte Formate und Einstellungen",
"CustomFormats": "Eigene Formate",
"CustomFormatsSettingsSummary": "Eigene Formate und Einstellungen",
"DailyEpisodeFormat": "Tägliches Episodenformat",
"Database": "Datenbank",
"Dates": "Termine",
@@ -540,7 +540,7 @@
"ApplyTagsHelpTextAdd": "Hinzufügen: Fügen Sie die Tags der vorhandenen Tag-Liste hinzu",
"ApplyTagsHelpTextRemove": "Entfernen: Die eingegebenen Tags entfernen",
"ApplyTagsHelpTextReplace": "Ersetzen: Ersetzen Sie die Tags durch die eingegebenen Tags (geben Sie keine Tags ein, um alle Tags zu löschen).",
"Wanted": " Gesucht",
"Wanted": "Gesucht",
"ConnectionLostToBackend": "{appName} hat die Verbindung zum Backend verloren und muss neu geladen werden, um die Funktionalität wiederherzustellen.",
"Continuing": "Fortsetzung",
"CopyUsingHardlinksHelpTextWarning": "Gelegentlich können Dateisperren das Umbenennen von Dateien verhindern, die geseedet werden. Sie können das Seeding vorübergehend deaktivieren und als Workaround die Umbenennungsfunktion von {appName} verwenden.",
@@ -550,7 +550,7 @@
"CountIndexersSelected": "{count} Indexer ausgewählt",
"CountSelectedFiles": "{selectedCount} ausgewählte Dateien",
"CustomFormatUnknownConditionOption": "Unbekannte Option „{key}“ für Bedingung „{implementation}“",
"CustomFormatsSettings": "Benutzerdefinierte Formateinstellungen",
"CustomFormatsSettings": "Einstellungen für eigene Formate",
"Daily": "Täglich",
"Dash": "Bindestrich",
"Debug": "Debuggen",
@@ -709,7 +709,7 @@
"ClickToChangeSeason": "Klicken Sie hier, um die Staffel zu ändern",
"BlackholeFolderHelpText": "Ordner, in dem {appName} die Datei {extension} speichert",
"BlackholeWatchFolder": "Überwachter Ordner",
"BlackholeWatchFolderHelpText": "Ordner, aus dem {appName} abgeschlossene Downloads importieren soll",
"BlackholeWatchFolderHelpText": "Der Ordner, aus dem {appName} fertige Downloads importieren soll",
"BrowserReloadRequired": "Neuladen des Browsers erforderlich",
"CalendarOptions": "Kalenderoptionen",
"CancelPendingTask": "Möchten Sie diese ausstehende Aufgabe wirklich abbrechen?",
@@ -776,5 +776,16 @@
"Airs": "Wird ausgestrahlt",
"AddRootFolderError": "Stammverzeichnis kann nicht hinzugefügt werden",
"IconForCutoffUnmet": "Symbol für Schwelle nicht erreicht",
"DownloadClientSettingsAddPaused": "Pausiert hinzufügen"
"DownloadClientSettingsAddPaused": "Pausiert hinzufügen",
"ClickToChangeIndexerFlags": "Klicken, um Indexer-Flags zu ändern",
"BranchUpdate": "Branch, der verwendet werden soll, um {appName} zu updaten",
"BlocklistAndSearch": "Sperrliste und Suche",
"AddDelayProfileError": "Verzögerungsprofil konnte nicht hinzugefügt werden. Bitte erneut versuchen.",
"BlocklistAndSearchHint": "Starte Suche nach einer Alternative, falls es der Sperrliste hinzugefügt wurde",
"BlocklistAndSearchMultipleHint": "Starte Suchen nach einer Alternative, falls es der Sperrliste hinzugefügt wurde",
"BlocklistMultipleOnlyHint": "Der Sperrliste hinzufügen, ohne nach Alternativen zu suchen",
"BlocklistOnly": "Nur der Sperrliste hinzufügen",
"BlocklistOnlyHint": "Der Sperrliste hinzufügen, ohne nach Alternative zu suchen",
"BlocklistReleaseHelpText": "Dieses Release für erneuten Download durch {appName} via RSS oder automatische Suche sperren",
"ChangeCategory": "Kategorie wechseln"
}

View File

@@ -245,7 +245,7 @@
"SubtitleLanguages": "Langues des sous-titres",
"Clone": "Dupliquer",
"ColonReplacementFormatHelpText": "Changer la manière dont {appName} remplace les « deux-points »",
"DefaultCase": "Casse par défaut",
"DefaultCase": "Case par défaut",
"Delete": "Supprimer",
"DelayProfiles": "Profils de retard",
"DelayProfilesLoadError": "Impossible de charger les profils de retard",
@@ -1281,8 +1281,8 @@
"CreateEmptySeriesFolders": "Créer des dossiers de séries vides",
"Custom": "Customisé",
"CopyUsingHardlinksSeriesHelpText": "Les liens physiques permettent à {appName} d'importer des torrents dans le dossier de la série sans prendre d'espace disque supplémentaire ni copier l'intégralité du contenu du fichier. Les liens physiques ne fonctionneront que si la source et la destination sont sur le même volume",
"CustomFormatsSettingsSummary": "Paramètres de formats personnalisés",
"CustomFormatsSettings": "Paramètres de formats personnalisés",
"CustomFormatsSettingsSummary": "Formats et paramètres personnalisés",
"CustomFormatsSettings": "Paramètre des formats personnalisés",
"DefaultDelayProfileSeries": "Il s'agit du profil par défaut. Cela s'applique à toutes les séries qui n'ont pas de profil explicite.",
"DeleteDownloadClient": "Supprimer le client de téléchargement",
"DeleteEmptyFolders": "Supprimer les dossiers vides",
@@ -1355,7 +1355,7 @@
"DownloadClientStatusAllClientHealthCheckMessage": "Tous les clients de téléchargement sont indisponibles en raison d'échecs",
"DownloadClientsLoadError": "Impossible de charger les clients de téléchargement",
"DownloadPropersAndRepacks": "Propriétés et reconditionnements",
"DownloadClientsSettingsSummary": "Clients de téléchargement, gestion des téléchargements et mappages de chemins distants",
"DownloadClientsSettingsSummary": "Clients de téléchargement, gestion des téléchargements et mappages de chemins d'accès à distance",
"DownloadPropersAndRepacksHelpText": "S'il faut ou non mettre à niveau automatiquement vers Propers/Repacks",
"DownloadPropersAndRepacksHelpTextWarning": "Utilisez des formats personnalisés pour les mises à niveau automatiques vers Propers/Repacks",
"DownloadPropersAndRepacksHelpTextCustomFormat": "Utilisez « Ne pas préférer » pour trier par score de format personnalisé sur Propers/Repacks",
@@ -1415,7 +1415,7 @@
"EpisodesLoadError": "Impossible de charger les épisodes",
"Files": "Fichiers",
"Continuing": "Continuer",
"Donate": "Faire un don",
"Donate": "Donation",
"EditConditionImplementation": "Modifier la condition {implementationName}",
"EditConnectionImplementation": "Modifier la connexion - {implementationName}",
"EditImportListImplementation": "Modifier la liste d'importation - {implementationName}",
@@ -1931,8 +1931,8 @@
"DownloadClientDelugeSettingsDirectoryHelpText": "Emplacement dans lequel placer les téléchargements (facultatif), laissez vide pour utiliser l'emplacement Deluge par défaut",
"DownloadClientDelugeSettingsDirectory": "Dossier de téléchargement",
"DownloadClientDelugeSettingsDirectoryCompleted": "Dossier de déplacement une fois terminé",
"ClickToChangeIndexerFlags": "Cliquer pour changer les attributs de l'indexer",
"CustomFormatsSpecificationFlag": "Attribut",
"ClickToChangeIndexerFlags": "Cliquez pour changer les drapeaux de l'indexeur",
"CustomFormatsSpecificationFlag": "Drapeau",
"CustomFilter": "Filtre personnalisé",
"ImportListsTraktSettingsAuthenticateWithTrakt": "S'authentifier avec Trakt",
"SelectIndexerFlags": "Sélectionner les drapeaux de l'indexeur",

View File

@@ -110,7 +110,7 @@
"AddAutoTagError": "Impossibile aggiungere un nuovo tag automatico, riprova.",
"AddCustomFormat": "Aggiungi Formato Personalizzato",
"AddDownloadClient": "Aggiungi Client di Download",
"AddCustomFormatError": "Non riesco ad aggiungere un nuovo formato personalizzato, riprova.",
"AddCustomFormatError": "Impossibile aggiungere un nuovo formato personalizzato, riprova.",
"AddDownloadClientError": "Impossibile aggiungere un nuovo client di download, riprova.",
"AddDelayProfile": "Aggiungi Profilo di Ritardo",
"AddIndexerError": "Impossibile aggiungere un nuovo Indicizzatore, riprova.",
@@ -248,5 +248,6 @@
"AnimeEpisodeTypeDescription": "Episodi rilasciati utilizzando un numero di episodio assoluto",
"AnimeEpisodeTypeFormat": "Numero assoluto dell'episodio ({format})",
"AutoRedownloadFailed": "Download fallito",
"AddDelayProfileError": "Impossibile aggiungere un nuovo profilo di ritardo, riprova."
"AddDelayProfileError": "Impossibile aggiungere un nuovo profilo di ritardo, riprova.",
"Cutoff": "Taglio"
}

View File

@@ -8,5 +8,12 @@
"Absolute": "Absolutt",
"Activity": "Aktivitet",
"About": "Om",
"CalendarOptions": "Kalenderinnstillinger"
"CalendarOptions": "Kalenderinnstillinger",
"AbsoluteEpisodeNumbers": "Absolutte Episode Numre",
"AddANewPath": "Legg til ny filsti",
"AddConditionImplementation": "Legg til betingelse - {implementationName}",
"AddConditionError": "Ikke mulig å legge til ny betingelse, vennligst prøv igjen",
"AbsoluteEpisodeNumber": "Absolutt Episode Nummer",
"AddAutoTagError": "Ikke mulig å legge til ny automatisk tagg, vennligst prøv igjen",
"Actions": "Handlinger"
}

View File

@@ -1786,7 +1786,7 @@
"DownloadClientAriaSettingsDirectoryHelpText": "可选的下载位置,留空使用 Aria2 默认位置",
"DownloadClientPriorityHelpText": "下载客户端优先级从1最高到50最低默认为1。具有相同优先级的客户端将轮换使用。",
"IndexerSettingsRejectBlocklistedTorrentHashes": "抓取时舍弃列入黑名单的种子散列值",
"ChangeCategory": "改分类",
"ChangeCategory": "改分类",
"IgnoreDownload": "忽略下载",
"IgnoreDownloads": "忽略下载",
"IgnoreDownloadsHint": "阻止 {appName} 进一步处理这些下载",
@@ -1808,5 +1808,6 @@
"ChangeCategoryHint": "将下载从下载客户端更改为“导入后类别”",
"IgnoreDownloadHint": "阻止 {appName} 进一步处理此下载",
"IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "如果 torrent 的哈希被屏蔽了某些索引器在使用RSS或者搜索期间可能无法正确拒绝它启用此功能将允许在抓取 torrent 之后但在将其发送到客户端之前拒绝它。",
"RemoveQueueItemRemovalMethodHelpTextWarning": "“从下载客户端移除”将从下载客户端移除下载内容和文件。"
"RemoveQueueItemRemovalMethodHelpTextWarning": "“从下载客户端移除”将从下载客户端移除下载内容和文件。",
"AutoTaggingSpecificationOriginalLanguage": "语言"
}

View File

@@ -23,7 +23,7 @@ namespace NzbDrone.Core.Messaging.Commands
}
public virtual bool UpdateScheduledTask => true;
public virtual string CompletionMessage => "Completed";
public virtual string CompletionMessage => null;
public virtual bool RequiresDiskAccess => false;
public virtual bool IsExclusive => false;
public virtual bool IsLongRunning => false;

View File

@@ -99,7 +99,7 @@ namespace NzbDrone.Core.Notifications.Plex.PlexTv
var clientIdentifier = _configService.PlexClientIdentifier;
var requestBuilder = new HttpRequestBuilder("https://metadata.provider.plex.tv/library/sections/watchlist/all")
var requestBuilder = new HttpRequestBuilder("https://discover.provider.plex.tv/library/sections/watchlist/all")
.Accept(HttpAccept.Json)
.AddQueryParam("clientID", clientIdentifier)
.AddQueryParam("context[device][product]", BuildInfo.AppName)
@@ -107,7 +107,8 @@ namespace NzbDrone.Core.Notifications.Plex.PlexTv
.AddQueryParam("context[device][platformVersion]", "7")
.AddQueryParam("context[device][version]", BuildInfo.Version.ToString())
.AddQueryParam("includeFields", "title,type,year,ratingKey")
.AddQueryParam("includeElements", "Guid")
.AddQueryParam("excludeElements", "Image")
.AddQueryParam("includeGuids", "1")
.AddQueryParam("sort", "watchlistedAt:desc")
.AddQueryParam("type", (int)PlexMediaType.Show)
.AddQueryParam("X-Plex-Container-Size", pageSize)

View File

@@ -50,10 +50,10 @@ namespace NzbDrone.Core.Organizer
private static readonly Regex TitleRegex = new Regex(@"(?<escaped>\{\{|\}\})|\{(?<prefix>[- ._\[(]*)(?<token>(?:[a-z0-9]+)(?:(?<separator>[- ._]+)(?:[a-z0-9]+))?)(?::(?<customFormat>[ ,a-z0-9+-]+(?<![- ])))?(?<suffix>[- ._)\]]*)\}",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
private static readonly Regex EpisodeRegex = new Regex(@"(?<episode>\{episode(?:\:0+)?})",
public static readonly Regex EpisodeRegex = new Regex(@"(?<episode>\{episode(?:\:0+)?})",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex SeasonRegex = new Regex(@"(?<season>\{season(?:\:0+)?})",
public static readonly Regex SeasonRegex = new Regex(@"(?<season>\{season(?:\:0+)?})",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex AbsoluteEpisodeRegex = new Regex(@"(?<absolute>\{absolute(?:\:0+)?})",

View File

@@ -75,6 +75,7 @@ namespace NzbDrone.Core.Organizer
}
return FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) ||
(FileNameBuilder.SeasonRegex.IsMatch(value) && FileNameBuilder.EpisodeRegex.IsMatch(value)) ||
FileNameValidation.OriginalTokenRegex.IsMatch(value);
}
}
@@ -91,6 +92,7 @@ namespace NzbDrone.Core.Organizer
}
return FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) ||
(FileNameBuilder.SeasonRegex.IsMatch(value) && FileNameBuilder.EpisodeRegex.IsMatch(value)) ||
FileNameBuilder.AirDateRegex.IsMatch(value) ||
FileNameValidation.OriginalTokenRegex.IsMatch(value);
}
@@ -109,6 +111,7 @@ namespace NzbDrone.Core.Organizer
}
return FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) ||
(FileNameBuilder.SeasonRegex.IsMatch(value) && FileNameBuilder.EpisodeRegex.IsMatch(value)) ||
FileNameBuilder.AbsoluteEpisodePatternRegex.IsMatch(value) ||
FileNameValidation.OriginalTokenRegex.IsMatch(value);
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FluentValidation.Results;
using NzbDrone.Core.Parser.Model;
@@ -20,7 +21,9 @@ namespace NzbDrone.Core.Organizer
public ValidationFailure ValidateStandardFilename(SampleResult sampleResult)
{
var validationFailure = new ValidationFailure("StandardEpisodeFormat", ERROR_MESSAGE);
var parsedEpisodeInfo = Parser.Parser.ParseTitle(sampleResult.FileName);
var parsedEpisodeInfo = sampleResult.FileName.Contains(Path.DirectorySeparatorChar)
? Parser.Parser.ParsePath(sampleResult.FileName)
: Parser.Parser.ParseTitle(sampleResult.FileName);
if (parsedEpisodeInfo == null)
{
@@ -38,7 +41,9 @@ namespace NzbDrone.Core.Organizer
public ValidationFailure ValidateDailyFilename(SampleResult sampleResult)
{
var validationFailure = new ValidationFailure("DailyEpisodeFormat", ERROR_MESSAGE);
var parsedEpisodeInfo = Parser.Parser.ParseTitle(sampleResult.FileName);
var parsedEpisodeInfo = sampleResult.FileName.Contains(Path.DirectorySeparatorChar)
? Parser.Parser.ParsePath(sampleResult.FileName)
: Parser.Parser.ParseTitle(sampleResult.FileName);
if (parsedEpisodeInfo == null)
{
@@ -66,7 +71,9 @@ namespace NzbDrone.Core.Organizer
public ValidationFailure ValidateAnimeFilename(SampleResult sampleResult)
{
var validationFailure = new ValidationFailure("AnimeEpisodeFormat", ERROR_MESSAGE);
var parsedEpisodeInfo = Parser.Parser.ParseTitle(sampleResult.FileName);
var parsedEpisodeInfo = sampleResult.FileName.Contains(Path.DirectorySeparatorChar)
? Parser.Parser.ParsePath(sampleResult.FileName)
: Parser.Parser.ParseTitle(sampleResult.FileName);
if (parsedEpisodeInfo == null)
{

View File

@@ -186,6 +186,10 @@ namespace NzbDrone.Core.Parser
new Regex(@"^((?<title>.*?)[ ._]\/[ ._])+\(?S(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:\W|_)?E?[ ._]?(?<episode>(?<!\d+)\d{1,2}(?!\d+))(?:-(?<episode>(?<!\d+)\d{1,2}(?!\d+)))?([ ._]of[ ._]\d+)?\)?[ ._][\(\[]",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Multi-episode with title (S01E99-100, S01E05-06)
new Regex(@"^(?<title>.+?)(?:[-_\W](?<![()\[!]))+S(?<season>(?<!\d+)(?:\d{1,2})(?!\d+))E(?<episode>\d{2,3}(?!\d+))(?:-(?<episode>\d{2,3}(?!\d+)))+(?:[-_. ]|$)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Multi-episode with title (S01E05-06, S01E05-6)
new Regex(@"^(?<title>.+?)(?:[-_\W](?<![()\[!]))+S(?<season>(?<!\d+)(?:\d{1,2})(?!\d+))E(?<episode>\d{1,2}(?!\d+))(?:-(?<episode>\d{1,2}(?!\d+)))+(?:[-_. ]|$)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
@@ -550,6 +554,8 @@ namespace NzbDrone.Core.Parser
private static readonly Regex ArticleWordRegex = new Regex(@"^(a|an|the)\s", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex SpecialEpisodeWordRegex = new Regex(@"\b(part|special|edition|christmas)\b\s?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex DuplicateSpacesRegex = new Regex(@"\s{2,}", RegexOptions.Compiled);
private static readonly Regex SeasonFolderRegex = new Regex(@"^(?:S|Season|Saison|Series|Stagione)[-_. ]*(?<season>(?<!\d+)\d{1,4}(?!\d+))(?:[_. ]+(?!\d+)|$)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex SimpleEpisodeNumberRegex = new Regex(@"^[ex]?(?<episode>(?<!\d+)\d{1,3}(?!\d+))(?:[ex-](?<episode>(?<!\d+)\d{1,3}(?!\d+)))?(?:[_. ]|$)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex RequestInfoRegex = new Regex(@"^(?:\[.+?\])+", RegexOptions.Compiled);
@@ -559,6 +565,28 @@ namespace NzbDrone.Core.Parser
{
var fileInfo = new FileInfo(path);
// Parse using the folder and file separately, but combine if they both parse correctly.
var episodeNumberMatch = SimpleEpisodeNumberRegex.Matches(fileInfo.Name);
if (episodeNumberMatch.Count != 0 && fileInfo.Directory?.Name != null)
{
var parsedFileInfo = ParseMatchCollection(episodeNumberMatch, fileInfo.Name);
if (parsedFileInfo != null)
{
var seasonMatch = SeasonFolderRegex.Match(fileInfo.Directory.Name);
if (seasonMatch.Success && seasonMatch.Groups["season"].Success)
{
parsedFileInfo.SeasonNumber = int.Parse(seasonMatch.Groups["season"].Value);
Logger.Debug("Episode parsed from file and folder names. {0}", parsedFileInfo);
return parsedFileInfo;
}
}
}
var result = ParseTitle(fileInfo.Name);
if (result == null && int.TryParse(Path.GetFileNameWithoutExtension(fileInfo.Name), out var number))

View File

@@ -1,10 +1,13 @@
using System;
using System;
using System.Threading;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.ProgressMessaging
{
public static class ProgressMessageContext
{
private static AsyncLocal<CommandModel> _commandModelAsync = new AsyncLocal<CommandModel>();
[ThreadStatic]
private static CommandModel _commandModel;
@@ -13,8 +16,15 @@ namespace NzbDrone.Core.ProgressMessaging
public static CommandModel CommandModel
{
get { return _commandModel; }
set { _commandModel = value; }
get
{
return _commandModel ?? _commandModelAsync.Value;
}
set
{
_commandModel = value;
_commandModelAsync.Value = value;
}
}
public static bool LockReentrancy()

View File

@@ -39,5 +39,7 @@ namespace NzbDrone.Core.Tv.Commands
public override bool UpdateScheduledTask => SeriesIds.Empty();
public override bool IsLongRunning => true;
public override string CompletionMessage => "Completed";
}
}

View File

@@ -6,7 +6,5 @@ namespace NzbDrone.Core.Update.Commands
{
public override bool SendUpdatesToClient => true;
public override bool IsExclusive => true;
public override string CompletionMessage => null;
}
}