mirror of
https://github.com/fergalmoran/podnoms.git
synced 2025-12-22 09:18:08 +00:00
Mixcloud playlists working
This commit is contained in:
@@ -118,7 +118,8 @@ namespace PodNoms.Api.Controllers {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (status == AudioType.Playlist && YouTubeParser.ValidateUrl(item.SourceUrl)) {
|
} else if ((status == AudioType.Playlist && YouTubeParser.ValidateUrl(item.SourceUrl))
|
||||||
|
|| MixcloudParser.ValidateUrl(item.SourceUrl)) {
|
||||||
entry.ProcessingStatus = ProcessingStatus.Deferred;
|
entry.ProcessingStatus = ProcessingStatus.Deferred;
|
||||||
var result = _mapper.Map<PodcastEntry, PodcastEntryViewModel>(entry);
|
var result = _mapper.Map<PodcastEntry, PodcastEntryViewModel>(entry);
|
||||||
return Accepted(result);
|
return Accepted(result);
|
||||||
|
|||||||
512
server/Migrations/20180512180833_Initial.Designer.cs
generated
Normal file
512
server/Migrations/20180512180833_Initial.Designer.cs
generated
Normal file
@@ -0,0 +1,512 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PodNoms.Api.Persistence;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PodNomsDbContext))]
|
||||||
|
[Migration("20180512180833_Initial")]
|
||||||
|
partial class Initial
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.1.0-rc1-32029")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("RoleNameIndex")
|
||||||
|
.HasFilter("[NormalizedName] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ChatMessage", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("FromUserId");
|
||||||
|
|
||||||
|
b.Property<string>("Message");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("MessageSeen");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<string>("ToUserId");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("FromUserId");
|
||||||
|
|
||||||
|
b.HasIndex("ToUserId");
|
||||||
|
|
||||||
|
b.ToTable("ChatMessages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ParsedPlaylistItem", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<bool>("IsProcessed");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<int>("PlaylistId");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("VideoId");
|
||||||
|
|
||||||
|
b.Property<string>("VideoType");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlaylistId");
|
||||||
|
|
||||||
|
b.ToTable("ParsedPlaylistItems");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("Playlists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<string>("AppUserId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<string>("Slug");
|
||||||
|
|
||||||
|
b.Property<string>("TemporaryImageUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
|
b.ToTable("Podcasts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<long>("AudioFileSize");
|
||||||
|
|
||||||
|
b.Property<float>("AudioLength");
|
||||||
|
|
||||||
|
b.Property<string>("AudioUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Author");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<int?>("PlaylistId");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<bool>("Processed");
|
||||||
|
|
||||||
|
b.Property<string>("ProcessingPayload");
|
||||||
|
|
||||||
|
b.Property<int>("ProcessingStatus");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlaylistId");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("PodcastEntries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ServerConfig", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Key");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ServerConfig","admin");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Services.Auth.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed");
|
||||||
|
|
||||||
|
b.Property<long?>("FacebookId");
|
||||||
|
|
||||||
|
b.Property<string>("FirstName");
|
||||||
|
|
||||||
|
b.Property<string>("LastName");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed");
|
||||||
|
|
||||||
|
b.Property<string>("PictureUrl");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp");
|
||||||
|
|
||||||
|
b.Property<string>("Slug");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("UserNameIndex")
|
||||||
|
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ChatMessage", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser", "FromUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FromUserId");
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser", "ToUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ToUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ParsedPlaylistItem", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Playlist", "Playlist")
|
||||||
|
.WithMany("ParsedPlaylistItems")
|
||||||
|
.HasForeignKey("PlaylistId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser", "AppUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AppUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Playlist")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PlaylistId");
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
451
server/Migrations/20180512180833_Initial.cs
Normal file
451
server/Migrations/20180512180833_Initial.cs
Normal file
@@ -0,0 +1,451 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Migrations
|
||||||
|
{
|
||||||
|
public partial class Initial : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.EnsureSchema(
|
||||||
|
name: "admin");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetRoles",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(nullable: false),
|
||||||
|
Name = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
ConcurrencyStamp = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUsers",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(nullable: false),
|
||||||
|
UserName = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
Email = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
EmailConfirmed = table.Column<bool>(nullable: false),
|
||||||
|
PasswordHash = table.Column<string>(nullable: true),
|
||||||
|
SecurityStamp = table.Column<string>(nullable: true),
|
||||||
|
ConcurrencyStamp = table.Column<string>(nullable: true),
|
||||||
|
PhoneNumber = table.Column<string>(nullable: true),
|
||||||
|
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
|
||||||
|
TwoFactorEnabled = table.Column<bool>(nullable: false),
|
||||||
|
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
|
||||||
|
LockoutEnabled = table.Column<bool>(nullable: false),
|
||||||
|
AccessFailedCount = table.Column<int>(nullable: false),
|
||||||
|
FirstName = table.Column<string>(nullable: true),
|
||||||
|
LastName = table.Column<string>(nullable: true),
|
||||||
|
FacebookId = table.Column<long>(nullable: true),
|
||||||
|
PictureUrl = table.Column<string>(nullable: true),
|
||||||
|
Slug = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "ServerConfig",
|
||||||
|
schema: "admin",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||||
|
Uid = table.Column<string>(nullable: true),
|
||||||
|
NewId = table.Column<Guid>(nullable: false, defaultValueSql: "newsequentialid()"),
|
||||||
|
CreateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
UpdateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
Key = table.Column<string>(nullable: true),
|
||||||
|
Value = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_ServerConfig", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetRoleClaims",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||||
|
RoleId = table.Column<string>(nullable: false),
|
||||||
|
ClaimType = table.Column<string>(nullable: true),
|
||||||
|
ClaimValue = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
||||||
|
column: x => x.RoleId,
|
||||||
|
principalTable: "AspNetRoles",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserClaims",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||||
|
UserId = table.Column<string>(nullable: false),
|
||||||
|
ClaimType = table.Column<string>(nullable: true),
|
||||||
|
ClaimValue = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserLogins",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
LoginProvider = table.Column<string>(nullable: false),
|
||||||
|
ProviderKey = table.Column<string>(nullable: false),
|
||||||
|
ProviderDisplayName = table.Column<string>(nullable: true),
|
||||||
|
UserId = table.Column<string>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserRoles",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
UserId = table.Column<string>(nullable: false),
|
||||||
|
RoleId = table.Column<string>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
||||||
|
column: x => x.RoleId,
|
||||||
|
principalTable: "AspNetRoles",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserTokens",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
UserId = table.Column<string>(nullable: false),
|
||||||
|
LoginProvider = table.Column<string>(nullable: false),
|
||||||
|
Name = table.Column<string>(nullable: false),
|
||||||
|
Value = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "ChatMessages",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||||
|
Uid = table.Column<string>(nullable: true),
|
||||||
|
NewId = table.Column<Guid>(nullable: false, defaultValueSql: "newsequentialid()"),
|
||||||
|
CreateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
UpdateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
FromUserId = table.Column<string>(nullable: true),
|
||||||
|
ToUserId = table.Column<string>(nullable: true),
|
||||||
|
Message = table.Column<string>(nullable: true),
|
||||||
|
MessageSeen = table.Column<DateTime>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_ChatMessages", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_ChatMessages_AspNetUsers_FromUserId",
|
||||||
|
column: x => x.FromUserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_ChatMessages_AspNetUsers_ToUserId",
|
||||||
|
column: x => x.ToUserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Podcasts",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||||
|
Uid = table.Column<string>(nullable: true),
|
||||||
|
NewId = table.Column<Guid>(nullable: false, defaultValueSql: "newsequentialid()"),
|
||||||
|
CreateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
UpdateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
AppUserId = table.Column<string>(nullable: true),
|
||||||
|
Title = table.Column<string>(nullable: true),
|
||||||
|
Description = table.Column<string>(nullable: true),
|
||||||
|
Slug = table.Column<string>(nullable: true),
|
||||||
|
TemporaryImageUrl = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Podcasts", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Podcasts_AspNetUsers_AppUserId",
|
||||||
|
column: x => x.AppUserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Playlists",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||||
|
Uid = table.Column<string>(nullable: true),
|
||||||
|
NewId = table.Column<Guid>(nullable: false, defaultValueSql: "newsequentialid()"),
|
||||||
|
CreateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
UpdateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
SourceUrl = table.Column<string>(nullable: true),
|
||||||
|
PodcastId = table.Column<int>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Playlists", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Playlists_Podcasts_PodcastId",
|
||||||
|
column: x => x.PodcastId,
|
||||||
|
principalTable: "Podcasts",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "ParsedPlaylistItems",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||||
|
Uid = table.Column<string>(nullable: true),
|
||||||
|
NewId = table.Column<Guid>(nullable: false, defaultValueSql: "newsequentialid()"),
|
||||||
|
CreateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
UpdateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
VideoId = table.Column<string>(nullable: true),
|
||||||
|
VideoType = table.Column<string>(nullable: true),
|
||||||
|
IsProcessed = table.Column<bool>(nullable: false),
|
||||||
|
PlaylistId = table.Column<int>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_ParsedPlaylistItems", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_ParsedPlaylistItems_Playlists_PlaylistId",
|
||||||
|
column: x => x.PlaylistId,
|
||||||
|
principalTable: "Playlists",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "PodcastEntries",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||||
|
Uid = table.Column<string>(nullable: true),
|
||||||
|
NewId = table.Column<Guid>(nullable: false, defaultValueSql: "newsequentialid()"),
|
||||||
|
CreateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
UpdateDate = table.Column<DateTime>(nullable: false, defaultValueSql: "getdate()"),
|
||||||
|
Author = table.Column<string>(nullable: true),
|
||||||
|
Title = table.Column<string>(nullable: true),
|
||||||
|
Description = table.Column<string>(nullable: true),
|
||||||
|
SourceUrl = table.Column<string>(nullable: true),
|
||||||
|
AudioUrl = table.Column<string>(nullable: true),
|
||||||
|
AudioLength = table.Column<float>(nullable: false),
|
||||||
|
AudioFileSize = table.Column<long>(nullable: false),
|
||||||
|
ImageUrl = table.Column<string>(nullable: true),
|
||||||
|
ProcessingPayload = table.Column<string>(nullable: true),
|
||||||
|
ProcessingStatus = table.Column<int>(nullable: false),
|
||||||
|
Processed = table.Column<bool>(nullable: false),
|
||||||
|
PodcastId = table.Column<int>(nullable: false),
|
||||||
|
PlaylistId = table.Column<int>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_PodcastEntries", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_PodcastEntries_Playlists_PlaylistId",
|
||||||
|
column: x => x.PlaylistId,
|
||||||
|
principalTable: "Playlists",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_PodcastEntries_Podcasts_PodcastId",
|
||||||
|
column: x => x.PodcastId,
|
||||||
|
principalTable: "Podcasts",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetRoleClaims_RoleId",
|
||||||
|
table: "AspNetRoleClaims",
|
||||||
|
column: "RoleId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "RoleNameIndex",
|
||||||
|
table: "AspNetRoles",
|
||||||
|
column: "NormalizedName",
|
||||||
|
unique: true,
|
||||||
|
filter: "[NormalizedName] IS NOT NULL");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetUserClaims_UserId",
|
||||||
|
table: "AspNetUserClaims",
|
||||||
|
column: "UserId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetUserLogins_UserId",
|
||||||
|
table: "AspNetUserLogins",
|
||||||
|
column: "UserId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetUserRoles_RoleId",
|
||||||
|
table: "AspNetUserRoles",
|
||||||
|
column: "RoleId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "EmailIndex",
|
||||||
|
table: "AspNetUsers",
|
||||||
|
column: "NormalizedEmail");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "UserNameIndex",
|
||||||
|
table: "AspNetUsers",
|
||||||
|
column: "NormalizedUserName",
|
||||||
|
unique: true,
|
||||||
|
filter: "[NormalizedUserName] IS NOT NULL");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_ChatMessages_FromUserId",
|
||||||
|
table: "ChatMessages",
|
||||||
|
column: "FromUserId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_ChatMessages_ToUserId",
|
||||||
|
table: "ChatMessages",
|
||||||
|
column: "ToUserId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_ParsedPlaylistItems_PlaylistId",
|
||||||
|
table: "ParsedPlaylistItems",
|
||||||
|
column: "PlaylistId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Playlists_PodcastId",
|
||||||
|
table: "Playlists",
|
||||||
|
column: "PodcastId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PodcastEntries_PlaylistId",
|
||||||
|
table: "PodcastEntries",
|
||||||
|
column: "PlaylistId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PodcastEntries_PodcastId",
|
||||||
|
table: "PodcastEntries",
|
||||||
|
column: "PodcastId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Podcasts_AppUserId",
|
||||||
|
table: "Podcasts",
|
||||||
|
column: "AppUserId");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetRoleClaims");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserClaims");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserLogins");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserRoles");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserTokens");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "ChatMessages");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "ParsedPlaylistItems");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "PodcastEntries");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "ServerConfig",
|
||||||
|
schema: "admin");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetRoles");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Playlists");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Podcasts");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUsers");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
516
server/Migrations/20180512181432_PK_OnParsedPlaylistItem.Designer.cs
generated
Normal file
516
server/Migrations/20180512181432_PK_OnParsedPlaylistItem.Designer.cs
generated
Normal file
@@ -0,0 +1,516 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PodNoms.Api.Persistence;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PodNomsDbContext))]
|
||||||
|
[Migration("20180512181432_PK_OnParsedPlaylistItem")]
|
||||||
|
partial class PK_OnParsedPlaylistItem
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.1.0-rc1-32029")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("RoleNameIndex")
|
||||||
|
.HasFilter("[NormalizedName] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ChatMessage", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("FromUserId");
|
||||||
|
|
||||||
|
b.Property<string>("Message");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("MessageSeen");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<string>("ToUserId");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("FromUserId");
|
||||||
|
|
||||||
|
b.HasIndex("ToUserId");
|
||||||
|
|
||||||
|
b.ToTable("ChatMessages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ParsedPlaylistItem", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<bool>("IsProcessed");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<int>("PlaylistId");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("VideoId");
|
||||||
|
|
||||||
|
b.Property<string>("VideoType");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlaylistId");
|
||||||
|
|
||||||
|
b.HasIndex("VideoId", "PlaylistId")
|
||||||
|
.IsUnique()
|
||||||
|
.HasFilter("[VideoId] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("ParsedPlaylistItems");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("Playlists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<string>("AppUserId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<string>("Slug");
|
||||||
|
|
||||||
|
b.Property<string>("TemporaryImageUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
|
b.ToTable("Podcasts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<long>("AudioFileSize");
|
||||||
|
|
||||||
|
b.Property<float>("AudioLength");
|
||||||
|
|
||||||
|
b.Property<string>("AudioUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Author");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<int?>("PlaylistId");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<bool>("Processed");
|
||||||
|
|
||||||
|
b.Property<string>("ProcessingPayload");
|
||||||
|
|
||||||
|
b.Property<int>("ProcessingStatus");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlaylistId");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("PodcastEntries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ServerConfig", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Key");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ServerConfig","admin");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Services.Auth.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed");
|
||||||
|
|
||||||
|
b.Property<long?>("FacebookId");
|
||||||
|
|
||||||
|
b.Property<string>("FirstName");
|
||||||
|
|
||||||
|
b.Property<string>("LastName");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed");
|
||||||
|
|
||||||
|
b.Property<string>("PictureUrl");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp");
|
||||||
|
|
||||||
|
b.Property<string>("Slug");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("UserNameIndex")
|
||||||
|
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ChatMessage", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser", "FromUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FromUserId");
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser", "ToUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ToUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ParsedPlaylistItem", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Playlist", "Playlist")
|
||||||
|
.WithMany("ParsedPlaylistItems")
|
||||||
|
.HasForeignKey("PlaylistId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser", "AppUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AppUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Playlist")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PlaylistId");
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
38
server/Migrations/20180512181432_PK_OnParsedPlaylistItem.cs
Normal file
38
server/Migrations/20180512181432_PK_OnParsedPlaylistItem.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Migrations
|
||||||
|
{
|
||||||
|
public partial class PK_OnParsedPlaylistItem : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "VideoId",
|
||||||
|
table: "ParsedPlaylistItems",
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldNullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_ParsedPlaylistItems_VideoId_PlaylistId",
|
||||||
|
table: "ParsedPlaylistItems",
|
||||||
|
columns: new[] { "VideoId", "PlaylistId" },
|
||||||
|
unique: true,
|
||||||
|
filter: "[VideoId] IS NOT NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_ParsedPlaylistItems_VideoId_PlaylistId",
|
||||||
|
table: "ParsedPlaylistItems");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "VideoId",
|
||||||
|
table: "ParsedPlaylistItems",
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldNullable: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
514
server/Migrations/PodNomsDbContextModelSnapshot.cs
Normal file
514
server/Migrations/PodNomsDbContextModelSnapshot.cs
Normal file
@@ -0,0 +1,514 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PodNoms.Api.Persistence;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PodNomsDbContext))]
|
||||||
|
partial class PodNomsDbContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.1.0-rc1-32029")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("RoleNameIndex")
|
||||||
|
.HasFilter("[NormalizedName] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ChatMessage", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("FromUserId");
|
||||||
|
|
||||||
|
b.Property<string>("Message");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("MessageSeen");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<string>("ToUserId");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("FromUserId");
|
||||||
|
|
||||||
|
b.HasIndex("ToUserId");
|
||||||
|
|
||||||
|
b.ToTable("ChatMessages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ParsedPlaylistItem", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<bool>("IsProcessed");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<int>("PlaylistId");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("VideoId");
|
||||||
|
|
||||||
|
b.Property<string>("VideoType");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlaylistId");
|
||||||
|
|
||||||
|
b.HasIndex("VideoId", "PlaylistId")
|
||||||
|
.IsUnique()
|
||||||
|
.HasFilter("[VideoId] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("ParsedPlaylistItems");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("Playlists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<string>("AppUserId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<string>("Slug");
|
||||||
|
|
||||||
|
b.Property<string>("TemporaryImageUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
|
b.ToTable("Podcasts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<long>("AudioFileSize");
|
||||||
|
|
||||||
|
b.Property<float>("AudioLength");
|
||||||
|
|
||||||
|
b.Property<string>("AudioUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Author");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<int?>("PlaylistId");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<bool>("Processed");
|
||||||
|
|
||||||
|
b.Property<string>("ProcessingPayload");
|
||||||
|
|
||||||
|
b.Property<int>("ProcessingStatus");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlaylistId");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("PodcastEntries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ServerConfig", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Key");
|
||||||
|
|
||||||
|
b.Property<Guid>("NewId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("newsequentialid()");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate")
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ServerConfig","admin");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Services.Auth.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed");
|
||||||
|
|
||||||
|
b.Property<long?>("FacebookId");
|
||||||
|
|
||||||
|
b.Property<string>("FirstName");
|
||||||
|
|
||||||
|
b.Property<string>("LastName");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed");
|
||||||
|
|
||||||
|
b.Property<string>("PictureUrl");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp");
|
||||||
|
|
||||||
|
b.Property<string>("Slug");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("UserNameIndex")
|
||||||
|
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ChatMessage", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser", "FromUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FromUserId");
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser", "ToUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ToUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.ParsedPlaylistItem", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Playlist", "Playlist")
|
||||||
|
.WithMany("ParsedPlaylistItems")
|
||||||
|
.HasForeignKey("PlaylistId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser", "AppUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AppUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Playlist")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PlaylistId");
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,9 @@ namespace PodNoms.Api.Persistence {
|
|||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder) {
|
protected override void OnModelCreating(ModelBuilder modelBuilder) {
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
|
modelBuilder.Entity<ParsedPlaylistItem>()
|
||||||
|
.HasIndex(p => new { p.VideoId, p.PlaylistId })
|
||||||
|
.IsUnique(true);
|
||||||
|
|
||||||
foreach (var pb in __getColumn(modelBuilder, "CreateDate")) {
|
foreach (var pb in __getColumn(modelBuilder, "CreateDate")) {
|
||||||
pb.ValueGeneratedOnAdd()
|
pb.ValueGeneratedOnAdd()
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ namespace PodNoms.Api.Persistence {
|
|||||||
public class PlaylistRepository : GenericRepository<Playlist>, IPlaylistRepository {
|
public class PlaylistRepository : GenericRepository<Playlist>, IPlaylistRepository {
|
||||||
public PlaylistRepository(PodNomsDbContext context, ILogger<PlaylistRepository> logger) : base(context, logger) {
|
public PlaylistRepository(PodNomsDbContext context, ILogger<PlaylistRepository> logger) : base(context, logger) {
|
||||||
}
|
}
|
||||||
|
public new async Task<Playlist> GetAsync(int id) {
|
||||||
|
return await GetContext().Playlists
|
||||||
|
.Include(i => i.ParsedPlaylistItems)
|
||||||
|
.SingleOrDefaultAsync(i => i.Id == id);
|
||||||
|
}
|
||||||
public async Task<ParsedPlaylistItem> GetParsedItem(string itemId, int playlistId) {
|
public async Task<ParsedPlaylistItem> GetParsedItem(string itemId, int playlistId) {
|
||||||
return await GetContext().ParsedPlaylistItems
|
return await GetContext().ParsedPlaylistItems
|
||||||
.Include(i => i.Playlist)
|
.Include(i => i.Playlist)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace PodNoms.Api.Services.Jobs {
|
|||||||
public static void BootstrapJobs() {
|
public static void BootstrapJobs() {
|
||||||
RecurringJob.AddOrUpdate<ClearOrphanAudioJob>(x => x.Execute(), Cron.Daily(1));
|
RecurringJob.AddOrUpdate<ClearOrphanAudioJob>(x => x.Execute(), Cron.Daily(1));
|
||||||
RecurringJob.AddOrUpdate<UpdateYouTubeDlJob>(x => x.Execute(), Cron.Daily(1, 30));
|
RecurringJob.AddOrUpdate<UpdateYouTubeDlJob>(x => x.Execute(), Cron.Daily(1, 30));
|
||||||
// BackgroundJob.Schedule<ProcessPlaylistsJob>(x => x.Execute(), TimeSpan.FromSeconds(1));
|
BackgroundJob.Schedule<ProcessPlaylistsJob>(x => x.Execute(3), TimeSpan.FromSeconds(1));
|
||||||
RecurringJob.AddOrUpdate<ProcessPlaylistsJob>(x => x.Execute(), Cron.Daily(2));
|
RecurringJob.AddOrUpdate<ProcessPlaylistsJob>(x => x.Execute(), Cron.Daily(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
150
server/Services/Jobs/MutexAttribute.cs
Normal file
150
server/Services/Jobs/MutexAttribute.cs
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Hangfire.Common;
|
||||||
|
using Hangfire.States;
|
||||||
|
using Hangfire.Storage;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Services.Jobs {
|
||||||
|
public class MutexAttribute : JobFilterAttribute, IElectStateFilter, IApplyStateFilter {
|
||||||
|
private static readonly TimeSpan DistributedLockTimeout = TimeSpan.FromMinutes(1);
|
||||||
|
|
||||||
|
private readonly string _resource;
|
||||||
|
|
||||||
|
public MutexAttribute(string resource) {
|
||||||
|
_resource = resource;
|
||||||
|
RetryInSeconds = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RetryInSeconds { get; set; }
|
||||||
|
public int MaxAttempts { get; set; }
|
||||||
|
|
||||||
|
public void OnStateElection(ElectStateContext context) {
|
||||||
|
// We are intercepting transitions to the Processed state, that is performed by
|
||||||
|
// a worker just before processing a job. During the state election phase we can
|
||||||
|
// change the target state to another one, causing a worker not to process the
|
||||||
|
// backgorund job.
|
||||||
|
if (context.CandidateState.Name != ProcessingState.StateName ||
|
||||||
|
context.BackgroundJob.Job == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This filter requires an extended set of storage operations. It's supported
|
||||||
|
// by all the official storages, and many of the community-based ones.
|
||||||
|
var storageConnection = context.Connection as JobStorageConnection;
|
||||||
|
if (storageConnection == null) {
|
||||||
|
throw new NotSupportedException("This version of storage doesn't support extended methods. Please try to update to the latest version.");
|
||||||
|
}
|
||||||
|
|
||||||
|
string blockedBy;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Distributed lock is needed here only to prevent a race condition, when another
|
||||||
|
// worker picks up a background job with the same resource between GET and SET
|
||||||
|
// operations.
|
||||||
|
// There will be no race condition, when two or more workers pick up background job
|
||||||
|
// with the same id, because state transitions are protected with distributed lock
|
||||||
|
// themselves.
|
||||||
|
using (AcquireDistributedSetLock(context.Connection, context.BackgroundJob.Job.Args)) {
|
||||||
|
// Resource set contains a background job id that acquired a mutex for the resource.
|
||||||
|
// We are getting only one element to see what background job blocked the invocation.
|
||||||
|
var range = storageConnection.GetRangeFromSet(
|
||||||
|
GetResourceKey(context.BackgroundJob.Job.Args),
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
|
||||||
|
blockedBy = range.Count > 0 ? range[0] : null;
|
||||||
|
|
||||||
|
// We should permit an invocation only when the set is empty, or if current background
|
||||||
|
// job is already owns a resource. This may happen, when the localTransaction succeeded,
|
||||||
|
// but outer transaction was failed.
|
||||||
|
if (blockedBy == null || blockedBy == context.BackgroundJob.Id) {
|
||||||
|
// We need to commit the changes inside a distributed lock, otherwise it's
|
||||||
|
// useless. So we create a local transaction instead of using the
|
||||||
|
// context.Transaction property.
|
||||||
|
var localTransaction = context.Connection.CreateWriteTransaction();
|
||||||
|
|
||||||
|
// Add the current background job identifier to a resource set. This means
|
||||||
|
// that resource is owned by the current background job. Identifier will be
|
||||||
|
// removed only on failed state, or in one of final states (succeeded or
|
||||||
|
// deleted).
|
||||||
|
localTransaction.AddToSet(GetResourceKey(context.BackgroundJob.Job.Args), context.BackgroundJob.Id);
|
||||||
|
localTransaction.Commit();
|
||||||
|
|
||||||
|
// Invocation is permitted, and we did all the required things.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DistributedLockTimeoutException) {
|
||||||
|
// We weren't able to acquire a distributed lock within a specified window. This may
|
||||||
|
// be caused by network delays, storage outages or abandoned locks in some storages.
|
||||||
|
// Since it is required to expire abandoned locks after some time, we can simply
|
||||||
|
// postpone the invocation.
|
||||||
|
context.CandidateState = new ScheduledState(TimeSpan.FromSeconds(RetryInSeconds)) {
|
||||||
|
Reason = "Couldn't acquire a distributed lock for mutex: timeout exceeded"
|
||||||
|
};
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background job execution is blocked. We should change the target state either to
|
||||||
|
// the Scheduled or to the Deleted one, depending on current retry attempt number.
|
||||||
|
var currentAttempt = context.GetJobParameter<int>("MutexAttempt") + 1;
|
||||||
|
context.SetJobParameter("MutexAttempt", currentAttempt);
|
||||||
|
|
||||||
|
context.CandidateState = MaxAttempts == 0 || currentAttempt <= MaxAttempts
|
||||||
|
? CreateScheduledState(blockedBy, currentAttempt)
|
||||||
|
: CreateDeletedState(blockedBy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction) {
|
||||||
|
if (context.BackgroundJob.Job == null) return;
|
||||||
|
|
||||||
|
if (context.OldStateName == ProcessingState.StateName) {
|
||||||
|
using (AcquireDistributedSetLock(context.Connection, context.BackgroundJob.Job.Args)) {
|
||||||
|
var localTransaction = context.Connection.CreateWriteTransaction();
|
||||||
|
localTransaction.RemoveFromSet(GetResourceKey(context.BackgroundJob.Job.Args), context.BackgroundJob.Id);
|
||||||
|
|
||||||
|
localTransaction.Commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DeletedState CreateDeletedState(string blockedBy) {
|
||||||
|
return new DeletedState {
|
||||||
|
Reason = $"Execution was blocked by background job {blockedBy}, all attempts exhausted"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private IState CreateScheduledState(string blockedBy, int currentAttempt) {
|
||||||
|
var reason = $"Execution is blocked by background job {blockedBy}, retry attempt: {currentAttempt}";
|
||||||
|
|
||||||
|
if (MaxAttempts > 0) {
|
||||||
|
reason += $"/{MaxAttempts}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ScheduledState(TimeSpan.FromSeconds(RetryInSeconds)) {
|
||||||
|
Reason = reason
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private IDisposable AcquireDistributedSetLock(IStorageConnection connection, IEnumerable<object> args) {
|
||||||
|
return connection.AcquireDistributedLock(GetDistributedLockKey(args), DistributedLockTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetDistributedLockKey(IEnumerable<object> args) {
|
||||||
|
return $"extension:job-mutex:lock:{GetKeyFormat(args, _resource)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetResourceKey(IEnumerable<object> args) {
|
||||||
|
return $"extension:job-mutex:set:{GetKeyFormat(args, _resource)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetKeyFormat(IEnumerable<object> args, string keyFormat) {
|
||||||
|
return String.Format(keyFormat, args.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,46 +33,54 @@ namespace PodNoms.Api.Services.Jobs {
|
|||||||
this._helpersSettings = _helpersSettings.Value;
|
this._helpersSettings = _helpersSettings.Value;
|
||||||
this._logger = logger;
|
this._logger = logger;
|
||||||
}
|
}
|
||||||
|
[Mutex("ProcessPlaylistItemJob")]
|
||||||
public async Task Execute() {
|
public async Task Execute() {
|
||||||
var items = await _playlistRepository.GetUnprocessedItems();
|
var items = await _playlistRepository.GetUnprocessedItems();
|
||||||
foreach (var item in items) {
|
foreach (var item in items) {
|
||||||
await ExecuteForItem(item.VideoId, item.Playlist.Id);
|
await ExecuteForItem(item.VideoId, item.Playlist.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[Mutex("ProcessPlaylistItemJob")]
|
||||||
public async Task ExecuteForItem(string itemId, int playlistId) {
|
public async Task ExecuteForItem(string itemId, int playlistId) {
|
||||||
var item = await _playlistRepository.GetParsedItem(itemId, playlistId);
|
var item = await _playlistRepository.GetParsedItem(itemId, playlistId);
|
||||||
if (item != null && !string.IsNullOrEmpty(item.VideoType) && item.VideoType.Equals("youtube")) {
|
if (item != null && !string.IsNullOrEmpty(item.VideoType) &&
|
||||||
var url = $"https://www.youtube.com/watch?v={item.VideoId}";
|
(item.VideoType.Equals("youtube") || item.VideoType.Equals("mixcloud"))) {
|
||||||
var downloader = new AudioDownloader(url, _helpersSettings.Downloader);
|
var url = item.VideoType.Equals("youtube") ? $"https://www.youtube.com/watch?v={item.VideoId}"
|
||||||
var info = downloader.GetInfo();
|
: item.VideoType.Equals("mixcloud") ? $"https://mixcloud.com/{item.VideoId}" : string.Empty;
|
||||||
if (info == AudioType.Valid) {
|
if (string.IsNullOrEmpty(url)) {
|
||||||
var podcast = await _podcastRepository.GetAsync(item.Playlist.PodcastId);
|
_logger.LogError($"Unknown video type for ParsedItem: {itemId} - {playlistId}");
|
||||||
var uid = System.Guid.NewGuid().ToString();
|
|
||||||
var file = downloader.DownloadAudio(uid);
|
|
||||||
if (System.IO.File.Exists(file)) {
|
|
||||||
//we have the file so lets create the entry and ship to CDN
|
|
||||||
var entry = new PodcastEntry {
|
|
||||||
Title = downloader.Properties?.Title,
|
|
||||||
Description = downloader.Properties?.Description,
|
|
||||||
ProcessingStatus = ProcessingStatus.Uploading,
|
|
||||||
ImageUrl = downloader.Properties?.Thumbnail
|
|
||||||
};
|
|
||||||
podcast.PodcastEntries.Add(entry);
|
|
||||||
await _unitOfWork.CompleteAsync();
|
|
||||||
var uploaded = await _uploadService.UploadAudio(entry.Id, file);
|
|
||||||
if (uploaded) {
|
|
||||||
item.IsProcessed = true;
|
|
||||||
await _unitOfWork.CompleteAsync();
|
|
||||||
BackgroundJob.Enqueue<INotifyJobCompleteService>(
|
|
||||||
service => service.NotifyUser(entry.Podcast.AppUser.Id, "PodNoms", $"{entry.Title} has finished processing",
|
|
||||||
entry.Podcast.GetThumbnailUrl(
|
|
||||||
this._options.GetSection("Storage")["CdnUrl"],
|
|
||||||
this._options.GetSection("ImageFileStorageSettings")["ContainerName"])
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
_logger.LogError($"Processing playlist item {itemId} failed");
|
var downloader = new AudioDownloader(url, _helpersSettings.Downloader);
|
||||||
|
var info = downloader.GetInfo();
|
||||||
|
if (info == AudioType.Valid) {
|
||||||
|
var podcast = await _podcastRepository.GetAsync(item.Playlist.PodcastId);
|
||||||
|
var uid = System.Guid.NewGuid().ToString();
|
||||||
|
var file = downloader.DownloadAudio(uid);
|
||||||
|
if (System.IO.File.Exists(file)) {
|
||||||
|
//we have the file so lets create the entry and ship to CDN
|
||||||
|
var entry = new PodcastEntry {
|
||||||
|
Title = downloader.Properties?.Title,
|
||||||
|
Description = downloader.Properties?.Description,
|
||||||
|
ProcessingStatus = ProcessingStatus.Uploading,
|
||||||
|
ImageUrl = downloader.Properties?.Thumbnail
|
||||||
|
};
|
||||||
|
podcast.PodcastEntries.Add(entry);
|
||||||
|
await _unitOfWork.CompleteAsync();
|
||||||
|
var uploaded = await _uploadService.UploadAudio(entry.Id, file);
|
||||||
|
if (uploaded) {
|
||||||
|
item.IsProcessed = true;
|
||||||
|
await _unitOfWork.CompleteAsync();
|
||||||
|
BackgroundJob.Enqueue<INotifyJobCompleteService>(
|
||||||
|
service => service.NotifyUser(entry.Podcast.AppUser.Id, "PodNoms", $"{entry.Title} has finished processing",
|
||||||
|
entry.Podcast.GetThumbnailUrl(
|
||||||
|
this._options.GetSection("Storage")["CdnUrl"],
|
||||||
|
this._options.GetSection("ImageFileStorageSettings")["ContainerName"])
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_logger.LogError($"Processing playlist item {itemId} failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -45,33 +46,38 @@ namespace PodNoms.Api.Services.Jobs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async Task Execute(int playlistId) {
|
public async Task Execute(int playlistId) {
|
||||||
|
try {
|
||||||
|
var playlist = await _playlistRepository.GetAsync(playlistId);
|
||||||
|
var resultList = new List<ParsedItemResult>();
|
||||||
|
|
||||||
var playlist = await _playlistRepository.GetAsync(playlistId);
|
var downloader = new AudioDownloader(playlist.SourceUrl, _helpersSettings.Downloader);
|
||||||
var resultList = new List<ParsedItemResult>();
|
var info = downloader.GetInfo();
|
||||||
|
var id = ((PlaylistDownloadInfo)downloader.RawProperties)?.Id;
|
||||||
var downloader = new AudioDownloader(playlist.SourceUrl, _helpersSettings.Downloader);
|
if (!string.IsNullOrEmpty(id)) {
|
||||||
var info = downloader.GetInfo();
|
if (YouTubeParser.ValidateUrl(playlist.SourceUrl)) {
|
||||||
var id = ((PlaylistDownloadInfo)downloader.RawProperties).Id;
|
var searchTerm = (playlist.SourceUrl.Contains("/user/")) ? "forUsername" : "id";
|
||||||
if (info == AudioType.Playlist && downloader.RawProperties is PlaylistDownloadInfo) {
|
resultList = await _youTubeParser.GetPlaylistEntriesForId(id);
|
||||||
if (YouTubeParser.ValidateUrl(playlist.SourceUrl)) {
|
//make sure the items are sorted in ascending date order
|
||||||
var searchTerm = (playlist.SourceUrl.Contains("/user/")) ? "forUsername" : "id";
|
//so they will be processed in the order they were created
|
||||||
resultList = await _youTubeParser.GetPlaylistEntriesForId(id);
|
} else if (MixcloudParser.ValidateUrl(playlist.SourceUrl)) {
|
||||||
//make sure the items are sorted in ascending date order
|
resultList = await _mixcloudParser.GetEntries(playlist.SourceUrl);
|
||||||
//so they will be processed in the order they were created
|
}
|
||||||
} else if (MixcloudParser.ValidateUrl(playlist.SourceUrl)) {
|
if (resultList != null) {
|
||||||
resultList = await _mixcloudParser.GetEntries(id);
|
//order in reverse so the newest item is added first
|
||||||
}
|
foreach (var item in resultList?.OrderBy(r => r.UploadDate)) {
|
||||||
}
|
if (!playlist.ParsedPlaylistItems.Any(p => p.VideoId == item.Id)) {
|
||||||
foreach (var item in resultList?.OrderBy(r => r.UploadDate)) {
|
playlist.ParsedPlaylistItems.Add(new ParsedPlaylistItem {
|
||||||
if (!playlist.ParsedPlaylistItems.Any(p => p.VideoId == item.Id)) {
|
VideoId = item.Id,
|
||||||
playlist.ParsedPlaylistItems.Add(new ParsedPlaylistItem {
|
VideoType = item.VideoType
|
||||||
VideoId = item.Id,
|
});
|
||||||
VideoType = item.VideoType
|
await _unitOfWork.CompleteAsync();
|
||||||
});
|
BackgroundJob.Enqueue<ProcessPlaylistItemJob>(service => service.ExecuteForItem(item.Id, playlist.Id));
|
||||||
await _unitOfWork.CompleteAsync();
|
}
|
||||||
|
}
|
||||||
BackgroundJob.Enqueue<ProcessPlaylistItemJob>(service => service.ExecuteForItem(item.Id, playlist.Id));
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,5 +17,19 @@ namespace PodNoms.Api.Utils {
|
|||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
public static string UrlCombine(string url1, string url2) {
|
||||||
|
if (url1.Length == 0) {
|
||||||
|
return url2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url2.Length == 0) {
|
||||||
|
return url1;
|
||||||
|
}
|
||||||
|
|
||||||
|
url1 = url1.TrimEnd('/', '\\');
|
||||||
|
url2 = url2.TrimStart('/', '\\');
|
||||||
|
|
||||||
|
return string.Format("{0}/{1}", url1, url2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
15
server/Utils/RemoteParsers/MixcloudJsonConverter.cs
Normal file
15
server/Utils/RemoteParsers/MixcloudJsonConverter.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Utils.RemoteParsers {
|
||||||
|
internal static class MixcloudJsonConverter {
|
||||||
|
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings {
|
||||||
|
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
|
||||||
|
DateParseHandling = DateParseHandling.None,
|
||||||
|
Converters = {
|
||||||
|
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,31 +4,58 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Security.Policy;
|
||||||
|
|
||||||
namespace PodNoms.Api.Utils.RemoteParsers {
|
namespace PodNoms.Api.Utils.RemoteParsers {
|
||||||
public class MixcloudParser {
|
public class MixcloudParser {
|
||||||
const string URL_REGEX = @"^(http(s)?:\/\/)?((w){3}.)?mixcloud?(\.com)?\/.+";
|
static string[] VALID_PATHS = new string[] {
|
||||||
|
"stream", "uploads", "favorites", "listens", "playlists"
|
||||||
|
};
|
||||||
|
|
||||||
private readonly IHttpClientFactory _httpClientFactory;
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
|
private readonly ILogger<MixcloudParser> _logger;
|
||||||
|
|
||||||
public MixcloudParser(IHttpClientFactory httpClientFactory) {
|
public MixcloudParser(IHttpClientFactory httpClientFactory, ILogger<MixcloudParser> logger) {
|
||||||
|
this._logger = logger;
|
||||||
this._httpClientFactory = httpClientFactory;
|
this._httpClientFactory = httpClientFactory;
|
||||||
}
|
}
|
||||||
public static bool ValidateUrl(string url) {
|
public static bool ValidateUrl(string url) {
|
||||||
var regex = new Regex(URL_REGEX);
|
try {
|
||||||
var result = regex.Match(url);
|
var uri = new Uri(url);
|
||||||
return result.Success;
|
if (uri.Host.EndsWith("mixcloud.com")) {
|
||||||
|
var path = uri.Segments[uri.Segments.Length - 1].ToString().TrimEnd(new[] { '/' });
|
||||||
|
return (VALID_PATHS.Any(path.Equals)) || uri.Segments.Length == 1;
|
||||||
|
}
|
||||||
|
} catch (Exception) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
public async Task<List<ParsedItemResult>> GetEntries(string identifier) {
|
public async Task<List<ParsedItemResult>> GetEntries(string url) {
|
||||||
var client = _httpClientFactory.CreateClient("mixcloud");
|
try {
|
||||||
var result = await client.GetAsync(identifier);
|
var path = new Uri(url).Segments.First(s => s != "/");
|
||||||
if (result.IsSuccessStatusCode) {
|
var newUrl = HttpUtils.UrlCombine(path, "cloudcasts");
|
||||||
var typed = JsonConvert.DeserializeObject<MixcloudResult>(await result.Content.ReadAsStringAsync());
|
var client = _httpClientFactory.CreateClient("mixcloud");
|
||||||
return typed.data[0].cloudcasts.Select(c => new ParsedItemResult {
|
var result = await client.GetAsync(newUrl);
|
||||||
Id = c.key,
|
|
||||||
VideoType = "mixcloud",
|
if (result.IsSuccessStatusCode) {
|
||||||
UploadDate = c.updated_time
|
var body = await result.Content.ReadAsStringAsync();
|
||||||
}).ToList();
|
Console.WriteLine(body);
|
||||||
|
System.IO.File.WriteAllText("/tmp/dump.json", body);
|
||||||
|
var typed = JsonConvert.DeserializeObject<Welcome>(body, MixcloudJsonConverter.Settings);
|
||||||
|
// var typed = JsonConvert.DeserializeObject<MixcloudResult>(body);
|
||||||
|
var data = typed.Data.OrderByDescending(p => p.UpdatedTime)
|
||||||
|
.Select(c => new ParsedItemResult {
|
||||||
|
Id = c.Key,
|
||||||
|
VideoType = "mixcloud",
|
||||||
|
UploadDate = c.UpdatedTime.DateTime
|
||||||
|
}).Take(10).ToList();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
_logger.LogError($"Error parsing url: {url}");
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +1,131 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PodNoms.Api.Utils.RemoteParsers {
|
namespace PodNoms.Api.Utils.RemoteParsers {
|
||||||
|
public partial class Welcome {
|
||||||
|
[JsonProperty("paging")]
|
||||||
|
public Paging Paging { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("data")]
|
||||||
|
public Datum[] Data { get; set; }
|
||||||
|
|
||||||
public class Paging {
|
[JsonProperty("name")]
|
||||||
public string previous { get; set; }
|
public string Name { get; set; }
|
||||||
public string next { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Pictures {
|
public partial class Datum {
|
||||||
public string medium { get; set; }
|
[JsonProperty("tags")]
|
||||||
public string extra_large { get; set; }
|
public Tag[] Tags { get; set; }
|
||||||
public string large { get; set; }
|
|
||||||
public string medium_mobile { get; set; }
|
[JsonProperty("play_count")]
|
||||||
public string small { get; set; }
|
public long PlayCount { get; set; }
|
||||||
public string thumbnail { get; set; }
|
|
||||||
|
[JsonProperty("user")]
|
||||||
|
public User User { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("created_time")]
|
||||||
|
public DateTimeOffset CreatedTime { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("audio_length")]
|
||||||
|
public long AudioLength { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("slug")]
|
||||||
|
public string Slug { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("favorite_count")]
|
||||||
|
public long FavoriteCount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("listener_count")]
|
||||||
|
public long ListenerCount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("url")]
|
||||||
|
public string Url { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("pictures")]
|
||||||
|
public Pictures Pictures { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("repost_count")]
|
||||||
|
public long RepostCount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("updated_time")]
|
||||||
|
public DateTimeOffset UpdatedTime { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("comment_count")]
|
||||||
|
public long CommentCount { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class From {
|
public partial class Pictures {
|
||||||
public string url { get; set; }
|
[JsonProperty("medium")]
|
||||||
public string username { get; set; }
|
public string Medium { get; set; }
|
||||||
public string name { get; set; }
|
|
||||||
public string key { get; set; }
|
[JsonProperty("768wx768h", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public Pictures pictures { get; set; }
|
public string The768Wx768H { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("320wx320h")]
|
||||||
|
public string The320Wx320H { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("extra_large")]
|
||||||
|
public string ExtraLarge { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("large")]
|
||||||
|
public string Large { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("640wx640h")]
|
||||||
|
public string The640Wx640H { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("medium_mobile")]
|
||||||
|
public string MediumMobile { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("small")]
|
||||||
|
public string Small { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("1024wx1024h", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string The1024Wx1024H { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("thumbnail")]
|
||||||
|
public string Thumbnail { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Tag {
|
public partial class Tag {
|
||||||
public string url { get; set; }
|
[JsonProperty("url")]
|
||||||
public string name { get; set; }
|
public string Url { get; set; }
|
||||||
public string key { get; set; }
|
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class User {
|
public partial class User {
|
||||||
public string url { get; set; }
|
[JsonProperty("url")]
|
||||||
public string username { get; set; }
|
public string Url { get; set; }
|
||||||
public string name { get; set; }
|
|
||||||
public string key { get; set; }
|
[JsonProperty("username")]
|
||||||
|
public string Username { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("pictures")]
|
||||||
|
public Pictures Pictures { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Cloudcast {
|
public partial class Paging {
|
||||||
public IList<Tag> tags { get; set; }
|
[JsonProperty("previous")]
|
||||||
public int play_count { get; set; }
|
public string Previous { get; set; }
|
||||||
public User user { get; set; }
|
|
||||||
public string key { get; set; }
|
|
||||||
public DateTime created_time { get; set; }
|
|
||||||
public int audio_length { get; set; }
|
|
||||||
public string slug { get; set; }
|
|
||||||
public int favorite_count { get; set; }
|
|
||||||
public int listener_count { get; set; }
|
|
||||||
public string name { get; set; }
|
|
||||||
public string url { get; set; }
|
|
||||||
public int repost_count { get; set; }
|
|
||||||
public DateTime updated_time { get; set; }
|
|
||||||
public int comment_count { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Datum {
|
[JsonProperty("next")]
|
||||||
public From from { get; set; }
|
public string Next { get; set; }
|
||||||
public string title { get; set; }
|
|
||||||
public string url { get; set; }
|
|
||||||
public string key { get; set; }
|
|
||||||
public DateTime created_time { get; set; }
|
|
||||||
public IList<Cloudcast> cloudcasts { get; set; }
|
|
||||||
public string type { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MixcloudResult {
|
|
||||||
public Paging paging { get; set; }
|
|
||||||
public IList<Datum> data { get; set; }
|
|
||||||
public string name { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user