mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-14 01:02:57 -07:00
feat(request-limits): ✨ Request limits are no longer a rolling date. But reset at the start of the week or month depending on the preference
This commit is contained in:
parent
847873c307
commit
364b9f11af
7 changed files with 87 additions and 20 deletions
|
@ -5,13 +5,16 @@ using NUnit.Framework;
|
||||||
using Ombi.Core.Authentication;
|
using Ombi.Core.Authentication;
|
||||||
using Ombi.Core.Engine;
|
using Ombi.Core.Engine;
|
||||||
using Ombi.Core.Models;
|
using Ombi.Core.Models;
|
||||||
|
using Ombi.Helpers;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Entities.Requests;
|
using Ombi.Store.Entities.Requests;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ombi.Core.Tests.Engine
|
namespace Ombi.Core.Tests.Engine
|
||||||
|
@ -26,6 +29,7 @@ namespace Ombi.Core.Tests.Engine
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp()
|
||||||
{
|
{
|
||||||
|
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
|
||||||
_mocker = new AutoMocker();
|
_mocker = new AutoMocker();
|
||||||
var principleMock = new Mock<IPrincipal>();
|
var principleMock = new Mock<IPrincipal>();
|
||||||
var identityMock = new Mock<IIdentity>();
|
var identityMock = new Mock<IIdentity>();
|
||||||
|
@ -246,6 +250,7 @@ namespace Ombi.Core.Tests.Engine
|
||||||
MovieRequestLimitType = RequestLimitType.Day,
|
MovieRequestLimitType = RequestLimitType.Day,
|
||||||
Id = "id1"
|
Id = "id1"
|
||||||
};
|
};
|
||||||
|
|
||||||
var today = DateTime.Now;
|
var today = DateTime.Now;
|
||||||
var log = new List<RequestLog>
|
var log = new List<RequestLog>
|
||||||
{
|
{
|
||||||
|
@ -265,7 +270,7 @@ namespace Ombi.Core.Tests.Engine
|
||||||
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(1)
|
.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)
|
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(0)
|
.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,
|
MovieRequestLimitType = RequestLimitType.Week,
|
||||||
Id = "id1"
|
Id = "id1"
|
||||||
};
|
};
|
||||||
var lastWeek = DateTime.Now.AddDays(-8);
|
var lastWeek = DateTime.Now.FirstDateInWeek().AddDays(-1); // Day before reset
|
||||||
var log = new List<RequestLog>
|
var log = new List<RequestLog>
|
||||||
{
|
{
|
||||||
new RequestLog
|
new RequestLog
|
||||||
|
@ -350,7 +355,7 @@ namespace Ombi.Core.Tests.Engine
|
||||||
MovieRequestLimitType = RequestLimitType.Week,
|
MovieRequestLimitType = RequestLimitType.Week,
|
||||||
Id = "id1"
|
Id = "id1"
|
||||||
};
|
};
|
||||||
var today = DateTime.Now;
|
var today = DateTime.UtcNow;
|
||||||
var log = new List<RequestLog>
|
var log = new List<RequestLog>
|
||||||
{
|
{
|
||||||
new RequestLog
|
new RequestLog
|
||||||
|
@ -369,7 +374,7 @@ namespace Ombi.Core.Tests.Engine
|
||||||
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(1)
|
.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)
|
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(0)
|
.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]
|
[Test]
|
||||||
|
@ -454,6 +459,7 @@ namespace Ombi.Core.Tests.Engine
|
||||||
Id = "id1"
|
Id = "id1"
|
||||||
};
|
};
|
||||||
var today = DateTime.Now;
|
var today = DateTime.Now;
|
||||||
|
var firstDayOfMonth = new DateTime(today.Year, today.Month, 1);
|
||||||
var log = new List<RequestLog>
|
var log = new List<RequestLog>
|
||||||
{
|
{
|
||||||
new RequestLog
|
new RequestLog
|
||||||
|
@ -472,7 +478,7 @@ namespace Ombi.Core.Tests.Engine
|
||||||
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(1)
|
.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"
|
Id = "id1"
|
||||||
};
|
};
|
||||||
var today = DateTime.Now;
|
var today = DateTime.Now;
|
||||||
|
var firstDayOfMonth = new DateTime(today.Year, today.Month, 1);
|
||||||
var log = new List<RequestLog>
|
var log = new List<RequestLog>
|
||||||
{
|
{
|
||||||
new RequestLog
|
new RequestLog
|
||||||
|
@ -511,7 +518,7 @@ namespace Ombi.Core.Tests.Engine
|
||||||
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
.And.Property(nameof(RequestQuotaCountModel.Limit)).EqualTo(2)
|
||||||
.And.Property(nameof(RequestQuotaCountModel.Remaining)).EqualTo(0)
|
.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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -813,23 +813,26 @@ namespace Ombi.Core.Engine
|
||||||
.OrderBy(x => x.RequestDate)
|
.OrderBy(x => x.RequestDate)
|
||||||
.Select(x => x.RequestDate)
|
.Select(x => x.RequestDate)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
nextRequest = oldestRequestedAt.AddDays(1);
|
nextRequest = oldestRequestedAt.AddDays(1).Date;
|
||||||
break;
|
break;
|
||||||
case RequestLimitType.Week:
|
case RequestLimitType.Week:
|
||||||
count = limit - await log.CountAsync(x => x.RequestDate >= DateTime.UtcNow.Date.AddDays(-7));
|
var fdow = DateTime.UtcNow.FirstDateInWeek();
|
||||||
oldestRequestedAt = await log.Where(x => x.RequestDate >= DateTime.UtcNow.Date.AddDays(-7))
|
count = limit - await log.CountAsync(x => x.RequestDate >= fdow);
|
||||||
|
oldestRequestedAt = await log.Where(x => x.RequestDate >= fdow)
|
||||||
.OrderBy(x => x.RequestDate)
|
.OrderBy(x => x.RequestDate)
|
||||||
.Select(x => x.RequestDate)
|
.Select(x => x.RequestDate)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
nextRequest = oldestRequestedAt.AddDays(7);
|
nextRequest = fdow.AddDays(7).Date;
|
||||||
break;
|
break;
|
||||||
case RequestLimitType.Month:
|
case RequestLimitType.Month:
|
||||||
count = limit - await log.CountAsync(x => x.RequestDate >= DateTime.UtcNow.Date.AddMonths(-1));
|
var now = DateTime.UtcNow;
|
||||||
oldestRequestedAt = await log.Where(x => x.RequestDate >= DateTime.UtcNow.Date.AddMonths(-1))
|
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)
|
.OrderBy(x => x.RequestDate)
|
||||||
.Select(x => x.RequestDate)
|
.Select(x => x.RequestDate)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
nextRequest = oldestRequestedAt.AddMonths(1);
|
nextRequest = firstDayOfMonth.AddMonths(1).Date;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1071,8 +1071,6 @@ namespace Ombi.Core.Engine
|
||||||
Remaining = count < 0 ? 0 : count,
|
Remaining = count < 0 ? 0 : count,
|
||||||
NextRequest = DateTime.SpecifyKind(nextRequest, DateTimeKind.Utc),
|
NextRequest = DateTime.SpecifyKind(nextRequest, DateTimeKind.Utc),
|
||||||
};
|
};
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestEngineResult> UpdateAdvancedOptions(MediaAdvancedOptions options)
|
public async Task<RequestEngineResult> UpdateAdvancedOptions(MediaAdvancedOptions options)
|
||||||
|
|
40
src/Ombi.Helpers.Tests/DateTimeExtensionsTests.cs
Normal file
40
src/Ombi.Helpers.Tests/DateTimeExtensionsTests.cs
Normal file
|
@ -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
src/Ombi.Helpers/DateTimeExtensions.cs
Normal file
18
src/Ombi.Helpers/DateTimeExtensions.cs
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,7 @@ namespace Ombi.Helpers
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not in the cache, so add this Key into our MediaServiceCache
|
// Not in the cache, so add this Key into our MediaServiceCache
|
||||||
await UpdateLocalCache(cacheKey);
|
UpdateLocalCache(cacheKey);
|
||||||
|
|
||||||
return await _memoryCache.GetOrCreateAsync<T>(cacheKey, entry =>
|
return await _memoryCache.GetOrCreateAsync<T>(cacheKey, entry =>
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@ namespace Ombi.Helpers
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateLocalCache(string cacheKey)
|
private void UpdateLocalCache(string cacheKey)
|
||||||
{
|
{
|
||||||
var mediaServiceCache = _memoryCache.Get<List<string>>(CacheKey);
|
var mediaServiceCache = _memoryCache.Get<List<string>>(CacheKey);
|
||||||
if (mediaServiceCache == null)
|
if (mediaServiceCache == null)
|
||||||
|
|
3
src/Ombi/.vscode/settings.json
vendored
3
src/Ombi/.vscode/settings.json
vendored
|
@ -12,6 +12,7 @@
|
||||||
],
|
],
|
||||||
"discord.enabled": true,
|
"discord.enabled": true,
|
||||||
"conventionalCommits.scopes": [
|
"conventionalCommits.scopes": [
|
||||||
"discover"
|
"discover",
|
||||||
|
"request-limits"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue