Merge branch 'main' into web-tests

This commit is contained in:
jvyden 2021-12-24 14:22:18 -05:00 committed by GitHub
commit d96c544d71
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 151 additions and 16 deletions

View file

@ -53,6 +53,11 @@ namespace LBPUnion.ProjectLighthouse.Controllers
photo.CreatorId = user.UserId;
photo.Creator = user;
if (photo.Subjects.Count > 4)
{
return this.BadRequest();
}
foreach (PhotoSubject subject in photo.Subjects)
{
subject.User = await this.database.Users.FirstOrDefaultAsync(u => u.Username == subject.Username);
@ -67,6 +72,17 @@ namespace LBPUnion.ProjectLighthouse.Controllers
await this.database.SaveChangesAsync();
// Check for duplicate photo subjects
List<int> subjectUserIds = new(4);
foreach (PhotoSubject subject in photo.Subjects)
{
if (subjectUserIds.Contains(subject.UserId))
{
return this.BadRequest();
}
subjectUserIds.Add(subject.UserId);
}
photo.PhotoSubjectIds = photo.Subjects.Select(subject => subject.PhotoSubjectId.ToString()).ToArray();
// photo.Slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == photo.SlotId);

View file

@ -0,0 +1,15 @@
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;
using Microsoft.Net.Http.Headers;
namespace LBPUnion.ProjectLighthouse.Helpers.Extensions
{
// yoinked and adapted from https://stackoverflow.com/a/68641796
public static class RequestExtensions
{
private static readonly Regex mobileCheck = new
("Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled);
public static bool IsMobile(this HttpRequest request) => mobileCheck.IsMatch(request.Headers[HeaderNames.UserAgent].ToString());
}
}

View file

@ -5,5 +5,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers
public static class TimestampHelper
{
public static long Timestamp => (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
public static long TimestampMillis => (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
}
}

View file

@ -13,7 +13,7 @@ namespace LBPUnion.ProjectLighthouse.Maintenance.MaintenanceJobs
{
private readonly Database database = new();
public string Name() => "Cleanup Broken Photos";
public string Description() => "Deletes all photos that have missing assets.";
public string Description() => "Deletes all photos that have missing assets or invalid photo subjects.";
[SuppressMessage("ReSharper", "LoopCanBePartlyConvertedToQuery")]
public async Task Run()
@ -23,6 +23,8 @@ namespace LBPUnion.ProjectLighthouse.Maintenance.MaintenanceJobs
bool hashNullOrEmpty = false;
bool noHashesExist = false;
bool largeHashIsInvalidFile = false;
bool tooManyPhotoSubjects = false;
bool duplicatePhotoSubjects = false;
hashNullOrEmpty = string.IsNullOrEmpty
(photo.LargeHash) ||
@ -50,6 +52,23 @@ namespace LBPUnion.ProjectLighthouse.Maintenance.MaintenanceJobs
goto removePhoto;
}
if (photo.Subjects.Count > 4)
{
tooManyPhotoSubjects = true;
goto removePhoto;
}
List<int> subjectUserIds = new(4);
foreach (PhotoSubject subject in photo.Subjects)
{
if (subjectUserIds.Contains(subject.UserId))
{
duplicatePhotoSubjects = true;
goto removePhoto;
}
subjectUserIds.Add(subject.UserId);
}
continue;
removePhoto:
@ -59,7 +78,9 @@ namespace LBPUnion.ProjectLighthouse.Maintenance.MaintenanceJobs
$"Removing photo (id: {photo.PhotoId}): " +
$"{nameof(hashNullOrEmpty)}: {hashNullOrEmpty}, " +
$"{nameof(noHashesExist)}: {noHashesExist}, " +
$"{nameof(largeHashIsInvalidFile)}: {largeHashIsInvalidFile}"
$"{nameof(largeHashIsInvalidFile)}: {largeHashIsInvalidFile}, " +
$"{nameof(tooManyPhotoSubjects)}: {tooManyPhotoSubjects}" +
$"{nameof(duplicatePhotoSubjects)}: {duplicatePhotoSubjects}"
);
this.database.Photos.Remove(photo);

View file

@ -1,4 +1,5 @@
@using LBPUnion.ProjectLighthouse.Helpers
@using LBPUnion.ProjectLighthouse.Helpers.Extensions
@using LBPUnion.ProjectLighthouse.Types
@using LBPUnion.ProjectLighthouse.Types.Settings
@model LBPUnion.ProjectLighthouse.Pages.Layouts.BaseLayout
@ -26,6 +27,9 @@
}
Model.NavigationItemsRight.Add(new PageNavigationItem("Log out", "/logout", "user alternate slash")); // should always be last
}
Model.IsMobile = Model.Request.IsMobile();
long timeStarted = TimestampHelper.TimestampMillis;
}
<!DOCTYPE html>
@ -48,10 +52,20 @@
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#008cff">
<meta name="msapplication-TileColor" content="#008cff">
@* Embed Stuff *@
<meta name="theme-color" data-react-helmet="true" content="#008cff">
<meta content="Project Lighthouse - @Model.Title" property="og:title">
@if (!string.IsNullOrEmpty(Model.Description))
{
<meta content="@Model.Description" property="og:description">
}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@* Google Analytics *@
@if (ServerSettings.Instance.GoogleAnalyticsEnabled)
{
<!-- Global site tag (gtag.js) - Google Analytics -->
@ -81,14 +95,21 @@
<header class="lighthouse-header">
<div class="ui attached menu">
<div class="ui container">
@{
string mobileIconStyle = Model.IsMobile ? "margin-right: 0;" : "";
}
@foreach (PageNavigationItem navigationItem in Model!.NavigationItems)
{
<a class="item" href="@navigationItem.Url">
@if (navigationItem.Icon != null)
{
<i class="@navigationItem.Icon icon"></i>
<i class="@navigationItem.Icon icon" style="@mobileIconStyle"></i>
}
@if (!Model.IsMobile)
{
@navigationItem.Name
}
@navigationItem.Name
</a>
}
<div class="right menu">
@ -97,9 +118,13 @@
<a class="item" href="@navigationItem.Url">
@if (navigationItem.Icon != null)
{
<i class="@navigationItem.Icon icon"></i>
<i class="@navigationItem.Icon icon" style="@mobileIconStyle"></i>
}
@if (!Model.IsMobile)
{
@navigationItem.Name
}
@navigationItem.Name
</a>
}
</div>
@ -143,6 +168,46 @@
}
</div>
</div>
@if (ServerStatics.IsDebug)
{
<div class="ui red attached inverted segment">
<div class="ui container">
<button type="button" class="ui inverted button collapsible">
<b>Show/Hide Debug Info</b>
</button>
<div style="display:none" id="lighthouse-debug-info">
<br>
<p>Model.IsMobile: @Model.IsMobile</p>
<p>Model.Title: @Model.Title</p>
<p>Model.Description: @Model.Description</p>
<p>Model.User.UserId: @(Model.User?.UserId.ToString() ?? "(not logged in)")</p>
<p>Render time: ~@(TimestampHelper.TimestampMillis - timeStarted)ms</p>
</div>
</div>
</div>
<script>
const collapsible = document.getElementsByClassName("collapsible");
for (let i = 0; i < collapsible.length; i++)
{
collapsible[i].addEventListener("click", function()
{
this.classList.toggle("active");
const content = this.nextElementSibling;
if (content.style.display === "block")
{
content.style.display = "none";
}
else
{
content.style.display = "block";
}
});
}
</script>
}
</footer>
</div>
</body>

