Allow tokens to be ignored, add example random generation, tweak return for sources
@@ -1,6 +1,7 @@
|
||||
using System.Net;
|
||||
using Exsersewo.Common.Utilities;
|
||||
using Kynareth.Helpers;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace Kynareth.Attributes;
|
||||
@@ -10,7 +11,11 @@ public class RequireTokenAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
if (await RequestHelper.IsRequestAuthenticatedAsync(context.HttpContext.Request))
|
||||
var methodInfo = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
|
||||
var shouldIgnoreToken = methodInfo.MethodInfo.CustomAttributes.Any(x=>x.AttributeType == typeof(IgnoreTokenAttribute));
|
||||
|
||||
if (shouldIgnoreToken || await RequestHelper.IsRequestAuthenticatedAsync(context.HttpContext.Request))
|
||||
{
|
||||
await next();
|
||||
return;
|
||||
@@ -24,3 +29,8 @@ public class RequireTokenAttribute : ActionFilterAttribute
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public class IgnoreTokenAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using Exsersewo.Common.Utilities;
|
||||
using ImageMagick;
|
||||
using Kynareth.Attributes;
|
||||
using Kynareth.Helpers;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Kynareth.Extensions;
|
||||
|
||||
namespace Kynareth.Controllers;
|
||||
|
||||
@@ -31,14 +33,17 @@ public class AmogusController : BaseController<AmogusController>
|
||||
}
|
||||
|
||||
[HttpGet("roles")]
|
||||
[IgnoreToken]
|
||||
public async Task<object> GetAmongUsRoles()
|
||||
=> Ok(EventResult.FromSuccess(Enum.GetNames<AmogusRole>().Except("None")));
|
||||
|
||||
[HttpGet("colours")]
|
||||
[IgnoreToken]
|
||||
public async Task<object> GetAmongUsColours()
|
||||
=> Ok(EventResult.FromSuccess(Enum.GetNames<AmogusColour>().Except("None")));
|
||||
|
||||
[HttpGet("skins")]
|
||||
[IgnoreToken]
|
||||
public async Task<object> GetAmongUsSkins()
|
||||
=> Ok(EventResult.FromSuccess(Enum.GetNames<AmogusSkin>().Except("None")));
|
||||
}
|
||||
@@ -17,6 +17,7 @@ public class ImageGenerationController : BaseController<ImageGenerationControlle
|
||||
|
||||
[HttpGet]
|
||||
[EndpointMetrics("image.generate.get.templates")]
|
||||
[IgnoreToken]
|
||||
[ProducesResponseType(typeof(IEnumerable<ImageGenerationEndpointRead>), StatusCodes.Status200OK)]
|
||||
public Task<object> GetTemplates()
|
||||
{
|
||||
@@ -54,4 +55,38 @@ public class ImageGenerationController : BaseController<ImageGenerationControlle
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{template}/random")]
|
||||
[EndpointMetrics("image.generate.generate.random")]
|
||||
[ProducesResponseType(typeof(Stream), StatusCodes.Status200OK, "image/png")]
|
||||
[ProducesResponseType(typeof(EventResult), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(EventResult), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(EventResult), StatusCodes.Status500InternalServerError)]
|
||||
[IgnoreToken]
|
||||
public async Task<object> GenerateMemeAsync(string template, [FromQuery] string variant = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(template))
|
||||
{
|
||||
var result = await ImageManager.GenerateImageAsync(template, variant, Request.HttpContext.RequestAborted);
|
||||
|
||||
if (result is byte[] data)
|
||||
{
|
||||
var image = new MemoryStream(data);
|
||||
|
||||
return HttpContext.SendStream(image, "image/png");
|
||||
}
|
||||
|
||||
return result as IResult;
|
||||
}
|
||||
|
||||
return HttpContext.Send(EventResult.FromFailure("No template has been provided"), System.Net.HttpStatusCode.BadRequest);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
_logger.LogCritical(ex.Message, ex);
|
||||
|
||||
return HttpContext.Send(EventResult.FromFailure("Can't parse result"), System.Net.HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ public class ImageManipulationController : BaseController<ImageManipulationContr
|
||||
/// BOTTOM TEXT ///
|
||||
/// ------------- ///
|
||||
[HttpGet]
|
||||
[IgnoreToken]
|
||||
[EndpointMetrics("image.generate.get.templates")]
|
||||
[ProducesResponseType(typeof(IEnumerable<ImageGenerationEndpointRead>), StatusCodes.Status200OK)]
|
||||
public Task<object> GetTemplates()
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
namespace Kynareth;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static T GetRandomEnumValue<T>() where T : Enum
|
||||
=> (T) Enum.GetValues(typeof(T)).OfType<Enum>().OrderBy(_ => Guid.NewGuid()).FirstOrDefault();
|
||||
|
||||
public static IList<int> Range(int start, int stop, int step)
|
||||
{
|
||||
var list = new List<int>();
|
||||
|
||||
for (int i = start; i < stop; i += step) {
|
||||
list.Add(i);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static T[] Except<T>(this T[] array, T specificValue) where T : IComparable {
|
||||
return array.Where<T>(val => val.CompareTo(specificValue) != 0).ToArray();
|
||||
}
|
||||
}
|
||||
46
src/Extensions/CollectionExtensions.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Exsersewo.Common.Extensions;
|
||||
|
||||
namespace Kynareth.Extensions;
|
||||
|
||||
public static class CollectionExtensions
|
||||
{
|
||||
public static ICollection<T> GetRandomAmount<T>(this ICollection<T> stack, int amount)
|
||||
{
|
||||
T[] entries = new T[amount];
|
||||
|
||||
for (int x = 0; x < amount; x++)
|
||||
{
|
||||
entries[x] = stack.CryptoRandom();
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
public static ICollection<T> GetRandomAmount<T>(this IEnumerable<T> stack, int amount)
|
||||
{
|
||||
T[] entries = new T[amount];
|
||||
|
||||
for (int x = 0; x < amount; x++)
|
||||
{
|
||||
entries[x] = stack.CryptoRandom();
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
public static IList<int> Range(int start, int stop, int step)
|
||||
{
|
||||
var list = new List<int>();
|
||||
|
||||
for (int i = start; i < stop; i += step) {
|
||||
list.Add(i);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static T[] Except<T>(this T[] array, T specificValue) where T : IComparable
|
||||
{
|
||||
return array.Where<T>(val => val.CompareTo(specificValue) != 0).ToArray();
|
||||
}
|
||||
}
|
||||
7
src/Extensions/EnumHelper.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Kynareth.Extensions;
|
||||
|
||||
public static class EnumHelper
|
||||
{
|
||||
public static T GetRandomEnumValue<T>() where T : Enum
|
||||
=> (T) Enum.GetValues(typeof(T)).OfType<Enum>().OrderBy(_ => Guid.NewGuid()).FirstOrDefault();
|
||||
}
|
||||
@@ -3,7 +3,8 @@ using System.Numerics;
|
||||
using System.Text;
|
||||
using ImageMagick;
|
||||
using Kynareth.Managers;
|
||||
using Kynareth.Models;
|
||||
using Kynareth.Extensions;
|
||||
using CollectionExtensions = Kynareth.Extensions.CollectionExtensions;
|
||||
|
||||
namespace Kynareth.Helpers;
|
||||
|
||||
@@ -412,7 +413,7 @@ public static class AmogusHelper
|
||||
using MagickImage stars2 = new MagickImage(stars);
|
||||
stars2.Distort(DistortMethod.ScaleRotateTranslate, 180);
|
||||
|
||||
foreach (var x in Extensions.Range(-800, width, 320))
|
||||
foreach (var x in CollectionExtensions.Range(-800, width, 320))
|
||||
{
|
||||
baseImage.Composite(stars2, Gravity.Northwest, x, (int)(x / 60f) - 200, CompositeOperator.Over);
|
||||
baseImage.Composite(stars, Gravity.Northwest, x, 100 + (int)(x / 120f), CompositeOperator.Over);
|
||||
@@ -458,16 +459,16 @@ public static class AmogusHelper
|
||||
/// <returns>A <see cref="MemoryStream"/> containing the Amogus Ejected Gif</returns>
|
||||
public static MagickImageCollection GenerateEjectionGif(string name, AmogusColour? colour = null, AmogusRole? role = null, AmogusSkin? skin = null, bool addStars = true)
|
||||
{
|
||||
if (role is null) role = Extensions.GetRandomEnumValue<AmogusRole>();
|
||||
if (role is null) role = EnumHelper.GetRandomEnumValue<AmogusRole>();
|
||||
|
||||
return GenerateCustomEjectionGif(GenerateEjectionMessage(name, role.Value), colour, role, skin, addStars);
|
||||
}
|
||||
|
||||
public static MagickImageCollection GenerateCustomEjectionGif(string text, AmogusColour? colour = null, AmogusRole? role = null, AmogusSkin? skin = null, bool addStars = true)
|
||||
{
|
||||
if (colour is null) colour = Extensions.GetRandomEnumValue<AmogusColour>();
|
||||
if (role is null) role = Extensions.GetRandomEnumValue<AmogusRole>();
|
||||
if (skin is null) skin = Extensions.GetRandomEnumValue<AmogusSkin>();
|
||||
if (colour is null) colour = EnumHelper.GetRandomEnumValue<AmogusColour>();
|
||||
if (role is null) role = EnumHelper.GetRandomEnumValue<AmogusRole>();
|
||||
if (skin is null) skin = EnumHelper.GetRandomEnumValue<AmogusSkin>();
|
||||
|
||||
var crewmate = GenerateCrewmate(colour.Value, skin.Value);
|
||||
crewmate = MakeSquare(crewmate);
|
||||
@@ -497,7 +498,7 @@ public static class AmogusHelper
|
||||
stars3.BackgroundColor = MagickColors.Transparent;
|
||||
}
|
||||
|
||||
var range = Extensions.Range(-120, background.Width * 3, 12);
|
||||
var range = CollectionExtensions.Range(-120, background.Width * 3, 12);
|
||||
|
||||
MagickImageCollection gifFrames = new MagickImageCollection();
|
||||
|
||||
|
||||
@@ -1,21 +1,43 @@
|
||||
using System.Collections.Immutable;
|
||||
using Exsersewo.Common.Utilities;
|
||||
using ImageMagick;
|
||||
using Kynareth.Models;
|
||||
using Kynareth.Extensions;
|
||||
|
||||
namespace Kynareth.Managers;
|
||||
|
||||
public static partial class ImageManager
|
||||
{
|
||||
private static List<ImageGenerationEndpoint> GenerationEndpoints;
|
||||
private static IReadOnlyList<string> sourceFiles;
|
||||
|
||||
private static string GenerationTemplateBaseFolder;
|
||||
|
||||
static void ConfigureGeneration(IConfiguration configuration, IWebHostEnvironment _appEnvironment)
|
||||
{
|
||||
sourceFiles = Directory.EnumerateFiles(Path.Combine(_appEnvironment.WebRootPath, configuration.GetValue<string>("ShitpostBot:Folder"), "..", "random")).ToImmutableList();
|
||||
GenerationTemplateBaseFolder = Path.Combine(_appEnvironment.WebRootPath, configuration.GetValue<string>("ShitpostBot:Folder"));
|
||||
GenerationEndpoints = configuration.GetSection("ShitpostBot:Templates").Get<List<ImageGenerationEndpoint>>();
|
||||
}
|
||||
|
||||
public static async Task<Object> GenerateImageAsync(string template, string variant, CancellationToken cancellationToken)
|
||||
{
|
||||
ImageGenerationImage imageTemplate = null;
|
||||
|
||||
var endpoint = GenerationEndpoints.FirstOrDefault(e => e.Name.ToLowerInvariant().Equals(template.ToLowerInvariant()));
|
||||
|
||||
if (endpoint is null)
|
||||
{
|
||||
var ex = new ArgumentException($"Couldn't find endpoint named \"{template}\"", nameof(template));
|
||||
|
||||
return GetResult(StatusCodes.Status404NotFound, EventResult.FromFailureException(ex.Message, ex));
|
||||
}
|
||||
|
||||
var sources = sourceFiles.GetRandomAmount(endpoint.SourcesRequired) as string[];
|
||||
|
||||
return await GenerateImageAsync(template, variant, sources, cancellationToken);
|
||||
}
|
||||
|
||||
public static async Task<object> GenerateImageAsync(string template, string variant, string[] sources, CancellationToken cancellationToken)
|
||||
{
|
||||
while (true)
|
||||
@@ -102,7 +124,17 @@ public static partial class ImageManager
|
||||
{
|
||||
var position = template.Positions.ElementAtOrDefault(img);
|
||||
|
||||
using MagickImage srcImg = new MagickImage(await HttpWebClient.GetStreamAsync(new Uri(src)));
|
||||
Stream imageData = null;
|
||||
if (File.Exists(src))
|
||||
{
|
||||
imageData = new MemoryStream(await File.ReadAllBytesAsync(src));
|
||||
}
|
||||
else if (src.StartsWith("http"))
|
||||
{
|
||||
imageData = await HttpWebClient.GetStreamAsync(new Uri(src));
|
||||
}
|
||||
|
||||
using MagickImage srcImg = new MagickImage(imageData);
|
||||
|
||||
srcImg.Resize(position.Width, position.Height);
|
||||
|
||||
@@ -121,6 +153,8 @@ public static partial class ImageManager
|
||||
|
||||
img++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
src/wwwroot/imagegen/random/00uc8hweoec11.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
src/wwwroot/imagegen/random/08f4c5f1uhk11.jpg
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
src/wwwroot/imagegen/random/0dvynk93sqh11.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
src/wwwroot/imagegen/random/0m0x2ygrdph11.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
src/wwwroot/imagegen/random/122kk4janjh11.jpg
Normal file
|
After Width: | Height: | Size: 146 KiB |
BIN
src/wwwroot/imagegen/random/13-5.jpg
Normal file
|
After Width: | Height: | Size: 422 KiB |
BIN
src/wwwroot/imagegen/random/189jlz9sd6h11.jpg
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
src/wwwroot/imagegen/random/1aiiyfa16qj11.jpg
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
src/wwwroot/imagegen/random/1hh7hesnwmg11.jpg
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
src/wwwroot/imagegen/random/2gkcmtvsknk11.jpg
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
src/wwwroot/imagegen/random/2xc8ta241ef11.jpg
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
src/wwwroot/imagegen/random/3vdcuwqyvwj11.jpg
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
src/wwwroot/imagegen/random/54wr08npgwf11.gif
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
src/wwwroot/imagegen/random/56gpa81abpf11.png
Normal file
|
After Width: | Height: | Size: 303 KiB |
BIN
src/wwwroot/imagegen/random/5aeb56nppuk11.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
BIN
src/wwwroot/imagegen/random/5spetics5kj11.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
src/wwwroot/imagegen/random/5vkjjdro5vf11.gif
Normal file
|
After Width: | Height: | Size: 186 KiB |
BIN
src/wwwroot/imagegen/random/5vlcwan2lmh11.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
src/wwwroot/imagegen/random/6sfo1cna2pj11.jpg
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
src/wwwroot/imagegen/random/77x7ii00zvi11.jpg
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
src/wwwroot/imagegen/random/7l5n5ujzepi11.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
src/wwwroot/imagegen/random/857p7046ccf11.jpg
Normal file
|
After Width: | Height: | Size: 242 KiB |
BIN
src/wwwroot/imagegen/random/8qa5fcz37gf11.jpg
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
src/wwwroot/imagegen/random/8qmocvg1m9j11.jpg
Normal file
|
After Width: | Height: | Size: 272 KiB |
BIN
src/wwwroot/imagegen/random/8suq2wcsymf11.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
src/wwwroot/imagegen/random/93b0rp4612h11.jpg
Normal file
|
After Width: | Height: | Size: 685 KiB |
BIN
src/wwwroot/imagegen/random/94w4fj9a1ai11.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
src/wwwroot/imagegen/random/9djtnidkcwf11.jpg
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
src/wwwroot/imagegen/random/9q16us8ysij11.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
src/wwwroot/imagegen/random/9sfe8wq12sh11.jpg
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
src/wwwroot/imagegen/random/a19wz17opyh11.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
src/wwwroot/imagegen/random/aUdeAY5.jpg
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
src/wwwroot/imagegen/random/aqnlxkgflvi11.jpg
Normal file
|
After Width: | Height: | Size: 183 KiB |
BIN
src/wwwroot/imagegen/random/aqx6idxqekg11.jpg
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
src/wwwroot/imagegen/random/b04p5ymhr6h11.png
Normal file
|
After Width: | Height: | Size: 753 KiB |
BIN
src/wwwroot/imagegen/random/bzj2nywuc8j11.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
src/wwwroot/imagegen/random/c429dw6y7ak11.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
src/wwwroot/imagegen/random/c7jy592gnsg11.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
src/wwwroot/imagegen/random/cx1hOwz.jpg
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
src/wwwroot/imagegen/random/cy200joshji11.jpg
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
src/wwwroot/imagegen/random/da1ponyybhf11.jpg
Normal file
|
After Width: | Height: | Size: 260 KiB |