using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace YTManager.Controllers { [Produces("application/json")] [Route("api/Channels")] public class ChannelsController : Controller { // Custom return type for API accesses. Done this way to ensure we // always return the expected data regardless of the underlying model. struct Channel_ForAPI { public string Title; public string Description; public string YTID; public List Video_IDs; public Channel_ForAPI(Models.Channel c) { Title = c.Title; Description = c.Description; YTID = c.YoutubeID; Video_IDs = c.Videos?.Select(v => v.YoutubeID).ToList(); } } // DB context used for all these calls. private readonly MediaDB db; // Maximum number of channels to return per query. private readonly int max_per_query = 20; // Constructor to fetch the db context. public ChannelsController(MediaDB context) => db = context; // Returns the most recently added channels. [HttpGet] public async Task Get() { // Get all the relevant channels. var chanels = await db.Channels .OrderByDescending(i => i.AddedtoDB) .Take(max_per_query) .ToListAsync(); // Convert them to what we will send out. var converted = chanels .Select(ch => new Channel_ForAPI(ch)) .ToList(); // Convert all the videos to what we will send back. return Ok(converted); } // GET api/Channels/sdfs6DFS65f [HttpGet("{YTchannelID}")] public async Task Get([FromQuery] string YTchannelID) { var channel = await db.Channels.SingleOrDefaultAsync(c => c.YoutubeID == YTchannelID); if (channel == null) return NotFound(); else return Ok(channel); } // GET: api/Channels/sdfs6DFS65f/Videos (using YouTube channel ID) [HttpGet("{YTChannelID}/Videos")] public async Task GetVideos([FromRoute] string YTchannelID) { if (!ModelState.IsValid) return BadRequest(ModelState); // Attempt to get the video from the database. var channel = await db.Channels.SingleOrDefaultAsync(m => m.YoutubeID == YTchannelID); // If the channel wasn't found then send back not found. if (channel == null) return NotFound(); // Send back the videos from the channel. return Ok(db.Entry(channel).Collection(c => c.Videos).LoadAsync()); } // POST api/Channels/sdfs6DFS65f [HttpPost("{YTchannelID}")] public async Task Post([FromRoute] string YTchannelID) { // Check if we were able to parse. if (!ModelState.IsValid) return BadRequest(ModelState); // Verify the channel doesn't already exist. if (db.Channels.Any(c => c.YoutubeID == YTchannelID)) return BadRequest(); // Get the channel info. var ch = await Tasks.FetchVideos.Get_YTChannel(YTchannelID); // Seems good, so add it. db.Channels.Add(ch); await db.SaveChangesAsync(); // And all is well. return Ok(); } // DELETE api/Channels/5 [HttpDelete("{YTChannelID}")] public async Task Delete([FromRoute] string YTChannelID) { // Check if we were able to parse. if (!ModelState.IsValid) return BadRequest(ModelState); // Attempt to find the channel. var channel = await db.Channels.Include(c => c.Videos).SingleOrDefaultAsync(c => c.YoutubeID == YTChannelID); // Check if such an entry exists already. if (channel == null) return NotFound(); // Remove all the channels videos. channel.Videos.ForEach(v => db.Videos.Remove(v)); // Remove the channel itself. db.Channels.Remove(channel); // Save all the changes. await db.SaveChangesAsync(); return Ok(channel); } } }