From f70850307269133148230dcaf4a49a59d107a5f2 Mon Sep 17 00:00:00 2001 From: hak8or Date: Fri, 23 Feb 2018 23:03:27 -0500 Subject: [PATCH] Beginings of api rework with channel inclusion --- YTManager/Controllers/Channels.cs | 40 ++++++++++++++-- YTManager/Controllers/Videos.cs | 76 +++++++++++++++++++++++++------ YTManager/Models/Video.cs | 4 ++ YTManager/Tasks/FetchVideos.cs | 7 ++- 4 files changed, 107 insertions(+), 20 deletions(-) diff --git a/YTManager/Controllers/Channels.cs b/YTManager/Controllers/Channels.cs index a7ccce5..a20c783 100644 --- a/YTManager/Controllers/Channels.cs +++ b/YTManager/Controllers/Channels.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -7,19 +8,50 @@ 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; - // GET api/Channels + // Returns the most recently added channels. [HttpGet] public async Task Get() { - return Ok(await db.Channels.OrderByDescending(c => c.AddedtoDB).ToListAsync()); + // 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/5 + // GET api/Channels/sdfs6DFS65f [HttpGet("{YTchannelID}")] public async Task Get([FromQuery] string YTchannelID) { var channel = await db.Channels.SingleOrDefaultAsync(c => c.YoutubeID == YTchannelID); diff --git a/YTManager/Controllers/Videos.cs b/YTManager/Controllers/Videos.cs index 5660003..24f622b 100644 --- a/YTManager/Controllers/Videos.cs +++ b/YTManager/Controllers/Videos.cs @@ -7,33 +7,79 @@ namespace YTManager.Controllers { [Produces("application/json")] [Route("api/Videos")] public class VideosController : Controller { + // Custom return type for API accesses. Done this way to ensure we + // always return the expected data regardless of the underlying model. + struct Video_ForAPI { + // Title of the video. + public string Title; + + // Description of the video. + public string Description; + + // Youtube ID of the video. + public string ID; + + // Thumbnail URL. + public string Thumbnail; + + // Channel youtube ID. + public string Channel; + + // Populate this struct using a model video. + public Video_ForAPI(Models.Video video) { + Title = video.Title; + Description = video.Description; + ID = video.YoutubeID; + Thumbnail = video.ThumbnailURL; + Channel = video.channel?.YoutubeID; + } + } + + // Maximum number of entries to return per query. + private readonly int max_per_query = 20; + // DB context used for all these calls. private readonly MediaDB db; // Constructor to fetch the db context. public VideosController(MediaDB context) => db = context; - // GET: api/Videos + // Returns the most recent videos. [HttpGet] public async Task GetVideos() { - return Ok(await db.Videos.OrderByDescending(i => i.AddedtoDB).ToListAsync()); + // Get all the relevant videos. + var vids = await db.Videos + .OrderByDescending(i => i.AddedtoDB) + .Take(max_per_query) + .ToListAsync(); + + // Convert them to what we will send out. + var converted = vids + .Select(v => new Video_ForAPI(v)) + .ToList(); + + // Convert all the videos to what we will send back. + return Ok(converted); } - // GET: api/Videos/5 - [HttpGet("{id}")] - public async Task GetVideo([FromRoute] long id){ - // Check if we were able to parse. - if (!ModelState.IsValid) return BadRequest(ModelState); + // Returns the most recent videos of a channel. + [HttpGet("fromchannel/{channelID}")] + public async Task Get_Channel_Videos([FromRoute] string channelID) { + // Get all the relevant videos. + var vids = await db.Videos + .Include(v => v.channel) + .Where(v => v.channel.YoutubeID == channelID) + .OrderByDescending(i => i.AddedtoDB) + .Take(max_per_query) + .ToListAsync(); - // Attempt to get the video from the database. - var video = await db.Videos.SingleOrDefaultAsync(m => m.PrimaryKey == id); + // Convert them to what we will send out. + var converted = vids + .Select(v => new Video_ForAPI(v)) + .ToList(); - // If the video wasn't found then send back not foud. - if (video == null) - return NotFound(); - - // Otherwise send back the video. - return Ok(video); + // Convert all the videos to what we will send back. + return Ok(converted); } } } \ No newline at end of file diff --git a/YTManager/Models/Video.cs b/YTManager/Models/Video.cs index e9be990..80e898b 100644 --- a/YTManager/Models/Video.cs +++ b/YTManager/Models/Video.cs @@ -32,6 +32,10 @@ namespace YTManager.Models { [Required] public DateTime AddedtoDB { get; set; } + // What channel this video comes from. + [Required] + public Channel channel; + // Tag this video applies to. [Required] public List Tags; diff --git a/YTManager/Tasks/FetchVideos.cs b/YTManager/Tasks/FetchVideos.cs index b22003a..8aec26f 100644 --- a/YTManager/Tasks/FetchVideos.cs +++ b/YTManager/Tasks/FetchVideos.cs @@ -99,7 +99,12 @@ namespace YTManager.Tasks { var Videos = await Get_YTVideos(channel.YoutubeID); // Get all the videos which haven't been put into this channels videos. - var newvids = Videos.Where(nv => !channel.Videos.Any(cv => cv.YoutubeID == nv.YoutubeID)); + var newvids = Videos + .Where(nv => !channel.Videos.Any(cv => cv.YoutubeID == nv.YoutubeID)); + + // Say what channel all the videos came from. + foreach (var v in newvids) + v.channel = channel; // Say the channel has been refreshed. channel.Refreshed = DateTime.Now;