Huge API rewrite
This commit is contained in:
parent
a37fe30b6f
commit
038d363b00
@ -20,7 +20,7 @@ namespace YTManager.Controllers {
|
|||||||
Title = c.Title;
|
Title = c.Title;
|
||||||
Description = c.Description;
|
Description = c.Description;
|
||||||
ID = c.YoutubeID;
|
ID = c.YoutubeID;
|
||||||
Video_IDs = c.Videos?.Select(v => v.YoutubeID).ToList();
|
Video_IDs = c.Videos.Select(v => v.YoutubeID).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +38,7 @@ namespace YTManager.Controllers {
|
|||||||
public async Task<IActionResult> Get() {
|
public async Task<IActionResult> Get() {
|
||||||
// Get all the relevant channels.
|
// Get all the relevant channels.
|
||||||
var chanels = await db.Channels
|
var chanels = await db.Channels
|
||||||
|
.Include(c => c.Videos)
|
||||||
.OrderByDescending(i => i.AddedtoDB)
|
.OrderByDescending(i => i.AddedtoDB)
|
||||||
.Take(max_per_query)
|
.Take(max_per_query)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
141
YTManager/Controllers/Raw/Private_Channel.cs
Normal file
141
YTManager/Controllers/Raw/Private_Channel.cs
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
namespace YTManager.Controllers.Private
|
||||||
|
{
|
||||||
|
[Produces("application/json")]
|
||||||
|
[Route("api_raw/Channels")]
|
||||||
|
public class Private_Channel : Controller
|
||||||
|
{
|
||||||
|
private readonly MediaDB db;
|
||||||
|
|
||||||
|
public Private_Channel(MediaDB context)
|
||||||
|
{
|
||||||
|
db = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IEnumerable<Channel> GetChannels()
|
||||||
|
{
|
||||||
|
return db.Channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public async Task<IActionResult> GetChannel([FromRoute] long id)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel = await db
|
||||||
|
.Channels
|
||||||
|
.Include(c => c.Videos)
|
||||||
|
.SingleOrDefaultAsync(m => m.PrimaryKey == id);
|
||||||
|
|
||||||
|
if (channel == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{id}")]
|
||||||
|
public async Task<IActionResult> PutChannel([FromRoute] long id, [FromBody] Channel channel)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id != channel.PrimaryKey)
|
||||||
|
{
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Entry(channel).State = EntityState.Modified;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch (DbUpdateConcurrencyException)
|
||||||
|
{
|
||||||
|
if (!ChannelExists(id))
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{channelid}")]
|
||||||
|
public async Task<IActionResult> PostChannel([FromRoute] string channelid) {
|
||||||
|
// Only add it to the databse if it's not in there already.
|
||||||
|
if (db.Channels.Any(c => c.YoutubeID == channelid))
|
||||||
|
return BadRequest();
|
||||||
|
|
||||||
|
// Get the channel contents from youtube.
|
||||||
|
var channel = await Tasks.FetchVideos.Get_YTChannel(channelid);
|
||||||
|
|
||||||
|
// Add it to the databse.
|
||||||
|
await db.Channels.AddAsync(channel);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
// Say all went ok.
|
||||||
|
return Ok(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> PostChannel([FromBody] Channel channel)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Channels.Add(channel);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
return CreatedAtAction("GetChannel", new { id = channel.PrimaryKey }, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
public async Task<IActionResult> DeleteChannel([FromRoute] long id)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel = await db.Channels.SingleOrDefaultAsync(m => m.PrimaryKey == id);
|
||||||
|
if (channel == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Channels.Remove(channel);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
return Ok(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ChannelExists(long id)
|
||||||
|
{
|
||||||
|
return db.Channels.Any(e => e.PrimaryKey == id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
129
YTManager/Controllers/Raw/Private_Video.cs
Normal file
129
YTManager/Controllers/Raw/Private_Video.cs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
namespace YTManager.Controllers
|
||||||
|
{
|
||||||
|
[Produces("application/json")]
|
||||||
|
[Route("api_raw/Videos")]
|
||||||
|
public class Private_Videos : Controller
|
||||||
|
{
|
||||||
|
private readonly MediaDB _context;
|
||||||
|
|
||||||
|
public Private_Videos(MediaDB context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/Videos
|
||||||
|
[HttpGet]
|
||||||
|
public IEnumerable<Video> GetVideos()
|
||||||
|
{
|
||||||
|
return _context.Videos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/Videos/5
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public async Task<IActionResult> GetVideo([FromRoute] long id)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
var video = await _context
|
||||||
|
.Videos
|
||||||
|
.Include(v => v.Channel)
|
||||||
|
.SingleOrDefaultAsync(m => m.PrimaryKey == id);
|
||||||
|
|
||||||
|
if (video == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(video);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT: api/Videos/5
|
||||||
|
[HttpPut("{id}")]
|
||||||
|
public async Task<IActionResult> PutVideo([FromRoute] long id, [FromBody] Video video)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id != video.PrimaryKey)
|
||||||
|
{
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.Entry(video).State = EntityState.Modified;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch (DbUpdateConcurrencyException)
|
||||||
|
{
|
||||||
|
if (!VideoExists(id))
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/Videos
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> PostVideo([FromBody] Video video)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.Videos.Add(video);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
return CreatedAtAction("GetVideo", new { id = video.PrimaryKey }, video);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: api/Videos/5
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
public async Task<IActionResult> DeleteVideo([FromRoute] long id)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
var video = await _context.Videos.SingleOrDefaultAsync(m => m.PrimaryKey == id);
|
||||||
|
if (video == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.Videos.Remove(video);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
return Ok(video);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool VideoExists(long id)
|
||||||
|
{
|
||||||
|
return _context.Videos.Any(e => e.PrimaryKey == id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,7 @@ namespace YTManager.Controllers {
|
|||||||
// Thumbnail URL.
|
// Thumbnail URL.
|
||||||
public string Thumbnail;
|
public string Thumbnail;
|
||||||
|
|
||||||
// Channel youtube ID.
|
// Channel on youtube that owns this video
|
||||||
public string Channel;
|
public string Channel;
|
||||||
|
|
||||||
// Populate this struct using a model video.
|
// Populate this struct using a model video.
|
||||||
@ -31,7 +31,7 @@ namespace YTManager.Controllers {
|
|||||||
Description = video.Description;
|
Description = video.Description;
|
||||||
ID = video.YoutubeID;
|
ID = video.YoutubeID;
|
||||||
Thumbnail = video.ThumbnailURL;
|
Thumbnail = video.ThumbnailURL;
|
||||||
Channel = video.channel?.YoutubeID;
|
Channel = video.Channel.Title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +49,7 @@ namespace YTManager.Controllers {
|
|||||||
public async Task<IActionResult> GetVideos() {
|
public async Task<IActionResult> GetVideos() {
|
||||||
// Get all the relevant videos.
|
// Get all the relevant videos.
|
||||||
var vids = await db.Videos
|
var vids = await db.Videos
|
||||||
|
.Include(v => v.Channel)
|
||||||
.OrderByDescending(i => i.AddedtoDB)
|
.OrderByDescending(i => i.AddedtoDB)
|
||||||
.Take(max_per_query)
|
.Take(max_per_query)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
@ -63,12 +64,12 @@ namespace YTManager.Controllers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the most recent videos of a channel.
|
// Returns the most recent videos of a channel.
|
||||||
[HttpGet("fromchannel/{channelID}")]
|
[HttpGet("fromchannel/{channelName}")]
|
||||||
public async Task<IActionResult> Get_Channel_Videos([FromRoute] string channelID) {
|
public async Task<IActionResult> Get_Channel_Videos([FromRoute] string channelName) {
|
||||||
// Get all the relevant videos.
|
// Get all the relevant videos.
|
||||||
var vids = await db.Videos
|
var vids = await db.Videos
|
||||||
.Include(v => v.channel)
|
.Include(v => v.Channel)
|
||||||
.Where(v => v.channel.YoutubeID == channelID)
|
.Where(v => v.Channel.Title == channelName)
|
||||||
.OrderByDescending(i => i.AddedtoDB)
|
.OrderByDescending(i => i.AddedtoDB)
|
||||||
.Take(max_per_query)
|
.Take(max_per_query)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace YTManager.Migrations
|
|
||||||
{
|
|
||||||
public partial class added_refreshed : Migration
|
|
||||||
{
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<DateTime>(
|
|
||||||
name: "Refreshed",
|
|
||||||
table: "Channels",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "Refreshed",
|
|
||||||
table: "Channels");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,8 +11,8 @@ using YTManager;
|
|||||||
namespace YTManager.Migrations
|
namespace YTManager.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(MediaDB))]
|
[DbContext(typeof(MediaDB))]
|
||||||
[Migration("20180220053952_added_refreshed")]
|
[Migration("20180224051602_initial")]
|
||||||
partial class added_refreshed
|
partial class initial
|
||||||
{
|
{
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace YTManager.Migrations
|
namespace YTManager.Migrations
|
||||||
{
|
{
|
||||||
public partial class initiailmigration : Migration
|
public partial class initial : Migration
|
||||||
{
|
{
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
@ -17,6 +17,7 @@ namespace YTManager.Migrations
|
|||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
|
||||||
AddedtoDB = table.Column<DateTime>(nullable: false),
|
AddedtoDB = table.Column<DateTime>(nullable: false),
|
||||||
Description = table.Column<string>(nullable: false),
|
Description = table.Column<string>(nullable: false),
|
||||||
|
Refreshed = table.Column<DateTime>(nullable: false),
|
||||||
ThumbnailURL = table.Column<string>(nullable: false),
|
ThumbnailURL = table.Column<string>(nullable: false),
|
||||||
Title = table.Column<string>(nullable: false),
|
Title = table.Column<string>(nullable: false),
|
||||||
YoutubeID = table.Column<string>(nullable: false)
|
YoutubeID = table.Column<string>(nullable: false)
|
@ -11,8 +11,8 @@ using YTManager;
|
|||||||
namespace YTManager.Migrations
|
namespace YTManager.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(MediaDB))]
|
[DbContext(typeof(MediaDB))]
|
||||||
[Migration("20180220032847_initiailmigration")]
|
[Migration("20180224055707_fix_channel_relationship")]
|
||||||
partial class initiailmigration
|
partial class fix_channel_relationship
|
||||||
{
|
{
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
@ -31,6 +31,8 @@ namespace YTManager.Migrations
|
|||||||
b.Property<string>("Description")
|
b.Property<string>("Description")
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<DateTime>("Refreshed");
|
||||||
|
|
||||||
b.Property<string>("ThumbnailURL")
|
b.Property<string>("ThumbnailURL")
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
@ -53,8 +55,12 @@ namespace YTManager.Migrations
|
|||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<long?>("VideoPrimaryKey");
|
||||||
|
|
||||||
b.HasKey("PrimaryKey");
|
b.HasKey("PrimaryKey");
|
||||||
|
|
||||||
|
b.HasIndex("VideoPrimaryKey");
|
||||||
|
|
||||||
b.ToTable("Tags");
|
b.ToTable("Tags");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -67,7 +73,7 @@ namespace YTManager.Migrations
|
|||||||
|
|
||||||
b.Property<DateTime>("AddedtoDB");
|
b.Property<DateTime>("AddedtoDB");
|
||||||
|
|
||||||
b.Property<long?>("ChannelPrimaryKey");
|
b.Property<long>("ChannelPrimaryKey");
|
||||||
|
|
||||||
b.Property<string>("Description")
|
b.Property<string>("Description")
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
@ -88,11 +94,19 @@ namespace YTManager.Migrations
|
|||||||
b.ToTable("Videos");
|
b.ToTable("Videos");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YTManager.Models.Tag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("YTManager.Models.Video")
|
||||||
|
.WithMany("Tags")
|
||||||
|
.HasForeignKey("VideoPrimaryKey");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("YTManager.Models.Video", b =>
|
modelBuilder.Entity("YTManager.Models.Video", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("YTManager.Models.Channel")
|
b.HasOne("YTManager.Models.Channel", "Channel")
|
||||||
.WithMany("Videos")
|
.WithMany("Videos")
|
||||||
.HasForeignKey("ChannelPrimaryKey");
|
.HasForeignKey("ChannelPrimaryKey")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
});
|
});
|
||||||
#pragma warning restore 612, 618
|
#pragma warning restore 612, 618
|
||||||
}
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YTManager.Migrations
|
||||||
|
{
|
||||||
|
public partial class fix_channel_relationship : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_Videos_Channels_ChannelPrimaryKey",
|
||||||
|
table: "Videos");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<long>(
|
||||||
|
name: "ChannelPrimaryKey",
|
||||||
|
table: "Videos",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(long),
|
||||||
|
oldNullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<long>(
|
||||||
|
name: "VideoPrimaryKey",
|
||||||
|
table: "Tags",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Tags_VideoPrimaryKey",
|
||||||
|
table: "Tags",
|
||||||
|
column: "VideoPrimaryKey");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_Tags_Videos_VideoPrimaryKey",
|
||||||
|
table: "Tags",
|
||||||
|
column: "VideoPrimaryKey",
|
||||||
|
principalTable: "Videos",
|
||||||
|
principalColumn: "PrimaryKey",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_Videos_Channels_ChannelPrimaryKey",
|
||||||
|
table: "Videos",
|
||||||
|
column: "ChannelPrimaryKey",
|
||||||
|
principalTable: "Channels",
|
||||||
|
principalColumn: "PrimaryKey",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_Tags_Videos_VideoPrimaryKey",
|
||||||
|
table: "Tags");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_Videos_Channels_ChannelPrimaryKey",
|
||||||
|
table: "Videos");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_Tags_VideoPrimaryKey",
|
||||||
|
table: "Tags");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "VideoPrimaryKey",
|
||||||
|
table: "Tags");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<long>(
|
||||||
|
name: "ChannelPrimaryKey",
|
||||||
|
table: "Videos",
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(long));
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_Videos_Channels_ChannelPrimaryKey",
|
||||||
|
table: "Videos",
|
||||||
|
column: "ChannelPrimaryKey",
|
||||||
|
principalTable: "Channels",
|
||||||
|
principalColumn: "PrimaryKey",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -54,8 +54,12 @@ namespace YTManager.Migrations
|
|||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<long?>("VideoPrimaryKey");
|
||||||
|
|
||||||
b.HasKey("PrimaryKey");
|
b.HasKey("PrimaryKey");
|
||||||
|
|
||||||
|
b.HasIndex("VideoPrimaryKey");
|
||||||
|
|
||||||
b.ToTable("Tags");
|
b.ToTable("Tags");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -68,7 +72,7 @@ namespace YTManager.Migrations
|
|||||||
|
|
||||||
b.Property<DateTime>("AddedtoDB");
|
b.Property<DateTime>("AddedtoDB");
|
||||||
|
|
||||||
b.Property<long?>("ChannelPrimaryKey");
|
b.Property<long>("ChannelPrimaryKey");
|
||||||
|
|
||||||
b.Property<string>("Description")
|
b.Property<string>("Description")
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
@ -89,11 +93,19 @@ namespace YTManager.Migrations
|
|||||||
b.ToTable("Videos");
|
b.ToTable("Videos");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YTManager.Models.Tag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("YTManager.Models.Video")
|
||||||
|
.WithMany("Tags")
|
||||||
|
.HasForeignKey("VideoPrimaryKey");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("YTManager.Models.Video", b =>
|
modelBuilder.Entity("YTManager.Models.Video", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("YTManager.Models.Channel")
|
b.HasOne("YTManager.Models.Channel", "Channel")
|
||||||
.WithMany("Videos")
|
.WithMany("Videos")
|
||||||
.HasForeignKey("ChannelPrimaryKey");
|
.HasForeignKey("ChannelPrimaryKey")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
});
|
});
|
||||||
#pragma warning restore 612, 618
|
#pragma warning restore 612, 618
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,10 @@ namespace YTManager.Models {
|
|||||||
|
|
||||||
// What channel this video comes from.
|
// What channel this video comes from.
|
||||||
[Required]
|
[Required]
|
||||||
public Channel channel;
|
public Channel Channel { get; set; }
|
||||||
|
|
||||||
// Tag this video applies to.
|
// Tag this video applies to.
|
||||||
[Required]
|
[Required]
|
||||||
public List<Tag> Tags;
|
public List<Tag> Tags { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,8 @@ namespace YTManager.Tasks {
|
|||||||
ThumbnailURL = response.Items.First().Snippet.Thumbnails.Medium.Url,
|
ThumbnailURL = response.Items.First().Snippet.Thumbnails.Medium.Url,
|
||||||
YoutubeID = channelID,
|
YoutubeID = channelID,
|
||||||
AddedtoDB = DateTime.Now,
|
AddedtoDB = DateTime.Now,
|
||||||
Refreshed = DateTime.MinValue
|
Refreshed = DateTime.MinValue,
|
||||||
|
Videos = null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ namespace YTManager.Tasks {
|
|||||||
ops.UseNpgsql(dbstr);
|
ops.UseNpgsql(dbstr);
|
||||||
|
|
||||||
// Get all the channels from the db that expired.
|
// Get all the channels from the db that expired.
|
||||||
var threshold = DateTime.Now.Subtract(TimeSpan.FromSeconds(100));
|
var threshold = DateTime.Now.Subtract(TimeSpan.FromMinutes(60));
|
||||||
var channel_ids = await
|
var channel_ids = await
|
||||||
(new MediaDB(ops.Options)).Channels
|
(new MediaDB(ops.Options)).Channels
|
||||||
.Where(ch => ch.Refreshed < threshold)
|
.Where(ch => ch.Refreshed < threshold)
|
||||||
@ -104,7 +105,7 @@ namespace YTManager.Tasks {
|
|||||||
|
|
||||||
// Say what channel all the videos came from.
|
// Say what channel all the videos came from.
|
||||||
foreach (var v in newvids)
|
foreach (var v in newvids)
|
||||||
v.channel = channel;
|
v.Channel = channel;
|
||||||
|
|
||||||
// Say the channel has been refreshed.
|
// Say the channel has been refreshed.
|
||||||
channel.Refreshed = DateTime.Now;
|
channel.Refreshed = DateTime.Now;
|
||||||
|
64
YTManager/wwwroot/Admin/index.css
Normal file
64
YTManager/wwwroot/Admin/index.css
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
body {
|
||||||
|
margin-left: 5%;
|
||||||
|
margin-right: 5%;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #003636;
|
||||||
|
background-color: #F8F8F8;
|
||||||
|
max-width: 1280px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pageheader {
|
||||||
|
max-width: 960px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.curvedbottom {
|
||||||
|
border-bottom-left-radius: 10px;
|
||||||
|
border-bottom-right-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#addnewchannelform {
|
||||||
|
width: inherit;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tinytext10px{ font-size: 10px; }
|
||||||
|
.tinytext12px{ font-size: 12px; }
|
||||||
|
.tinytext14px{ font-size: 14px; }
|
||||||
|
.tinytext16px{ font-size: 16px; }
|
||||||
|
.tinytext18px{ font-size: 18px; }
|
||||||
|
|
||||||
|
[v-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-active, .fade-leave-active {
|
||||||
|
transition: opacity 0.75s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter, .fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apistatusicon {
|
||||||
|
animation-duration: 1s;
|
||||||
|
animation-name: spinny;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spinny {
|
||||||
|
from {
|
||||||
|
transform: rotate(-15deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: rotate(15deg);
|
||||||
|
}
|
||||||
|
}
|
@ -39,6 +39,6 @@
|
|||||||
<script src="https://unpkg.com/vue"></script>
|
<script src="https://unpkg.com/vue"></script>
|
||||||
|
|
||||||
<!-- All of my custom JS. Put here so body loads before Vue based stuff loads/attempts to bind. -->
|
<!-- All of my custom JS. Put here so body loads before Vue based stuff loads/attempts to bind. -->
|
||||||
<script src="admin.js"></script>
|
<script src="index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -59,7 +59,7 @@ var addchanel0 = new Vue({
|
|||||||
submit: function (event) {
|
submit: function (event) {
|
||||||
// Send the channel to our API and request tables be updated.
|
// Send the channel to our API and request tables be updated.
|
||||||
var d = this.entry;
|
var d = this.entry;
|
||||||
axios.post('/api/Channels/' + this.entry.yTChannelID)
|
axios.post('/api_raw/Channels/' + this.entry.yTChannelID)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
this.entry.title = "";
|
this.entry.title = "";
|
||||||
this.entry.description = "";
|
this.entry.description = "";
|
||||||
@ -229,9 +229,9 @@ var videostb = new Vue({
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-cloak v-for="video in Videos">
|
<tr v-cloak v-for="video in Videos">
|
||||||
|
<td class="tinytext12px">{{video.id}}</td>
|
||||||
<td class="tinytext12px">{{video.title}}</td>
|
<td class="tinytext12px">{{video.title}}</td>
|
||||||
<td class="tinytext12px">{{video.description}}</td>
|
<td class="tinytext12px">{{video.description}}</td>
|
||||||
<td class="tinytext12px">{{video.id}}</td>
|
|
||||||
<td class="tinytext12px">{{video.channel}}</td>
|
<td class="tinytext12px">{{video.channel}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
@ -14,20 +14,11 @@
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
|
||||||
background-color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.curvedbottom {
|
.curvedbottom {
|
||||||
border-bottom-left-radius: 10px;
|
border-bottom-left-radius: 10px;
|
||||||
border-bottom-right-radius: 10px;
|
border-bottom-right-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#addnewchannelform {
|
|
||||||
width: inherit;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tinytext10px{ font-size: 10px; }
|
.tinytext10px{ font-size: 10px; }
|
||||||
.tinytext12px{ font-size: 12px; }
|
.tinytext12px{ font-size: 12px; }
|
||||||
.tinytext14px{ font-size: 14px; }
|
.tinytext14px{ font-size: 14px; }
|
||||||
@ -45,20 +36,3 @@
|
|||||||
.fade-enter, .fade-leave-to {
|
.fade-enter, .fade-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.apistatusicon {
|
|
||||||
animation-duration: 1s;
|
|
||||||
animation-name: spinny;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
animation-direction: alternate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spinny {
|
|
||||||
from {
|
|
||||||
transform: rotate(-15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user