Added duration and tags to videos
This commit is contained in:
parent
e140cae317
commit
ccef5fee0c
@ -26,6 +26,12 @@ namespace YTManager.Controllers {
|
||||
// Channel on youtube that owns this video
|
||||
public string Channel;
|
||||
|
||||
// Duration of the video in seconds.
|
||||
public int Seconds;
|
||||
|
||||
// What tags are relevant with this video.
|
||||
public List<string> Tags;
|
||||
|
||||
// Populate this struct using a model video.
|
||||
public Video_ForAPI(Models.Video video) {
|
||||
Title = video.Title;
|
||||
@ -33,6 +39,8 @@ namespace YTManager.Controllers {
|
||||
ID = video.YoutubeID;
|
||||
Thumbnail = video.ThumbnailURL;
|
||||
Channel = video.Channel.Title;
|
||||
Seconds = (int)video.Duration.TotalSeconds;
|
||||
Tags = video.Tags?.Select(t => t.Name).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,9 +58,10 @@ namespace YTManager.Controllers {
|
||||
public async Task<IActionResult> GetVideos() {
|
||||
// Get all the relevant videos.
|
||||
var vids = await db.Videos
|
||||
.Include(v => v.Channel)
|
||||
.OrderByDescending(i => i.AddedToYT)
|
||||
.Take(max_per_query)
|
||||
.Include(v => v.Channel)
|
||||
.Include(v => v.Tags)
|
||||
.ToListAsync();
|
||||
|
||||
// Convert them to what we will send out.
|
||||
@ -69,10 +78,11 @@ namespace YTManager.Controllers {
|
||||
public async Task<IActionResult> Get_Channel_Videos([FromRoute] string channelName) {
|
||||
// Get all the relevant videos.
|
||||
var vids = await db.Videos
|
||||
.Include(v => v.Channel)
|
||||
.Where(v => v.Channel.Title == channelName)
|
||||
.OrderByDescending(i => i.AddedToYT)
|
||||
.Take(max_per_query)
|
||||
.Include(v => v.Channel)
|
||||
.Include(v => v.Tags)
|
||||
.ToListAsync();
|
||||
|
||||
// Convert them to what we will send out.
|
||||
|
116
YTManager/Migrations/20180228202611_added_vid_duration.Designer.cs
generated
Normal file
116
YTManager/Migrations/20180228202611_added_vid_duration.Designer.cs
generated
Normal file
@ -0,0 +1,116 @@
|
||||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
||||
using System;
|
||||
using YTManager;
|
||||
|
||||
namespace YTManager.Migrations
|
||||
{
|
||||
[DbContext(typeof(MediaDB))]
|
||||
[Migration("20180228202611_added_vid_duration")]
|
||||
partial class added_vid_duration
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
|
||||
.HasAnnotation("ProductVersion", "2.0.1-rtm-125");
|
||||
|
||||
modelBuilder.Entity("YTManager.Models.Channel", b =>
|
||||
{
|
||||
b.Property<long>("PrimaryKey")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("AddedtoDB");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<DateTime>("Refreshed");
|
||||
|
||||
b.Property<string>("ThumbnailURL")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("YoutubeID")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("PrimaryKey");
|
||||
|
||||
b.ToTable("Channels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("YTManager.Models.Tag", b =>
|
||||
{
|
||||
b.Property<long>("PrimaryKey")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("VideoPrimaryKey");
|
||||
|
||||
b.HasKey("PrimaryKey");
|
||||
|
||||
b.HasIndex("VideoPrimaryKey");
|
||||
|
||||
b.ToTable("Tags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("YTManager.Models.Video", b =>
|
||||
{
|
||||
b.Property<long>("PrimaryKey")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("AddedToYT");
|
||||
|
||||
b.Property<DateTime>("AddedtoDB");
|
||||
|
||||
b.Property<long>("ChannelPrimaryKey");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<TimeSpan>("Duration");
|
||||
|
||||
b.Property<string>("ThumbnailURL")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("YoutubeID")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("PrimaryKey");
|
||||
|
||||
b.HasIndex("ChannelPrimaryKey");
|
||||
|
||||
b.ToTable("Videos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("YTManager.Models.Tag", b =>
|
||||
{
|
||||
b.HasOne("YTManager.Models.Video")
|
||||
.WithMany("Tags")
|
||||
.HasForeignKey("VideoPrimaryKey");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("YTManager.Models.Video", b =>
|
||||
{
|
||||
b.HasOne("YTManager.Models.Channel", "Channel")
|
||||
.WithMany("Videos")
|
||||
.HasForeignKey("ChannelPrimaryKey")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
25
YTManager/Migrations/20180228202611_added_vid_duration.cs
Normal file
25
YTManager/Migrations/20180228202611_added_vid_duration.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YTManager.Migrations
|
||||
{
|
||||
public partial class added_vid_duration : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<TimeSpan>(
|
||||
name: "Duration",
|
||||
table: "Videos",
|
||||
nullable: false,
|
||||
defaultValue: "00:00:00");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Duration",
|
||||
table: "Videos");
|
||||
}
|
||||
}
|
||||
}
|
@ -77,6 +77,8 @@ namespace YTManager.Migrations
|
||||
b.Property<string>("Description")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<TimeSpan>("Duration");
|
||||
|
||||
b.Property<string>("ThumbnailURL")
|
||||
.IsRequired();
|
||||
|
||||
|
@ -32,6 +32,10 @@ namespace YTManager.Models {
|
||||
[Required]
|
||||
public DateTime AddedtoDB { get; set; }
|
||||
|
||||
// How long the video is
|
||||
[Required]
|
||||
public TimeSpan Duration { get; set; }
|
||||
|
||||
// What channel this video comes from.
|
||||
[Required]
|
||||
public Channel Channel { get; set; }
|
||||
|
@ -20,7 +20,7 @@
|
||||
"commandName": "Project",
|
||||
"launchUrl": "api/values",
|
||||
"environmentVariables": {
|
||||
"POSTGRESQL_DBSTR": "Server=192.168.1.211;Port=32768;Database=postgres;User Id=postgres;",
|
||||
"POSTGRESQL_DBSTR": "Server=192.168.1.2;Port=32768;Database=postgres;User Id=postgres;",
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:62214/"
|
||||
|
@ -8,7 +8,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
namespace YTManager.Tasks {
|
||||
public class FetchVideos {
|
||||
// Get a bunch of videos from youtube that the channel generated.
|
||||
private static async Task<List<Models.Video>> Get_YTVideos(string channelID) {
|
||||
public static async Task<List<Models.Video>> Get_YTVideos(string channelID, int max = 50) {
|
||||
// YT API access key
|
||||
var youtubeService = new YouTubeService(new Google.Apis.Services.BaseClientService.Initializer()
|
||||
{
|
||||
@ -16,15 +16,18 @@ namespace YTManager.Tasks {
|
||||
ApplicationName = "testingapppp"
|
||||
});
|
||||
|
||||
// Max cannot be larger than 50, so clamp it.
|
||||
max = max > 50 ? 50 : max;
|
||||
|
||||
// Search youtube for all the relevant data of the channel.
|
||||
var query = youtubeService.Search.List("snippet");
|
||||
query.ChannelId = channelID;
|
||||
query.Order = SearchResource.ListRequest.OrderEnum.Date;
|
||||
query.MaxResults = 50;
|
||||
var response = await query.ExecuteAsync();
|
||||
var videos_query = youtubeService.Search.List("snippet");
|
||||
videos_query.ChannelId = channelID;
|
||||
videos_query.Order = SearchResource.ListRequest.OrderEnum.Date;
|
||||
videos_query.MaxResults = max;
|
||||
var videos_response = await videos_query.ExecuteAsync();
|
||||
|
||||
// Convert the response into models.
|
||||
return response.Items?
|
||||
var videos = videos_response.Items?
|
||||
.Where(i => i.Id.Kind == "youtube#video")
|
||||
.Select(newvid => new Models.Video
|
||||
{
|
||||
@ -35,6 +38,28 @@ namespace YTManager.Tasks {
|
||||
AddedtoDB = DateTime.Now,
|
||||
ThumbnailURL = newvid.Snippet.Thumbnails.Medium.Url
|
||||
}).ToList();
|
||||
|
||||
// Search youtube to get the length and tags for each video.
|
||||
var duration_query = youtubeService.Videos.List("contentDetails,snippet");
|
||||
duration_query.Id = string.Join(',', videos.Select(v => v.YoutubeID));
|
||||
var duration_response = await duration_query.ExecuteAsync();
|
||||
|
||||
// Pair each video with the result.
|
||||
foreach(var contentdetail in duration_response.Items.Where(i => i.Kind == "youtube#video")){
|
||||
var vid = videos.Single(v => v.YoutubeID == contentdetail.Id);
|
||||
|
||||
// Yes, really, ISO8601 time span => c#'s TimeSpan is not in TimeSpan, it's in xmlconvert! Wtf?!
|
||||
vid.Duration = System.Xml.XmlConvert.ToTimeSpan(contentdetail.ContentDetails.Duration);
|
||||
|
||||
// Copy over all the created tags if any tags were provided.
|
||||
if (contentdetail.Snippet.Tags == null)
|
||||
vid.Tags = new List<Models.Tag>();
|
||||
else
|
||||
vid.Tags = contentdetail.Snippet.Tags.Select(t => new Models.Tag { Name = t }).ToList();
|
||||
}
|
||||
|
||||
// Send back the parsed vids.
|
||||
return videos;
|
||||
}
|
||||
|
||||
// Gets some info about a youtube channel.
|
||||
|
Loading…
Reference in New Issue
Block a user