diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts
index abaaacb..ce01ca8 100644
--- a/client/src/app/app.module.ts
+++ b/client/src/app/app.module.ts
@@ -1,5 +1,4 @@
import { GlobalsService } from './services/globals.service';
-import { CallbackComponent } from './components/callback/callback.component';
import { PodcastUploadFormComponent } from './components/podcast/podcast-upload-form/podcast-upload-form.component';
import { PodcastAddUrlFormComponent } from './components/podcast/podcast-add-url-form/podcast-add-url-form.component';
import { PodcastAddFormComponent } from './components/podcast/podcast-add-form/podcast-add-form.component';
@@ -70,7 +69,7 @@ import { PodNomsApiInterceptor } from './interceptors/podnoms-api.interceptor';
import { SideOverlayComponent } from './components/side-overlay/side-overlay.component';
import { UiStateService } from './services/ui-state.service';
-let config = new AuthServiceConfig([
+const config = new AuthServiceConfig([
{
id: GoogleLoginProvider.PROVIDER_ID,
provider: new GoogleLoginProvider('357461672895-2mevm3b10b4bd3gjdvugl00up8ba2n4m.apps.googleusercontent.com')
@@ -101,7 +100,6 @@ export function provideConfig() {
PodcastAddUrlFormComponent,
DebugComponent,
SidebarComponent,
- CallbackComponent,
RegisterComponent,
ResetComponent,
ProfileComponent,
diff --git a/client/src/app/app.router.ts b/client/src/app/app.router.ts
index e073f98..8175a1d 100644
--- a/client/src/app/app.router.ts
+++ b/client/src/app/app.router.ts
@@ -1,7 +1,6 @@
import { ProfileComponent } from 'app/components/profile/profile.component';
import { ResetComponent } from 'app/components/reset/reset.component';
import { RegisterComponent } from 'app/components/register/register.component';
-import { CallbackComponent } from 'app/components/callback/callback.component';
import { LoginComponent } from 'app/components/login/login.component';
import { DebugComponent } from 'app/components/debug/debug.component';
import { NgModule } from '@angular/core';
@@ -18,7 +17,6 @@ const routes: Routes = [
{ path: 'about', component: AboutComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'reset', component: ResetComponent, pathMatch: 'full' },
- { path: 'callback', component: CallbackComponent },
{ path: 'debug', component: DebugComponent, canActivate: [AuthGuard] },
{ path: 'profile', component: ProfileComponent, canActivate: [AuthGuard] },
{ path: 'podcasts', component: PodcastComponent, canActivate: [AuthGuard] },
diff --git a/client/src/app/components/callback/callback.component.css b/client/src/app/components/callback/callback.component.css
deleted file mode 100644
index e69de29..0000000
diff --git a/client/src/app/components/callback/callback.component.html b/client/src/app/components/callback/callback.component.html
deleted file mode 100644
index c725f56..0000000
--- a/client/src/app/components/callback/callback.component.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Loading......
-
\ No newline at end of file
diff --git a/client/src/app/components/callback/callback.component.ts b/client/src/app/components/callback/callback.component.ts
deleted file mode 100644
index facbb9c..0000000
--- a/client/src/app/components/callback/callback.component.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-import { PodnomsAuthService } from 'app/services/podnoms-auth.service';
-import { Router } from '@angular/router';
-
-@Component({
- selector: 'app-callback',
- templateUrl: './callback.component.html',
- styleUrls: ['./callback.component.css']
-})
-export class CallbackComponent implements OnInit {
- constructor(private _authService: PodnomsAuthService, private _router: Router) {}
-
- ngOnInit() {
- debugger;
- this._router.navigate(['/podcasts']);
- }
-}
diff --git a/client/src/app/effects/entries.effects.ts b/client/src/app/effects/entries.effects.ts
index 11738e2..aa25e85 100644
--- a/client/src/app/effects/entries.effects.ts
+++ b/client/src/app/effects/entries.effects.ts
@@ -33,8 +33,8 @@ export class EntriesEffects {
add$ = this.actions$
.ofType(entries.ADD)
.switchMap((action: entries.AddAction) =>
- //this is probably (definitely) superfluous as we've now moved
- //the addEntry into the component
+ // this is probably (definitely) superfluous as we've now moved
+ // the addEntry into the component
this._service.updateEntry(action.payload)
.map(res => {
console.log('EntriesEffects', 'add$', res);
diff --git a/server/Controllers/EntryController.cs b/server/Controllers/EntryController.cs
index e96abba..849a60a 100644
--- a/server/Controllers/EntryController.cs
+++ b/server/Controllers/EntryController.cs
@@ -8,6 +8,7 @@ using Hangfire;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using PodNoms.Api.Models;
@@ -25,6 +26,9 @@ namespace PodNoms.Api.Controllers {
public class EntryController : BaseAuthController {
private readonly IPodcastRepository _podcastRepository;
private readonly IEntryRepository _repository;
+
+ public IConfiguration _options { get; }
+
private readonly IUnitOfWork _unitOfWork;
private readonly IMapper _mapper;
private readonly IUrlProcessService _processor;
@@ -36,12 +40,14 @@ namespace PodNoms.Api.Controllers {
IPodcastRepository podcastRepository,
IUnitOfWork unitOfWork, IMapper mapper, IOptions storageSettings,
IOptions audioFileStorageSettings,
+ IConfiguration options,
IUrlProcessService processor, ILoggerFactory logger,
UserManager userManager,
IHttpContextAccessor contextAccessor) : base(contextAccessor, userManager) {
this._logger = logger.CreateLogger();
this._podcastRepository = podcastRepository;
this._repository = repository;
+ this._options = options;
this._storageSettings = storageSettings.Value;
this._unitOfWork = unitOfWork;
this._audioFileStorageSettings = audioFileStorageSettings.Value;
@@ -57,7 +63,10 @@ namespace PodNoms.Api.Controllers {
extractJobId, service => service.UploadAudio(entry.Id, entry.AudioUrl));
var notify = BackgroundJob.ContinueWith(
uploadJobId, service => service.NotifyUser(entry.Podcast.AppUser.Id, "PodNoms", $"{entry.Title} has finished processing",
- entry.Podcast.ImageUrl));
+ entry.Podcast.GetThumbnailUrl(
+ this._options.GetSection("Storage")["CdnUrl"],
+ this._options.GetSection("ImageFileStorageSettings")["ContainerName"])
+ ));
} catch (InvalidOperationException ex) {
_logger.LogError($"Failed submitting job to processor\n{ex.Message}");
entry.ProcessingStatus = ProcessingStatus.Failed;
diff --git a/server/Controllers/ImageUploadController.cs b/server/Controllers/ImageUploadController.cs
index bd79137..4863f27 100644
--- a/server/Controllers/ImageUploadController.cs
+++ b/server/Controllers/ImageUploadController.cs
@@ -63,7 +63,6 @@ namespace PodNoms.Api.Controllers {
var destinationFile = $"{podcast.Uid}.{extension}";
var destinationFileThumbnail = $"{podcast.Uid}-32x32.{extension}";
- podcast.ImageUrl = destinationFile;
await _fileUploader.UploadFile(finishedFile, _imageFileStorageSettings.ContainerName,
destinationFile, "image/png", (p, t) => _logger.LogDebug($"Uploading image: {p} - {t}"));
@@ -72,7 +71,7 @@ namespace PodNoms.Api.Controllers {
destinationFileThumbnail, "image/png", (p, t) => _logger.LogDebug($"Uploading image: {p} - {t}"));
await _repository.AddOrUpdateAsync(podcast);
-
+ podcast.TemporaryImageUrl = string.Empty;
await this._unitOfWork.CompleteAsync();
return new OkObjectResult(_mapper.Map(podcast));
diff --git a/server/Migrations/20180427010607_ImageUrlUpdates.Designer.cs b/server/Migrations/20180427010607_ImageUrlUpdates.Designer.cs
new file mode 100644
index 0000000..7e9e4b5
--- /dev/null
+++ b/server/Migrations/20180427010607_ImageUrlUpdates.Designer.cs
@@ -0,0 +1,365 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+using Microsoft.EntityFrameworkCore.Migrations;
+using PodNoms.Api.Persistence;
+
+namespace PodNoms.Api.Migrations
+{
+ [DbContext(typeof(PodnomsDbContext))]
+ [Migration("20180427010607_ImageUrlUpdates")]
+ partial class ImageUrlUpdates
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "2.1.0-preview2-30571")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Name")
+ .HasMaxLength(256);
+
+ b.Property("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", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("RoleId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider");
+
+ b.Property("ProviderKey");
+
+ b.Property("ProviderDisplayName");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("RoleId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("LoginProvider");
+
+ b.Property("Name");
+
+ b.Property("Value");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("CreateDate");
+
+ b.Property("PodcastId");
+
+ b.Property("SourceUrl");
+
+ b.Property("UpdateDate");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PodcastId");
+
+ b.ToTable("Playlists");
+ });
+
+ modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AppUserId");
+
+ b.Property("CreateDate")
+ .ValueGeneratedOnAdd()
+ .HasDefaultValueSql("getdate()");
+
+ b.Property("Description");
+
+ b.Property("Slug")
+ .IsUnicode(true);
+
+ b.Property("TemporaryImageUrl");
+
+ b.Property("Title");
+
+ b.Property("Uid");
+
+ b.Property("UpdateDate");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AppUserId");
+
+ b.ToTable("Podcasts");
+ });
+
+ modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AudioFileSize");
+
+ b.Property("AudioLength");
+
+ b.Property("AudioUrl");
+
+ b.Property("Author");
+
+ b.Property("CreateDate")
+ .ValueGeneratedOnAdd()
+ .HasDefaultValueSql("getdate()");
+
+ b.Property("Description");
+
+ b.Property("ImageUrl");
+
+ b.Property("PlaylistId");
+
+ b.Property("PodcastId");
+
+ b.Property("Processed");
+
+ b.Property("ProcessingPayload");
+
+ b.Property("ProcessingStatus");
+
+ b.Property("SourceUrl");
+
+ b.Property("Title");
+
+ b.Property("Uid");
+
+ b.Property("UpdateDate");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PlaylistId");
+
+ b.HasIndex("PodcastId");
+
+ b.ToTable("PodcastEntries");
+ });
+
+ modelBuilder.Entity("PodNoms.Api.Services.Auth.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AccessFailedCount");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Email")
+ .HasMaxLength(256);
+
+ b.Property("EmailConfirmed");
+
+ b.Property("FacebookId");
+
+ b.Property("FirstName");
+
+ b.Property("LastName");
+
+ b.Property("LockoutEnabled");
+
+ b.Property("LockoutEnd");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256);
+
+ b.Property("PasswordHash");
+
+ b.Property("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed");
+
+ b.Property("PictureUrl");
+
+ b.Property("SecurityStamp");
+
+ b.Property("Slug");
+
+ b.Property("TwoFactorEnabled");
+
+ b.Property("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", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", 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", b =>
+ {
+ b.HasOne("PodNoms.Api.Services.Auth.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .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
+ }
+ }
+}
diff --git a/server/Migrations/20180427010607_ImageUrlUpdates.cs b/server/Migrations/20180427010607_ImageUrlUpdates.cs
new file mode 100644
index 0000000..377032b
--- /dev/null
+++ b/server/Migrations/20180427010607_ImageUrlUpdates.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace PodNoms.Api.Migrations
+{
+ public partial class ImageUrlUpdates : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.RenameColumn(
+ name: "ImageUrl",
+ table: "Podcasts",
+ newName: "TemporaryImageUrl");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.RenameColumn(
+ name: "TemporaryImageUrl",
+ table: "Podcasts",
+ newName: "ImageUrl");
+ }
+ }
+}
diff --git a/server/Migrations/PodnomsDbContextModelSnapshot.cs b/server/Migrations/PodnomsDbContextModelSnapshot.cs
index a0ba407..3bd4e5b 100644
--- a/server/Migrations/PodnomsDbContextModelSnapshot.cs
+++ b/server/Migrations/PodnomsDbContextModelSnapshot.cs
@@ -160,11 +160,11 @@ namespace PodNoms.Api.Migrations
b.Property("Description");
- b.Property("ImageUrl");
-
b.Property("Slug")
.IsUnicode(true);
+ b.Property("TemporaryImageUrl");
+
b.Property("Title");
b.Property("Uid");
diff --git a/server/Models/Podcast.cs b/server/Models/Podcast.cs
index 1665705..5273a8f 100644
--- a/server/Models/Podcast.cs
+++ b/server/Models/Podcast.cs
@@ -11,17 +11,17 @@ namespace PodNoms.Api.Models {
public string Title { get; set; }
public string Description { get; set; }
public string Slug { get; set; }
- public string ImageUrl { get; set; }
+ public string TemporaryImageUrl { get; set; }
public List PodcastEntries { get; set; }
public Podcast() {
PodcastEntries = new List();
}
public string GetImageUrl(string cdnUrl, string containerName) {
- return $"{cdnUrl}{containerName}/{this.ImageUrl}";
+ return string.IsNullOrEmpty(TemporaryImageUrl) ? $"{cdnUrl}{containerName}/{this.Uid}.png" : TemporaryImageUrl;
}
- public string GetThumnnailUrl(string cdnUrl, string containerName) {
- return $"{cdnUrl}{containerName}/{this.Uid}-32x32.png";
+ public string GetThumbnailUrl(string cdnUrl, string containerName) {
+ return string.IsNullOrEmpty(TemporaryImageUrl) ? $"{cdnUrl}{containerName}/{this.Uid}-32x32.png" : TemporaryImageUrl;
}
}
}
\ No newline at end of file
diff --git a/server/Persistence/PodcastRepository.cs b/server/Persistence/PodcastRepository.cs
index 99cde34..09e79c8 100644
--- a/server/Persistence/PodcastRepository.cs
+++ b/server/Persistence/PodcastRepository.cs
@@ -54,7 +54,7 @@ namespace PodNoms.Api.Persistence {
from p in _context.Podcasts
select p.Slug);
}
- item.ImageUrl = $"standard/podcast-image-{Randomisers.RandomInteger(1, 16)}.png";
+ item.TemporaryImageUrl = $"standard/podcast-image-{Randomisers.RandomInteger(1, 16)}.png";
_context.Podcasts.Add(item);
}
diff --git a/server/Providers/MappingProvider.cs b/server/Providers/MappingProvider.cs
index 38238ba..e1ac2fa 100644
--- a/server/Providers/MappingProvider.cs
+++ b/server/Providers/MappingProvider.cs
@@ -24,7 +24,7 @@ namespace PodNoms.Api.Providers {
this._options.GetSection("ImageFileStorageSettings")["ContainerName"])))
.ForMember(
v => v.ThumbnailUrl,
- e => e.MapFrom(m => m.GetThumnnailUrl(
+ e => e.MapFrom(m => m.GetThumbnailUrl(
this._options.GetSection("Storage")["CdnUrl"],
this._options.GetSection("ImageFileStorageSettings")["ContainerName"])));
@@ -42,9 +42,7 @@ namespace PodNoms.Api.Providers {
map => map.MapFrom(s => s.PictureUrl));
//API Resource to Domain
- CreateMap()
- .ForMember(v => v.ImageUrl, map => map.Ignore())
- ;
+ CreateMap();
CreateMap()
.ForMember(
e => e.ImageUrl,