From ceb03484dd8192c0f2d370ebb1f472642804aede Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Wed, 14 Mar 2018 00:03:11 +0000 Subject: [PATCH 01/13] Added migrations and new repository --- .../podcast-add-url-form.component.ts | 3 +- .../components/podcast/podcast.component.html | 92 +++++++------------ .../components/podcast/podcast.component.ts | 22 ++++- client/src/app/services/podcast.service.ts | 14 ++- server/Controllers/EntryController.cs | 1 + .../PodnomsDbContextModelSnapshot.cs | 41 ++++++++- server/Models/Podcast.cs | 12 +-- server/Persistence/IEntryRepository.cs | 6 +- server/Persistence/PodnomsContext.cs | 10 +- server/Startup.cs | 1 + 10 files changed, 119 insertions(+), 83 deletions(-) diff --git a/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.ts b/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.ts index 7cf7740..72da584 100644 --- a/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.ts +++ b/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.ts @@ -8,6 +8,7 @@ import { ViewChild } from '@angular/core'; import { PodcastService } from 'app/services/podcast.service'; +import { debounceTime } from 'rxjs/operator/debounceTime'; @Component({ selector: 'app-podcast-add-url-form', @@ -41,7 +42,7 @@ export class PodcastAddUrlFormComponent implements AfterViewInit { this._service.addEntry(entry).subscribe( e => { if (e) { - if (e.ProcessingStatus == 6) { + if (e.processingStatus == 6) { this.onUploadDeferred.emit(e); } else { this.onUrlAddComplete.emit(e); diff --git a/client/src/app/components/podcast/podcast.component.html b/client/src/app/components/podcast/podcast.component.html index 7ffbc20..a0c0442 100644 --- a/client/src/app/components/podcast/podcast.component.html +++ b/client/src/app/components/podcast/podcast.component.html @@ -1,89 +1,68 @@ -
+

{{podcast.title}}

-
- + - + +
+
+

This looks like a playlist? Shall we add all items (please note, this may result in a lot of episodes being downloaded to your device).

+
+ + +
+
+
- - +
- - + \ No newline at end of file diff --git a/client/src/app/components/podcast/podcast.component.ts b/client/src/app/components/podcast/podcast.component.ts index 5882e4d..1c2ce01 100644 --- a/client/src/app/components/podcast/podcast.component.ts +++ b/client/src/app/components/podcast/podcast.component.ts @@ -13,6 +13,7 @@ import { UpdateAction, AddAction } from 'app/actions/entries.actions'; import * as fromPodcast from 'app/reducers'; import * as fromPodcastActions from 'app/actions/podcast.actions'; import * as fromEntriesActions from 'app/actions/entries.actions'; +import { PodcastService } from 'app/services/podcast.service'; @Component({ selector: 'app-podcast', @@ -21,6 +22,7 @@ import * as fromEntriesActions from 'app/actions/entries.actions'; }) export class PodcastComponent { selectedPodcast$: Observable; + pendingEntry: PodcastEntryModel = null; entries$: Observable; uploadMode = false; urlMode = false; @@ -36,6 +38,8 @@ export class PodcastComponent { constructor( private _store: Store, + private _service: PodcastService, + private _toasty: ToastyService, route: ActivatedRoute, private _location: Location ) { @@ -88,11 +92,25 @@ export class PodcastComponent { this._store.dispatch(new fromEntriesActions.AddSuccessAction(entry)); this._store.dispatch(new fromEntriesActions.UpdateAction(entry)); } - onEntryUploadDeferred($event) { - + onEntryUploadDeferred(entry: PodcastEntryModel) { + this.pendingEntry = entry; } onUrlAddComplete(entry: PodcastEntryModel) { this.urlMode = false; this._store.dispatch(new fromEntriesActions.AddSuccessAction(entry)); } + processPlaylist() { + if (this.pendingEntry) { + this._service.addPlaylist(this.pendingEntry) + .subscribe(e => { + if (e) { + this._toasty.info('Playlist added, check back here (and on your device) for new episodes'); + } + }); + } + } + dismissPlaylist() { + this.urlMode = false; + this.pendingEntry = null; + } } diff --git a/client/src/app/services/podcast.service.ts b/client/src/app/services/podcast.service.ts index 0d2783b..a186a76 100644 --- a/client/src/app/services/podcast.service.ts +++ b/client/src/app/services/podcast.service.ts @@ -13,7 +13,7 @@ export class PodcastService { } return value; } - constructor(private _http: AuthHttp) {} + constructor(private _http: AuthHttp) { } //#region Podcasts get(): Observable { return this._http @@ -68,8 +68,16 @@ export class PodcastService { } reSubmitEntry(entry: PodcastEntryModel): Observable { return this._http - .post(environment.API_HOST + '/entry/resubmit', entry) - .map(res => res.json()); + .post(environment.API_HOST + '/entry/resubmit', entry) + .map(res => res.json()); + } + //#endregion + + //#region Playlists + addPlaylist(entry: PodcastEntryModel) { + return this._http + .post(environment.API_HOST + '/playlist', JSON.stringify(entry)) + .map(res => res.json()); } //#endregion } diff --git a/server/Controllers/EntryController.cs b/server/Controllers/EntryController.cs index cd2d8dd..e24cb0c 100644 --- a/server/Controllers/EntryController.cs +++ b/server/Controllers/EntryController.cs @@ -16,6 +16,7 @@ using PodNoms.Api.Services.Processor; using PodNoms.Api.Services.Storage; namespace PodNoms.Api.Controllers { + [Route("[controller]")] public class EntryController : Controller { private readonly IPodcastRepository _podcastRepository; diff --git a/server/Migrations/PodnomsDbContextModelSnapshot.cs b/server/Migrations/PodnomsDbContextModelSnapshot.cs index dc5481b..3b369cd 100644 --- a/server/Migrations/PodnomsDbContextModelSnapshot.cs +++ b/server/Migrations/PodnomsDbContextModelSnapshot.cs @@ -1,13 +1,14 @@ // +using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; using PodNoms.Api.Models; using PodNoms.Api.Persistence; -using System; namespace PodNoms.Api.Migrations { @@ -18,9 +19,29 @@ namespace PodNoms.Api.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "2.0.0-rtm-26452") + .HasAnnotation("ProductVersion", "2.1.0-preview1-28290") .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + 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") @@ -73,6 +94,8 @@ namespace PodNoms.Api.Migrations b.Property("ImageUrl"); + b.Property("PlaylistId"); + b.Property("PodcastId"); b.Property("Processed"); @@ -91,6 +114,8 @@ namespace PodNoms.Api.Migrations b.HasKey("Id"); + b.HasIndex("PlaylistId"); + b.HasIndex("PodcastId"); b.ToTable("PodcastEntries"); @@ -136,6 +161,14 @@ namespace PodNoms.Api.Migrations b.ToTable("Users"); }); + 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.Models.User", "User") @@ -145,6 +178,10 @@ namespace PodNoms.Api.Migrations 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") diff --git a/server/Models/Podcast.cs b/server/Models/Podcast.cs index 887b1f2..7262bff 100644 --- a/server/Models/Podcast.cs +++ b/server/Models/Podcast.cs @@ -2,10 +2,8 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using Microsoft.Extensions.Options; -namespace PodNoms.Api.Models -{ - public class Podcast : BaseModel - { +namespace PodNoms.Api.Models { + public class Podcast : BaseModel { public int Id { get; set; } public string Uid { get; set; } public User User { get; set; } @@ -14,13 +12,11 @@ namespace PodNoms.Api.Models public string Slug { get; set; } public string ImageUrl { get; set; } public List PodcastEntries { get; set; } - public Podcast() - { + public Podcast() { PodcastEntries = new List(); } - public string GetImageUrl(string cdnUrl, string containerName) - { + public string GetImageUrl(string cdnUrl, string containerName) { return $"{cdnUrl}{containerName}/{this.ImageUrl}"; } } diff --git a/server/Persistence/IEntryRepository.cs b/server/Persistence/IEntryRepository.cs index 02b58d1..009252b 100644 --- a/server/Persistence/IEntryRepository.cs +++ b/server/Persistence/IEntryRepository.cs @@ -2,10 +2,8 @@ using System.Collections.Generic; using System.Threading.Tasks; using PodNoms.Api.Models; -namespace PodNoms.Api.Persistence -{ - public interface IEntryRepository - { +namespace PodNoms.Api.Persistence { + public interface IEntryRepository { Task GetAsync(int id); Task GetByUidAsync(string uid); Task> GetAllAsync(int podcastId); diff --git a/server/Persistence/PodnomsContext.cs b/server/Persistence/PodnomsContext.cs index 6fb2da5..88a0dae 100644 --- a/server/Persistence/PodnomsContext.cs +++ b/server/Persistence/PodnomsContext.cs @@ -6,15 +6,12 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.Configuration; using PodNoms.Api.Models; -namespace PodNoms.Api.Persistence -{ +namespace PodNoms.Api.Persistence { - public class PodnomsDbContext : DbContext - { + public class PodnomsDbContext : DbContext { public PodnomsDbContext(DbContextOptions options) : base(options) { } - protected override void OnModelCreating(ModelBuilder modelBuilder) - { + protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); @@ -38,6 +35,7 @@ namespace PodNoms.Api.Persistence public DbSet Podcasts { get; set; } public DbSet PodcastEntries { get; set; } + public DbSet Playlists { get; set; } public DbSet Users { get; set; } } } \ No newline at end of file diff --git a/server/Startup.cs b/server/Startup.cs index cbc61d1..a950863 100644 --- a/server/Startup.cs +++ b/server/Startup.cs @@ -151,6 +151,7 @@ namespace PodNoms.Api { services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); From 666cf20732bc3624595e0365d12c03070c41aa9d Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Wed, 14 Mar 2018 00:03:28 +0000 Subject: [PATCH 02/13] Added migrations and new repository --- server/Controllers/PlaylistController.cs | 42 ++++ ...313232409_Added playlist model.Designer.cs | 194 ++++++++++++++++++ .../20180313232409_Added playlist model.cs | 76 +++++++ server/Models/Playlist.cs | 11 + server/Persistence/IPlaylistRepository.cs | 9 + server/Persistence/PlaylistRepository.cs | 30 +++ 6 files changed, 362 insertions(+) create mode 100644 server/Controllers/PlaylistController.cs create mode 100644 server/Migrations/20180313232409_Added playlist model.Designer.cs create mode 100644 server/Migrations/20180313232409_Added playlist model.cs create mode 100644 server/Models/Playlist.cs create mode 100644 server/Persistence/IPlaylistRepository.cs create mode 100644 server/Persistence/PlaylistRepository.cs diff --git a/server/Controllers/PlaylistController.cs b/server/Controllers/PlaylistController.cs new file mode 100644 index 0000000..67e3f39 --- /dev/null +++ b/server/Controllers/PlaylistController.cs @@ -0,0 +1,42 @@ +using System.Threading.Tasks; +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using PodNoms.Api.Models; +using PodNoms.Api.Models.ViewModels; +using PodNoms.Api.Persistence; + +namespace PodNoms.Api.Controllers { + [Route("[controller]")] + public class PlaylistController : Controller { + private readonly IPlaylistRepository _playlistRepository; + private readonly IPodcastRepository _podcastRepository; + private readonly IUnitOfWork _unitOfWork; + private readonly IMapper _mapper; + private readonly ILogger _logger; + + public PlaylistController(IPlaylistRepository playlistRepository, IPodcastRepository podcastRepository, + IUnitOfWork unitOfWork, IMapper mapper, ILoggerFactory logger) { + this._logger = logger.CreateLogger(); + this._playlistRepository = playlistRepository; + this._podcastRepository = podcastRepository; + this._unitOfWork = unitOfWork; + this._mapper = mapper; + } + + [HttpPost] + public async Task> Post([FromBody] PodcastEntryViewModel entry) { + var podcast = await _podcastRepository.GetAsync(entry.PodcastId); + if (podcast != null) { + var playlist = new Playlist() { + PodcastId = entry.PodcastId, + SourceUrl = entry.SourceUrl + }; + await _playlistRepository.AddOrUpdateAsync(playlist); + await _unitOfWork.CompleteAsync(); + return Ok(playlist); + } + return NotFound(); + } + } +} diff --git a/server/Migrations/20180313232409_Added playlist model.Designer.cs b/server/Migrations/20180313232409_Added playlist model.Designer.cs new file mode 100644 index 0000000..110cea7 --- /dev/null +++ b/server/Migrations/20180313232409_Added playlist model.Designer.cs @@ -0,0 +1,194 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Internal; +using PodNoms.Api.Models; +using PodNoms.Api.Persistence; + +namespace PodNoms.Api.Migrations +{ + [DbContext(typeof(PodnomsDbContext))] + [Migration("20180313232409_Added playlist model")] + partial class Addedplaylistmodel + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.1.0-preview1-28290") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + 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("CreateDate") + .ValueGeneratedOnAdd() + .HasDefaultValueSql("getdate()"); + + b.Property("Description"); + + b.Property("ImageUrl"); + + b.Property("Slug") + .IsUnicode(true); + + b.Property("Title"); + + b.Property("Uid"); + + b.Property("UpdateDate"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + 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.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ApiKey") + .HasMaxLength(50); + + b.Property("CreateDate"); + + b.Property("EmailAddress") + .HasMaxLength(100); + + b.Property("FullName") + .HasMaxLength(100); + + b.Property("ProfileImage"); + + b.Property("ProviderId") + .HasMaxLength(50); + + b.Property("RefreshToken"); + + b.Property("Sid") + .HasMaxLength(50); + + b.Property("Slug") + .HasMaxLength(50); + + b.Property("UpdateDate"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique() + .HasFilter("[Slug] IS NOT NULL"); + + b.ToTable("Users"); + }); + + 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.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + 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/20180313232409_Added playlist model.cs b/server/Migrations/20180313232409_Added playlist model.cs new file mode 100644 index 0000000..488cb3f --- /dev/null +++ b/server/Migrations/20180313232409_Added playlist model.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace PodNoms.Api.Migrations +{ + public partial class Addedplaylistmodel : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "PlaylistId", + table: "PodcastEntries", + nullable: true); + + migrationBuilder.CreateTable( + name: "Playlists", + columns: table => new + { + CreateDate = table.Column(nullable: false), + UpdateDate = table.Column(nullable: false), + Id = table.Column(nullable: false) + .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), + PodcastId = table.Column(nullable: false), + SourceUrl = table.Column(nullable: true) + }, + 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.CreateIndex( + name: "IX_PodcastEntries_PlaylistId", + table: "PodcastEntries", + column: "PlaylistId"); + + migrationBuilder.CreateIndex( + name: "IX_Playlists_PodcastId", + table: "Playlists", + column: "PodcastId"); + + migrationBuilder.AddForeignKey( + name: "FK_PodcastEntries_Playlists_PlaylistId", + table: "PodcastEntries", + column: "PlaylistId", + principalTable: "Playlists", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PodcastEntries_Playlists_PlaylistId", + table: "PodcastEntries"); + + migrationBuilder.DropTable( + name: "Playlists"); + + migrationBuilder.DropIndex( + name: "IX_PodcastEntries_PlaylistId", + table: "PodcastEntries"); + + migrationBuilder.DropColumn( + name: "PlaylistId", + table: "PodcastEntries"); + } + } +} diff --git a/server/Models/Playlist.cs b/server/Models/Playlist.cs new file mode 100644 index 0000000..faa81f1 --- /dev/null +++ b/server/Models/Playlist.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace PodNoms.Api.Models { + public class Playlist : BaseModel { + public int Id { get; set; } + public int PodcastId { get; set; } + public string SourceUrl { get; set; } + public Podcast Podcast { get; set; } + public List PodcastEntries { get; set; } + } +} \ No newline at end of file diff --git a/server/Persistence/IPlaylistRepository.cs b/server/Persistence/IPlaylistRepository.cs new file mode 100644 index 0000000..bdb6ff8 --- /dev/null +++ b/server/Persistence/IPlaylistRepository.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; +using PodNoms.Api.Models; + +namespace PodNoms.Api.Persistence { + public interface IPlaylistRepository { + Task GetAsync(int id); + Task AddOrUpdateAsync(Playlist playlist); + } +} \ No newline at end of file diff --git a/server/Persistence/PlaylistRepository.cs b/server/Persistence/PlaylistRepository.cs new file mode 100644 index 0000000..efb58f0 --- /dev/null +++ b/server/Persistence/PlaylistRepository.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using PodNoms.Api.Models; + +namespace PodNoms.Api.Persistence { + public class PlaylistRepository : IPlaylistRepository { + private readonly PodnomsDbContext _context; + + public PlaylistRepository(PodnomsDbContext context) { + this._context = context; + } + public async Task GetAsync(int id) { + var entry = await _context.Playlists + .Include(e => e.Podcast) + .Include(e => e.Podcast.User) + .SingleOrDefaultAsync(e => e.Id == id); + return entry; + } + public async Task AddOrUpdateAsync(Playlist playlist) { + if (playlist.Id != 0) { + // _context.Entry(entry).State = EntityState.Modified + _context.Playlists.Attach(playlist); + _context.Entry(playlist).State = EntityState.Modified; + } else { + await _context.Playlists.AddAsync(playlist); + } + return playlist; + } + } +} \ No newline at end of file From 1a92ad80ebb925e8942c519bc788c8d20288c38d Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Wed, 14 Mar 2018 10:50:57 +0000 Subject: [PATCH 03/13] Feature switch --- .gitignore | 0 client/.angular-cli.json | 0 client/.editorconfig | 0 client/.gitignore | 0 client/.npmrc | 0 client/.vscode/launch.json | 0 client/README.md | 0 client/package-lock.json | 0 client/package.json | 0 client/src/app/actions/entries.actions.ts | 0 client/src/app/actions/podcast.actions.ts | 0 client/src/app/actions/profile.actions.ts | 0 client/src/app/app.component.css | 0 client/src/app/app.component.html | 0 client/src/app/app.component.ts | 0 client/src/app/app.module.ts | 0 client/src/app/app.router.ts | 0 .../app/components/about/about.component.css | 0 .../app/components/about/about.component.html | 0 .../app/components/about/about.component.ts | 0 .../callback/callback.component.css | 0 .../callback/callback.component.html | 0 .../components/callback/callback.component.ts | 0 .../app/components/debug/debug.component.css | 0 .../app/components/debug/debug.component.html | 0 .../app/components/debug/debug.component.ts | 0 .../components/footer/footer.component.css | 0 .../components/footer/footer.component.html | 0 .../app/components/footer/footer.component.ts | 0 .../app/components/home/home.component.css | 0 .../app/components/home/home.component.html | 0 .../src/app/components/home/home.component.ts | 0 .../app/components/login/login.component.css | 0 .../app/components/login/login.component.html | 0 .../app/components/login/login.component.ts | 0 .../components/navbar/navbar.component.css | 0 .../components/navbar/navbar.component.html | 0 .../app/components/navbar/navbar.component.ts | 0 .../entry-list-item.component.css | 0 .../entry-list-item.component.html | 0 .../entry-list-item.component.ts | 0 .../podcast-add-form.component.css | 0 .../podcast-add-form.component.html | 0 .../podcast-add-form.component.ts | 0 .../podcast-add-url-form.component.css | 0 .../podcast-add-url-form.component.html | 0 .../podcast-add-url-form.component.ts | 0 .../podcast-upload-form.component.css | 0 .../podcast-upload-form.component.html | 0 .../podcast-upload-form.component.ts | 0 .../components/podcast/podcast.component.css | 0 .../components/podcast/podcast.component.html | 0 .../components/podcast/podcast.component.ts | 0 .../components/profile/profile.component.css | 0 .../components/profile/profile.component.html | 0 .../components/profile/profile.component.ts | 0 .../register/register.component.css | 0 .../register/register.component.html | 0 .../components/register/register.component.ts | 0 .../app/components/reset/reset.component.css | 0 .../app/components/reset/reset.component.html | 0 .../app/components/reset/reset.component.ts | 0 .../shared/dropzone/dropzone.component.css | 0 .../shared/dropzone/dropzone.component.html | 0 .../shared/dropzone/dropzone.component.ts | 0 .../shared/dropzone/dropzone.directive.ts | 0 .../shared/dropzone/dropzone.interfaces.ts | 0 .../shared/dropzone/dropzone.module.ts | 0 .../components/sidebar/sidebar.component.css | 0 .../components/sidebar/sidebar.component.html | 0 .../components/sidebar/sidebar.component.ts | 0 client/src/app/effects/entries.effects.ts | 0 client/src/app/effects/podcast.effects.ts | 0 client/src/app/effects/profile.effects.ts | 0 client/src/app/models/podcasts.models.ts | 0 client/src/app/models/profile.model.ts | 0 client/src/app/pipes/filter-entry.pipe.ts | 0 client/src/app/pipes/order-by.pipe.ts | 0 client/src/app/pipes/pretty-print.pipe.ts | 0 client/src/app/pipes/safe.util.ts | 0 client/src/app/reducers/entries.reducer.ts | 0 client/src/app/reducers/index.ts | 0 client/src/app/reducers/podcasts.reducer.ts | 0 client/src/app/reducers/profile.reducer.ts | 0 client/src/app/services/auth.guard.ts | 0 client/src/app/services/auth.service.ts | 0 client/src/app/services/debug.service.ts | 0 client/src/app/services/entries.service.ts | 0 client/src/app/services/globals.service.ts | 0 client/src/app/services/image.service.ts | 0 client/src/app/services/jobs.service.ts | 0 client/src/app/services/podcast.service.ts | 0 client/src/app/services/profile.service.ts | 0 client/src/app/services/pusher.service.ts | 0 client/src/app/services/signalr.service.ts | 0 client/src/app/store/index.ts | 0 client/src/assets/.gitkeep | 0 client/src/assets/css/style.css | 0 client/src/assets/img/logo-icon.png | Bin client/src/assets/img/logo.png | Bin client/src/assets/img/processing.gif | Bin client/src/assets/img/robothand.jpg | Bin client/src/assets/img/select.png | Bin client/src/assets/img/select2-spinner.gif | Bin client/src/assets/img/select2.png | Bin client/src/assets/img/select2x2.png | Bin client/src/assets/img/sort_asc.png | Bin client/src/assets/img/sort_asc_disabled.png | Bin client/src/assets/img/sort_both.png | Bin client/src/assets/img/sort_desc.png | Bin client/src/assets/img/sort_desc_disabled.png | Bin client/src/assets/img/sprite-skin-modern.png | Bin client/src/environments/environment.prod.ts | 0 client/src/environments/environment.ts | 0 client/src/favicon.ico | Bin client/src/index.html | 0 client/src/main.ts | 0 client/src/polyfills.ts | 0 client/src/styles.css | 0 client/src/tsconfig.app.json | 0 client/src/typings.d.ts | 0 client/tsconfig.json | 0 client/tslint.json | 0 client/upgrade_cli | 0 docker/.gitignore | 0 docker/docker-compose.yml | 0 docker/letsencrypt.sh | 0 docker/nginx/Dockerfile | 0 docker/nginx/conf.d/podnoms.conf | 0 server/.dockerignore | 0 server/.gitignore | 0 server/Controllers/AudioUploadController.cs | 0 server/Controllers/DebugController.cs | 0 server/Controllers/EntryController.cs | 0 server/Controllers/ImageUploadController.cs | 0 server/Controllers/JobController.cs | 0 server/Controllers/PlaylistController.cs | 0 server/Controllers/PodcastController.cs | 0 server/Controllers/ProfileController.cs | 0 server/Controllers/RssController.cs | 0 server/Controllers/SilentController.cs | 0 server/Dockerfile | 0 .../20170717195629_Initial.Designer.cs | 0 server/Migrations/20170717195629_Initial.cs | 0 .../20170717210912_SlugInUser.Designer.cs | 0 .../Migrations/20170717210912_SlugInUser.cs | 0 ...170718193205_AddedUserSlugKeys.Designer.cs | 0 .../20170718193205_AddedUserSlugKeys.cs | 0 ...720194622_CreatedDate defaults.Designer.cs | 0 .../20170720194622_CreatedDate defaults.cs | 0 ..._UidInPodcastAndRemoveImageUrl.Designer.cs | 0 ...806234745_UidInPodcastAndRemoveImageUrl.cs | 0 ...171016143832_PodcastUniqueSlug.Designer.cs | 0 .../20171016143832_PodcastUniqueSlug.cs | 0 ...1023212048_RemoveSlugFromEntry.Designer.cs | 0 .../20171023212048_RemoveSlugFromEntry.cs | 0 ...20171028164700_PodcastImageUrl.Designer.cs | 0 .../20171028164700_PodcastImageUrl.cs | 0 ...0171218202137_UserRefreshToken.Designer.cs | 0 .../20171218202137_UserRefreshToken.cs | 0 ...313232409_Added playlist model.Designer.cs | 0 .../20180313232409_Added playlist model.cs | 0 .../PodnomsDbContextModelSnapshot.cs | 0 server/Models/AppSettings.cs | 0 server/Models/BaseModel.cs | 0 server/Models/ImageSettings.cs | 0 server/Models/Playlist.cs | 0 server/Models/Podcast.cs | 0 server/Models/PodcastEntry.cs | 0 server/Models/User.cs | 0 server/Models/ViewModels/DownloadProgress.cs | 0 server/Models/ViewModels/ProfileViewModel.cs | 0 .../ViewModels/Resources/EntryViewModel.cs | 0 .../ViewModels/Resources/PodcastViewModel.cs | 0 .../RssViewModels/PodcastRssViewModel.cs | 0 server/NuGet.config | 0 server/Persistence/EntryRepository.cs | 0 server/Persistence/IEntryRepository.cs | 0 server/Persistence/IPlaylistRepository.cs | 2 + server/Persistence/IPodcastRepository.cs | 0 server/Persistence/IUnitOfWork.cs | 0 server/Persistence/IUserRepository.cs | 0 server/Persistence/PlaylistRepository.cs | 4 ++ server/Persistence/PodcastRepository.cs | 43 ++++++------------ server/Persistence/PodnomsContext.cs | 0 server/Persistence/UnitOfWork.cs | 0 server/Persistence/UserRepository.cs | 0 server/PodNoms.Api.csproj | 0 server/Program.cs | 0 .../DisableFormValueModelBindingAttribute.cs | 0 server/Providers/MappingProvider.cs | 0 server/Resources/podcast.xml | 0 .../Services/Auth/AuthenticationMiddleware.cs | 0 .../Auth/ClaimsPrincipalExtensions.cs | 0 .../Auth/HangFireAuthorizationFilter.cs | 0 server/Services/Downloader/AudioDownloader.cs | 0 .../Services/Downloader/DownloadEventArgs.cs | 0 server/Services/Hubs/AudioProcessingHub.cs | 0 server/Services/Hubs/DebugHub.cs | 0 .../Services/Hubs/DebugHubLifetimeManager.cs | 0 server/Services/Jobs/ClearOrphanAudioJob.cs | 0 server/Services/Jobs/IJob.cs | 6 +-- server/Services/Jobs/JobBootstrapper.cs | 0 .../Processor/AudioUploadProcessService.cs | 0 .../Processor/IAudioUploadProcessService.cs | 0 .../Services/Processor/IUrlProcessService.cs | 0 server/Services/Processor/ProcessService.cs | 0 .../Processor/ServiceProviderActivator.cs | 0 .../Services/Processor/UrlProcessService.cs | 0 server/Services/Realtime/EntityUpdateHub.cs | 0 server/Services/Realtime/IRealTimeUpdater.cs | 0 server/Services/Realtime/SignalRUpdater.cs | 0 server/Services/RemoteAudioTypes.cs | 0 server/Services/Storage/AzureFileUploader.cs | 0 .../Services/Storage/CachedFormFileStorage.cs | 0 server/Services/Storage/IFileUploader.cs | 0 server/Startup.cs | 0 server/Utils/Crypt/HMACGenerator.cs | 0 server/Utils/Crypt/MD5Generator.cs | 0 server/Utils/DateUtils.cs | 0 server/Utils/Extensions/DateTime.cs | 0 server/Utils/Extensions/ProcessExtensions.cs | 0 server/Utils/Extensions/String.cs | 0 server/Utils/HttpUtils.cs | 0 server/Utils/HumanFriendlyInteger.cs | 0 server/Utils/ImageUtils.cs | 0 server/Utils/MultipartRequestHelper.cs | 0 server/Utils/Randomisers.cs | 0 server/Utils/ResourceReader.cs | 0 server/Utils/SwashbuckleLowercaseUrlFilter.cs | 0 server/appsettings.json | 0 server/commands.sql | 0 server/rebuild.sh | 0 server/resetdb.sh | 0 234 files changed, 22 insertions(+), 33 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 client/.angular-cli.json mode change 100644 => 100755 client/.editorconfig mode change 100644 => 100755 client/.gitignore mode change 100644 => 100755 client/.npmrc mode change 100644 => 100755 client/.vscode/launch.json mode change 100644 => 100755 client/README.md mode change 100644 => 100755 client/package-lock.json mode change 100644 => 100755 client/package.json mode change 100644 => 100755 client/src/app/actions/entries.actions.ts mode change 100644 => 100755 client/src/app/actions/podcast.actions.ts mode change 100644 => 100755 client/src/app/actions/profile.actions.ts mode change 100644 => 100755 client/src/app/app.component.css mode change 100644 => 100755 client/src/app/app.component.html mode change 100644 => 100755 client/src/app/app.component.ts mode change 100644 => 100755 client/src/app/app.module.ts mode change 100644 => 100755 client/src/app/app.router.ts mode change 100644 => 100755 client/src/app/components/about/about.component.css mode change 100644 => 100755 client/src/app/components/about/about.component.html mode change 100644 => 100755 client/src/app/components/about/about.component.ts mode change 100644 => 100755 client/src/app/components/callback/callback.component.css mode change 100644 => 100755 client/src/app/components/callback/callback.component.html mode change 100644 => 100755 client/src/app/components/callback/callback.component.ts mode change 100644 => 100755 client/src/app/components/debug/debug.component.css mode change 100644 => 100755 client/src/app/components/debug/debug.component.html mode change 100644 => 100755 client/src/app/components/debug/debug.component.ts mode change 100644 => 100755 client/src/app/components/footer/footer.component.css mode change 100644 => 100755 client/src/app/components/footer/footer.component.html mode change 100644 => 100755 client/src/app/components/footer/footer.component.ts mode change 100644 => 100755 client/src/app/components/home/home.component.css mode change 100644 => 100755 client/src/app/components/home/home.component.html mode change 100644 => 100755 client/src/app/components/home/home.component.ts mode change 100644 => 100755 client/src/app/components/login/login.component.css mode change 100644 => 100755 client/src/app/components/login/login.component.html mode change 100644 => 100755 client/src/app/components/login/login.component.ts mode change 100644 => 100755 client/src/app/components/navbar/navbar.component.css mode change 100644 => 100755 client/src/app/components/navbar/navbar.component.html mode change 100644 => 100755 client/src/app/components/navbar/navbar.component.ts mode change 100644 => 100755 client/src/app/components/podcast/entry-list-item/entry-list-item.component.css mode change 100644 => 100755 client/src/app/components/podcast/entry-list-item/entry-list-item.component.html mode change 100644 => 100755 client/src/app/components/podcast/entry-list-item/entry-list-item.component.ts mode change 100644 => 100755 client/src/app/components/podcast/podcast-add-form/podcast-add-form.component.css mode change 100644 => 100755 client/src/app/components/podcast/podcast-add-form/podcast-add-form.component.html mode change 100644 => 100755 client/src/app/components/podcast/podcast-add-form/podcast-add-form.component.ts mode change 100644 => 100755 client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.css mode change 100644 => 100755 client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.html mode change 100644 => 100755 client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.ts mode change 100644 => 100755 client/src/app/components/podcast/podcast-upload-form/podcast-upload-form.component.css mode change 100644 => 100755 client/src/app/components/podcast/podcast-upload-form/podcast-upload-form.component.html mode change 100644 => 100755 client/src/app/components/podcast/podcast-upload-form/podcast-upload-form.component.ts mode change 100644 => 100755 client/src/app/components/podcast/podcast.component.css mode change 100644 => 100755 client/src/app/components/podcast/podcast.component.html mode change 100644 => 100755 client/src/app/components/podcast/podcast.component.ts mode change 100644 => 100755 client/src/app/components/profile/profile.component.css mode change 100644 => 100755 client/src/app/components/profile/profile.component.html mode change 100644 => 100755 client/src/app/components/profile/profile.component.ts mode change 100644 => 100755 client/src/app/components/register/register.component.css mode change 100644 => 100755 client/src/app/components/register/register.component.html mode change 100644 => 100755 client/src/app/components/register/register.component.ts mode change 100644 => 100755 client/src/app/components/reset/reset.component.css mode change 100644 => 100755 client/src/app/components/reset/reset.component.html mode change 100644 => 100755 client/src/app/components/reset/reset.component.ts mode change 100644 => 100755 client/src/app/components/shared/dropzone/dropzone.component.css mode change 100644 => 100755 client/src/app/components/shared/dropzone/dropzone.component.html mode change 100644 => 100755 client/src/app/components/shared/dropzone/dropzone.component.ts mode change 100644 => 100755 client/src/app/components/shared/dropzone/dropzone.directive.ts mode change 100644 => 100755 client/src/app/components/shared/dropzone/dropzone.interfaces.ts mode change 100644 => 100755 client/src/app/components/shared/dropzone/dropzone.module.ts mode change 100644 => 100755 client/src/app/components/sidebar/sidebar.component.css mode change 100644 => 100755 client/src/app/components/sidebar/sidebar.component.html mode change 100644 => 100755 client/src/app/components/sidebar/sidebar.component.ts mode change 100644 => 100755 client/src/app/effects/entries.effects.ts mode change 100644 => 100755 client/src/app/effects/podcast.effects.ts mode change 100644 => 100755 client/src/app/effects/profile.effects.ts mode change 100644 => 100755 client/src/app/models/podcasts.models.ts mode change 100644 => 100755 client/src/app/models/profile.model.ts mode change 100644 => 100755 client/src/app/pipes/filter-entry.pipe.ts mode change 100644 => 100755 client/src/app/pipes/order-by.pipe.ts mode change 100644 => 100755 client/src/app/pipes/pretty-print.pipe.ts mode change 100644 => 100755 client/src/app/pipes/safe.util.ts mode change 100644 => 100755 client/src/app/reducers/entries.reducer.ts mode change 100644 => 100755 client/src/app/reducers/index.ts mode change 100644 => 100755 client/src/app/reducers/podcasts.reducer.ts mode change 100644 => 100755 client/src/app/reducers/profile.reducer.ts mode change 100644 => 100755 client/src/app/services/auth.guard.ts mode change 100644 => 100755 client/src/app/services/auth.service.ts mode change 100644 => 100755 client/src/app/services/debug.service.ts mode change 100644 => 100755 client/src/app/services/entries.service.ts mode change 100644 => 100755 client/src/app/services/globals.service.ts mode change 100644 => 100755 client/src/app/services/image.service.ts mode change 100644 => 100755 client/src/app/services/jobs.service.ts mode change 100644 => 100755 client/src/app/services/podcast.service.ts mode change 100644 => 100755 client/src/app/services/profile.service.ts mode change 100644 => 100755 client/src/app/services/pusher.service.ts mode change 100644 => 100755 client/src/app/services/signalr.service.ts mode change 100644 => 100755 client/src/app/store/index.ts mode change 100644 => 100755 client/src/assets/.gitkeep mode change 100644 => 100755 client/src/assets/css/style.css mode change 100644 => 100755 client/src/assets/img/logo-icon.png mode change 100644 => 100755 client/src/assets/img/logo.png mode change 100644 => 100755 client/src/assets/img/processing.gif mode change 100644 => 100755 client/src/assets/img/robothand.jpg mode change 100644 => 100755 client/src/assets/img/select.png mode change 100644 => 100755 client/src/assets/img/select2-spinner.gif mode change 100644 => 100755 client/src/assets/img/select2.png mode change 100644 => 100755 client/src/assets/img/select2x2.png mode change 100644 => 100755 client/src/assets/img/sort_asc.png mode change 100644 => 100755 client/src/assets/img/sort_asc_disabled.png mode change 100644 => 100755 client/src/assets/img/sort_both.png mode change 100644 => 100755 client/src/assets/img/sort_desc.png mode change 100644 => 100755 client/src/assets/img/sort_desc_disabled.png mode change 100644 => 100755 client/src/assets/img/sprite-skin-modern.png mode change 100644 => 100755 client/src/environments/environment.prod.ts mode change 100644 => 100755 client/src/environments/environment.ts mode change 100644 => 100755 client/src/favicon.ico mode change 100644 => 100755 client/src/index.html mode change 100644 => 100755 client/src/main.ts mode change 100644 => 100755 client/src/polyfills.ts mode change 100644 => 100755 client/src/styles.css mode change 100644 => 100755 client/src/tsconfig.app.json mode change 100644 => 100755 client/src/typings.d.ts mode change 100644 => 100755 client/tsconfig.json mode change 100644 => 100755 client/tslint.json mode change 100644 => 100755 client/upgrade_cli mode change 100644 => 100755 docker/.gitignore mode change 100644 => 100755 docker/docker-compose.yml mode change 100644 => 100755 docker/letsencrypt.sh mode change 100644 => 100755 docker/nginx/Dockerfile mode change 100644 => 100755 docker/nginx/conf.d/podnoms.conf mode change 100644 => 100755 server/.dockerignore mode change 100644 => 100755 server/.gitignore mode change 100644 => 100755 server/Controllers/AudioUploadController.cs mode change 100644 => 100755 server/Controllers/DebugController.cs mode change 100644 => 100755 server/Controllers/EntryController.cs mode change 100644 => 100755 server/Controllers/ImageUploadController.cs mode change 100644 => 100755 server/Controllers/JobController.cs mode change 100644 => 100755 server/Controllers/PlaylistController.cs mode change 100644 => 100755 server/Controllers/PodcastController.cs mode change 100644 => 100755 server/Controllers/ProfileController.cs mode change 100644 => 100755 server/Controllers/RssController.cs mode change 100644 => 100755 server/Controllers/SilentController.cs mode change 100644 => 100755 server/Dockerfile mode change 100644 => 100755 server/Migrations/20170717195629_Initial.Designer.cs mode change 100644 => 100755 server/Migrations/20170717195629_Initial.cs mode change 100644 => 100755 server/Migrations/20170717210912_SlugInUser.Designer.cs mode change 100644 => 100755 server/Migrations/20170717210912_SlugInUser.cs mode change 100644 => 100755 server/Migrations/20170718193205_AddedUserSlugKeys.Designer.cs mode change 100644 => 100755 server/Migrations/20170718193205_AddedUserSlugKeys.cs mode change 100644 => 100755 server/Migrations/20170720194622_CreatedDate defaults.Designer.cs mode change 100644 => 100755 server/Migrations/20170720194622_CreatedDate defaults.cs mode change 100644 => 100755 server/Migrations/20170806234745_UidInPodcastAndRemoveImageUrl.Designer.cs mode change 100644 => 100755 server/Migrations/20170806234745_UidInPodcastAndRemoveImageUrl.cs mode change 100644 => 100755 server/Migrations/20171016143832_PodcastUniqueSlug.Designer.cs mode change 100644 => 100755 server/Migrations/20171016143832_PodcastUniqueSlug.cs mode change 100644 => 100755 server/Migrations/20171023212048_RemoveSlugFromEntry.Designer.cs mode change 100644 => 100755 server/Migrations/20171023212048_RemoveSlugFromEntry.cs mode change 100644 => 100755 server/Migrations/20171028164700_PodcastImageUrl.Designer.cs mode change 100644 => 100755 server/Migrations/20171028164700_PodcastImageUrl.cs mode change 100644 => 100755 server/Migrations/20171218202137_UserRefreshToken.Designer.cs mode change 100644 => 100755 server/Migrations/20171218202137_UserRefreshToken.cs mode change 100644 => 100755 server/Migrations/20180313232409_Added playlist model.Designer.cs mode change 100644 => 100755 server/Migrations/20180313232409_Added playlist model.cs mode change 100644 => 100755 server/Migrations/PodnomsDbContextModelSnapshot.cs mode change 100644 => 100755 server/Models/AppSettings.cs mode change 100644 => 100755 server/Models/BaseModel.cs mode change 100644 => 100755 server/Models/ImageSettings.cs mode change 100644 => 100755 server/Models/Playlist.cs mode change 100644 => 100755 server/Models/Podcast.cs mode change 100644 => 100755 server/Models/PodcastEntry.cs mode change 100644 => 100755 server/Models/User.cs mode change 100644 => 100755 server/Models/ViewModels/DownloadProgress.cs mode change 100644 => 100755 server/Models/ViewModels/ProfileViewModel.cs mode change 100644 => 100755 server/Models/ViewModels/Resources/EntryViewModel.cs mode change 100644 => 100755 server/Models/ViewModels/Resources/PodcastViewModel.cs mode change 100644 => 100755 server/Models/ViewModels/RssViewModels/PodcastRssViewModel.cs mode change 100644 => 100755 server/NuGet.config mode change 100644 => 100755 server/Persistence/EntryRepository.cs mode change 100644 => 100755 server/Persistence/IEntryRepository.cs mode change 100644 => 100755 server/Persistence/IPlaylistRepository.cs mode change 100644 => 100755 server/Persistence/IPodcastRepository.cs mode change 100644 => 100755 server/Persistence/IUnitOfWork.cs mode change 100644 => 100755 server/Persistence/IUserRepository.cs mode change 100644 => 100755 server/Persistence/PlaylistRepository.cs mode change 100644 => 100755 server/Persistence/PodcastRepository.cs mode change 100644 => 100755 server/Persistence/PodnomsContext.cs mode change 100644 => 100755 server/Persistence/UnitOfWork.cs mode change 100644 => 100755 server/Persistence/UserRepository.cs mode change 100644 => 100755 server/PodNoms.Api.csproj mode change 100644 => 100755 server/Program.cs mode change 100644 => 100755 server/Providers/DisableFormValueModelBindingAttribute.cs mode change 100644 => 100755 server/Providers/MappingProvider.cs mode change 100644 => 100755 server/Resources/podcast.xml mode change 100644 => 100755 server/Services/Auth/AuthenticationMiddleware.cs mode change 100644 => 100755 server/Services/Auth/ClaimsPrincipalExtensions.cs mode change 100644 => 100755 server/Services/Auth/HangFireAuthorizationFilter.cs mode change 100644 => 100755 server/Services/Downloader/AudioDownloader.cs mode change 100644 => 100755 server/Services/Downloader/DownloadEventArgs.cs mode change 100644 => 100755 server/Services/Hubs/AudioProcessingHub.cs mode change 100644 => 100755 server/Services/Hubs/DebugHub.cs mode change 100644 => 100755 server/Services/Hubs/DebugHubLifetimeManager.cs mode change 100644 => 100755 server/Services/Jobs/ClearOrphanAudioJob.cs mode change 100644 => 100755 server/Services/Jobs/IJob.cs mode change 100644 => 100755 server/Services/Jobs/JobBootstrapper.cs mode change 100644 => 100755 server/Services/Processor/AudioUploadProcessService.cs mode change 100644 => 100755 server/Services/Processor/IAudioUploadProcessService.cs mode change 100644 => 100755 server/Services/Processor/IUrlProcessService.cs mode change 100644 => 100755 server/Services/Processor/ProcessService.cs mode change 100644 => 100755 server/Services/Processor/ServiceProviderActivator.cs mode change 100644 => 100755 server/Services/Processor/UrlProcessService.cs mode change 100644 => 100755 server/Services/Realtime/EntityUpdateHub.cs mode change 100644 => 100755 server/Services/Realtime/IRealTimeUpdater.cs mode change 100644 => 100755 server/Services/Realtime/SignalRUpdater.cs mode change 100644 => 100755 server/Services/RemoteAudioTypes.cs mode change 100644 => 100755 server/Services/Storage/AzureFileUploader.cs mode change 100644 => 100755 server/Services/Storage/CachedFormFileStorage.cs mode change 100644 => 100755 server/Services/Storage/IFileUploader.cs mode change 100644 => 100755 server/Startup.cs mode change 100644 => 100755 server/Utils/Crypt/HMACGenerator.cs mode change 100644 => 100755 server/Utils/Crypt/MD5Generator.cs mode change 100644 => 100755 server/Utils/DateUtils.cs mode change 100644 => 100755 server/Utils/Extensions/DateTime.cs mode change 100644 => 100755 server/Utils/Extensions/ProcessExtensions.cs mode change 100644 => 100755 server/Utils/Extensions/String.cs mode change 100644 => 100755 server/Utils/HttpUtils.cs mode change 100644 => 100755 server/Utils/HumanFriendlyInteger.cs mode change 100644 => 100755 server/Utils/ImageUtils.cs mode change 100644 => 100755 server/Utils/MultipartRequestHelper.cs mode change 100644 => 100755 server/Utils/Randomisers.cs mode change 100644 => 100755 server/Utils/ResourceReader.cs mode change 100644 => 100755 server/Utils/SwashbuckleLowercaseUrlFilter.cs mode change 100644 => 100755 server/appsettings.json mode change 100644 => 100755 server/commands.sql mode change 100644 => 100755 server/rebuild.sh mode change 100644 => 100755 server/resetdb.sh diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/client/.angular-cli.json b/client/.angular-cli.json old mode 100644 new mode 100755 diff --git a/client/.editorconfig b/client/.editorconfig old mode 100644 new mode 100755 diff --git a/client/.gitignore b/client/.gitignore old mode 100644 new mode 100755 diff --git a/client/.npmrc b/client/.npmrc old mode 100644 new mode 100755 diff --git a/client/.vscode/launch.json b/client/.vscode/launch.json old mode 100644 new mode 100755 diff --git a/client/README.md b/client/README.md old mode 100644 new mode 100755 diff --git a/client/package-lock.json b/client/package-lock.json old mode 100644 new mode 100755 diff --git a/client/package.json b/client/package.json old mode 100644 new mode 100755 diff --git a/client/src/app/actions/entries.actions.ts b/client/src/app/actions/entries.actions.ts old mode 100644 new mode 100755 diff --git a/client/src/app/actions/podcast.actions.ts b/client/src/app/actions/podcast.actions.ts old mode 100644 new mode 100755 diff --git a/client/src/app/actions/profile.actions.ts b/client/src/app/actions/profile.actions.ts old mode 100644 new mode 100755 diff --git a/client/src/app/app.component.css b/client/src/app/app.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts old mode 100644 new mode 100755 diff --git a/client/src/app/app.router.ts b/client/src/app/app.router.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/about/about.component.css b/client/src/app/components/about/about.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/about/about.component.html b/client/src/app/components/about/about.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/about/about.component.ts b/client/src/app/components/about/about.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/callback/callback.component.css b/client/src/app/components/callback/callback.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/callback/callback.component.html b/client/src/app/components/callback/callback.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/callback/callback.component.ts b/client/src/app/components/callback/callback.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/debug/debug.component.css b/client/src/app/components/debug/debug.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/debug/debug.component.html b/client/src/app/components/debug/debug.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/debug/debug.component.ts b/client/src/app/components/debug/debug.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/footer/footer.component.css b/client/src/app/components/footer/footer.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/footer/footer.component.html b/client/src/app/components/footer/footer.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/footer/footer.component.ts b/client/src/app/components/footer/footer.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/home/home.component.css b/client/src/app/components/home/home.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/home/home.component.html b/client/src/app/components/home/home.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/home/home.component.ts b/client/src/app/components/home/home.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/login/login.component.css b/client/src/app/components/login/login.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/login/login.component.html b/client/src/app/components/login/login.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/login/login.component.ts b/client/src/app/components/login/login.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/navbar/navbar.component.css b/client/src/app/components/navbar/navbar.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/navbar/navbar.component.html b/client/src/app/components/navbar/navbar.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/navbar/navbar.component.ts b/client/src/app/components/navbar/navbar.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/entry-list-item/entry-list-item.component.css b/client/src/app/components/podcast/entry-list-item/entry-list-item.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/entry-list-item/entry-list-item.component.html b/client/src/app/components/podcast/entry-list-item/entry-list-item.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/entry-list-item/entry-list-item.component.ts b/client/src/app/components/podcast/entry-list-item/entry-list-item.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast-add-form/podcast-add-form.component.css b/client/src/app/components/podcast/podcast-add-form/podcast-add-form.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast-add-form/podcast-add-form.component.html b/client/src/app/components/podcast/podcast-add-form/podcast-add-form.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast-add-form/podcast-add-form.component.ts b/client/src/app/components/podcast/podcast-add-form/podcast-add-form.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.css b/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.html b/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.ts b/client/src/app/components/podcast/podcast-add-url-form/podcast-add-url-form.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast-upload-form/podcast-upload-form.component.css b/client/src/app/components/podcast/podcast-upload-form/podcast-upload-form.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast-upload-form/podcast-upload-form.component.html b/client/src/app/components/podcast/podcast-upload-form/podcast-upload-form.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast-upload-form/podcast-upload-form.component.ts b/client/src/app/components/podcast/podcast-upload-form/podcast-upload-form.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast.component.css b/client/src/app/components/podcast/podcast.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast.component.html b/client/src/app/components/podcast/podcast.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/podcast/podcast.component.ts b/client/src/app/components/podcast/podcast.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/profile/profile.component.css b/client/src/app/components/profile/profile.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/profile/profile.component.html b/client/src/app/components/profile/profile.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/profile/profile.component.ts b/client/src/app/components/profile/profile.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/register/register.component.css b/client/src/app/components/register/register.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/register/register.component.html b/client/src/app/components/register/register.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/register/register.component.ts b/client/src/app/components/register/register.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/reset/reset.component.css b/client/src/app/components/reset/reset.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/reset/reset.component.html b/client/src/app/components/reset/reset.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/reset/reset.component.ts b/client/src/app/components/reset/reset.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/shared/dropzone/dropzone.component.css b/client/src/app/components/shared/dropzone/dropzone.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/shared/dropzone/dropzone.component.html b/client/src/app/components/shared/dropzone/dropzone.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/shared/dropzone/dropzone.component.ts b/client/src/app/components/shared/dropzone/dropzone.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/shared/dropzone/dropzone.directive.ts b/client/src/app/components/shared/dropzone/dropzone.directive.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/shared/dropzone/dropzone.interfaces.ts b/client/src/app/components/shared/dropzone/dropzone.interfaces.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/shared/dropzone/dropzone.module.ts b/client/src/app/components/shared/dropzone/dropzone.module.ts old mode 100644 new mode 100755 diff --git a/client/src/app/components/sidebar/sidebar.component.css b/client/src/app/components/sidebar/sidebar.component.css old mode 100644 new mode 100755 diff --git a/client/src/app/components/sidebar/sidebar.component.html b/client/src/app/components/sidebar/sidebar.component.html old mode 100644 new mode 100755 diff --git a/client/src/app/components/sidebar/sidebar.component.ts b/client/src/app/components/sidebar/sidebar.component.ts old mode 100644 new mode 100755 diff --git a/client/src/app/effects/entries.effects.ts b/client/src/app/effects/entries.effects.ts old mode 100644 new mode 100755 diff --git a/client/src/app/effects/podcast.effects.ts b/client/src/app/effects/podcast.effects.ts old mode 100644 new mode 100755 diff --git a/client/src/app/effects/profile.effects.ts b/client/src/app/effects/profile.effects.ts old mode 100644 new mode 100755 diff --git a/client/src/app/models/podcasts.models.ts b/client/src/app/models/podcasts.models.ts old mode 100644 new mode 100755 diff --git a/client/src/app/models/profile.model.ts b/client/src/app/models/profile.model.ts old mode 100644 new mode 100755 diff --git a/client/src/app/pipes/filter-entry.pipe.ts b/client/src/app/pipes/filter-entry.pipe.ts old mode 100644 new mode 100755 diff --git a/client/src/app/pipes/order-by.pipe.ts b/client/src/app/pipes/order-by.pipe.ts old mode 100644 new mode 100755 diff --git a/client/src/app/pipes/pretty-print.pipe.ts b/client/src/app/pipes/pretty-print.pipe.ts old mode 100644 new mode 100755 diff --git a/client/src/app/pipes/safe.util.ts b/client/src/app/pipes/safe.util.ts old mode 100644 new mode 100755 diff --git a/client/src/app/reducers/entries.reducer.ts b/client/src/app/reducers/entries.reducer.ts old mode 100644 new mode 100755 diff --git a/client/src/app/reducers/index.ts b/client/src/app/reducers/index.ts old mode 100644 new mode 100755 diff --git a/client/src/app/reducers/podcasts.reducer.ts b/client/src/app/reducers/podcasts.reducer.ts old mode 100644 new mode 100755 diff --git a/client/src/app/reducers/profile.reducer.ts b/client/src/app/reducers/profile.reducer.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/auth.guard.ts b/client/src/app/services/auth.guard.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/auth.service.ts b/client/src/app/services/auth.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/debug.service.ts b/client/src/app/services/debug.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/entries.service.ts b/client/src/app/services/entries.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/globals.service.ts b/client/src/app/services/globals.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/image.service.ts b/client/src/app/services/image.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/jobs.service.ts b/client/src/app/services/jobs.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/podcast.service.ts b/client/src/app/services/podcast.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/profile.service.ts b/client/src/app/services/profile.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/pusher.service.ts b/client/src/app/services/pusher.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/services/signalr.service.ts b/client/src/app/services/signalr.service.ts old mode 100644 new mode 100755 diff --git a/client/src/app/store/index.ts b/client/src/app/store/index.ts old mode 100644 new mode 100755 diff --git a/client/src/assets/.gitkeep b/client/src/assets/.gitkeep old mode 100644 new mode 100755 diff --git a/client/src/assets/css/style.css b/client/src/assets/css/style.css old mode 100644 new mode 100755 diff --git a/client/src/assets/img/logo-icon.png b/client/src/assets/img/logo-icon.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/logo.png b/client/src/assets/img/logo.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/processing.gif b/client/src/assets/img/processing.gif old mode 100644 new mode 100755 diff --git a/client/src/assets/img/robothand.jpg b/client/src/assets/img/robothand.jpg old mode 100644 new mode 100755 diff --git a/client/src/assets/img/select.png b/client/src/assets/img/select.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/select2-spinner.gif b/client/src/assets/img/select2-spinner.gif old mode 100644 new mode 100755 diff --git a/client/src/assets/img/select2.png b/client/src/assets/img/select2.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/select2x2.png b/client/src/assets/img/select2x2.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/sort_asc.png b/client/src/assets/img/sort_asc.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/sort_asc_disabled.png b/client/src/assets/img/sort_asc_disabled.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/sort_both.png b/client/src/assets/img/sort_both.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/sort_desc.png b/client/src/assets/img/sort_desc.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/sort_desc_disabled.png b/client/src/assets/img/sort_desc_disabled.png old mode 100644 new mode 100755 diff --git a/client/src/assets/img/sprite-skin-modern.png b/client/src/assets/img/sprite-skin-modern.png old mode 100644 new mode 100755 diff --git a/client/src/environments/environment.prod.ts b/client/src/environments/environment.prod.ts old mode 100644 new mode 100755 diff --git a/client/src/environments/environment.ts b/client/src/environments/environment.ts old mode 100644 new mode 100755 diff --git a/client/src/favicon.ico b/client/src/favicon.ico old mode 100644 new mode 100755 diff --git a/client/src/index.html b/client/src/index.html old mode 100644 new mode 100755 diff --git a/client/src/main.ts b/client/src/main.ts old mode 100644 new mode 100755 diff --git a/client/src/polyfills.ts b/client/src/polyfills.ts old mode 100644 new mode 100755 diff --git a/client/src/styles.css b/client/src/styles.css old mode 100644 new mode 100755 diff --git a/client/src/tsconfig.app.json b/client/src/tsconfig.app.json old mode 100644 new mode 100755 diff --git a/client/src/typings.d.ts b/client/src/typings.d.ts old mode 100644 new mode 100755 diff --git a/client/tsconfig.json b/client/tsconfig.json old mode 100644 new mode 100755 diff --git a/client/tslint.json b/client/tslint.json old mode 100644 new mode 100755 diff --git a/client/upgrade_cli b/client/upgrade_cli old mode 100644 new mode 100755 diff --git a/docker/.gitignore b/docker/.gitignore old mode 100644 new mode 100755 diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml old mode 100644 new mode 100755 diff --git a/docker/letsencrypt.sh b/docker/letsencrypt.sh old mode 100644 new mode 100755 diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile old mode 100644 new mode 100755 diff --git a/docker/nginx/conf.d/podnoms.conf b/docker/nginx/conf.d/podnoms.conf old mode 100644 new mode 100755 diff --git a/server/.dockerignore b/server/.dockerignore old mode 100644 new mode 100755 diff --git a/server/.gitignore b/server/.gitignore old mode 100644 new mode 100755 diff --git a/server/Controllers/AudioUploadController.cs b/server/Controllers/AudioUploadController.cs old mode 100644 new mode 100755 diff --git a/server/Controllers/DebugController.cs b/server/Controllers/DebugController.cs old mode 100644 new mode 100755 diff --git a/server/Controllers/EntryController.cs b/server/Controllers/EntryController.cs old mode 100644 new mode 100755 diff --git a/server/Controllers/ImageUploadController.cs b/server/Controllers/ImageUploadController.cs old mode 100644 new mode 100755 diff --git a/server/Controllers/JobController.cs b/server/Controllers/JobController.cs old mode 100644 new mode 100755 diff --git a/server/Controllers/PlaylistController.cs b/server/Controllers/PlaylistController.cs old mode 100644 new mode 100755 diff --git a/server/Controllers/PodcastController.cs b/server/Controllers/PodcastController.cs old mode 100644 new mode 100755 diff --git a/server/Controllers/ProfileController.cs b/server/Controllers/ProfileController.cs old mode 100644 new mode 100755 diff --git a/server/Controllers/RssController.cs b/server/Controllers/RssController.cs old mode 100644 new mode 100755 diff --git a/server/Controllers/SilentController.cs b/server/Controllers/SilentController.cs old mode 100644 new mode 100755 diff --git a/server/Dockerfile b/server/Dockerfile old mode 100644 new mode 100755 diff --git a/server/Migrations/20170717195629_Initial.Designer.cs b/server/Migrations/20170717195629_Initial.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20170717195629_Initial.cs b/server/Migrations/20170717195629_Initial.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20170717210912_SlugInUser.Designer.cs b/server/Migrations/20170717210912_SlugInUser.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20170717210912_SlugInUser.cs b/server/Migrations/20170717210912_SlugInUser.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20170718193205_AddedUserSlugKeys.Designer.cs b/server/Migrations/20170718193205_AddedUserSlugKeys.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20170718193205_AddedUserSlugKeys.cs b/server/Migrations/20170718193205_AddedUserSlugKeys.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20170720194622_CreatedDate defaults.Designer.cs b/server/Migrations/20170720194622_CreatedDate defaults.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20170720194622_CreatedDate defaults.cs b/server/Migrations/20170720194622_CreatedDate defaults.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20170806234745_UidInPodcastAndRemoveImageUrl.Designer.cs b/server/Migrations/20170806234745_UidInPodcastAndRemoveImageUrl.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20170806234745_UidInPodcastAndRemoveImageUrl.cs b/server/Migrations/20170806234745_UidInPodcastAndRemoveImageUrl.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20171016143832_PodcastUniqueSlug.Designer.cs b/server/Migrations/20171016143832_PodcastUniqueSlug.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20171016143832_PodcastUniqueSlug.cs b/server/Migrations/20171016143832_PodcastUniqueSlug.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20171023212048_RemoveSlugFromEntry.Designer.cs b/server/Migrations/20171023212048_RemoveSlugFromEntry.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20171023212048_RemoveSlugFromEntry.cs b/server/Migrations/20171023212048_RemoveSlugFromEntry.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20171028164700_PodcastImageUrl.Designer.cs b/server/Migrations/20171028164700_PodcastImageUrl.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20171028164700_PodcastImageUrl.cs b/server/Migrations/20171028164700_PodcastImageUrl.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20171218202137_UserRefreshToken.Designer.cs b/server/Migrations/20171218202137_UserRefreshToken.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20171218202137_UserRefreshToken.cs b/server/Migrations/20171218202137_UserRefreshToken.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20180313232409_Added playlist model.Designer.cs b/server/Migrations/20180313232409_Added playlist model.Designer.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/20180313232409_Added playlist model.cs b/server/Migrations/20180313232409_Added playlist model.cs old mode 100644 new mode 100755 diff --git a/server/Migrations/PodnomsDbContextModelSnapshot.cs b/server/Migrations/PodnomsDbContextModelSnapshot.cs old mode 100644 new mode 100755 diff --git a/server/Models/AppSettings.cs b/server/Models/AppSettings.cs old mode 100644 new mode 100755 diff --git a/server/Models/BaseModel.cs b/server/Models/BaseModel.cs old mode 100644 new mode 100755 diff --git a/server/Models/ImageSettings.cs b/server/Models/ImageSettings.cs old mode 100644 new mode 100755 diff --git a/server/Models/Playlist.cs b/server/Models/Playlist.cs old mode 100644 new mode 100755 diff --git a/server/Models/Podcast.cs b/server/Models/Podcast.cs old mode 100644 new mode 100755 diff --git a/server/Models/PodcastEntry.cs b/server/Models/PodcastEntry.cs old mode 100644 new mode 100755 diff --git a/server/Models/User.cs b/server/Models/User.cs old mode 100644 new mode 100755 diff --git a/server/Models/ViewModels/DownloadProgress.cs b/server/Models/ViewModels/DownloadProgress.cs old mode 100644 new mode 100755 diff --git a/server/Models/ViewModels/ProfileViewModel.cs b/server/Models/ViewModels/ProfileViewModel.cs old mode 100644 new mode 100755 diff --git a/server/Models/ViewModels/Resources/EntryViewModel.cs b/server/Models/ViewModels/Resources/EntryViewModel.cs old mode 100644 new mode 100755 diff --git a/server/Models/ViewModels/Resources/PodcastViewModel.cs b/server/Models/ViewModels/Resources/PodcastViewModel.cs old mode 100644 new mode 100755 diff --git a/server/Models/ViewModels/RssViewModels/PodcastRssViewModel.cs b/server/Models/ViewModels/RssViewModels/PodcastRssViewModel.cs old mode 100644 new mode 100755 diff --git a/server/NuGet.config b/server/NuGet.config old mode 100644 new mode 100755 diff --git a/server/Persistence/EntryRepository.cs b/server/Persistence/EntryRepository.cs old mode 100644 new mode 100755 diff --git a/server/Persistence/IEntryRepository.cs b/server/Persistence/IEntryRepository.cs old mode 100644 new mode 100755 diff --git a/server/Persistence/IPlaylistRepository.cs b/server/Persistence/IPlaylistRepository.cs old mode 100644 new mode 100755 index bdb6ff8..5261083 --- a/server/Persistence/IPlaylistRepository.cs +++ b/server/Persistence/IPlaylistRepository.cs @@ -1,9 +1,11 @@ +using System.Collections.Generic; using System.Threading.Tasks; using PodNoms.Api.Models; namespace PodNoms.Api.Persistence { public interface IPlaylistRepository { Task GetAsync(int id); + Task> GetAllAsync(); Task AddOrUpdateAsync(Playlist playlist); } } \ No newline at end of file diff --git a/server/Persistence/IPodcastRepository.cs b/server/Persistence/IPodcastRepository.cs old mode 100644 new mode 100755 diff --git a/server/Persistence/IUnitOfWork.cs b/server/Persistence/IUnitOfWork.cs old mode 100644 new mode 100755 diff --git a/server/Persistence/IUserRepository.cs b/server/Persistence/IUserRepository.cs old mode 100644 new mode 100755 diff --git a/server/Persistence/PlaylistRepository.cs b/server/Persistence/PlaylistRepository.cs old mode 100644 new mode 100755 index efb58f0..c44d211 --- a/server/Persistence/PlaylistRepository.cs +++ b/server/Persistence/PlaylistRepository.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using PodNoms.Api.Models; @@ -16,6 +17,9 @@ namespace PodNoms.Api.Persistence { .SingleOrDefaultAsync(e => e.Id == id); return entry; } + public async Task> GetAllAsync() { + return await _context.Playlists.ToListAsync(); + } public async Task AddOrUpdateAsync(Playlist playlist) { if (playlist.Id != 0) { // _context.Entry(entry).State = EntityState.Modified diff --git a/server/Persistence/PodcastRepository.cs b/server/Persistence/PodcastRepository.cs old mode 100644 new mode 100755 index 8ce37dd..fd19d00 --- a/server/Persistence/PodcastRepository.cs +++ b/server/Persistence/PodcastRepository.cs @@ -10,21 +10,17 @@ using PodNoms.Api.Services.Storage; using PodNoms.Api.Utils; using PodNoms.Api.Utils.Extensions; -namespace PodNoms.Api.Persistence -{ - public class PodcastRepository : IPodcastRepository - { +namespace PodNoms.Api.Persistence { + public class PodcastRepository : IPodcastRepository { private readonly PodnomsDbContext _context; public IFileUploader _fileUploader { get; } public ImageFileStorageSettings _imageStorageSettings { get; } - public PodcastRepository(PodnomsDbContext context, IFileUploader fileUploader, IOptions imageStorageSettings) - { + public PodcastRepository(PodnomsDbContext context, IFileUploader fileUploader, IOptions imageStorageSettings) { this._imageStorageSettings = imageStorageSettings.Value; this._fileUploader = fileUploader; this._context = context; } - public async Task GetAsync(int id) - { + public async Task GetAsync(int id) { var ret = await _context.Podcasts .Where(p => p.Id == id) .Include(p => p.User) @@ -32,8 +28,7 @@ namespace PodNoms.Api.Persistence return ret; } - public async Task GetAsync(string emailAddress, string slug) - { + public async Task GetAsync(string emailAddress, string slug) { var ret = await _context.Podcasts .Where(p => p.Slug == slug && p.User.EmailAddress == emailAddress) .Include(p => p.PodcastEntries) @@ -42,26 +37,20 @@ namespace PodNoms.Api.Persistence return ret; } - public async Task> GetAllAsync(string emailAddress) - { + public async Task> GetAllAsync(string emailAddress) { var ret = _context.Podcasts .Where(u => u.User.EmailAddress == emailAddress) .Include(p => p.User) .OrderByDescending(p => p.Id); return await ret.ToListAsync(); } - public async Task AddOrUpdateAsync(Podcast item) - { - if (item.Id != 0) - { + public async Task AddOrUpdateAsync(Podcast item) { + if (item.Id != 0) { _context.Entry(item).State = EntityState.Modified; - } - else - { + } else { var localFile = await HttpUtils.DownloadFile($"http://lorempixel.com/1400/1400/?{System.Guid.NewGuid().ToString()}"); item.Uid = System.Guid.NewGuid().ToString(); - if (string.IsNullOrEmpty(item.Slug) && !string.IsNullOrEmpty(item.Title)) - { + if (string.IsNullOrEmpty(item.Slug) && !string.IsNullOrEmpty(item.Title)) { item.Slug = item.Title.Slugify( from p in _context.Podcasts select p.Slug); @@ -74,15 +63,11 @@ namespace PodNoms.Api.Persistence return item; } - public async Task DeleteAsync(int id) - { + public async Task DeleteAsync(int id) { var podcast = await _context.Podcasts.SingleAsync(p => p.Id == id); - if (podcast != null) - { - if (podcast.PodcastEntries != null) - { - foreach (var entry in podcast.PodcastEntries) - { + if (podcast != null) { + if (podcast.PodcastEntries != null) { + foreach (var entry in podcast.PodcastEntries) { _context.Remove(entry); } } diff --git a/server/Persistence/PodnomsContext.cs b/server/Persistence/PodnomsContext.cs old mode 100644 new mode 100755 diff --git a/server/Persistence/UnitOfWork.cs b/server/Persistence/UnitOfWork.cs old mode 100644 new mode 100755 diff --git a/server/Persistence/UserRepository.cs b/server/Persistence/UserRepository.cs old mode 100644 new mode 100755 diff --git a/server/PodNoms.Api.csproj b/server/PodNoms.Api.csproj old mode 100644 new mode 100755 diff --git a/server/Program.cs b/server/Program.cs old mode 100644 new mode 100755 diff --git a/server/Providers/DisableFormValueModelBindingAttribute.cs b/server/Providers/DisableFormValueModelBindingAttribute.cs old mode 100644 new mode 100755 diff --git a/server/Providers/MappingProvider.cs b/server/Providers/MappingProvider.cs old mode 100644 new mode 100755 diff --git a/server/Resources/podcast.xml b/server/Resources/podcast.xml old mode 100644 new mode 100755 diff --git a/server/Services/Auth/AuthenticationMiddleware.cs b/server/Services/Auth/AuthenticationMiddleware.cs old mode 100644 new mode 100755 diff --git a/server/Services/Auth/ClaimsPrincipalExtensions.cs b/server/Services/Auth/ClaimsPrincipalExtensions.cs old mode 100644 new mode 100755 diff --git a/server/Services/Auth/HangFireAuthorizationFilter.cs b/server/Services/Auth/HangFireAuthorizationFilter.cs old mode 100644 new mode 100755 diff --git a/server/Services/Downloader/AudioDownloader.cs b/server/Services/Downloader/AudioDownloader.cs old mode 100644 new mode 100755 diff --git a/server/Services/Downloader/DownloadEventArgs.cs b/server/Services/Downloader/DownloadEventArgs.cs old mode 100644 new mode 100755 diff --git a/server/Services/Hubs/AudioProcessingHub.cs b/server/Services/Hubs/AudioProcessingHub.cs old mode 100644 new mode 100755 diff --git a/server/Services/Hubs/DebugHub.cs b/server/Services/Hubs/DebugHub.cs old mode 100644 new mode 100755 diff --git a/server/Services/Hubs/DebugHubLifetimeManager.cs b/server/Services/Hubs/DebugHubLifetimeManager.cs old mode 100644 new mode 100755 diff --git a/server/Services/Jobs/ClearOrphanAudioJob.cs b/server/Services/Jobs/ClearOrphanAudioJob.cs old mode 100644 new mode 100755 diff --git a/server/Services/Jobs/IJob.cs b/server/Services/Jobs/IJob.cs old mode 100644 new mode 100755 index c987433..0c4b66e --- a/server/Services/Jobs/IJob.cs +++ b/server/Services/Jobs/IJob.cs @@ -1,9 +1,7 @@ using System.Threading.Tasks; -namespace PodNoms.Api.Services.Jobs -{ - public interface IJob - { +namespace PodNoms.Api.Services.Jobs { + public interface IJob { Task Execute(); } } \ No newline at end of file diff --git a/server/Services/Jobs/JobBootstrapper.cs b/server/Services/Jobs/JobBootstrapper.cs old mode 100644 new mode 100755 diff --git a/server/Services/Processor/AudioUploadProcessService.cs b/server/Services/Processor/AudioUploadProcessService.cs old mode 100644 new mode 100755 diff --git a/server/Services/Processor/IAudioUploadProcessService.cs b/server/Services/Processor/IAudioUploadProcessService.cs old mode 100644 new mode 100755 diff --git a/server/Services/Processor/IUrlProcessService.cs b/server/Services/Processor/IUrlProcessService.cs old mode 100644 new mode 100755 diff --git a/server/Services/Processor/ProcessService.cs b/server/Services/Processor/ProcessService.cs old mode 100644 new mode 100755 diff --git a/server/Services/Processor/ServiceProviderActivator.cs b/server/Services/Processor/ServiceProviderActivator.cs old mode 100644 new mode 100755 diff --git a/server/Services/Processor/UrlProcessService.cs b/server/Services/Processor/UrlProcessService.cs old mode 100644 new mode 100755 diff --git a/server/Services/Realtime/EntityUpdateHub.cs b/server/Services/Realtime/EntityUpdateHub.cs old mode 100644 new mode 100755 diff --git a/server/Services/Realtime/IRealTimeUpdater.cs b/server/Services/Realtime/IRealTimeUpdater.cs old mode 100644 new mode 100755 diff --git a/server/Services/Realtime/SignalRUpdater.cs b/server/Services/Realtime/SignalRUpdater.cs old mode 100644 new mode 100755 diff --git a/server/Services/RemoteAudioTypes.cs b/server/Services/RemoteAudioTypes.cs old mode 100644 new mode 100755 diff --git a/server/Services/Storage/AzureFileUploader.cs b/server/Services/Storage/AzureFileUploader.cs old mode 100644 new mode 100755 diff --git a/server/Services/Storage/CachedFormFileStorage.cs b/server/Services/Storage/CachedFormFileStorage.cs old mode 100644 new mode 100755 diff --git a/server/Services/Storage/IFileUploader.cs b/server/Services/Storage/IFileUploader.cs old mode 100644 new mode 100755 diff --git a/server/Startup.cs b/server/Startup.cs old mode 100644 new mode 100755 diff --git a/server/Utils/Crypt/HMACGenerator.cs b/server/Utils/Crypt/HMACGenerator.cs old mode 100644 new mode 100755 diff --git a/server/Utils/Crypt/MD5Generator.cs b/server/Utils/Crypt/MD5Generator.cs old mode 100644 new mode 100755 diff --git a/server/Utils/DateUtils.cs b/server/Utils/DateUtils.cs old mode 100644 new mode 100755 diff --git a/server/Utils/Extensions/DateTime.cs b/server/Utils/Extensions/DateTime.cs old mode 100644 new mode 100755 diff --git a/server/Utils/Extensions/ProcessExtensions.cs b/server/Utils/Extensions/ProcessExtensions.cs old mode 100644 new mode 100755 diff --git a/server/Utils/Extensions/String.cs b/server/Utils/Extensions/String.cs old mode 100644 new mode 100755 diff --git a/server/Utils/HttpUtils.cs b/server/Utils/HttpUtils.cs old mode 100644 new mode 100755 diff --git a/server/Utils/HumanFriendlyInteger.cs b/server/Utils/HumanFriendlyInteger.cs old mode 100644 new mode 100755 diff --git a/server/Utils/ImageUtils.cs b/server/Utils/ImageUtils.cs old mode 100644 new mode 100755 diff --git a/server/Utils/MultipartRequestHelper.cs b/server/Utils/MultipartRequestHelper.cs old mode 100644 new mode 100755 diff --git a/server/Utils/Randomisers.cs b/server/Utils/Randomisers.cs old mode 100644 new mode 100755 diff --git a/server/Utils/ResourceReader.cs b/server/Utils/ResourceReader.cs old mode 100644 new mode 100755 diff --git a/server/Utils/SwashbuckleLowercaseUrlFilter.cs b/server/Utils/SwashbuckleLowercaseUrlFilter.cs old mode 100644 new mode 100755 diff --git a/server/appsettings.json b/server/appsettings.json old mode 100644 new mode 100755 diff --git a/server/commands.sql b/server/commands.sql old mode 100644 new mode 100755 diff --git a/server/rebuild.sh b/server/rebuild.sh old mode 100644 new mode 100755 diff --git a/server/resetdb.sh b/server/resetdb.sh old mode 100644 new mode 100755 From b2931886aa97a69b27f4e418e59147c3a8a8162f Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Wed, 14 Mar 2018 10:51:09 +0000 Subject: [PATCH 04/13] Feature switch --- server/Services/Jobs/ProcessPlaylistsJob.cs | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100755 server/Services/Jobs/ProcessPlaylistsJob.cs diff --git a/server/Services/Jobs/ProcessPlaylistsJob.cs b/server/Services/Jobs/ProcessPlaylistsJob.cs new file mode 100755 index 0000000..fe3ff85 --- /dev/null +++ b/server/Services/Jobs/ProcessPlaylistsJob.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using PodNoms.Api.Models; +using PodNoms.Api.Persistence; +using PodNoms.Api.Services.Downloader; + +namespace PodNoms.Api.Services.Jobs { + public class ProcessPlaylistsJob : IJob { + public readonly IPlaylistRepository _playlistRepository; + public readonly IEntryRepository _entryRepository; + private readonly ApplicationsSettings _applicationsSettings; + private readonly ILogger _logger; + + public ProcessPlaylistsJob(IPlaylistRepository playlistRepository, + IEntryRepository entryRepository, IOptions applicationsSettings, ILoggerFactory logger) { + _playlistRepository = playlistRepository; + _entryRepository = entryRepository; + _applicationsSettings = applicationsSettings.Value; + _logger = logger.CreateLogger(); + } + + public async Task Execute() { + var playists = await _playlistRepository.GetAllAsync(); + + foreach (var playlist in playists) { + var downloader = new AudioDownloader(playlist.SourceUrl, _applicationsSettings.Downloader); + var info = await downloader.GetInfo(); + if (info == AudioType.Playlist){ + var + for (var item in downloader.Properties.) + } + } + } + } +} \ No newline at end of file From b9b3a1c58c0ada30f71306586548f899041d2cc5 Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Wed, 14 Mar 2018 11:22:55 +0000 Subject: [PATCH 05/13] Added app insights --- client/package-lock.json | 13 ++++++++++++- client/package.json | 2 ++ client/src/app/app.component.ts | 3 ++- client/src/app/app.module.ts | 2 ++ client/src/app/services/app-insights.service.ts | 16 ++++++++++++++++ client/src/environments/environment.ts | 5 ++++- 6 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 client/src/app/services/app-insights.service.ts diff --git a/client/package-lock.json b/client/package-lock.json index 1ecf354..285e093 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,6 +1,6 @@ { "name": "pod-noms.web", - "version": "0.16.0", + "version": "0.17.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -309,6 +309,12 @@ } } }, + "@types/applicationinsights-js": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/applicationinsights-js/-/applicationinsights-js-1.0.5.tgz", + "integrity": "sha512-/obMaLeIWrL6FDYJC8v9VE2BrQJ2Y6iHgT/9UI6Xd30S/x0uDkJv/DGt1wMMJEmu+ShkR2KiR9L9OaJ1d91uoA==", + "dev": true + }, "@types/jasmine": { "version": "2.8.6", "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.6.tgz", @@ -568,6 +574,11 @@ "default-require-extensions": "1.0.0" } }, + "applicationinsights-js": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/applicationinsights-js/-/applicationinsights-js-1.0.15.tgz", + "integrity": "sha512-lxO7LOIkK38q3VE8covJMsGS3O04hPGgPaA8BmGyR3SYQhuIYX9qy14KMojqx239TlPR9YuPexVXTHdrGBATow==" + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", diff --git a/client/package.json b/client/package.json index 4655bd6..0b27d87 100644 --- a/client/package.json +++ b/client/package.json @@ -31,6 +31,7 @@ "@qontu/ngx-inline-editor": "^0.2.0-alpha.12", "angular2-jwt": "^0.2.3", "angular2-moment": "^1.8.0", + "applicationinsights-js": "^1.0.15", "auth0": "^2.9.1", "auth0-lock": "^11.3.1", "bootstrap": "4.0.0", @@ -54,6 +55,7 @@ "@angular/cli": "1.6.8", "@angular/compiler-cli": "^5.2.6", "@angular/language-service": "^5.2.6", + "@types/applicationinsights-js": "^1.0.5", "@types/jasmine": "^2.8.6", "@types/node": "~9.4.6", "codelyzer": "^4.2.1", diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts index 1a7e742..c50d54d 100644 --- a/client/src/app/app.component.ts +++ b/client/src/app/app.component.ts @@ -2,6 +2,7 @@ import { GlobalsService } from './services/globals.service'; import { Component, HostBinding } from '@angular/core'; import { Store } from '@ngrx/store'; import { AuthService } from 'app/services/auth.service'; +import { AppInsightsService } from 'app/services/app-insights.service'; @Component({ selector: 'app-root', @@ -9,7 +10,7 @@ import { AuthService } from 'app/services/auth.service'; styleUrls: ['./app.component.css'] }) export class AppComponent { - constructor(private _authService: AuthService) { + constructor(private _authService: AuthService, _appInsights: AppInsightsService) { _authService.handleAuthentication(); _authService.scheduleRenewal(); } diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts index 3448dfb..786b6ff 100644 --- a/client/src/app/app.module.ts +++ b/client/src/app/app.module.ts @@ -49,6 +49,7 @@ import { ProfileComponent } from './components/profile/profile.component'; import { AboutComponent } from './components/about/about.component'; import { FooterComponent } from './components/footer/footer.component'; import { JobsService } from 'app/services/jobs.service'; +import { AppInsightsService } from 'app/services/app-insights.service'; export function authHttpServiceFactory(http: Http, options: RequestOptions) { return new AuthHttp( @@ -123,6 +124,7 @@ export function authHttpServiceFactory(http: Http, options: RequestOptions) { PodcastService, ImageService, DebugService, + AppInsightsService, JobsService, GlobalsService ], diff --git a/client/src/app/services/app-insights.service.ts b/client/src/app/services/app-insights.service.ts new file mode 100644 index 0000000..89fc097 --- /dev/null +++ b/client/src/app/services/app-insights.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { AppInsights } from 'applicationinsights-js'; +import { environment } from 'environments/environment'; + +@Injectable() +export class AppInsightsService { + + private config: Microsoft.ApplicationInsights.IConfig = { + instrumentationKey: environment.appInsights.instrumentationKey + }; + constructor() { + if (!AppInsights.config){ + AppInsights.downloadAndSetup(this.config); + } + } +} diff --git a/client/src/environments/environment.ts b/client/src/environments/environment.ts index a1d9d01..1f8a637 100644 --- a/client/src/environments/environment.ts +++ b/client/src/environments/environment.ts @@ -3,5 +3,8 @@ export const environment = { API_HOST: 'http://dev.podnoms.com:5000', SIGNALR_HOST: 'http://dev.podnoms.com:5000/', AUTH0_REDIRECT_URL: 'http://dev.podnoms.com:4200/callback', - BASE_URL: 'http://dev.podnoms.com:4200/' + BASE_URL: 'http://dev.podnoms.com:4200/', + appInsights: { + instrumentationKey: '020b002a-bd3d-4b25-8a74-cab16fd39dfc' + } }; From f5299cfdf260cb2a476b89f3c4b8cecfaf60ca6d Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Thu, 15 Mar 2018 18:24:45 +0000 Subject: [PATCH 06/13] Env --- client/src/environments/environment.prod.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/environments/environment.prod.ts b/client/src/environments/environment.prod.ts index 68d80fc..a302bfa 100644 --- a/client/src/environments/environment.prod.ts +++ b/client/src/environments/environment.prod.ts @@ -3,6 +3,9 @@ export const environment = { API_HOST: 'https://podnoms.com/api', SIGNALR_HOST: 'https://rt.podnoms.com/', AUTH0_REDIRECT_URL: 'https://podnoms.com/callback', - BASE_URL: 'https://podnoms.com' + BASE_URL: 'https://podnoms.com', + appInsights: { + instrumentationKey: '020b002a-bd3d-4b25-8a74-cab16fd39dfc' + } }; From 740824256de113cee7ec140bb5cf605bd612423f Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Thu, 15 Mar 2018 20:04:25 +0000 Subject: [PATCH 07/13] Go suck it --- .gitignore | 1 + .../app/components/debug/debug.component.html | 4 ++ .../app/components/debug/debug.component.ts | 66 +++++++++++++------ client/src/app/services/jobs.service.ts | 9 ++- server/Controllers/JobController.cs | 19 ++++-- server/PodNoms.Api.csproj | 2 +- server/Services/Downloader/AudioDownloader.cs | 12 ++-- server/Services/Jobs/ProcessPlaylistsJob.cs | 4 +- server/Services/Jobs/UpdateYouTubeDlJob.cs | 15 +++++ server/commands | 3 + 10 files changed, 100 insertions(+), 35 deletions(-) create mode 100644 server/Services/Jobs/UpdateYouTubeDlJob.cs create mode 100644 server/commands diff --git a/.gitignore b/.gitignore index b2bf6fd..df089c2 100755 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ promotion .working extension client/tags +NYoutubeDL diff --git a/client/src/app/components/debug/debug.component.html b/client/src/app/components/debug/debug.component.html index b175847..17f2f69 100755 --- a/client/src/app/components/debug/debug.component.html +++ b/client/src/app/components/debug/debug.component.html @@ -28,6 +28,10 @@
+ +
diff --git a/client/src/app/components/debug/debug.component.ts b/client/src/app/components/debug/debug.component.ts index 16eab78..da5aa41 100755 --- a/client/src/app/components/debug/debug.component.ts +++ b/client/src/app/components/debug/debug.component.ts @@ -1,14 +1,14 @@ -import { Observable } from 'rxjs/Observable'; -import { SignalRService } from 'app/services/signalr.service'; -import { Component, OnInit } from '@angular/core'; -import { DebugService } from 'app/services/debug.service'; -import { environment } from 'environments/environment'; -import { JobsService } from 'app/services/jobs.service'; +import { Observable } from "rxjs/Observable"; +import { SignalRService } from "app/services/signalr.service"; +import { Component, OnInit } from "@angular/core"; +import { DebugService } from "app/services/debug.service"; +import { environment } from "environments/environment"; +import { JobsService } from "app/services/jobs.service"; @Component({ - selector: 'app-debug', - templateUrl: './debug.component.html', - styleUrls: ['./debug.component.css'] + selector: "app-debug", + templateUrl: "./debug.component.html", + styleUrls: ["./debug.component.css"] }) export class DebugComponent implements OnInit { realtimeMessage: string; @@ -17,35 +17,59 @@ export class DebugComponent implements OnInit { debugInfo$: Observable; apiHost = environment.API_HOST; signalrHost = environment.SIGNALR_HOST; - pingPong = ''; + pingPong = ""; - constructor(private _debugService: DebugService, private _jobsService: JobsService, - private _signalrService: SignalRService) {} + constructor( + private _debugService: DebugService, + private _jobsService: JobsService, + private _signalrService: SignalRService + ) {} ngOnInit() { this._signalrService .init(`${environment.SIGNALR_HOST}hubs/debug`) .then(() => { - this._signalrService.connection.on('Send', data => { - console.log('DebugService', 'signalr', data); + this._signalrService.connection.on("Send", data => { + console.log("DebugService", "signalr", data); this.messagesReceived.push(data); - this.realtimeMessage = ''; + this.realtimeMessage = ""; }); this.debugInfo$ = this._debugService.getDebugInfo(); }) - .catch(err => console.error('debug.component.ts', '_signalrService.init', err)); + .catch(err => + console.error("debug.component.ts", "_signalrService.init", err) + ); this._debugService.ping().subscribe(r => (this.pingPong = r)); } sendMessage() { - this._debugService.sendRealtime(this.realtimeMessage).subscribe(r => console.log(r)); + this._debugService + .sendRealtime(this.realtimeMessage) + .subscribe(r => console.log(r)); } doSomething() { - alert('doSomething was did'); + alert("doSomething was did"); } - processOrphans(){ - this._jobsService.processOrphans() - .subscribe(e => console.log('debug.component.ts', 'processOrphans', e)); + processOrphans() { + this._jobsService + .processOrphans() + .subscribe(e => + console.log("debug.component.ts", "processOrphans", e) + ); + } + processPlaylists() { + this._jobsService + .processPlaylists() + .subscribe(e => + console.log("debug.component.ts", "processPlaylists", e) + ); + } + updateYouTubeDl() { + this._jobsService + .updateYouTubeDl() + .subscribe(e => + console.log("debug.component.ts", "updateYouTubeDl", e) + ); } } diff --git a/client/src/app/services/jobs.service.ts b/client/src/app/services/jobs.service.ts index 12f52e2..4d5c9ca 100755 --- a/client/src/app/services/jobs.service.ts +++ b/client/src/app/services/jobs.service.ts @@ -6,9 +6,16 @@ import { environment } from 'environments/environment'; @Injectable() export class JobsService { - constructor(private _http: AuthHttp) {} + constructor(private _http: AuthHttp) { } processOrphans(): Observable { return this._http.get(environment.API_HOST + '/job/processorphans'); } + + processPlaylists(): Observable { + return this._http.get(environment.API_HOST + '/job/processplaylists'); + } + updateYouTubeDl(): Observable { + return this._http.get(environment.API_HOST + '/job/updateyoutubedl'); + } } diff --git a/server/Controllers/JobController.cs b/server/Controllers/JobController.cs index 93a8324..8db8431 100755 --- a/server/Controllers/JobController.cs +++ b/server/Controllers/JobController.cs @@ -4,18 +4,25 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PodNoms.Api.Services.Jobs; -namespace PodNoms.Api.Controllers -{ +namespace PodNoms.Api.Controllers { [Authorize] [Route("[controller]")] [ApiExplorerSettings(IgnoreApi = true)] - public class JobController : Controller - { + public class JobController : Controller { [HttpGet("processorphans")] - public IActionResult ProcessOrphans() - { + public IActionResult ProcessOrphans() { var infoJobId = BackgroundJob.Enqueue(service => service.Execute()); return Ok(); } + [HttpGet("processplaylists")] + public IActionResult ProcessPlaylists() { + var infoJobId = BackgroundJob.Enqueue(service => service.Execute()); + return Ok(); + } + [HttpGet("updateyoutubedl")] + public IActionResult UpdateYouTubeDl() { + var infoJobId = BackgroundJob.Enqueue(service => service.Execute()); + return Ok(); + } } } \ No newline at end of file diff --git a/server/PodNoms.Api.csproj b/server/PodNoms.Api.csproj index ce388e0..b2fe915 100755 --- a/server/PodNoms.Api.csproj +++ b/server/PodNoms.Api.csproj @@ -16,7 +16,7 @@ - + diff --git a/server/Services/Downloader/AudioDownloader.cs b/server/Services/Downloader/AudioDownloader.cs index 8a99654..9e99a2f 100755 --- a/server/Services/Downloader/AudioDownloader.cs +++ b/server/Services/Downloader/AudioDownloader.cs @@ -16,7 +16,11 @@ namespace PodNoms.Api.Services.Downloader { private readonly string _url; private readonly string _downloader; - public VideoDownloadInfo Properties { get; private set; } + + private DownloadInfo _properties; + public VideoDownloadInfo Properties => _properties is VideoDownloadInfo ? (VideoDownloadInfo)_properties : null; + public DownloadInfo RawProperties => _properties; + protected const string DOWNLOADRATESTRING = "iB/s"; protected const string DOWNLOADSIZESTRING = "iB"; protected const string ETASTRING = "ETA"; @@ -55,15 +59,15 @@ namespace PodNoms.Api.Services.Downloader { await Task.Run(() => { var youtubeDl = new YoutubeDL(); youtubeDl.VideoUrl = this._url; - DownloadInfo info = youtubeDl.GetDownloadInfo(); + var info = youtubeDl.GetDownloadInfo(); if (info != null && (info.Errors.Count == 0 || info.VideoSize != null)) { - if (info is PlaylistDownloadInfo) { + this._properties = info; + if (info is PlaylistDownloadInfo && ((PlaylistDownloadInfo)info).Videos.Count > 0) { ret = AudioType.Playlist; } else if (info is VideoDownloadInfo) { ret = AudioType.Valid; - this.Properties = (VideoDownloadInfo)info; } } }); diff --git a/server/Services/Jobs/ProcessPlaylistsJob.cs b/server/Services/Jobs/ProcessPlaylistsJob.cs index fe3ff85..5afcbab 100755 --- a/server/Services/Jobs/ProcessPlaylistsJob.cs +++ b/server/Services/Jobs/ProcessPlaylistsJob.cs @@ -27,8 +27,8 @@ namespace PodNoms.Api.Services.Jobs { var downloader = new AudioDownloader(playlist.SourceUrl, _applicationsSettings.Downloader); var info = await downloader.GetInfo(); if (info == AudioType.Playlist){ - var - for (var item in downloader.Properties.) + //var + //for (var item in downloader.Properties.) } } } diff --git a/server/Services/Jobs/UpdateYouTubeDlJob.cs b/server/Services/Jobs/UpdateYouTubeDlJob.cs new file mode 100644 index 0000000..cf3176f --- /dev/null +++ b/server/Services/Jobs/UpdateYouTubeDlJob.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using NYoutubeDL; +using PodNoms.Api.Services.Jobs; + +namespace PodNoms.Api.Services.Jobs { + public class UpdateYouTubeDlJob : IJob { + public async Task Execute() { + await Task.Run(() => { + var yt = new YoutubeDL(); + yt.Options.GeneralOptions.Update = true; + yt.Download("https://www.youtube.com/watch?v=OJ2wOKDzKyI"); + }); + } + } +} \ No newline at end of file diff --git a/server/commands b/server/commands new file mode 100644 index 0000000..d34c3bb --- /dev/null +++ b/server/commands @@ -0,0 +1,3 @@ +get-info +youtube-dl --flat-playlist -i -J -s + From 979f31cdcfcbacaf5ba18e6d67d2afecde99e337 Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Thu, 15 Mar 2018 20:05:15 +0000 Subject: [PATCH 08/13] Disable playlists --- server/Services/Downloader/AudioDownloader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/Services/Downloader/AudioDownloader.cs b/server/Services/Downloader/AudioDownloader.cs index 9e99a2f..ba9d5e4 100755 --- a/server/Services/Downloader/AudioDownloader.cs +++ b/server/Services/Downloader/AudioDownloader.cs @@ -64,7 +64,8 @@ namespace PodNoms.Api.Services.Downloader { if (info != null && (info.Errors.Count == 0 || info.VideoSize != null)) { this._properties = info; - if (info is PlaylistDownloadInfo && ((PlaylistDownloadInfo)info).Videos.Count > 0) { + // have to dump playlist handling for now + if (false && info is PlaylistDownloadInfo && ((PlaylistDownloadInfo)info).Videos.Count > 0) { ret = AudioType.Playlist; } else if (info is VideoDownloadInfo) { ret = AudioType.Valid; From c09dbfde55238376be8e2055108d6ceb4834b6fa Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Fri, 16 Mar 2018 17:30:56 +0000 Subject: [PATCH 09/13] Mailgun API implemented --- .gitignore | 1 + server/Models/EmailSettings.cs | 10 +++++ server/Services/Jobs/JobBootstrapper.cs | 2 +- server/Services/Jobs/UpdateYouTubeDlJob.cs | 26 ++++++++--- server/Services/MailSender.cs | 50 ++++++++++++++++++++++ server/Startup.cs | 4 +- 6 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 server/Models/EmailSettings.cs create mode 100644 server/Services/MailSender.cs diff --git a/.gitignore b/.gitignore index df089c2..1f84816 100755 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ promotion extension client/tags NYoutubeDL +tags diff --git a/server/Models/EmailSettings.cs b/server/Models/EmailSettings.cs new file mode 100644 index 0000000..ac7f011 --- /dev/null +++ b/server/Models/EmailSettings.cs @@ -0,0 +1,10 @@ +namespace PodNoms.Api.Models { + + public class EmailSettings { + public string ApiKey { get; set; } + public string ApiBaseUri { get; set; } + public string RequestUri { get; set; } + public string From { get; set; } + } + +} diff --git a/server/Services/Jobs/JobBootstrapper.cs b/server/Services/Jobs/JobBootstrapper.cs index 8c6dcc1..946c311 100755 --- a/server/Services/Jobs/JobBootstrapper.cs +++ b/server/Services/Jobs/JobBootstrapper.cs @@ -10,4 +10,4 @@ namespace PodNoms.Api.Services.Jobs { RecurringJob.AddOrUpdate(x => x.Execute(), Cron.Daily(1)); } } -} \ No newline at end of file +} diff --git a/server/Services/Jobs/UpdateYouTubeDlJob.cs b/server/Services/Jobs/UpdateYouTubeDlJob.cs index cf3176f..17b69aa 100644 --- a/server/Services/Jobs/UpdateYouTubeDlJob.cs +++ b/server/Services/Jobs/UpdateYouTubeDlJob.cs @@ -1,15 +1,29 @@ using System.Threading.Tasks; using NYoutubeDL; +using Microsoft.Extensions.Logging; + using PodNoms.Api.Services.Jobs; +using PodNoms.Api.Services; namespace PodNoms.Api.Services.Jobs { public class UpdateYouTubeDlJob : IJob { + private readonly IMailSender _sender; + private readonly ILogger _logger; + + public UpdateYouTubeDlJob(IMailSender sender, ILogger logger){ + this._sender = sender; + this._logger = logger; + } + public async Task Execute() { - await Task.Run(() => { - var yt = new YoutubeDL(); - yt.Options.GeneralOptions.Update = true; - yt.Download("https://www.youtube.com/watch?v=OJ2wOKDzKyI"); - }); + _logger.LogInformation("Updating YoutubeDL"); + + var yt = new YoutubeDL(); + yt.Options.GeneralOptions.Update = true; + yt.Download("https://www.youtube.com/watch?v=OJ2wOKDzKyI"); + + var results = await _sender.SendEmail("fergal.moran@gmail.com", "PodNoms: UpdateYouTubeDlJob completed", "As you were"); + _logger.LogInformation($"{results}"); } } -} \ No newline at end of file +} diff --git a/server/Services/MailSender.cs b/server/Services/MailSender.cs new file mode 100644 index 0000000..1a252b6 --- /dev/null +++ b/server/Services/MailSender.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using PodNoms.Api.Models; +using System.Net; + +namespace PodNoms.Api.Services { + + public interface IMailSender { + Task SendEmail(string email, string subject, string message); + } + public class MailSender : IMailSender { + private readonly EmailSettings _emailSettings; + private readonly ILogger _logger; + public MailSender(IOptions emailSettings, ILogger logger){ + _emailSettings = emailSettings.Value; + _logger = logger; + } + + public async Task SendEmail(string email, string subject, string message){ + using (var client = new HttpClient { BaseAddress = new Uri(_emailSettings.ApiBaseUri) }) { + client.DefaultRequestHeaders.Authorization = + new AuthenticationHeaderValue("Basic", + Convert.ToBase64String(Encoding.ASCII.GetBytes(_emailSettings.ApiKey))); + + _logger.LogInformation($"From: {_emailSettings.From}\nTo: {email}\nApi key: {_emailSettings.ApiKey}"); + + var content = new FormUrlEncodedContent(new[] + { + new KeyValuePair("from", _emailSettings.From), + new KeyValuePair("to", email), + new KeyValuePair("subject", subject), + new KeyValuePair("html", message) + }); + + var result = await client.PostAsync(_emailSettings.RequestUri, content).ConfigureAwait(false); + if (result.StatusCode == HttpStatusCode.OK) + return true; + + _logger.LogError($"Error {result.StatusCode} sending mail\n{result.ReasonPhrase}"); + return false; + } + } + } +} diff --git a/server/Startup.cs b/server/Startup.cs index a950863..ed9ef66 100755 --- a/server/Startup.cs +++ b/server/Startup.cs @@ -67,6 +67,7 @@ namespace PodNoms.Api { services.Configure(Configuration.GetSection("App")); services.Configure(Configuration.GetSection("Storage")); services.Configure(Configuration.GetSection("ApplicationsSettings")); + services.Configure(Configuration.GetSection("EmailSettings")); services.Configure(Configuration.GetSection("ImageFileStorageSettings")); services.Configure(Configuration.GetSection("AudioFileStorageSettings")); services.Configure(options => { @@ -155,6 +156,7 @@ namespace PodNoms.Api { services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddSingleton(typeof(HubLifetimeManager), typeof(DebugHubLifetimeManager)); @@ -219,4 +221,4 @@ namespace PodNoms.Api { JobBootstrapper.BootstrapJobs(); } } -} \ No newline at end of file +} From 9a75bb207c87f5b4b594cef438c0ae3336dca0ed Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Fri, 16 Mar 2018 17:31:53 +0000 Subject: [PATCH 10/13] Refactor mail sender name --- server/Services/MailSender.cs | 50 ----------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 server/Services/MailSender.cs diff --git a/server/Services/MailSender.cs b/server/Services/MailSender.cs deleted file mode 100644 index 1a252b6..0000000 --- a/server/Services/MailSender.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using PodNoms.Api.Models; -using System.Net; - -namespace PodNoms.Api.Services { - - public interface IMailSender { - Task SendEmail(string email, string subject, string message); - } - public class MailSender : IMailSender { - private readonly EmailSettings _emailSettings; - private readonly ILogger _logger; - public MailSender(IOptions emailSettings, ILogger logger){ - _emailSettings = emailSettings.Value; - _logger = logger; - } - - public async Task SendEmail(string email, string subject, string message){ - using (var client = new HttpClient { BaseAddress = new Uri(_emailSettings.ApiBaseUri) }) { - client.DefaultRequestHeaders.Authorization = - new AuthenticationHeaderValue("Basic", - Convert.ToBase64String(Encoding.ASCII.GetBytes(_emailSettings.ApiKey))); - - _logger.LogInformation($"From: {_emailSettings.From}\nTo: {email}\nApi key: {_emailSettings.ApiKey}"); - - var content = new FormUrlEncodedContent(new[] - { - new KeyValuePair("from", _emailSettings.From), - new KeyValuePair("to", email), - new KeyValuePair("subject", subject), - new KeyValuePair("html", message) - }); - - var result = await client.PostAsync(_emailSettings.RequestUri, content).ConfigureAwait(false); - if (result.StatusCode == HttpStatusCode.OK) - return true; - - _logger.LogError($"Error {result.StatusCode} sending mail\n{result.ReasonPhrase}"); - return false; - } - } - } -} From 86e46c5de0b6391b27572c43c82510b5c16f2612 Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Fri, 16 Mar 2018 17:40:54 +0000 Subject: [PATCH 11/13] Added job & emails --- server/Services/Jobs/ClearOrphanAudioJob.cs | 8 ++++++-- server/Services/Jobs/JobBootstrapper.cs | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/server/Services/Jobs/ClearOrphanAudioJob.cs b/server/Services/Jobs/ClearOrphanAudioJob.cs index 4bdddfc..1a9d4f1 100755 --- a/server/Services/Jobs/ClearOrphanAudioJob.cs +++ b/server/Services/Jobs/ClearOrphanAudioJob.cs @@ -13,9 +13,11 @@ namespace PodNoms.Api.Services.Jobs { public readonly StorageSettings _storageSettings; public readonly AudioFileStorageSettings _audioStorageSettings; private readonly ILogger _logger; + private readonly IMailSender _mailSender; public ClearOrphanAudioJob(IEntryRepository entryRepository, IOptions storageSettings, - IOptions audioStorageSettings, ILoggerFactory logger) { + IOptions audioStorageSettings, ILoggerFactory logger, IMailSender mailSender) { + this._mailSender = mailSender; this._storageSettings = storageSettings.Value; this._audioStorageSettings = audioStorageSettings.Value; this._entryRepository = entryRepository; @@ -28,7 +30,7 @@ namespace PodNoms.Api.Services.Jobs { CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_storageSettings.ConnectionString); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference(_audioStorageSettings.ContainerName); - + short blobCount = 0; var blobs = await container.ListBlobsSegmentedAsync(null); foreach (CloudBlockBlob blob in blobs.Results) { try { @@ -38,12 +40,14 @@ namespace PodNoms.Api.Services.Jobs { var entry = await _entryRepository.GetByUidAsync(guid); if (entry == null) { await blob.DeleteIfExistsAsync(); + blobCount++; } } } catch (Exception e) { _logger.LogWarning($"Error processing blob {blob.Uri}\n{e.Message}"); } } + await this._mailSender.SendEmail("fergal.moran@gmail.com", $"ClearOrphanAudioJob: Complete {blobCount}", string.Empty); } catch (Exception ex) { _logger.LogError($"Error clearing orphans\n{ex.Message}"); } diff --git a/server/Services/Jobs/JobBootstrapper.cs b/server/Services/Jobs/JobBootstrapper.cs index 946c311..9267e04 100755 --- a/server/Services/Jobs/JobBootstrapper.cs +++ b/server/Services/Jobs/JobBootstrapper.cs @@ -8,6 +8,7 @@ namespace PodNoms.Api.Services.Jobs { public static class JobBootstrapper { public static void BootstrapJobs() { RecurringJob.AddOrUpdate(x => x.Execute(), Cron.Daily(1)); + RecurringJob.AddOrUpdate(x => x.Execute(), Cron.Daily(1, 30)); } } } From e244b626cbd60289df60f4944caaeb0c35694f33 Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Fri, 16 Mar 2018 17:44:29 +0000 Subject: [PATCH 12/13] Bump da versions --- client/package.json | 2 +- server/appsettings.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/package.json b/client/package.json index 0b27d87..ad50256 100755 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "pod-noms.web", - "version": "0.17.0", + "version": "0.18.0", "license": "MIT", "scripts": { "ng": "ng", diff --git a/server/appsettings.json b/server/appsettings.json index ca0b093..b285e03 100755 --- a/server/appsettings.json +++ b/server/appsettings.json @@ -8,7 +8,7 @@ } }, "App": { - "Version": "0.17.0", + "Version": "0.18.0", "RssUrl": "http://localhost:5000/rss/" }, "ConnectionStrings": { From 17d14fba83fa2ea56c2f343ee7c89b2f5d9ce33a Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Fri, 16 Mar 2018 18:30:53 +0000 Subject: [PATCH 13/13] missing files --- server/Services/IMailSender.cs | 7 +++++ server/Services/MailgunSender.cs | 46 ++++++++++++++++++++++++++++++++ server/Startup.cs | 2 +- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 server/Services/IMailSender.cs create mode 100644 server/Services/MailgunSender.cs diff --git a/server/Services/IMailSender.cs b/server/Services/IMailSender.cs new file mode 100644 index 0000000..88ba954 --- /dev/null +++ b/server/Services/IMailSender.cs @@ -0,0 +1,7 @@ +using System.Threading.Tasks; + +namespace PodNoms.Api.Services { + public interface IMailSender { + Task SendEmail(string email, string subject, string message); + } +} diff --git a/server/Services/MailgunSender.cs b/server/Services/MailgunSender.cs new file mode 100644 index 0000000..54ad2ae --- /dev/null +++ b/server/Services/MailgunSender.cs @@ -0,0 +1,46 @@ +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using PodNoms.Api.Models; +using System.Net; + +namespace PodNoms.Api.Services { + public class MailgunSender : IMailSender { + private readonly EmailSettings _emailSettings; + private readonly ILogger _logger; + public MailgunSender(IOptions emailSettings, ILogger logger){ + _emailSettings = emailSettings.Value; + _logger = logger; + } + + public async Task SendEmail(string email, string subject, string message){ + using (var client = new HttpClient { BaseAddress = new Uri(_emailSettings.ApiBaseUri) }) { + client.DefaultRequestHeaders.Authorization = + new AuthenticationHeaderValue("Basic", + Convert.ToBase64String(Encoding.ASCII.GetBytes(_emailSettings.ApiKey))); + + _logger.LogInformation($"From: {_emailSettings.From}\nTo: {email}\nApi key: {_emailSettings.ApiKey}"); + + var content = new FormUrlEncodedContent(new[] + { + new KeyValuePair("from", _emailSettings.From), + new KeyValuePair("to", email), + new KeyValuePair("subject", subject), + new KeyValuePair("html", message) + }); + + var result = await client.PostAsync(_emailSettings.RequestUri, content).ConfigureAwait(false); + if (result.StatusCode == HttpStatusCode.OK) + return true; + + _logger.LogError($"Error {result.StatusCode} sending mail\n{result.ReasonPhrase}"); + return false; + } + } + } +} diff --git a/server/Startup.cs b/server/Startup.cs index ed9ef66..becec7f 100755 --- a/server/Startup.cs +++ b/server/Startup.cs @@ -156,7 +156,7 @@ namespace PodNoms.Api { services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); services.AddSingleton(typeof(HubLifetimeManager), typeof(DebugHubLifetimeManager));