From 2a9537e7695a8045c3d788d8d6b7452913dd0e25 Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 11 Jan 2022 00:42:43 -0500 Subject: [PATCH] Add ability to fetch levels from a category --- .../Controllers/CollectionController.cs | 59 ++++++++++++--- ProjectLighthouse/Helpers/CollectionHelper.cs | 17 +++++ ProjectLighthouse/Logging/LoggerLevels.cs | 6 ++ .../Types/Categories/Category.cs | 2 + .../Types/Categories/CategoryWithUser.cs | 72 +++++++++++++++++++ .../Types/Categories/NewestLevelsCategory.cs | 5 ++ .../Types/Categories/QueueCategory.cs | 24 ++----- .../Types/Categories/TeamPicksCategory.cs | 5 ++ 8 files changed, 165 insertions(+), 25 deletions(-) create mode 100644 ProjectLighthouse/Helpers/CollectionHelper.cs create mode 100644 ProjectLighthouse/Types/Categories/CategoryWithUser.cs diff --git a/ProjectLighthouse/Controllers/CollectionController.cs b/ProjectLighthouse/Controllers/CollectionController.cs index 1578e4a1..6be7c155 100644 --- a/ProjectLighthouse/Controllers/CollectionController.cs +++ b/ProjectLighthouse/Controllers/CollectionController.cs @@ -2,9 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Kettu; +using LBPUnion.ProjectLighthouse.Helpers; +using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Serialization; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Categories; +using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; namespace LBPUnion.ProjectLighthouse.Controllers @@ -31,14 +35,19 @@ namespace LBPUnion.ProjectLighthouse.Controllers User? user = await this.database.UserFromGameRequest(this.Request); if (user == null) return this.StatusCode(403, ""); - List categories = new() - { - new TeamPicksCategory(), - new NewestLevelsCategory(), - new QueueCategory(user), - }; + string categoriesSerialized = CollectionHelper.Categories.Aggregate + ( + string.Empty, + (current, category) => + { + string serialized; - string categoriesSerialized = categories.Aggregate(string.Empty, (current, category) => current + category.Serialize(this.database)); + if (category is CategoryWithUser categoryWithUser) serialized = categoryWithUser.Serialize(this.database, user); + else serialized = category.Serialize(this.database); + + return current + serialized; + } + ); return this.Ok ( @@ -55,7 +64,41 @@ namespace LBPUnion.ProjectLighthouse.Controllers "hint_start", 1 }, { - "total", categories.Count + "total", CollectionHelper.Categories.Count + }, + } + ) + ); + } + + [HttpGet("searches/{endpointName}")] + public async Task GetCategorySlots(string endpointName, [FromQuery] int pageStart, [FromQuery] int pageSize) + { + User? user = await this.database.UserFromGameRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + + Category? category = CollectionHelper.Categories.FirstOrDefault(c => c.Endpoint == endpointName); + if (category == null) return this.NotFound(); + + Logger.Log("Found category " + category, LoggerLevelCategory.Instance); + + List slots = category.GetSlots(this.database, pageStart, pageSize).ToList(); + + string slotsSerialized = slots.Aggregate(string.Empty, (current, slot) => current + slot.Serialize()); + + return this.Ok + ( + LbpSerializer.TaggedStringElement + ( + "results", + slotsSerialized, + new Dictionary + { + { + "total", category.GetTotalSlots(this.database) + }, + { + "hint_start", pageStart + pageSize }, } ) diff --git a/ProjectLighthouse/Helpers/CollectionHelper.cs b/ProjectLighthouse/Helpers/CollectionHelper.cs new file mode 100644 index 00000000..4e1c7985 --- /dev/null +++ b/ProjectLighthouse/Helpers/CollectionHelper.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using LBPUnion.ProjectLighthouse.Types.Categories; + +namespace LBPUnion.ProjectLighthouse.Helpers +{ + public static class CollectionHelper + { + public static readonly List Categories = new(); + + static CollectionHelper() + { + Categories.Add(new TeamPicksCategory()); + Categories.Add(new NewestLevelsCategory()); + Categories.Add(new QueueCategory()); + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Logging/LoggerLevels.cs b/ProjectLighthouse/Logging/LoggerLevels.cs index 9d81a53b..c8b2e458 100644 --- a/ProjectLighthouse/Logging/LoggerLevels.cs +++ b/ProjectLighthouse/Logging/LoggerLevels.cs @@ -72,4 +72,10 @@ namespace LBPUnion.ProjectLighthouse.Logging } public override string Name => "AspNet"; } + + public class LoggerLevelCategory : LoggerLevel + { + public static readonly LoggerLevelCategory Instance = new(); + public override string Name => "Category"; + } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/Categories/Category.cs b/ProjectLighthouse/Types/Categories/Category.cs index 10e4ef72..b5bebf07 100644 --- a/ProjectLighthouse/Types/Categories/Category.cs +++ b/ProjectLighthouse/Types/Categories/Category.cs @@ -30,6 +30,8 @@ namespace LBPUnion.ProjectLighthouse.Types.Categories public abstract Slot? GetPreviewSlot(Database database); + public abstract IEnumerable GetSlots(Database database, int pageStart, int pageSize); + public abstract int GetTotalSlots(Database database); public string Serialize(Database database) diff --git a/ProjectLighthouse/Types/Categories/CategoryWithUser.cs b/ProjectLighthouse/Types/Categories/CategoryWithUser.cs new file mode 100644 index 00000000..76fea879 --- /dev/null +++ b/ProjectLighthouse/Types/Categories/CategoryWithUser.cs @@ -0,0 +1,72 @@ +#nullable enable +using System.Collections.Generic; +using System.Diagnostics; +using Kettu; +using LBPUnion.ProjectLighthouse.Logging; +using LBPUnion.ProjectLighthouse.Serialization; +using LBPUnion.ProjectLighthouse.Types.Levels; + +namespace LBPUnion.ProjectLighthouse.Types.Categories; + +public abstract class CategoryWithUser : Category +{ + public abstract Slot? GetPreviewSlot(Database database, User user); + public override Slot? GetPreviewSlot(Database database) + { + #if DEBUG + Logger.Log("tried to get preview slot without user on CategoryWithUser", LoggerLevelCategory.Instance); + if (Debugger.IsAttached) Debugger.Break(); + #endif + return null; + } + + public abstract int GetTotalSlots(Database database, User user); + public override int GetTotalSlots(Database database) + { + #if DEBUG + Logger.Log("tried to get total slots without user on CategoryWithUser", LoggerLevelCategory.Instance); + if (Debugger.IsAttached) Debugger.Break(); + #endif + return -1; + } + + public new string Serialize(Database database) + { + Logger.Log("tried to serialize without user on CategoryWithUser", LoggerLevelCategory.Instance); + return string.Empty; + } + + public string Serialize(Database database, User user) + { + Slot? previewSlot = this.GetPreviewSlot(database, user); + + string previewResults = ""; + if (previewSlot != null) + { + previewResults = LbpSerializer.TaggedStringElement + ( + "results", + previewSlot.Serialize(), + new Dictionary + { + { + "total", this.GetTotalSlots(database, user) + }, + { + "hint_start", "2" + }, + } + ); + } + + return LbpSerializer.StringElement + ( + "category", + LbpSerializer.StringElement("name", this.Name) + + LbpSerializer.StringElement("description", this.Description) + + LbpSerializer.StringElement("url", this.IngameEndpoint) + + (previewSlot == null ? "" : previewResults) + + LbpSerializer.StringElement("icon", IconHash) + ); + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Categories/NewestLevelsCategory.cs b/ProjectLighthouse/Types/Categories/NewestLevelsCategory.cs index efd76b90..fffd85a1 100644 --- a/ProjectLighthouse/Types/Categories/NewestLevelsCategory.cs +++ b/ProjectLighthouse/Types/Categories/NewestLevelsCategory.cs @@ -1,4 +1,6 @@ #nullable enable +using System; +using System.Collections.Generic; using System.Linq; using LBPUnion.ProjectLighthouse.Types.Levels; @@ -11,6 +13,9 @@ namespace LBPUnion.ProjectLighthouse.Types.Categories public override string IconHash { get; set; } = "g820623"; public override string Endpoint { get; set; } = "newest"; public override Slot? GetPreviewSlot(Database database) => database.Slots.OrderByDescending(s => s.FirstUploaded).FirstOrDefault(); + public override IEnumerable GetSlots + (Database database, int pageStart, int pageSize) + => database.Slots.OrderByDescending(s => s.FirstUploaded).Skip(pageStart).Take(Math.Min(pageSize, 20)); public override int GetTotalSlots(Database database) => database.Slots.Count(); } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/Categories/QueueCategory.cs b/ProjectLighthouse/Types/Categories/QueueCategory.cs index 63de388a..c8c24c30 100644 --- a/ProjectLighthouse/Types/Categories/QueueCategory.cs +++ b/ProjectLighthouse/Types/Categories/QueueCategory.cs @@ -1,33 +1,23 @@ #nullable enable +using System.Collections.Generic; using System.Linq; using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.EntityFrameworkCore; namespace LBPUnion.ProjectLighthouse.Types.Categories { - public class QueueCategory : Category + public class QueueCategory : CategoryWithUser { - private User user; - - public QueueCategory(User user) - { - this.user = user; - } - public override string Name { get; set; } = "My Queue"; public override string Description { get; set; } = "Your queued levels"; public override string IconHash { get; set; } = "g820614"; - public override string Endpoint { - get => $"queue/{this.user.UserId}"; - set { - // cry about it, i don't care - } - } + public override string Endpoint { get; set; } = "queue"; + public override IEnumerable GetSlots(Database database, int pageStart, int pageSize) => new List(); - public override Slot? GetPreviewSlot(Database database) - => database.QueuedLevels.Include(q => q.Slot).FirstOrDefault(q => q.UserId == this.user.UserId)?.Slot; + public override Slot? GetPreviewSlot(Database database, User user) + => database.QueuedLevels.Include(q => q.Slot).FirstOrDefault(q => q.UserId == user.UserId)?.Slot; - public override int GetTotalSlots(Database database) => database.QueuedLevels.Count(q => q.UserId == this.user.UserId); + public override int GetTotalSlots(Database database, User user) => database.QueuedLevels.Count(q => q.UserId == user.UserId); } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/Categories/TeamPicksCategory.cs b/ProjectLighthouse/Types/Categories/TeamPicksCategory.cs index 44bd36af..5bb6f4af 100644 --- a/ProjectLighthouse/Types/Categories/TeamPicksCategory.cs +++ b/ProjectLighthouse/Types/Categories/TeamPicksCategory.cs @@ -1,4 +1,6 @@ #nullable enable +using System; +using System.Collections.Generic; using System.Linq; using LBPUnion.ProjectLighthouse.Types.Levels; @@ -11,6 +13,9 @@ namespace LBPUnion.ProjectLighthouse.Types.Categories public override string IconHash { get; set; } = "g820626"; public override string Endpoint { get; set; } = "team_picks"; public override Slot? GetPreviewSlot(Database database) => database.Slots.OrderByDescending(s => s.FirstUploaded).FirstOrDefault(s => s.TeamPick); + public override IEnumerable GetSlots + (Database database, int pageStart, int pageSize) + => database.Slots.OrderByDescending(s => s.FirstUploaded).Where(s => s.TeamPick).Skip(pageStart).Take(Math.Min(pageSize, 20)); public override int GetTotalSlots(Database database) => database.Slots.Count(s => s.TeamPick); } } \ No newline at end of file