using API.APIEndpointRecords; using API.Schema.MangaContext; using API.Workers; using Asp.Versioning; using log4net; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; using static Microsoft.AspNetCore.Http.StatusCodes; // ReSharper disable InconsistentNaming namespace API.Controllers; [ApiVersion(2)] [ApiController] [Route("v{version:apiVersion}/[controller]")] public class WorkerController(ILog Log) : Controller { /// /// Returns all /// /// [HttpGet] [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetAllWorkers() { return Ok(Tranga.Workers.ToArray()); } /// /// Returns with requested /// /// Array of .Key /// [HttpPost("WithIDs")] [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetJobs([FromBody]string[] WorkerIds) { return Ok(Tranga.Workers.Where(worker => WorkerIds.Contains(worker.Key)).ToArray()); } /// /// Get all in requested /// /// Requested /// [HttpGet("State/{State}")] [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetJobsInState(WorkerExecutionState State) { return Ok(Tranga.Workers.Where(worker => worker.State == State).ToArray()); } /// /// Return with /// /// .Key /// /// with could not be found [HttpGet("{WorkerId}")] [ProducesResponseType(Status200OK, "application/json")] [ProducesResponseType(Status404NotFound)] public IActionResult GetJob(string WorkerId) { if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); return Ok(worker); } /// /// Delete with and all child-s /// /// .Key /// /// with could not be found [HttpDelete("{WorkerId}")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] public IActionResult DeleteJob(string WorkerId) { if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); Tranga.RemoveWorker(worker); return Ok(); } /// /// Modify Job with ID /// /// Job-ID /// Fields to modify, set to null to keep previous value /// Job modified /// Malformed request /// Job with ID not found /// Error during Database Operation [HttpPatch("{JobId}")] [ProducesResponseType(Status202Accepted, "application/json")] [ProducesResponseType(Status400BadRequest)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status500InternalServerError, "text/plain")] public IActionResult ModifyJob(string JobId, [FromBody]ModifyJobRecord modifyJobRecord) { try { Job? ret = context.Jobs.Find(JobId); if(ret is null) return NotFound(); ret.RecurrenceMs = modifyJobRecord.RecurrenceMs ?? ret.RecurrenceMs; ret.Enabled = modifyJobRecord.Enabled ?? ret.Enabled; context.SaveChanges(); return new AcceptedResult(ret.Key, ret); } catch (Exception e) { Log.Error(e); return StatusCode(500, e.Message); } } /// /// Starts the Job with the requested ID /// /// Job-ID /// Start Jobs necessary for execution /// Job started /// Job with ID not found /// Job was already running /// Error during Database Operation [HttpPost("{JobId}/Start")] [ProducesResponseType(Status202Accepted)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status409Conflict)] [ProducesResponseType(Status500InternalServerError, "text/plain")] public IActionResult StartJob(string JobId, [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)]bool startDependencies = false) { Job? ret = context.Jobs.Find(JobId); if (ret is null) return NotFound(); List dependencies = startDependencies ? ret.GetDependenciesAndSelf() : [ret]; try { if(dependencies.Any(d => d.state >= JobState.Running && d.state < JobState.Completed)) return new ConflictResult(); dependencies.ForEach(d => { d.LastExecution = DateTime.UnixEpoch; d.state = JobState.CompletedWaiting; }); context.SaveChanges(); return Accepted(); } catch (Exception e) { Log.Error(e); return StatusCode(500, e.Message); } } /// /// Stops the Job with the requested ID /// /// Job-ID ///

NOT IMPLEMENTED

[HttpPost("{JobId}/Stop")] [ProducesResponseType(Status501NotImplemented)] public IActionResult StopJob(string JobId) { return StatusCode(Status501NotImplemented); } /// /// Removes failed and completed Jobs (that are not recurring) /// /// Job started /// Error during Database Operation [HttpPost("Cleanup")] public IActionResult CleanupJobs() { try { context.Jobs.RemoveRange(context.Jobs.Where(j => j.state == JobState.Failed || j.state == JobState.Completed)); context.SaveChanges(); return Ok(); } catch (Exception e) { Log.Error(e); return StatusCode(500, e.Message); } } }