From 28de8f1279e70aeae2ff501c8e27ab0768d8ad95 Mon Sep 17 00:00:00 2001 From: hak8or Date: Sun, 3 Sep 2017 03:00:16 -0400 Subject: [PATCH] Added API for managing job of updating videos --- YTManager/Controllers/AdminController.cs | 48 +++++++++++++++++++++++ YTManager/Controllers/ValuesController.cs | 15 +++---- YTManager/Startup.cs | 17 ++++---- YTManager/Tasks/FetchVideos.cs | 11 ++++-- YTManager/wwwroot/admin.html | 2 + YTManager/wwwroot/admin.js | 48 ++++++++++++++++++++++- YTManager/wwwroot/index.css | 17 ++++++++ 7 files changed, 133 insertions(+), 25 deletions(-) create mode 100644 YTManager/Controllers/AdminController.cs diff --git a/YTManager/Controllers/AdminController.cs b/YTManager/Controllers/AdminController.cs new file mode 100644 index 0000000..3c7faa5 --- /dev/null +++ b/YTManager/Controllers/AdminController.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using YTManager; +using YTManager.Models; +using Hangfire.Storage; + +namespace YTManager.Controllers { + [Produces("application/json")] + [Route("api/Admin")] + public class AdminController : Controller { + // POST api/Admin/refreshytvids + // Force a general youtube channel update. + [HttpPost("job_update")] + public void Post_forcejobupdate() { + Hangfire.RecurringJob.Trigger(Startup.periodicupdatejobID); + } + + // POST api/Admin/job_periodicupdate/YTChannelID + // Force a YT Channel update. + [HttpPost("job_update/{id}")] + public void Post_forcejobupdateID([FromRoute] string id) { + Hangfire.BackgroundJob.Enqueue(() => YTManager.Tasks.FetchVideos.run(id)); + } + + // POST api/Admin/job_periodicupdate + // Ensures that the background YT Channel update API is running. + [HttpPost("job_periodicupdate")] + public void Post_periodicupdatejob() { + Hangfire.RecurringJob.AddOrUpdate( + Startup.periodicupdatejobID, + () => YTManager.Tasks.FetchVideos.run(""), + Hangfire.Cron.Hourly); + } + + // GET api/Admin/job_periodicupdate + // Check if the periodic update job is enqued. + [HttpGet("job_periodicupdate")] + public IActionResult Get_periodicupdatejob() { + bool exists = Hangfire.JobStorage.Current.GetConnection().GetRecurringJobs().Count(j => j.Id == Startup.periodicupdatejobID) > 0; + return Ok(exists ? "true" : "false"); + } + } +} diff --git a/YTManager/Controllers/ValuesController.cs b/YTManager/Controllers/ValuesController.cs index 2db8751..7bf69c7 100644 --- a/YTManager/Controllers/ValuesController.cs +++ b/YTManager/Controllers/ValuesController.cs @@ -7,16 +7,6 @@ using Newtonsoft.Json.Linq; using Microsoft.EntityFrameworkCore; namespace YTManager.Controllers { - [Produces("application/json")] - [Route("api/Admin")] - public class AdminController : Controller { - // POST api/Admin/refreshytvids - [HttpPost("refreshytvids")] - public void Post() { - Hangfire.BackgroundJob.Enqueue(() => YTManager.Tasks.FetchVideos.run()); - } - } - [Produces("application/json")] [Route("api/Channels")] public class ChannelsController : Controller { @@ -71,6 +61,11 @@ namespace YTManager.Controllers { // Seems good, so add it. _context.Channels.Add(posted); _context.SaveChanges(); + + // Get all new videos for the channel. + Hangfire.RecurringJob.Trigger(Startup.periodicupdatejobID); + + // And all is well. return Ok(); } diff --git a/YTManager/Startup.cs b/YTManager/Startup.cs index e586554..e0e3b3a 100644 --- a/YTManager/Startup.cs +++ b/YTManager/Startup.cs @@ -13,10 +13,8 @@ using Hangfire.PostgreSql; using Microsoft.EntityFrameworkCore; namespace YTManager { - public class Startup - { - public Startup(IConfiguration configuration) - { + public class Startup { + public Startup(IConfiguration configuration) { Configuration = configuration; } @@ -25,21 +23,20 @@ namespace YTManager { // String used for connecting to the database server. public static string dbstr { get; } = "Host=192.168.1.130;Database=postgres;Username=postgres;Password=pass"; + // ID for periodic job to update all channels. + public static string periodicupdatejobID { get; } = "2013066213"; + // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { + public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddHangfire(x => x.UsePostgreSqlStorage(dbstr)); services.AddDbContext(options => options.UseNpgsql(dbstr)); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { + public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) - { app.UseDeveloperExceptionPage(); - } app.UseDefaultFiles(); app.UseStaticFiles(); diff --git a/YTManager/Tasks/FetchVideos.cs b/YTManager/Tasks/FetchVideos.cs index 5d90c0f..34ba357 100644 --- a/YTManager/Tasks/FetchVideos.cs +++ b/YTManager/Tasks/FetchVideos.cs @@ -9,7 +9,7 @@ namespace YTManager.Tasks { public class FetchVideos { - public static void run() + public static void run(string youtubechannelIDstr = "") { // YT API access key var youtubeService = new YouTubeService(new Google.Apis.Services.BaseClientService.Initializer() @@ -22,7 +22,12 @@ namespace YTManager.Tasks var ops = new DbContextOptionsBuilder(); ops.UseNpgsql(YTManager.Startup.dbstr); using (var dbcontext = new MediaDB(ops.Options)) { - var channels = dbcontext.Channels.ToList(); + // Get all the potential relevant channels. + List channels; + if (youtubechannelIDstr == "") + channels = dbcontext.Channels.ToList(); + else + channels = dbcontext.Channels.Where(c => c.YTChannelID == youtubechannelIDstr).ToList(); // Get all the most recent videos for each channel. channels.ForEach(ch => { @@ -35,7 +40,7 @@ namespace YTManager.Tasks // Get all videos which aren't already in the DB. var notindb = response.Items .Where(i => i.Id.Kind == "youtube#video") - .Where(i => !dbcontext.Videos.Any(dbvid => dbvid.YTVideoID != i.Id.VideoId)) + .Where(i => !dbcontext.Videos.Any(dbvid => dbvid.YTVideoID == i.Id.VideoId)) .Select(newvid => new Models.Video { Title = newvid.Snippet.Title, diff --git a/YTManager/wwwroot/admin.html b/YTManager/wwwroot/admin.html index 49863b2..a59774b 100644 --- a/YTManager/wwwroot/admin.html +++ b/YTManager/wwwroot/admin.html @@ -12,6 +12,8 @@
diff --git a/YTManager/wwwroot/admin.js b/YTManager/wwwroot/admin.js index 5d3d684..74265b2 100644 --- a/YTManager/wwwroot/admin.js +++ b/YTManager/wwwroot/admin.js @@ -67,8 +67,6 @@ var addchanel0 = new Vue({ this.entry.thumbnailURL = ""; this.expanded = false; tbody0.retrieve(); - - axios.post('/api/admin/refreshytvids'); setTimeout(() => videostb.retrieve(), 1000); }.bind(this)) .catch(function (error) { @@ -129,6 +127,7 @@ var tbody0 = new Vue({ Title Description ID + Update @@ -137,6 +136,7 @@ var tbody0 = new Vue({ {{entry.title}} {{entry.description}} {{entry.channelId}} +