diff --git a/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs b/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs index feb487fd5..3c8953665 100644 --- a/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs +++ b/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs @@ -5,13 +5,16 @@ using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; using Ombi.Core.Models; +using Ombi.Helpers; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Security.Principal; +using System.Threading; using System.Threading.Tasks; namespace Ombi.Core.Tests.Engine @@ -26,6 +29,7 @@ namespace Ombi.Core.Tests.Engine [SetUp] public void SetUp() { + Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); _mocker = new AutoMocker(); var principleMock = new Mock(); var identityMock = new Mock(); @@ -246,6 +250,7 @@ namespace Ombi.Core.Tests.Engine MovieRequestLimitType = RequestLimitType.Day, Id = "id1" }; + var today = DateTime.Now; var log = new List { @@ -265,7 +270,7 @@ namespace Ombi.Core.Tests.Engine .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) .And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2) .And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(1) - .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.AddDays(1).AddHours(-1)) + .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.AddDays(1).Date) ); } @@ -304,7 +309,7 @@ namespace Ombi.Core.Tests.Engine .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) .And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2) .And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(0) - .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.AddDays(1).AddHours(-2)) + .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.AddDays(1).Date) ); } @@ -318,7 +323,7 @@ namespace Ombi.Core.Tests.Engine MovieRequestLimitType = RequestLimitType.Week, Id = "id1" }; - var lastWeek = DateTime.Now.AddDays(-8); + var lastWeek = DateTime.Now.FirstDateInWeek().AddDays(-1); // Day before reset var log = new List { new RequestLog @@ -350,7 +355,7 @@ namespace Ombi.Core.Tests.Engine MovieRequestLimitType = RequestLimitType.Week, Id = "id1" }; - var today = DateTime.Now; + var today = DateTime.UtcNow; var log = new List { new RequestLog @@ -369,7 +374,7 @@ namespace Ombi.Core.Tests.Engine .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) .And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2) .And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(1) - .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.AddDays(7)) + .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.FirstDateInWeek().AddDays(7).Date) ); } @@ -408,7 +413,7 @@ namespace Ombi.Core.Tests.Engine .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) .And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2) .And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(0) - .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.AddDays(6)) + .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.FirstDateInWeek().AddDays(7).Date) ); } [Test] @@ -454,6 +459,7 @@ namespace Ombi.Core.Tests.Engine Id = "id1" }; var today = DateTime.Now; + var firstDayOfMonth = new DateTime(today.Year, today.Month, 1); var log = new List { new RequestLog @@ -472,7 +478,7 @@ namespace Ombi.Core.Tests.Engine .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) .And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2) .And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(1) - .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.AddMonths(1)) + .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(firstDayOfMonth.AddMonths(1).Date) ); } @@ -487,6 +493,7 @@ namespace Ombi.Core.Tests.Engine Id = "id1" }; var today = DateTime.Now; + var firstDayOfMonth = new DateTime(today.Year, today.Month, 1); var log = new List { new RequestLog @@ -511,7 +518,7 @@ namespace Ombi.Core.Tests.Engine .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) .And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2) .And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(0) - .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(today.AddMonths(1).AddDays(-1)) + .And.Property(nameof(RequestQuotaCountModel.NextRequest)).EqualTo(firstDayOfMonth.AddMonths(1).Date) ); } } diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index 2593378a6..1601254a2 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -813,23 +813,26 @@ namespace Ombi.Core.Engine .OrderBy(x => x.RequestDate) .Select(x => x.RequestDate) .FirstOrDefaultAsync(); - nextRequest = oldestRequestedAt.AddDays(1); + nextRequest = oldestRequestedAt.AddDays(1).Date; break; case RequestLimitType.Week: - count = limit - await log.CountAsync(x => x.RequestDate >= DateTime.UtcNow.Date.AddDays(-7)); - oldestRequestedAt = await log.Where(x => x.RequestDate >= DateTime.UtcNow.Date.AddDays(-7)) + var fdow = DateTime.UtcNow.FirstDateInWeek(); + count = limit - await log.CountAsync(x => x.RequestDate >= fdow); + oldestRequestedAt = await log.Where(x => x.RequestDate >= fdow) .OrderBy(x => x.RequestDate) .Select(x => x.RequestDate) .FirstOrDefaultAsync(); - nextRequest = oldestRequestedAt.AddDays(7); + nextRequest = fdow.AddDays(7).Date; break; case RequestLimitType.Month: - count = limit - await log.CountAsync(x => x.RequestDate >= DateTime.UtcNow.Date.AddMonths(-1)); - oldestRequestedAt = await log.Where(x => x.RequestDate >= DateTime.UtcNow.Date.AddMonths(-1)) + var now = DateTime.UtcNow; + var firstDayOfMonth = new DateTime(now.Year, now.Month, 1); + count = limit - await log.CountAsync(x => x.RequestDate >= firstDayOfMonth); + oldestRequestedAt = await log.Where(x => x.RequestDate >= firstDayOfMonth) .OrderBy(x => x.RequestDate) .Select(x => x.RequestDate) .FirstOrDefaultAsync(); - nextRequest = oldestRequestedAt.AddMonths(1); + nextRequest = firstDayOfMonth.AddMonths(1).Date; break; default: break; diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index 2c37dc609..c5c49bf83 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -1071,8 +1071,6 @@ namespace Ombi.Core.Engine Remaining = count < 0 ? 0 : count, NextRequest = DateTime.SpecifyKind(nextRequest, DateTimeKind.Utc), }; - - return null; } public async Task UpdateAdvancedOptions(MediaAdvancedOptions options) diff --git a/src/Ombi.Helpers.Tests/DateTimeExtensionsTests.cs b/src/Ombi.Helpers.Tests/DateTimeExtensionsTests.cs new file mode 100644 index 000000000..b0455a7e8 --- /dev/null +++ b/src/Ombi.Helpers.Tests/DateTimeExtensionsTests.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using NUnit.Framework; +using NUnit.Framework.Internal; + +namespace Ombi.Helpers.Tests +{ + [TestFixture] + public class DateTimeExtensionsTests + { + [TestCaseSource(nameof(DayOfWeekData))] + public DateTime FirstDateInWeekTests(DateTime input, string culture) + { + Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(culture); + return input.FirstDateInWeek(); + } + + public static IEnumerable DayOfWeekData + { + get + { + yield return new TestCaseData(new DateTime(2021, 09, 20), "en-GB").Returns(new DateTime(2021, 09, 20)).SetName("en-GB Monday, FDOW is Monday"); + yield return new TestCaseData(new DateTime(2021, 09, 21), "en-GB").Returns(new DateTime(2021, 09, 20)).SetName("en-GB Tuesday, FDOW is Monday"); + yield return new TestCaseData(new DateTime(2021, 09, 22), "en-GB").Returns(new DateTime(2021, 09, 20)).SetName("en-GB Wednesday, FDOW is Monday"); + yield return new TestCaseData(new DateTime(2021, 09, 23), "en-GB").Returns(new DateTime(2021, 09, 20)).SetName("en-GB Thursday, FDOW is Monday"); + yield return new TestCaseData(new DateTime(2021, 09, 24), "en-GB").Returns(new DateTime(2021, 09, 20)).SetName("en-GB Friday, FDOW is Monday"); + yield return new TestCaseData(new DateTime(2021, 09, 25), "en-GB").Returns(new DateTime(2021, 09, 20)).SetName("en-GB Sat, FDOW is Monday"); + yield return new TestCaseData(new DateTime(2021, 09, 26), "en-GB").Returns(new DateTime(2021, 09, 20)).SetName("en-GB Sun, FDOW is Monday"); + yield return new TestCaseData(new DateTime(2021, 09, 20), "en-US").Returns(new DateTime(2021, 09, 19)).SetName("en-US Monday, FDOW is Sunday"); + yield return new TestCaseData(new DateTime(2021, 09, 21), "en-US").Returns(new DateTime(2021, 09, 19)).SetName("en-US Tuesday, FDOW is Sunday"); + yield return new TestCaseData(new DateTime(2021, 09, 22), "en-US").Returns(new DateTime(2021, 09, 19)).SetName("en-US Wednesday, FDOW is Sunday"); + yield return new TestCaseData(new DateTime(2021, 09, 23), "en-US").Returns(new DateTime(2021, 09, 19)).SetName("en-US Thursday, FDOW is Sunday"); + yield return new TestCaseData(new DateTime(2021, 09, 24), "en-US").Returns(new DateTime(2021, 09, 19)).SetName("en-US Friday, FDOW is Sunday"); + yield return new TestCaseData(new DateTime(2021, 09, 25), "en-US").Returns(new DateTime(2021, 09, 19)).SetName("en-US Sat, FDOW is Sunday"); + yield return new TestCaseData(new DateTime(2021, 09, 26), "en-US").Returns(new DateTime(2021, 09, 26)).SetName("en-US Sun, FDOW is Sunday"); + } + } + } +} diff --git a/src/Ombi.Helpers/DateTimeExtensions.cs b/src/Ombi.Helpers/DateTimeExtensions.cs new file mode 100644 index 000000000..d33126934 --- /dev/null +++ b/src/Ombi.Helpers/DateTimeExtensions.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading; + +namespace Ombi.Helpers +{ + public static class DateTimeExtensions + { + public static DateTime FirstDateInWeek(this DateTime dt) + { + while (dt.DayOfWeek != Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek) + { + dt = dt.AddDays(-1); + } + + return dt; + } + } +} diff --git a/src/Ombi.Helpers/MediaCacheService.cs b/src/Ombi.Helpers/MediaCacheService.cs index c514c8e25..d99090b62 100644 --- a/src/Ombi.Helpers/MediaCacheService.cs +++ b/src/Ombi.Helpers/MediaCacheService.cs @@ -32,7 +32,7 @@ namespace Ombi.Helpers } // Not in the cache, so add this Key into our MediaServiceCache - await UpdateLocalCache(cacheKey); + UpdateLocalCache(cacheKey); return await _memoryCache.GetOrCreateAsync(cacheKey, entry => { @@ -41,7 +41,7 @@ namespace Ombi.Helpers }); } - private async Task UpdateLocalCache(string cacheKey) + private void UpdateLocalCache(string cacheKey) { var mediaServiceCache = _memoryCache.Get>(CacheKey); if (mediaServiceCache == null) diff --git a/src/Ombi/.vscode/settings.json b/src/Ombi/.vscode/settings.json index 676b52dae..2d597fd8d 100644 --- a/src/Ombi/.vscode/settings.json +++ b/src/Ombi/.vscode/settings.json @@ -12,6 +12,7 @@ ], "discord.enabled": true, "conventionalCommits.scopes": [ - "discover" + "discover", + "request-limits" ] }