View file

@ -7,6 +7,13 @@ namespace LBPUnion.ProjectLighthouse.Pages.Layouts
{
public class BaseLayout : PageModel
{
public BaseLayout(Database database)
{
this.Database = database;
}
public bool IsMobile;
public readonly Database Database;
public readonly List<PageNavigationItem> NavigationItems = new()
@ -21,14 +28,10 @@ namespace LBPUnion.ProjectLighthouse.Pages.Layouts
public bool ShowTitleInPage = true;
public string Title = string.Empty;
public string Description = string.Empty;
private User? user;
public BaseLayout(Database database)
{
this.Database = database;
}
public new User? User {
get {
if (this.user != null) return this.user;

View file

@ -3,8 +3,10 @@
@{
Layout = "Layouts/BaseLayout";
Model.Title = Model.Slot.Name;
Model.ShowTitleInPage = false;
Model.Title = Model.Slot.Name;
Model.Description = Model.Slot.Description;
}
@await Html.PartialAsync("Partials/SlotCardPartial", Model.Slot, new ViewDataDictionary(ViewData)

View file

@ -8,8 +8,10 @@
@{
Layout = "Layouts/BaseLayout";
Model.Title = Model.ProfileUser!.Username + "'s user page";
Model.ShowTitleInPage = false;
Model.Title = Model.ProfileUser!.Username + "'s user page";
Model.Description = Model.ProfileUser!.Biography;
}
<div class="ui grid">

View file

@ -16,3 +16,6 @@ div.statsUnderTitle > span {
margin-right: 5px;
}
#lighthouse-debug-info > p {
margin-bottom: 1px;
}

View file

@ -27,5 +27,11 @@ namespace LBPUnion.ProjectLighthouse.Types.Settings
}
public static bool IsUnitTesting => AppDomain.CurrentDomain.GetAssemblies().Any(assembly => assembly.FullName.StartsWith("xunit"));
#if DEBUG
public static readonly bool IsDebug = true;
#else
public static readonly bool IsDebug = false;
#endif
}
}