diff options
| author | Jake Mannens <jake@asger.xyz> | 2026-05-09 02:54:42 +1000 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2026-05-09 02:54:42 +1000 |
| commit | a565ebb08901e9d1854f8bcfc669063ddea49bce (patch) | |
| tree | 5b190037a582db86b7bbcf9a669afffa615b2f02 /Controllers | |
| parent | a45ad8d3f8da273f80029ba6d34beb7e4ff7d7b5 (diff) | |
v0.15av0.15a
Diffstat (limited to 'Controllers')
| -rw-r--r-- | Controllers/ApiMediaController.cs | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/Controllers/ApiMediaController.cs b/Controllers/ApiMediaController.cs index a324f35..a1b07b1 100644 --- a/Controllers/ApiMediaController.cs +++ b/Controllers/ApiMediaController.cs @@ -97,4 +97,125 @@ public class ApiMediaController : Controller { [HttpDelete("{mediaId}")] public void Delete([FromRoute] Guid mediaId) => mediaService.Delete(mediaId); + + [HttpGet("{mediaId}/tags")] + public async Task<IActionResult> GetMediaTagsAsync([FromRoute] Guid mediaId) { + using var db = dbFactory.CreateDbContext(); + + var media = await db.Media + .Include(m => m.Tags) + .ThenInclude(t => t.TagDefinition) + .ThenInclude(td => td.ImplicitTags) + .FirstOrDefaultAsync(m => m.Guid == mediaId); + if(media is null) + return NotFound(); + + return Ok(media.Tags.Select(t => (ApiModels.TagDefinition) t.TagDefinition).ToArray()); + } + + [HttpPatch("{mediaId}/tags")] + public async Task<IActionResult> AddTagsToMediaAsync( + [FromRoute] Guid mediaId, + [FromBody] Guid[] tagIds) { + + using var db = dbFactory.CreateDbContext(); + using var transaction = await db.Database.BeginTransactionAsync(); + + var media = await db.Media + .Include(m => m.Tags) + .ThenInclude(t => t.TagDefinition) + .ThenInclude(td => td.ImplicitTags) + .FirstOrDefaultAsync(m => m.Guid == mediaId); + if(media is null) + return NotFound(); + + tagIds = tagIds.Distinct().ToArray(); + + var tags = await db.TagDefinitions + .Where(td => tagIds.Contains(td.Guid)) + .ToArrayAsync(); + + if(tags.Count() < tagIds.Count()) + return NotFound("Invalid tag IDs specified"); + + media.Tags.AddRange(tags + .Where(td => !media.Tags.Select(t => t.TagDefinition.Guid).Contains(td.Guid)) + .Select(td => new Tag() { TagDefinition = td })); + + await db.SaveChangesAsync(); + await transaction.CommitAsync(); + + return Ok(media.Tags.Select(t => (ApiModels.TagDefinition) t.TagDefinition).ToArray()); + } + + [HttpPut("{mediaId}/tags")] + public async Task<IActionResult> ReplaceMediaTagsAsync( + [FromRoute] Guid mediaId, + [FromBody] Guid[] tagIds) { + + using var db = dbFactory.CreateDbContext(); + using var transaction = await db.Database.BeginTransactionAsync(); + + var media = await db.Media + .Include(m => m.Tags) + .ThenInclude(t => t.TagDefinition) + .ThenInclude(td => td.ImplicitTags) + .FirstOrDefaultAsync(m => m.Guid == mediaId); + if(media is null) + return NotFound(); + + tagIds = tagIds.Distinct().Order().ToArray(); + var tags = await db.TagDefinitions + .Where(td => tagIds.Contains(td.Guid)) + .ToArrayAsync(); + + var missingTags = tagIds.Except(tags.Select(td => td.Guid)); + var missingTagsString = string.Join(", ", missingTags.Select(t => t.ToString())); + if(missingTags.Any()) + return BadRequest($"Invalid tag IDs specified: {missingTagsString}"); + + media.Tags.AddRange(tags + .Where(td => !media.Tags.Select(t => t.TagDefinition.Guid).Contains(td.Guid)) + .Select(td => new Tag() { TagDefinition = td })); + + db.Tags.RemoveRange( + media.Tags.Where(t => !tagIds.Contains(t.TagDefinition.Guid))); + + await db.SaveChangesAsync(); + await transaction.CommitAsync(); + + return Ok(media.Tags.Select(t => (ApiModels.TagDefinition) t.TagDefinition).ToArray()); + } + + [HttpPatch("{mediaId}/tags/delete")] + public async Task<IActionResult> DeleteTagsFromMediaAsync( + [FromRoute] Guid mediaId, + [FromBody] Guid[] tagIds) { + + using var db = dbFactory.CreateDbContext(); + using var transaction = await db.Database.BeginTransactionAsync(); + + var media = await db.Media + .Include(m => m.Tags) + .ThenInclude(t => t.TagDefinition) + .ThenInclude(td => td.ImplicitTags) + .FirstOrDefaultAsync(m => m.Guid == mediaId); + if(media is null) + return NotFound(); + + tagIds = tagIds.Distinct().Order().ToArray(); + + var missingTags = tagIds.Except(media.Tags.Select(t => t.TagDefinition.Guid)); + var missingTagsString = string.Join(", ", missingTags.Select(t => t.ToString())); + if(missingTags.Any()) + return BadRequest($"Media does not contain the following tags: {missingTagsString}"); + + db.Tags.RemoveRange( + media.Tags.Where(t => tagIds.Contains(t.TagDefinition.Guid))); + + await db.SaveChangesAsync(); + await transaction.CommitAsync(); + + return Ok(media.Tags.Select(t => (ApiModels.TagDefinition) t.TagDefinition).ToArray()); + } } |
