mirror of
https://github.com/Sonarr/Sonarr.git
synced 2026-04-14 20:54:58 -04:00
Compare commits
1 Commits
importing-
...
auth-succe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98c737a146 |
@@ -90,7 +90,7 @@ function QueueStatus(props: QueueStatusProps) {
|
||||
|
||||
if (trackedDownloadState === 'importing') {
|
||||
title += ` - ${translate('Importing')}`;
|
||||
iconKind = kinds.PRIMARY;
|
||||
iconKind = kinds.PURPLE;
|
||||
}
|
||||
|
||||
if (trackedDownloadState === 'failedPending') {
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
color: var(--warningColor);
|
||||
}
|
||||
|
||||
.primary {
|
||||
color: var(--primaryColor);
|
||||
}
|
||||
|
||||
.purple {
|
||||
color: var(--purple);
|
||||
}
|
||||
|
||||
1
frontend/src/Components/Icon.css.d.ts
vendored
1
frontend/src/Components/Icon.css.d.ts
vendored
@@ -6,7 +6,6 @@ interface CssExports {
|
||||
'disabled': string;
|
||||
'info': string;
|
||||
'pink': string;
|
||||
'primary': string;
|
||||
'purple': string;
|
||||
'success': string;
|
||||
'warning': string;
|
||||
|
||||
@@ -4,8 +4,6 @@ namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class DateTimeExtensions
|
||||
{
|
||||
public static readonly DateTime EpochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
public static bool InNextDays(this DateTime dateTime, int days)
|
||||
{
|
||||
return InNext(dateTime, new TimeSpan(days, 0, 0, 0));
|
||||
@@ -45,10 +43,5 @@ namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
return dateTime.AddTicks(-(dateTime.Ticks % TimeSpan.TicksPerSecond));
|
||||
}
|
||||
|
||||
public static DateTime WithTicksFrom(this DateTime dateTime, DateTime other)
|
||||
{
|
||||
return dateTime.WithoutTicks().AddTicks(other.Ticks % TimeSpan.TicksPerSecond);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.MediaFiles.UpdateEpisodeFileServiceTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class ChangeFileDateForFileFixture : CoreTest<UpdateEpisodeFileService>
|
||||
{
|
||||
private readonly DateTime _veryOldAirDateUtc = new(1965, 01, 01, 0, 0, 0, 512, 512, DateTimeKind.Utc);
|
||||
private DateTime _lastWrite = new(2025, 07, 27, 12, 0, 0, 512, 512, DateTimeKind.Utc);
|
||||
private Series _series;
|
||||
private EpisodeFile _episodeFile;
|
||||
private string _seriesFolder;
|
||||
private List<Episode> _episodes;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_seriesFolder = @"C:\Test\TV\Series Title".AsOsAgnostic();
|
||||
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.With(s => s.Path = _seriesFolder)
|
||||
.Build();
|
||||
|
||||
_episodes = Builder<Episode>.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(e => e.AirDateUtc = _lastWrite.AddDays(2))
|
||||
.Build()
|
||||
.ToList();
|
||||
|
||||
_episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||
.With(f => f.Path = Path.Combine(_series.Path, "Season 1", "Series Title - S01E01.mkv").AsOsAgnostic())
|
||||
.With(f => f.RelativePath = @"Season 1\Series Title - S01E01.mkv".AsOsAgnostic())
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(x => x.FileGetLastWrite(_episodeFile.Path))
|
||||
.Returns(() => _lastWrite);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(x => x.FileSetLastWriteTime(_episodeFile.Path, It.IsAny<DateTime>()))
|
||||
.Callback<string, DateTime>((path, dateTime) =>
|
||||
{
|
||||
_lastWrite = dateTime.Kind == DateTimeKind.Utc
|
||||
? dateTime
|
||||
: dateTime.ToUniversalTime();
|
||||
});
|
||||
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(x => x.FileDate)
|
||||
.Returns(FileDateType.LocalAirDate);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_change_date_once_only()
|
||||
{
|
||||
var previousWrite = new DateTime(_lastWrite.Ticks, _lastWrite.Kind);
|
||||
|
||||
Subject.ChangeFileDateForFile(_episodeFile, _series, _episodes);
|
||||
Subject.ChangeFileDateForFile(_episodeFile, _series, _episodes);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.FileSetLastWriteTime(_episodeFile.Path, It.IsAny<DateTime>()), Times.Once());
|
||||
|
||||
var actualWriteTime = Mocker.GetMock<IDiskProvider>().Object.FileGetLastWrite(_episodeFile.Path).ToLocalTime();
|
||||
actualWriteTime.Should().Be(_episodes[0].AirDateUtc.Value.ToLocalTime().WithTicksFrom(previousWrite));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_clamp_mtime_on_posix()
|
||||
{
|
||||
PosixOnly();
|
||||
|
||||
var previousWrite = new DateTime(_lastWrite.Ticks, _lastWrite.Kind);
|
||||
_episodes[0].AirDateUtc = _veryOldAirDateUtc;
|
||||
|
||||
Subject.ChangeFileDateForFile(_episodeFile, _series, _episodes);
|
||||
Subject.ChangeFileDateForFile(_episodeFile, _series, _episodes);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.FileSetLastWriteTime(_episodeFile.Path, It.IsAny<DateTime>()), Times.Once());
|
||||
|
||||
var actualWriteTime = Mocker.GetMock<IDiskProvider>().Object.FileGetLastWrite(_episodeFile.Path).ToLocalTime();
|
||||
actualWriteTime.Should().Be(DateTimeExtensions.EpochTime.ToLocalTime().WithTicksFrom(previousWrite));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_clamp_mtime_on_windows()
|
||||
{
|
||||
WindowsOnly();
|
||||
|
||||
var previousWrite = new DateTime(_lastWrite.Ticks, _lastWrite.Kind);
|
||||
_episodes[0].AirDateUtc = _veryOldAirDateUtc;
|
||||
|
||||
Subject.ChangeFileDateForFile(_episodeFile, _series, _episodes);
|
||||
Subject.ChangeFileDateForFile(_episodeFile, _series, _episodes);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.FileSetLastWriteTime(_episodeFile.Path, It.IsAny<DateTime>()), Times.Once());
|
||||
|
||||
var actualWriteTime = Mocker.GetMock<IDiskProvider>().Object.FileGetLastWrite(_episodeFile.Path).ToLocalTime();
|
||||
actualWriteTime.Should().Be(_episodes[0].AirDateUtc.Value.ToLocalTime().WithTicksFrom(previousWrite));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,8 +86,6 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
[TestCase("Series Title S01 1080p Eng Fra [mkvonly]")]
|
||||
[TestCase("Series Title S01 Eng Fre Multi Subs 720p [H264 mp4]")]
|
||||
[TestCase("Series-Title-S01-[DVDRip]-H264-Fra-Ac3-2-0-Eng-5-1")]
|
||||
[TestCase("Series Title S01 1080p FR ENG [mkvonly]")]
|
||||
[TestCase("Series Title S01 1080p ENG FR [mkvonly]")]
|
||||
public void should_parse_language_french_english(string postTitle)
|
||||
{
|
||||
var result = LanguageParser.ParseLanguages(postTitle);
|
||||
|
||||
@@ -1874,6 +1874,7 @@
|
||||
"DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "La cua de torrent no està activada a la configuració del qBittorrent. Activeu-lo a qBittorrent o seleccioneu 'Last' com a prioritat.",
|
||||
"DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent està configurat per a eliminar els torrents quan arribin al límit de la relació de compartició",
|
||||
"DownloadClientTransmissionSettingsUrlBaseHelpText": "Afegeix un prefix a l'URL rpc de {clientName}, ex. {url}, per defecte a ‘{defaultUrl}’",
|
||||
"DownloadClientUTorrentProviderMessage": "uTorrent té un historial d'inclusió de criptominers, programari maliciós i anuncis, us animem a triar un client diferent.",
|
||||
"DownloadClientValidationAuthenticationFailureDetail": "Verifiqueu el vostre nom d'usuari i contrasenya. Verifiqueu també si el servidor que executa {appName} no està bloquejat per accedir a {clientName} per les limitacions de WhiteList a la configuració {clientName}.",
|
||||
"DownloadClientValidationCategoryMissingDetail": "La categoria que heu introduït no existeix a {clientName}. Primer creeu-lo a {clientName}.",
|
||||
"DownloadClientValidationSslConnectFailure": "No s'ha pogut connectar a través de SSL",
|
||||
|
||||
@@ -537,6 +537,7 @@
|
||||
"DownloadClientFreeboxUnableToReachFreebox": "Nelze se připojit k Freebox API. Zkontrolujte nastavení 'Host', 'Port' nebo 'Použít SSL'. (Chyba: {exceptionMessage})",
|
||||
"IndexerHDBitsSettingsCodecsHelpText": "Pokud nespecifikováno, použijí se všechny možnosti.",
|
||||
"DownloadClientDownloadStationValidationSharedFolderMissing": "Sdílená složka neexistuje",
|
||||
"DownloadClientUTorrentProviderMessage": "uTorrent je známý tím, že zahrnuje cryptominery, malware a reklamy, důrazně vám doporučujeme zvolit jiného klienta.",
|
||||
"DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Přihlaste se do vaší DiskStation jako {username} a ručně to nastavte v nastavení DownloadStation pod BT/HTTP/FTP/NZB -> Umístění.",
|
||||
"IndexerLongTermStatusUnavailableHealthCheckMessage": "Indexery nedostupné z důvodu selhání delším než 6 hodin: {indexerNames}",
|
||||
"DownloadClientFloodSettingsRemovalInfo": "{appName} se postará o automatické mazání torrentů podle aktuálních kritérií seedování v Nastavení -> Indexery",
|
||||
|
||||
@@ -2151,6 +2151,7 @@
|
||||
"NotificationsTelegramSettingsLinkPreviewHelpText": "Determina qué enlaces se previsualizarán en las notificaciones de Telegram. Elige 'Ninguno' para deshabilitarlo",
|
||||
"MediaInfoFootNote2": "MediaInfo AudioLanguages excluye el inglés si es el único idioma. Usa MediaInfo AudioLanguagesAll para incluir solo el inglés",
|
||||
"ReleaseSource": "Fuente de lanzamiento",
|
||||
"DownloadClientUTorrentProviderMessage": "uTorrent tiene un amplio historial de incluir criptomineros, malware y publicidad, por lo que recomendamos encarecidamente que elijas un cliente diferente.",
|
||||
"NotificationsPushcutSettingsIncludePoster": "Incluir póster",
|
||||
"NotificationsPushcutSettingsIncludePosterHelpText": "Incluir póster con notificación",
|
||||
"NotificationsPushcutSettingsMetadataLinks": "Enlaces de metadatos",
|
||||
|
||||
@@ -2152,6 +2152,7 @@
|
||||
"QualityDefinitionsSizeNotice": "Kokorajoitukset on siirretty laatuprofiileihin",
|
||||
"NotificationsTelegramSettingsLinkPreview": "Linkin esikatselu",
|
||||
"NotificationsTelegramSettingsLinkPreviewHelpText": "Määrittää minkä linkin esikatselu Telegram-ilmoituksessa näytetään. Poista käytöstä valitsemalla \"Ei mitään\".",
|
||||
"DownloadClientUTorrentProviderMessage": "Koska uTorrent on tunnettu crypto-, haitta- and mainossisällöstä ja sovelluksista, suosittelemme qBittorrentin, Delugen ja ruTorrentin kaltaisten vaihtoehtojen käyttämistä.",
|
||||
"NotificationsPushcutSettingsIncludePoster": "Sisällytä juliste",
|
||||
"NotificationsPushcutSettingsIncludePosterHelpText": "Näytä juliste ilmoituksessa.",
|
||||
"NotificationsPushcutSettingsMetadataLinks": "Metatietolinkit",
|
||||
|
||||
@@ -800,7 +800,7 @@
|
||||
"UpdaterLogFiles": "Journaux du programme de mise à jour",
|
||||
"UpgradeUntil": "Mise à niveau jusqu'à",
|
||||
"UpgradeUntilCustomFormatScore": "Mise à niveau jusqu'au score de format personnalisé",
|
||||
"UpgradeUntilCustomFormatScoreEpisodeHelpText": "Une fois que la qualité minimum est atteinte ou dépassée et que le score de format personnalisé est atteint, {appName} ne récupérera plus les sorties d'épisodes",
|
||||
"UpgradeUntilCustomFormatScoreEpisodeHelpText": "Une fois ce score de format personnalisé atteint, {appName} ne récupérera plus les sorties d'épisodes",
|
||||
"UrlBase": "URL de base",
|
||||
"UseHardlinksInsteadOfCopy": "Utiliser les liens durs au lieu de copier",
|
||||
"UseSeasonFolder": "Utiliser le dossier de la saison",
|
||||
@@ -904,7 +904,7 @@
|
||||
"UnmappedFilesOnly": "Fichiers non mappés uniquement",
|
||||
"UnmonitorSpecialsEpisodesDescription": "Annulez la surveillance de tous les épisodes spéciaux sans modifier le statut surveillé des autres épisodes",
|
||||
"UpdateUiNotWritableHealthCheckMessage": "Impossible d'installer la mise à jour, car le dossier de l'interface utilisateur « {uiFolder} » n'est pas accessible en écriture par l'utilisateur « {userName} ».",
|
||||
"UpgradeUntilEpisodeHelpText": "Une fois cette qualité atteinte, {appName} ne téléchargera plus d'épisodes une fois le que le score du format personnalisé est atteint ou dépassé",
|
||||
"UpgradeUntilEpisodeHelpText": "Une fois cette qualité atteinte, {appName} ne téléchargera plus d'épisodes",
|
||||
"UpgradeUntilThisQualityIsMetOrExceeded": "Mise à niveau jusqu'à ce que cette qualité soit atteinte ou dépassée",
|
||||
"UseProxy": "Utiliser le proxy",
|
||||
"WaitingToImport": "En attente d'import",
|
||||
@@ -2152,6 +2152,7 @@
|
||||
"NotificationsTelegramSettingsLinkPreview": "Aperçu du lien",
|
||||
"FavoriteFolderAdd": "Ajouter un dossier favori",
|
||||
"FavoriteFolderRemove": "Supprimer le dossier favori",
|
||||
"DownloadClientUTorrentProviderMessage": "uTorrent a l'habitude d'inclure des cryptomineurs, des logiciels malveillants et des publicités, nous vous encourageons fortement à choisir un client différent.",
|
||||
"DownloadClientQbittorrentSettingsAddSeriesTags": "Ajouter des tags de séries",
|
||||
"DownloadClientQbittorrentSettingsAddSeriesTagsHelpText": "Ajouter des tags de séries aux nouveaux torrents ajoutés au client de téléchargement (qBittorrent 4.1.0+)",
|
||||
"FavoriteFolders": "Dossier favori",
|
||||
@@ -2162,7 +2163,5 @@
|
||||
"UserRejectedExtensions": "Extensions de fichiers rejetées supplémentaires",
|
||||
"UserRejectedExtensionsHelpText": "Liste séparée par des virgules des extensions de fichiers à échouer (“Échouer les téléchargements” doit également être activé dans l’indexeur)",
|
||||
"UserRejectedExtensionsTextsExamples": "Examples : '.ext, .xyz' or 'ext,xyz'",
|
||||
"Warning": "Avertissement",
|
||||
"QualityDefinitionsSizeNotice": "Les restrictions de taille sont maintenant dans les profils de qualité",
|
||||
"UserInvokedSearch": "Recherche invoquée par l’utilisateur"
|
||||
"Warning": "Avertissement"
|
||||
}
|
||||
|
||||
@@ -2152,6 +2152,7 @@
|
||||
"QualityDefinitionsSizeNotice": "As restrições de tamanho foram transferidas para Perfis de Qualidade",
|
||||
"NotificationsTelegramSettingsLinkPreview": "Prévia do Link",
|
||||
"NotificationsTelegramSettingsLinkPreviewHelpText": "Determina qual link será visualizado na notificação do Telegram. Escolha 'Nenhum' para desativar",
|
||||
"DownloadClientUTorrentProviderMessage": "O uTorrent tem um histórico de incluir criptomineradores, malware e anúncios, recomendamos fortemente que você escolha um cliente diferente.",
|
||||
"NotificationsPushcutSettingsIncludePoster": "Incluir pôster",
|
||||
"NotificationsPushcutSettingsMetadataLinks": "Links de metadados",
|
||||
"NotificationsPushcutSettingsIncludePosterHelpText": "Incluir pôster com notificação",
|
||||
|
||||
@@ -2155,6 +2155,7 @@
|
||||
"UpdatePath": "Обновить путь",
|
||||
"UpdateSeriesPath": "Обновить путь до сериала",
|
||||
"ReleasePush": "Через API",
|
||||
"DownloadClientUTorrentProviderMessage": "Мы настоятельно советуем не использовать uTorrent, т.к. он известен как программа-шифровальщик и в целом вредоносное ПО.",
|
||||
"CloneImportList": "Копировать список импорта",
|
||||
"EpisodesInSeason": "{episodeCount} эпизодов в сезоне",
|
||||
"DefaultNameCopiedImportList": "{name} - копировать",
|
||||
|
||||
@@ -2152,6 +2152,7 @@
|
||||
"QualityDefinitionsSizeNotice": "Boyut kısıtlamaları Kalite Profillerine taşındı",
|
||||
"NotificationsTelegramSettingsLinkPreview": "Bağlantı Önizlemesi",
|
||||
"NotificationsTelegramSettingsLinkPreviewHelpText": "Telegram bildiriminde hangi bağlantının önizleneceğini belirler. Devre dışı bırakmak için 'Hiçbiri'ni seçin",
|
||||
"DownloadClientUTorrentProviderMessage": "uTorrent'in kripto para madenciliği, kötü amaçlı yazılım ve reklam içerme geçmişi vardır, bu nedenle farklı bir istemci seçmenizi önemle tavsiye ederiz.",
|
||||
"NotificationsPushcutSettingsIncludePoster": "Posteri Dahil Et",
|
||||
"NotificationsPushcutSettingsMetadataLinks": "Meta Veri Bağlantıları",
|
||||
"NotificationsPushcutSettingsMetadataLinksHelpText": "Bildirim içeriğine meta verilerin bağlantılarını ekleyin",
|
||||
|
||||
@@ -2123,6 +2123,7 @@
|
||||
"Airs": "Ефіри",
|
||||
"DoneEditingSizes": "Редагування розмірів завершено",
|
||||
"IndexerSettingsFailDownloads": "Не вдалося завантажити",
|
||||
"DownloadClientUTorrentProviderMessage": "uTorrent має історію включення криптомайнерів, шкідливого програмного забезпечення та реклами. Ми наполегливо рекомендуємо вибрати інший клієнт.",
|
||||
"EditSelectedCustomFormats": "Змінити вибрані власні формати",
|
||||
"EditSizes": "Змінити розміри",
|
||||
"FailedToFetchSettings": "Не вдалося отримати налаштування",
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly Logger _logger;
|
||||
private static readonly DateTime EpochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
public UpdateEpisodeFileService(IDiskProvider diskProvider,
|
||||
IConfigService configService,
|
||||
@@ -46,48 +47,90 @@ namespace NzbDrone.Core.MediaFiles
|
||||
private bool ChangeFileDate(EpisodeFile episodeFile, Series series, List<Episode> episodes)
|
||||
{
|
||||
var episodeFilePath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||
var airDateUtc = episodes.First().AirDateUtc;
|
||||
|
||||
if (!airDateUtc.HasValue)
|
||||
switch (_configService.FileDate)
|
||||
{
|
||||
return false;
|
||||
case FileDateType.LocalAirDate:
|
||||
{
|
||||
var airDate = episodes.First().AirDate;
|
||||
var airTime = series.AirTime;
|
||||
|
||||
if (airDate.IsNullOrWhiteSpace() || airTime.IsNullOrWhiteSpace())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ChangeFileDateToLocalAirDate(episodeFilePath, airDate, airTime);
|
||||
}
|
||||
|
||||
case FileDateType.UtcAirDate:
|
||||
{
|
||||
var airDateUtc = episodes.First().AirDateUtc;
|
||||
|
||||
if (!airDateUtc.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ChangeFileDateToUtcAirDate(episodeFilePath, airDateUtc.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return _configService.FileDate switch
|
||||
{
|
||||
FileDateType.LocalAirDate =>
|
||||
ChangeFileDateToLocalDate(episodeFilePath, airDateUtc.Value.ToLocalTime()),
|
||||
|
||||
// Intentionally pass UTC as local per user preference
|
||||
FileDateType.UtcAirDate =>
|
||||
ChangeFileDateToLocalDate(
|
||||
episodeFilePath,
|
||||
DateTime.SpecifyKind(airDateUtc.Value, DateTimeKind.Local)),
|
||||
|
||||
_ => false,
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ChangeFileDateToLocalDate(string filePath, DateTime localDate)
|
||||
private bool ChangeFileDateToLocalAirDate(string filePath, string fileDate, string fileTime)
|
||||
{
|
||||
// FileGetLastWrite returns UTC; convert to local to compare
|
||||
var oldLastWrite = _diskProvider.FileGetLastWrite(filePath).ToLocalTime();
|
||||
|
||||
if (OsInfo.IsNotWindows && localDate.ToUniversalTime() < DateTimeExtensions.EpochTime)
|
||||
if (DateTime.TryParse(fileDate + ' ' + fileTime, out var airDate))
|
||||
{
|
||||
_logger.Debug("Setting date of file to 1970-01-01 as actual airdate is before that time and will not be set properly");
|
||||
localDate = DateTimeExtensions.EpochTime.ToLocalTime();
|
||||
// avoiding false +ve checks and set date skewing by not using UTC (Windows)
|
||||
var oldLastWrite = _diskProvider.FileGetLastWrite(filePath);
|
||||
|
||||
if (OsInfo.IsNotWindows && airDate < EpochTime)
|
||||
{
|
||||
_logger.Debug("Setting date of file to 1970-01-01 as actual airdate is before that time and will not be set properly");
|
||||
airDate = EpochTime;
|
||||
}
|
||||
|
||||
if (!DateTime.Equals(airDate.WithoutTicks(), oldLastWrite.WithoutTicks()))
|
||||
{
|
||||
try
|
||||
{
|
||||
_diskProvider.FileSetLastWriteTime(filePath, airDate);
|
||||
_logger.Debug("Date of file [{0}] changed from '{1}' to '{2}'", filePath, oldLastWrite, airDate);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to set date of file [" + filePath + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug("Could not create valid date to change file [{0}]", filePath);
|
||||
}
|
||||
|
||||
if (!DateTime.Equals(localDate.WithoutTicks(), oldLastWrite.WithoutTicks()))
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ChangeFileDateToUtcAirDate(string filePath, DateTime airDateUtc)
|
||||
{
|
||||
var oldLastWrite = _diskProvider.FileGetLastWrite(filePath);
|
||||
|
||||
if (OsInfo.IsNotWindows && airDateUtc < EpochTime)
|
||||
{
|
||||
_logger.Debug("Setting date of file to 1970-01-01 as actual airdate is before that time and will not be set properly");
|
||||
airDateUtc = EpochTime;
|
||||
}
|
||||
|
||||
if (!DateTime.Equals(airDateUtc.WithoutTicks(), oldLastWrite.WithoutTicks()))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Preserve prior mtime subseconds per https://github.com/Sonarr/Sonarr/issues/7228
|
||||
var mtime = localDate.WithTicksFrom(oldLastWrite);
|
||||
|
||||
_diskProvider.FileSetLastWriteTime(filePath, mtime);
|
||||
_logger.Debug("Date of file [{0}] changed from '{1}' to '{2}'", filePath, oldLastWrite, mtime);
|
||||
_diskProvider.FileSetLastWriteTime(filePath, airDateUtc.AddMilliseconds(oldLastWrite.Millisecond));
|
||||
_logger.Debug("Date of file [{0}] changed from '{1}' to '{2}'", filePath, oldLastWrite, airDateUtc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.Parser
|
||||
new RegexReplace(@".*?[_. ](S\d{2}(?:E\d{2,4})*[_. ].*)", "$1", RegexOptions.Compiled | RegexOptions.IgnoreCase)
|
||||
};
|
||||
|
||||
private static readonly Regex LanguageRegex = new Regex(@"(?<english>\b(?:ing|eng)\b)|(?<italian>\b(?:ita|italian)\b)|(?<german>(?:swiss)?german\b|videomann|ger[. ]dub|\bger\b)|(?<flemish>flemish)|(?<greek>greek)|(?<french>(?:\W|_|\b)(?:FR|VF|VF2|VFF|VFI|VFQ|TRUEFRENCH|FRENCH|FRE|FRA)(?:\W|_|\b))|(?<russian>\b(?:rus|ru)\b)|(?<hungarian>\b(?:HUNDUB|HUN)\b)|(?<hebrew>\bHebDub\b)|(?<polish>\b(?:PL\W?DUB|DUB\W?PL|LEK\W?PL|PL\W?LEK)\b)|(?<chinese>\[(?:CH[ST]|BIG5|GB)\]|简|繁|字幕)|(?<bulgarian>\bbgaudio\b)|(?<spanish>\b(?:español|castellano|esp|spa(?!\(Latino\)))\b)|(?<ukrainian>\b(?:\dx?)?(?:ukr))|(?<thai>\b(?:THAI)\b)|(?<romanian>\b(?:RoDubbed|ROMANIAN)\b)|(?<catalan>[-,. ]cat[. ](?:DD|subs)|\b(?:catalan|catalán)\b)|(?<latvian>\b(?:lat|lav|lv)\b)|(?<turkish>\b(?:tur)\b)|(?<urdu>\burdu\b)|(?<romansh>\b(?:romansh|rumantsch|romansch)\b)|(?<japanese>\(JA\))|(?<original>\b(?:orig|original)\b)",
|
||||
private static readonly Regex LanguageRegex = new Regex(@"(?:\W|_)(?<english>\b(?:ing|eng)\b)|(?<italian>\b(?:ita|italian)\b)|(?<german>(?:swiss)?german\b|videomann|ger[. ]dub|\bger\b)|(?<flemish>flemish)|(?<greek>greek)|(?<french>(?:\W|_|\b)(?:FR|VF|VF2|VFF|VFI|VFQ|TRUEFRENCH|FRENCH|FRE|FRA)(?:\W|_|\b))|(?<russian>\b(?:rus|ru)\b)|(?<hungarian>\b(?:HUNDUB|HUN)\b)|(?<hebrew>\bHebDub\b)|(?<polish>\b(?:PL\W?DUB|DUB\W?PL|LEK\W?PL|PL\W?LEK)\b)|(?<chinese>\[(?:CH[ST]|BIG5|GB)\]|简|繁|字幕)|(?<bulgarian>\bbgaudio\b)|(?<spanish>\b(?:español|castellano|esp|spa(?!\(Latino\)))\b)|(?<ukrainian>\b(?:\dx?)?(?:ukr))|(?<thai>\b(?:THAI)\b)|(?<romanian>\b(?:RoDubbed|ROMANIAN)\b)|(?<catalan>[-,. ]cat[. ](?:DD|subs)|\b(?:catalan|catalán)\b)|(?<latvian>\b(?:lat|lav|lv)\b)|(?<turkish>\b(?:tur)\b)|(?<urdu>\burdu\b)|(?<romansh>\b(?:romansh|rumantsch|romansch)\b)|(?<japanese>\(JA\))|(?<original>\b(?:orig|original)\b)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex CaseSensitiveLanguageRegex = new Regex(@"(?:(?i)(?<!SUB[\W|_|^]))(?:(?<lithuanian>\bLT\b)|(?<czech>\bCZ\b)|(?<polish>\bPL\b)|(?<bulgarian>\bBG\b)|(?<slovak>\bSK\b)|(?<german>\bDE\b))(?:(?i)(?![\W|_|^]SUB))",
|
||||
|
||||
@@ -1062,24 +1062,6 @@
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"malIds": {
|
||||
"uniqueItems": true,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"aniListIds": {
|
||||
"uniqueItems": true,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"firstAired": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
|
||||
Reference in New Issue
Block a user