Skip to content

Commit

Permalink
feat(request-limits): ✨ Request limits are no longer a rolling date. …
Browse files Browse the repository at this point in the history
…But reset at the start of the week or month depending on the preference
  • Loading branch information
tidusjar committed Sep 22, 2021
1 parent 847873c commit 364b9f1
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 20 deletions.
23 changes: 15 additions & 8 deletions src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
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
Expand All @@ -26,6 +29,7 @@ public class MovieRequestLimitsTests
[SetUp]
public void SetUp()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
_mocker = new AutoMocker();
var principleMock = new Mock<IPrincipal>();
var identityMock = new Mock<IIdentity>();
Expand Down Expand Up @@ -246,6 +250,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Daily_OneRequestsToday()
MovieRequestLimitType = RequestLimitType.Day,
Id = "id1"
};

var today = DateTime.Now;
var log = new List<RequestLog>
{
Expand All @@ -265,7 +270,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Daily_OneRequestsToday()
.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)
);
}

Expand Down Expand Up @@ -304,7 +309,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Daily_AllRequestsToday()
.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)
);
}

Expand All @@ -318,7 +323,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Weekly_NoRequests()
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<RequestLog>
{
new RequestLog
Expand Down Expand Up @@ -350,7 +355,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Weekly_OneRequestsWeek()
MovieRequestLimitType = RequestLimitType.Week,
Id = "id1"
};
var today = DateTime.Now;
var today = DateTime.UtcNow;
var log = new List<RequestLog>
{
new RequestLog
Expand All @@ -369,7 +374,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Weekly_OneRequestsWeek()
.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)
);
}

Expand Down Expand Up @@ -408,7 +413,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Weekly_AllRequestsWeek()
.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]
Expand Down Expand Up @@ -454,6 +459,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Monthly_OneRequests()
Id = "id1"
};
var today = DateTime.Now;
var firstDayOfMonth = new DateTime(today.Year, today.Month, 1);
var log = new List<RequestLog>
{
new RequestLog
Expand All @@ -472,7 +478,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Monthly_OneRequests()
.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)
);
}

Expand All @@ -487,6 +493,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Monthly_AllRequests()
Id = "id1"
};
var today = DateTime.Now;
var firstDayOfMonth = new DateTime(today.Year, today.Month, 1);
var log = new List<RequestLog>
{
new RequestLog
Expand All @@ -511,7 +518,7 @@ public async Task UserPassedIn_MovieLimit_Set_Limit_Monthly_AllRequests()
.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)
);
}
}
Expand Down
17 changes: 10 additions & 7 deletions src/Ombi.Core/Engine/MovieRequestEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -813,23 +813,26 @@ public async Task<RequestQuotaCountModel> GetRemainingRequests(OmbiUser user)
.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;
Expand Down
2 changes: 0 additions & 2 deletions src/Ombi.Core/Engine/TvRequestEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1071,8 +1071,6 @@ public async Task<RequestQuotaCountModel> GetRemainingRequests(OmbiUser user)
Remaining = count < 0 ? 0 : count,
NextRequest = DateTime.SpecifyKind(nextRequest, DateTimeKind.Utc),
};

return null;
}

public async Task<RequestEngineResult> UpdateAdvancedOptions(MediaAdvancedOptions options)
Expand Down
40 changes: 40 additions & 0 deletions src/Ombi.Helpers.Tests/DateTimeExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -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<TestCaseData> 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");
}
}
}
}
18 changes: 18 additions & 0 deletions src/Ombi.Helpers/DateTimeExtensions.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
4 changes: 2 additions & 2 deletions src/Ombi.Helpers/MediaCacheService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async override Task<T> GetOrAddAsync<T>(string cacheKey, System.Func<Task
}

// Not in the cache, so add this Key into our MediaServiceCache
await UpdateLocalCache(cacheKey);
UpdateLocalCache(cacheKey);

return await _memoryCache.GetOrCreateAsync<T>(cacheKey, entry =>
{
Expand All @@ -41,7 +41,7 @@ public async override Task<T> GetOrAddAsync<T>(string cacheKey, System.Func<Task
});
}

private async Task UpdateLocalCache(string cacheKey)
private void UpdateLocalCache(string cacheKey)
{
var mediaServiceCache = _memoryCache.Get<List<string>>(CacheKey);
if (mediaServiceCache == null)
Expand Down
3 changes: 2 additions & 1 deletion src/Ombi/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
],
"discord.enabled": true,
"conventionalCommits.scopes": [
"discover"
"discover",
"request-limits"
]
}

0 comments on commit 364b9f1

Please sign in to comment.