mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-26 07:29:00 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,580 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.Extensions;
|
||||
using RadicadeServer.RecNet.CDN;
|
||||
using RadicadeServer.RecNet.Enums;
|
||||
using RadicadeServer.RecNet.Images;
|
||||
using RadicadeServer.RecNet.Responses;
|
||||
using RadicadeServer.Radicade.Discord.Templates;
|
||||
|
||||
namespace RadicadeServer.API
|
||||
{
|
||||
[Route("api/images")]
|
||||
public class ImagesAPI : Controller
|
||||
{
|
||||
RecDBContext db;
|
||||
public ImagesAPI(RecDBContext context)
|
||||
{
|
||||
this.db = context;
|
||||
}
|
||||
|
||||
|
||||
private static object ToSavedImage(ImageDB image, int cheerCount) => new
|
||||
{
|
||||
Id = image.Id,
|
||||
SavedImageId = image.Id,
|
||||
Type = (int)image.ImageType,
|
||||
SavedImageType = (int)image.ImageType,
|
||||
Accessibility = (int)image.Accessibility,
|
||||
AccessibilityLocked = false,
|
||||
ImageName = image.Name,
|
||||
Description = (string?)null,
|
||||
PlayerId = image.OwnerId,
|
||||
TaggedPlayerIds = ParseTaggedPlayerIds(image.PlayerIds),
|
||||
RoomId = image.RoomId,
|
||||
PlayerEventId = image.EventId,
|
||||
CreatedAt = image.CreatedAt,
|
||||
CheerCount = cheerCount,
|
||||
CommentCount = 0
|
||||
};
|
||||
|
||||
private static object ToImagesPlayer(ImageDB image, int cheerCount) => new
|
||||
{
|
||||
SavedImageId = image.Id,
|
||||
Id = image.Id,
|
||||
SavedImageType = (int)image.ImageType,
|
||||
Type = (int)image.ImageType,
|
||||
Accessibility = (int)image.Accessibility,
|
||||
AccessibilityLocked = false,
|
||||
CheerCount = cheerCount,
|
||||
CommentCount = 0,
|
||||
CreatedAt = image.CreatedAt,
|
||||
Description = (string?)null,
|
||||
ImageName = image.Name,
|
||||
PlayerEventId = image.EventId,
|
||||
PlayerId = image.OwnerId,
|
||||
RoomId = image.RoomId
|
||||
};
|
||||
|
||||
private static List<long> ParseTaggedPlayerIds(string json)
|
||||
{
|
||||
try
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(json)
|
||||
? new List<long>()
|
||||
: (json.FromJson<List<long>>() ?? new List<long>());
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new List<long>();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Dictionary<long, int>> CheerCountsAsync(IEnumerable<long> imageIds)
|
||||
{
|
||||
var ids = imageIds.Distinct().ToList();
|
||||
if (ids.Count == 0)
|
||||
return new Dictionary<long, int>();
|
||||
|
||||
return await db.ImageInteractions.AsNoTracking()
|
||||
.Where(c => c.IsCheered && ids.Contains(c.SavedImageId))
|
||||
.GroupBy(c => c.SavedImageId)
|
||||
.Select(g => new { g.Key, Count = g.Count() })
|
||||
.ToDictionaryAsync(g => g.Key, g => g.Count);
|
||||
}
|
||||
|
||||
private static string[] TagMatchPatterns(long playerId) => new[]
|
||||
{
|
||||
$"[{playerId},", $",{playerId},", $",{playerId}]", $"[{playerId}]"
|
||||
};
|
||||
|
||||
|
||||
[HttpGet("v5/player/{id:long}")]
|
||||
public async Task<List<object>> GetImagesFromPlayer(long id, [FromQuery] int sort = 0, [FromQuery] int skip = 0, [FromQuery] int take = 100)
|
||||
{
|
||||
var images = await db.Images.AsNoTracking()
|
||||
.Where(image => image.OwnerId == id && image.Accessibility == SavedImageAccessibility.Public)
|
||||
.ToListAsync();
|
||||
|
||||
var cheers = await CheerCountsAsync(images.Select(image => image.Id));
|
||||
var ordered = OrderImages(images, sort, cheers)
|
||||
.Skip(skip).Take(take)
|
||||
.ToList();
|
||||
|
||||
return ordered.Select(image => ToImagesPlayer(image, cheers.GetValueOrDefault(image.Id))).ToList();
|
||||
}
|
||||
|
||||
[HttpGet("v4/player/{id:long}")]
|
||||
public Task<List<object>> GetImagesFromPlayerV4(long id, [FromQuery] int skip = 0, [FromQuery] int take = 100)
|
||||
=> GetImagesFromPlayer(id, 0, skip, take);
|
||||
|
||||
[HttpGet("v4/room/{id}")]
|
||||
public async Task<List<object>> GetImagesFromRoom(long? id, [FromQuery] int sort = 0, [FromQuery] int filter = 0, [FromQuery] int skip = 0, [FromQuery] int take = 100)
|
||||
{
|
||||
var result = new List<object>();
|
||||
if (id == null)
|
||||
return result;
|
||||
|
||||
var images = await db.Images.AsNoTracking()
|
||||
.Where(x => x.RoomId == id && x.Accessibility == SavedImageAccessibility.Public)
|
||||
.ToListAsync();
|
||||
|
||||
if (filter > 0)
|
||||
images = images.Where(x => (int)x.ImageType == filter).ToList();
|
||||
|
||||
var cheers = await CheerCountsAsync(images.Select(x => x.Id));
|
||||
var ordered = OrderImages(images, sort, cheers)
|
||||
.Skip(skip).Take(take)
|
||||
.ToList();
|
||||
|
||||
return ordered.Select(image => ToSavedImage(image, cheers.GetValueOrDefault(image.Id))).ToList();
|
||||
}
|
||||
|
||||
[HttpGet("v1/playerevent/{eventId}")]
|
||||
public async Task<List<object>> GetImagesFromEvent(long eventId, [FromQuery] int skip = 0, [FromQuery] int take = 100)
|
||||
{
|
||||
var images = await db.Images.AsNoTracking()
|
||||
.Where(x => x.EventId == eventId && x.Accessibility == SavedImageAccessibility.Public)
|
||||
.ToListAsync();
|
||||
|
||||
var cheers = await CheerCountsAsync(images.Select(x => x.Id));
|
||||
var ordered = OrderImages(images, 0, cheers)
|
||||
.Skip(skip).Take(take)
|
||||
.ToList();
|
||||
|
||||
return ordered.Select(image => ToSavedImage(image, cheers.GetValueOrDefault(image.Id))).ToList();
|
||||
}
|
||||
|
||||
private static IEnumerable<ImageDB> OrderImages(IEnumerable<ImageDB> images, int sort, Dictionary<long, int> cheers)
|
||||
{
|
||||
return sort == 1
|
||||
? images.OrderByDescending(x => cheers.GetValueOrDefault(x.Id))
|
||||
.ThenByDescending(x => x.CreatedAt).ThenByDescending(x => x.Id)
|
||||
: images.OrderByDescending(x => x.CreatedAt).ThenByDescending(x => x.Id);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("v3/feed/player/{id:long}")]
|
||||
public async Task<List<object>> GetPlayerFeed(long id, [FromQuery] int skip = 0, [FromQuery] int take = 100)
|
||||
{
|
||||
var patterns = TagMatchPatterns(id);
|
||||
var images = await db.Images.AsNoTracking()
|
||||
.Where(x => x.Accessibility == SavedImageAccessibility.Public &&
|
||||
(x.OwnerId == id ||
|
||||
x.PlayerIds.Contains(patterns[0]) ||
|
||||
x.PlayerIds.Contains(patterns[1]) ||
|
||||
x.PlayerIds.Contains(patterns[2]) ||
|
||||
x.PlayerIds.Contains(patterns[3])))
|
||||
.ToListAsync();
|
||||
|
||||
var cheers = await CheerCountsAsync(images.Select(x => x.Id));
|
||||
var ordered = OrderImages(images, 0, cheers)
|
||||
.Skip(skip).Take(take)
|
||||
.ToList();
|
||||
|
||||
return ordered.Select(image => ToImagesPlayer(image, cheers.GetValueOrDefault(image.Id))).ToList();
|
||||
}
|
||||
|
||||
[HttpGet("v3/feed/global")]
|
||||
public async Task<object> GetGlobalFeed([FromQuery] int skip = 0, [FromQuery] int take = 100)
|
||||
{
|
||||
var images = await db.Images.AsNoTracking()
|
||||
.Where(x => x.Accessibility == SavedImageAccessibility.Public &&
|
||||
x.ImageType == SavedImageType.ShareCamera)
|
||||
.OrderByDescending(x => x.CreatedAt).ThenByDescending(x => x.Id)
|
||||
.Skip(skip).Take(Math.Clamp(take, 1, 100))
|
||||
.ToListAsync();
|
||||
|
||||
var ownerIds = images.Select(x => x.OwnerId).Distinct().ToList();
|
||||
var roomIds = images.Where(x => x.RoomId != null).Select(x => x.RoomId!.Value).Distinct().ToList();
|
||||
|
||||
var usernames = await db.Profiles.AsNoTracking()
|
||||
.Where(p => ownerIds.Contains(p.accountId))
|
||||
.ToDictionaryAsync(p => p.accountId, p => p.username);
|
||||
var roomNames = await db.Rooms.AsNoTracking()
|
||||
.Where(r => roomIds.Contains(r.RoomId))
|
||||
.ToDictionaryAsync(r => r.RoomId, r => r.Name);
|
||||
|
||||
var entries = images.Select(image => new
|
||||
{
|
||||
SavedImageId = image.Id,
|
||||
ImageName = image.Name,
|
||||
Username = usernames.TryGetValue(image.OwnerId, out var username) ? username : $"Player{image.OwnerId}",
|
||||
RoomName = image.RoomId != null && roomNames.TryGetValue(image.RoomId.Value, out var roomName) ? roomName : (string?)null,
|
||||
RoomId = image.RoomId,
|
||||
SavedImageType = (int)image.ImageType,
|
||||
PlayerEventId = image.EventId,
|
||||
Accessibility = (int)image.Accessibility,
|
||||
PlayerIds = ParseTaggedPlayerIds(image.PlayerIds)
|
||||
}).ToList();
|
||||
|
||||
return new { Images = entries, ValidTill = DateTime.UtcNow.AddMinutes(2) };
|
||||
}
|
||||
|
||||
[HttpGet("v3/bulk")]
|
||||
public async Task<List<object>> GetBulkImages([FromQuery] string ids)
|
||||
{
|
||||
var result = new List<object>();
|
||||
if (string.IsNullOrWhiteSpace(ids))
|
||||
return result;
|
||||
|
||||
var parsed = ids
|
||||
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
.Select(part => long.TryParse(part, out var value) ? value : -1)
|
||||
.Where(value => value > 0)
|
||||
.ToList();
|
||||
if (parsed.Count == 0)
|
||||
return result;
|
||||
|
||||
var images = await db.Images.AsNoTracking()
|
||||
.Where(x => parsed.Contains(x.Id) && x.Accessibility == SavedImageAccessibility.Public)
|
||||
.ToListAsync();
|
||||
var byId = images.ToDictionary(x => x.Id);
|
||||
var cheers = await CheerCountsAsync(images.Select(x => x.Id));
|
||||
|
||||
foreach (var id in parsed)
|
||||
{
|
||||
if (byId.TryGetValue(id, out var image))
|
||||
result.Add(ToSavedImage(image, cheers.GetValueOrDefault(image.Id)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpGet("v4/{photoId:long}")]
|
||||
public async Task<IActionResult> GetImageById(long photoId)
|
||||
{
|
||||
var image = await db.Images.AsNoTracking().FirstOrDefaultAsync(x => x.Id == photoId);
|
||||
if (image == null)
|
||||
return NotFound();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (image.Accessibility == SavedImageAccessibility.Private)
|
||||
return NotFound();
|
||||
return Ok(ToSavedImage(image, await db.ImageInteractions.AsNoTracking()
|
||||
.CountAsync(c => c.SavedImageId == image.Id && c.IsCheered)));
|
||||
}
|
||||
|
||||
[HttpGet("v5/bulk")]
|
||||
public async Task<List<object>> GetBulkImageMetadata([FromQuery] string[]? ids)
|
||||
{
|
||||
var result = new List<object>();
|
||||
var parsed = (ids ?? Array.Empty<string>())
|
||||
.SelectMany(raw => (raw ?? "").Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
|
||||
.Select(part => long.TryParse(part, out var value) ? value : -1)
|
||||
.Where(value => value > 0)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
if (parsed.Count == 0)
|
||||
return result;
|
||||
|
||||
var images = await db.Images.AsNoTracking()
|
||||
.Where(x => parsed.Contains(x.Id) && x.Accessibility == SavedImageAccessibility.Public)
|
||||
.ToListAsync();
|
||||
var byId = images.ToDictionary(x => x.Id);
|
||||
var cheers = await CheerCountsAsync(images.Select(x => x.Id));
|
||||
|
||||
foreach (var id in parsed)
|
||||
{
|
||||
if (byId.TryGetValue(id, out var image))
|
||||
result.Add(ToBulkSavedImage(image, cheers.GetValueOrDefault(image.Id)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static object ToBulkSavedImage(ImageDB image, int cheerCount) => new
|
||||
{
|
||||
Id = image.Id,
|
||||
Type = (int)image.ImageType,
|
||||
Accessibility = (int)image.Accessibility,
|
||||
AccessibilityLocked = false,
|
||||
ImageName = image.Name,
|
||||
Description = (string?)null,
|
||||
PlayerId = image.OwnerId,
|
||||
TaggedPlayerIds = ParseTaggedPlayerIds(image.PlayerIds),
|
||||
RoomId = image.RoomId,
|
||||
PlayerEventId = image.EventId,
|
||||
CreatedAt = image.CreatedAt,
|
||||
CheerCount = cheerCount,
|
||||
CommentCount = 0,
|
||||
SavedImageId = image.Id,
|
||||
SavedImageType = (int)image.ImageType,
|
||||
ClubId = 0
|
||||
};
|
||||
|
||||
[HttpGet("v6")]
|
||||
public async Task<IActionResult> GetImageByName([FromQuery] string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
return BadRequest(new { error = "name is required" });
|
||||
|
||||
var image = await db.Images.AsNoTracking().FirstOrDefaultAsync(x => x.Name == name);
|
||||
if (image == null)
|
||||
return NotFound();
|
||||
|
||||
|
||||
|
||||
if (image.Accessibility == SavedImageAccessibility.Private)
|
||||
return NotFound();
|
||||
|
||||
var viewerId = User.GetUserId() ?? Request.Headers.Authorization.ToString().GetUserId();
|
||||
if (viewerId != null)
|
||||
RecentImageReferences.Remember(viewerId.Value, image.Id);
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
SavedImageId = image.Id,
|
||||
ImageName = image.Name,
|
||||
PlayerId = image.OwnerId,
|
||||
RoomId = image.RoomId ?? 0,
|
||||
PlayerEventId = image.EventId ?? 0,
|
||||
ClubId = 0,
|
||||
Description = "",
|
||||
Accessibility = (int)image.Accessibility,
|
||||
AccessibilityLocked = false,
|
||||
SavedImageType = (int)image.ImageType,
|
||||
CreatedAt = image.CreatedAt,
|
||||
CheerCount = await db.ImageInteractions.AsNoTracking()
|
||||
.CountAsync(c => c.SavedImageId == image.Id && c.IsCheered),
|
||||
CommentCount = 0
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("v1/cheer"), Authorize]
|
||||
public async Task<Success> CheerImage([FromBody] ImageCheerRequest req)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
if (userId == null)
|
||||
return new Success(false, "Not signed in", null);
|
||||
|
||||
var existingInteraction = await db.ImageInteractions.FirstOrDefaultAsync(x =>
|
||||
x.PlayerId == userId && x.SavedImageId == req.SavedImageId);
|
||||
if (existingInteraction != null)
|
||||
existingInteraction.IsCheered = req.Cheer;
|
||||
else
|
||||
await db.ImageInteractions.AddAsync(
|
||||
new CheeredImage { IsCheered = req.Cheer, PlayerId = (long)userId, SavedImageId = req.SavedImageId }
|
||||
);
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return new Success(true, null, null);
|
||||
}
|
||||
|
||||
[HttpGet("v1/{imageId:long}/cheers")]
|
||||
public async Task<List<long>> GetImageCheers(long imageId)
|
||||
{
|
||||
return await db.ImageInteractions.AsNoTracking()
|
||||
.Where(x => x.SavedImageId == imageId && x.IsCheered)
|
||||
.Select(x => x.PlayerId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
[HttpGet("v2/named")]
|
||||
public List<NamedImage> GetNamedImages()
|
||||
{
|
||||
var config = db.ServerConfig.FirstOrDefault(x => x.Key == "NamedImages");
|
||||
return config?.Value.FromJson<List<NamedImage>>() ?? new List<NamedImage>();
|
||||
}
|
||||
|
||||
private async Task<List<object>> CheerLookup(List<long> ids)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
if (userId == null)
|
||||
return new List<object>();
|
||||
|
||||
ids ??= new List<long>();
|
||||
var cheeredIds = await db.ImageInteractions.AsNoTracking()
|
||||
.Where(x => x.PlayerId == userId && x.IsCheered && ids.Contains(x.SavedImageId))
|
||||
.Select(x => x.SavedImageId)
|
||||
.ToListAsync();
|
||||
var cheeredSet = cheeredIds.ToHashSet();
|
||||
|
||||
return ids.Select(id => (object)new { SavedImageId = id, IsCheered = cheeredSet.Contains(id) }).ToList();
|
||||
}
|
||||
|
||||
[HttpGet("v5/cheered/bulk"), Authorize]
|
||||
public Task<List<object>> GetBulkImageCheers([FromQuery] long[] id)
|
||||
=> CheerLookup((id ?? Array.Empty<long>()).ToList());
|
||||
|
||||
[HttpPost("v5/cheered/bulk"), Authorize]
|
||||
public async Task<List<object>> PostBulkImageCheers()
|
||||
{
|
||||
var ids = new List<long>();
|
||||
if (Request.HasFormContentType)
|
||||
{
|
||||
var form = await Request.ReadFormAsync();
|
||||
foreach (var value in form["id"])
|
||||
{
|
||||
if (long.TryParse(value, out var parsed))
|
||||
ids.Add(parsed);
|
||||
}
|
||||
}
|
||||
return await CheerLookup(ids);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("v1/{imageId:long}/report"), Authorize]
|
||||
public async Task<IActionResult> ReportImage(long imageId)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return Ok(new { success = true });
|
||||
}
|
||||
|
||||
[HttpPost("v1/{imageId:long}/player/{playerId:long}/untag"), Authorize]
|
||||
public async Task<IActionResult> UntagFromImage(long imageId, long playerId)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var image = await db.Images.FirstOrDefaultAsync(x => x.Id == imageId);
|
||||
if (image == null)
|
||||
return NotFound();
|
||||
|
||||
if (userId != playerId && userId != image.OwnerId)
|
||||
return StatusCode(403);
|
||||
|
||||
var tagged = ParseTaggedPlayerIds(image.PlayerIds);
|
||||
if (!tagged.Remove(playerId))
|
||||
return Ok(new { success = true });
|
||||
|
||||
image.PlayerIds = tagged.ToJson();
|
||||
await db.SaveChangesAsync();
|
||||
return Ok(new { success = true });
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("v4/uploadsaved"), Authorize]
|
||||
public async Task<ActionResult<ImageNameDTO?>> UploadSavedImage([FromForm] IFormFile? image, [FromForm] SavedImageMetaDTO? imgMeta)
|
||||
{
|
||||
if (imgMeta == null)
|
||||
return BadRequest();
|
||||
if (image == null || image.Length <= 0 || image.Length >= 2 * 1024 * 1024)
|
||||
return StatusCode(413);
|
||||
|
||||
var userId = User.GetUserId();
|
||||
if (userId == null)
|
||||
return Unauthorized();
|
||||
|
||||
var presence = await db.Presences.FirstOrDefaultAsync(x => x.playerId == userId);
|
||||
var roomInstance = presence != null
|
||||
? await db.RoomInstances.FirstOrDefaultAsync(x => x.roomInstanceId == presence.roomInstance)
|
||||
: null;
|
||||
|
||||
string imageName = Guid.NewGuid().ToString() + ".png";
|
||||
string path = Path.Join(DBConfig.CDNImages, imageName);
|
||||
|
||||
using (var stream = new FileStream(path, FileMode.Create))
|
||||
{
|
||||
await image.CopyToAsync(stream);
|
||||
}
|
||||
|
||||
SavedImageAccessibility accessibility = imgMeta.accessibility;
|
||||
if (imgMeta.savedImageType == SavedImageType.InventionThumbnail ||
|
||||
imgMeta.savedImageType == SavedImageType.OutfitThumbnail ||
|
||||
imgMeta.savedImageType == SavedImageType.ProfileThumbnail ||
|
||||
imgMeta.savedImageType == SavedImageType.RoomThumbnail)
|
||||
{
|
||||
accessibility = SavedImageAccessibility.Private;
|
||||
}
|
||||
|
||||
var taggedPlayerIds = (imgMeta.playerIds ?? new List<long>())
|
||||
.Where(id => id > 0)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
var savedImage = new ImageDB { CreatedAt = DateTime.Now, Name = imageName, OwnerId = (long)userId, Accessibility = accessibility, ImageType = imgMeta.savedImageType, RoomId = imgMeta.roomId ?? roomInstance?.roomId, EventId = imgMeta.playerEventId, PlayerIds = taggedPlayerIds.ToJson() };
|
||||
await db.Images.AddAsync(savedImage);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
RecentImageReferences.Remember((long)userId, savedImage.Id);
|
||||
|
||||
if (imgMeta.savedImageType == SavedImageType.ProfileThumbnail)
|
||||
{
|
||||
var profile = await db.Profiles.FirstOrDefaultAsync(x => x.accountId == userId);
|
||||
if (profile != null)
|
||||
{
|
||||
profile.profileImage = imageName;
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
if (accessibility == SavedImageAccessibility.Public || imgMeta.savedImageType == SavedImageType.ShareCamera)
|
||||
{
|
||||
var room = await db.Rooms.AsNoTracking().FirstOrDefaultAsync(x => x.RoomId == imgMeta.roomId);
|
||||
var ownerProfile = await db.Profiles.AsNoTracking().FirstOrDefaultAsync(x => x.accountId == userId);
|
||||
|
||||
string? roomName = null;
|
||||
|
||||
if (ownerProfile != null)
|
||||
{
|
||||
if (room != null)
|
||||
{
|
||||
if (room.Accessibility >= Accessibility.Public)
|
||||
roomName = "^" + room.Name;
|
||||
else if (room.IsDorm && roomInstance != null)
|
||||
roomName = roomInstance?.name;
|
||||
else
|
||||
roomName = "[PRIVATE]";
|
||||
}
|
||||
|
||||
await WebhookImageUpload.Send($"{DBConfig.NameServer.Images}/img/{imageName}", ownerProfile.username, ownerProfile.displayName, $"{DBConfig.NameServer.Images}/img/{ownerProfile.profileImage}", roomName);
|
||||
}
|
||||
}
|
||||
|
||||
return new ImageNameDTO { ImageName = imageName };
|
||||
}
|
||||
|
||||
[HttpDelete("v1/deletesaved"), Authorize]
|
||||
[HttpPost("v1/deletesaved"), Authorize]
|
||||
public async Task<IActionResult> DeleteSavedImage()
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
string? imageName = null;
|
||||
|
||||
if (Request.HasFormContentType)
|
||||
{
|
||||
var form = await Request.ReadFormAsync();
|
||||
imageName = form["ImageName"].ToString();
|
||||
if (string.IsNullOrWhiteSpace(imageName))
|
||||
imageName = form["imageName"].ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
using var doc = await System.Text.Json.JsonDocument.ParseAsync(Request.Body);
|
||||
if (doc.RootElement.ValueKind == System.Text.Json.JsonValueKind.Object &&
|
||||
doc.RootElement.TryGetProperty("ImageName", out var prop) &&
|
||||
prop.ValueKind == System.Text.Json.JsonValueKind.String)
|
||||
imageName = prop.GetString();
|
||||
}
|
||||
catch (System.Text.Json.JsonException) { }
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(imageName))
|
||||
return BadRequest(new { error = "ImageName is required" });
|
||||
|
||||
var image = await db.Images.FirstOrDefaultAsync(x => x.Name == imageName);
|
||||
if (image == null)
|
||||
return NotFound();
|
||||
if (image.OwnerId != userId)
|
||||
return StatusCode(403, new { error = "Not your image" });
|
||||
|
||||
var cheers = db.ImageInteractions.Where(x => x.SavedImageId == image.Id);
|
||||
db.ImageInteractions.RemoveRange(cheers);
|
||||
db.Images.Remove(image);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var fullPath = Path.Join(DBConfig.CDNImages, imageName);
|
||||
if (System.IO.File.Exists(fullPath))
|
||||
System.IO.File.Delete(fullPath);
|
||||
|
||||
return Ok(new { success = true });
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user