diff options
Diffstat (limited to 'Controllers/ApiMediaController.cs')
| -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()); + } } |
