From d47e7a7c57b413b2b0a09d77c07aafb6724906a9 Mon Sep 17 00:00:00 2001
From: Jamie <tidusjar@gmail.com>
Date: Fri, 24 Aug 2018 16:32:19 +0100
Subject: [PATCH] Requests now work for albums !wip

---
 src/Ombi.Api.Lidarr/LidarrApi.cs              |    6 +-
 src/Ombi.Core/Engine/MovieRequestEngine.cs    |    1 +
 src/Ombi.Core/Engine/MusicRequestEngine.cs    |   13 +-
 .../Models/Requests/RequestService.cs         |    4 +-
 .../20180824152254_MusicRequests.Designer.cs  | 1045 +++++++++++++++++
 .../20180824152254_MusicRequests.cs           |   67 ++
 .../Migrations/OmbiContextModelSnapshot.cs    |   57 +
 .../ClientApp/app/interfaces/IRequestModel.ts |   20 +
 .../app/interfaces/ISearchMusicResult.ts      |    1 +
 .../recentlyAdded/recentlyAdded.component.ts  |    2 +-
 .../app/search/music/albumsearch.component.ts |    8 +-
 .../ClientApp/app/services/request.service.ts |   41 +-
 .../app/wizard/plex/plexoauth.component.ts    |    2 +-
 13 files changed, 1250 insertions(+), 17 deletions(-)
 create mode 100644 src/Ombi.Store/Migrations/20180824152254_MusicRequests.Designer.cs
 create mode 100644 src/Ombi.Store/Migrations/20180824152254_MusicRequests.cs

diff --git a/src/Ombi.Api.Lidarr/LidarrApi.cs b/src/Ombi.Api.Lidarr/LidarrApi.cs
index 8512b6f5b..52bacd105 100644
--- a/src/Ombi.Api.Lidarr/LidarrApi.cs
+++ b/src/Ombi.Api.Lidarr/LidarrApi.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Net.Http;
 using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
@@ -72,13 +73,14 @@ namespace Ombi.Api.Lidarr
         }
 
 
-        public Task<AlbumLookup> GetAlbumByForeignId(string foreignArtistId, string apiKey, string baseUrl)
+        public async Task<AlbumLookup> GetAlbumByForeignId(string foreignArtistId, string apiKey, string baseUrl)
         {
             var request = new Request($"{ApiVersion}/album/lookup", baseUrl, HttpMethod.Get);
 
             request.AddQueryString("term", $"lidarr:{foreignArtistId}");
             AddHeaders(request, apiKey);
-            return Api.Request<AlbumLookup>(request);
+            var albums = await Api.Request<List<AlbumLookup>>(request);
+            return albums.FirstOrDefault();
         }
 
         public Task<AlbumByArtistResponse> GetAlbumsByArtist(int artistId, string apiKey, string baseUrl)
diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs
index f73c6fda1..f0a4e1f29 100644
--- a/src/Ombi.Core/Engine/MovieRequestEngine.cs
+++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs
@@ -336,6 +336,7 @@ namespace Ombi.Core.Engine
                 };
             }
 
+            request.MarkedAsApproved = DateTime.Now;
             request.Approved = true;
             request.Denied = false;
             await MovieRepository.Update(request);
diff --git a/src/Ombi.Core/Engine/MusicRequestEngine.cs b/src/Ombi.Core/Engine/MusicRequestEngine.cs
index 95ec41b51..bcf9e8c02 100644
--- a/src/Ombi.Core/Engine/MusicRequestEngine.cs
+++ b/src/Ombi.Core/Engine/MusicRequestEngine.cs
@@ -39,7 +39,7 @@ namespace Ombi.Core.Engine
             _lidarrApi = lidarr;
             _lidarrSettings = lidarrSettings;
         }
-        
+
         private INotificationHelper NotificationHelper { get; }
         //private IMovieSender Sender { get; }
         private ILogger Logger { get; }
@@ -327,12 +327,11 @@ namespace Ombi.Core.Engine
                 };
             }
 
-            if (!request.Approved)
-            {
-                request.Approved = true;
-                request.Denied = false;
-                await MusicRepository.Update(request);
-            }
+            request.MarkedAsApproved = DateTime.Now;
+            request.Approved = true;
+            request.Denied = false;
+            await MusicRepository.Update(request);
+
 
             var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification);
             if (canNotify.Success)
diff --git a/src/Ombi.Core/Models/Requests/RequestService.cs b/src/Ombi.Core/Models/Requests/RequestService.cs
index 049666440..6f7431baa 100644
--- a/src/Ombi.Core/Models/Requests/RequestService.cs
+++ b/src/Ombi.Core/Models/Requests/RequestService.cs
@@ -5,13 +5,15 @@ namespace Ombi.Core.Models.Requests
 {
     public class RequestService : IRequestServiceMain
     {
-        public RequestService(ITvRequestRepository tv, IMovieRequestRepository movie)
+        public RequestService(ITvRequestRepository tv, IMovieRequestRepository movie, IMusicRequestRepository music)
         {
             TvRequestService = tv;
             MovieRequestService = movie;
+            MusicRequestRepository = music;
         }
 
         public ITvRequestRepository TvRequestService { get; }
+        public IMusicRequestRepository MusicRequestRepository { get; }
         public IMovieRequestRepository MovieRequestService { get; }
     }
 }
\ No newline at end of file
diff --git a/src/Ombi.Store/Migrations/20180824152254_MusicRequests.Designer.cs b/src/Ombi.Store/Migrations/20180824152254_MusicRequests.Designer.cs
new file mode 100644
index 000000000..415563212
--- /dev/null
+++ b/src/Ombi.Store/Migrations/20180824152254_MusicRequests.Designer.cs
@@ -0,0 +1,1045 @@
+// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Ombi.Store.Context;
+
+namespace Ombi.Store.Migrations
+{
+    [DbContext(typeof(OmbiContext))]
+    [Migration("20180824152254_MusicRequests")]
+    partial class MusicRequests
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "2.1.1-rtm-30846");
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+                {
+                    b.Property<string>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken();
+
+                    b.Property<string>("Name")
+                        .HasMaxLength(256);
+
+                    b.Property<string>("NormalizedName")
+                        .HasMaxLength(256);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedName")
+                        .IsUnique()
+                        .HasName("RoleNameIndex");
+
+                    b.ToTable("AspNetRoles");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("ClaimType");
+
+                    b.Property<string>("ClaimValue");
+
+                    b.Property<string>("RoleId")
+                        .IsRequired();
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("RoleId");
+
+                    b.ToTable("AspNetRoleClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("ClaimType");
+
+                    b.Property<string>("ClaimValue");
+
+                    b.Property<string>("UserId")
+                        .IsRequired();
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.Property<string>("LoginProvider");
+
+                    b.Property<string>("ProviderKey");
+
+                    b.Property<string>("ProviderDisplayName");
+
+                    b.Property<string>("UserId")
+                        .IsRequired();
+
+                    b.HasKey("LoginProvider", "ProviderKey");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserLogins");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.Property<string>("UserId");
+
+                    b.Property<string>("RoleId");
+
+                    b.HasKey("UserId", "RoleId");
+
+                    b.HasIndex("RoleId");
+
+                    b.ToTable("AspNetUserRoles");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.Property<string>("UserId");
+
+                    b.Property<string>("LoginProvider");
+
+                    b.Property<string>("Name");
+
+                    b.Property<string>("Value");
+
+                    b.HasKey("UserId", "LoginProvider", "Name");
+
+                    b.ToTable("AspNetUserTokens");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("Type");
+
+                    b.Property<string>("Value");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("ApplicationConfiguration");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("AuditArea");
+
+                    b.Property<int>("AuditType");
+
+                    b.Property<DateTime>("DateTime");
+
+                    b.Property<string>("Description");
+
+                    b.Property<string>("User");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("Audit");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("TheMovieDbId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("CouchPotatoCache");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("AddedAt");
+
+                    b.Property<string>("EmbyId")
+                        .IsRequired();
+
+                    b.Property<string>("ImdbId");
+
+                    b.Property<string>("ProviderId");
+
+                    b.Property<string>("TheMovieDbId");
+
+                    b.Property<string>("Title");
+
+                    b.Property<string>("TvDbId");
+
+                    b.Property<int>("Type");
+
+                    b.Property<string>("Url");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("EmbyContent");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("AddedAt");
+
+                    b.Property<string>("EmbyId");
+
+                    b.Property<int>("EpisodeNumber");
+
+                    b.Property<string>("ImdbId");
+
+                    b.Property<string>("ParentId");
+
+                    b.Property<string>("ProviderId");
+
+                    b.Property<int>("SeasonNumber");
+
+                    b.Property<string>("TheMovieDbId");
+
+                    b.Property<string>("Title");
+
+                    b.Property<string>("TvDbId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ParentId");
+
+                    b.ToTable("EmbyEpisode");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content");
+
+                    b.Property<string>("SettingsName");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("GlobalSettings");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("Agent");
+
+                    b.Property<bool>("Enabled");
+
+                    b.Property<string>("Message");
+
+                    b.Property<int>("NotificationType");
+
+                    b.Property<string>("Subject");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("NotificationTemplates");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("AddedAt");
+
+                    b.Property<string>("PlayerId");
+
+                    b.Property<string>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("NotificationUserId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b =>
+                {
+                    b.Property<string>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("AccessFailedCount");
+
+                    b.Property<string>("Alias");
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken();
+
+                    b.Property<string>("Email")
+                        .HasMaxLength(256);
+
+                    b.Property<bool>("EmailConfirmed");
+
+                    b.Property<string>("EmbyConnectUserId");
+
+                    b.Property<int?>("EpisodeRequestLimit");
+
+                    b.Property<DateTime?>("LastLoggedIn");
+
+                    b.Property<bool>("LockoutEnabled");
+
+                    b.Property<DateTimeOffset?>("LockoutEnd");
+
+                    b.Property<int?>("MovieRequestLimit");
+
+                    b.Property<int?>("MusicRequestLimit");
+
+                    b.Property<string>("NormalizedEmail")
+                        .HasMaxLength(256);
+
+                    b.Property<string>("NormalizedUserName")
+                        .HasMaxLength(256);
+
+                    b.Property<string>("PasswordHash");
+
+                    b.Property<string>("PhoneNumber");
+
+                    b.Property<bool>("PhoneNumberConfirmed");
+
+                    b.Property<string>("ProviderUserId");
+
+                    b.Property<string>("SecurityStamp");
+
+                    b.Property<bool>("TwoFactorEnabled");
+
+                    b.Property<string>("UserAccessToken");
+
+                    b.Property<string>("UserName")
+                        .HasMaxLength(256);
+
+                    b.Property<int>("UserType");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedEmail")
+                        .HasName("EmailIndex");
+
+                    b.HasIndex("NormalizedUserName")
+                        .IsUnique()
+                        .HasName("UserNameIndex");
+
+                    b.ToTable("AspNetUsers");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("EpisodeNumber");
+
+                    b.Property<int>("GrandparentKey");
+
+                    b.Property<int>("Key");
+
+                    b.Property<int>("ParentKey");
+
+                    b.Property<int>("SeasonNumber");
+
+                    b.Property<string>("Title");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("GrandparentKey");
+
+                    b.ToTable("PlexEpisode");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("ParentKey");
+
+                    b.Property<int>("PlexContentId");
+
+                    b.Property<int?>("PlexServerContentId");
+
+                    b.Property<int>("SeasonKey");
+
+                    b.Property<int>("SeasonNumber");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("PlexServerContentId");
+
+                    b.ToTable("PlexSeasonsContent");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("AddedAt");
+
+                    b.Property<string>("ImdbId");
+
+                    b.Property<int>("Key");
+
+                    b.Property<string>("Quality");
+
+                    b.Property<string>("ReleaseYear");
+
+                    b.Property<string>("TheMovieDbId");
+
+                    b.Property<string>("Title");
+
+                    b.Property<string>("TvDbId");
+
+                    b.Property<int>("Type");
+
+                    b.Property<string>("Url");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("PlexServerContent");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("HasFile");
+
+                    b.Property<int>("TheMovieDbId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("RadarrCache");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("AddedAt");
+
+                    b.Property<int>("ContentId");
+
+                    b.Property<int>("ContentType");
+
+                    b.Property<int?>("EpisodeNumber");
+
+                    b.Property<int?>("SeasonNumber");
+
+                    b.Property<int>("Type");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("RecentlyAddedLog");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("Approved");
+
+                    b.Property<string>("ArtistName");
+
+                    b.Property<bool>("Available");
+
+                    b.Property<string>("Cover");
+
+                    b.Property<bool?>("Denied");
+
+                    b.Property<string>("DeniedReason");
+
+                    b.Property<string>("Disk");
+
+                    b.Property<string>("ForeignAlbumId");
+
+                    b.Property<string>("ForeignArtistId");
+
+                    b.Property<DateTime>("MarkedAsApproved");
+
+                    b.Property<DateTime?>("MarkedAsAvailable");
+
+                    b.Property<DateTime>("MarkedAsDenied");
+
+                    b.Property<decimal>("Rating");
+
+                    b.Property<DateTime>("ReleaseDate");
+
+                    b.Property<int>("RequestType");
+
+                    b.Property<DateTime>("RequestedDate");
+
+                    b.Property<string>("RequestedUserId");
+
+                    b.Property<string>("Title");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("RequestedUserId");
+
+                    b.ToTable("AlbumRequests");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("Approved");
+
+                    b.Property<bool>("Available");
+
+                    b.Property<bool?>("Denied");
+
+                    b.Property<string>("DeniedReason");
+
+                    b.Property<int?>("IssueId");
+
+                    b.Property<DateTime>("MarkedAsApproved");
+
+                    b.Property<DateTime?>("MarkedAsAvailable");
+
+                    b.Property<DateTime>("MarkedAsDenied");
+
+                    b.Property<int>("ParentRequestId");
+
+                    b.Property<int>("RequestType");
+
+                    b.Property<DateTime>("RequestedDate");
+
+                    b.Property<string>("RequestedUserId");
+
+                    b.Property<int>("SeriesType");
+
+                    b.Property<string>("Title");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ParentRequestId");
+
+                    b.HasIndex("RequestedUserId");
+
+                    b.ToTable("ChildRequests");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Value");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("IssueCategory");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Comment");
+
+                    b.Property<DateTime>("Date");
+
+                    b.Property<int?>("IssuesId");
+
+                    b.Property<string>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("IssuesId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("IssueComments");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Description");
+
+                    b.Property<int>("IssueCategoryId");
+
+                    b.Property<int?>("IssueId");
+
+                    b.Property<string>("ProviderId");
+
+                    b.Property<int?>("RequestId");
+
+                    b.Property<int>("RequestType");
+
+                    b.Property<DateTime?>("ResovledDate");
+
+                    b.Property<int>("Status");
+
+                    b.Property<string>("Subject");
+
+                    b.Property<string>("Title");
+
+                    b.Property<string>("UserReportedId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("IssueCategoryId");
+
+                    b.HasIndex("IssueId");
+
+                    b.HasIndex("UserReportedId");
+
+                    b.ToTable("Issues");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("Approved");
+
+                    b.Property<bool>("Available");
+
+                    b.Property<string>("Background");
+
+                    b.Property<bool?>("Denied");
+
+                    b.Property<string>("DeniedReason");
+
+                    b.Property<DateTime?>("DigitalReleaseDate");
+
+                    b.Property<string>("ImdbId");
+
+                    b.Property<int?>("IssueId");
+
+                    b.Property<DateTime>("MarkedAsApproved");
+
+                    b.Property<DateTime?>("MarkedAsAvailable");
+
+                    b.Property<DateTime>("MarkedAsDenied");
+
+                    b.Property<string>("Overview");
+
+                    b.Property<string>("PosterPath");
+
+                    b.Property<int>("QualityOverride");
+
+                    b.Property<DateTime>("ReleaseDate");
+
+                    b.Property<int>("RequestType");
+
+                    b.Property<DateTime>("RequestedDate");
+
+                    b.Property<string>("RequestedUserId");
+
+                    b.Property<int>("RootPathOverride");
+
+                    b.Property<string>("Status");
+
+                    b.Property<int>("TheMovieDbId");
+
+                    b.Property<string>("Title");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("RequestedUserId");
+
+                    b.ToTable("MovieRequests");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("EpisodeCount");
+
+                    b.Property<DateTime>("RequestDate");
+
+                    b.Property<int>("RequestId");
+
+                    b.Property<int>("RequestType");
+
+                    b.Property<string>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("RequestLog");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Background");
+
+                    b.Property<string>("ImdbId");
+
+                    b.Property<string>("Overview");
+
+                    b.Property<string>("PosterPath");
+
+                    b.Property<int?>("QualityOverride");
+
+                    b.Property<DateTime>("ReleaseDate");
+
+                    b.Property<int?>("RootFolder");
+
+                    b.Property<string>("Status");
+
+                    b.Property<string>("Title");
+
+                    b.Property<int>("TvDbId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("TvRequests");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("RequestId");
+
+                    b.Property<int>("RequestType");
+
+                    b.Property<string>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("RequestSubscription");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("TvDbId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("SickRageCache");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("EpisodeNumber");
+
+                    b.Property<int>("SeasonNumber");
+
+                    b.Property<int>("TvDbId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("SickRageEpisodeCache");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("TvDbId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("SonarrCache");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("EpisodeNumber");
+
+                    b.Property<bool>("HasFile");
+
+                    b.Property<int>("SeasonNumber");
+
+                    b.Property<int>("TvDbId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("SonarrEpisodeCache");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Token");
+
+                    b.Property<string>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("Tokens");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("AirDate");
+
+                    b.Property<bool>("Approved");
+
+                    b.Property<bool>("Available");
+
+                    b.Property<int>("EpisodeNumber");
+
+                    b.Property<bool>("Requested");
+
+                    b.Property<int>("SeasonId");
+
+                    b.Property<string>("Title");
+
+                    b.Property<string>("Url");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("SeasonId");
+
+                    b.ToTable("EpisodeRequests");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("ChildRequestId");
+
+                    b.Property<int>("SeasonNumber");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ChildRequestId");
+
+                    b.ToTable("SeasonRequests");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("Ombi.Store.Entities.OmbiUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.EmbyContent", "Series")
+                        .WithMany("Episodes")
+                        .HasForeignKey("ParentId")
+                        .HasPrincipalKey("EmbyId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
+                        .WithMany("NotificationUserIds")
+                        .HasForeignKey("UserId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series")
+                        .WithMany("Episodes")
+                        .HasForeignKey("GrandparentKey")
+                        .HasPrincipalKey("Key")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.PlexServerContent")
+                        .WithMany("Seasons")
+                        .HasForeignKey("PlexServerContentId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
+                        .WithMany()
+                        .HasForeignKey("RequestedUserId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest")
+                        .WithMany("ChildRequests")
+                        .HasForeignKey("ParentRequestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
+                        .WithMany()
+                        .HasForeignKey("RequestedUserId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues")
+                        .WithMany("Comments")
+                        .HasForeignKey("IssuesId");
+
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
+                        .WithMany()
+                        .HasForeignKey("UserId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory")
+                        .WithMany()
+                        .HasForeignKey("IssueCategoryId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("Ombi.Store.Entities.Requests.ChildRequests")
+                        .WithMany("Issues")
+                        .HasForeignKey("IssueId");
+
+                    b.HasOne("Ombi.Store.Entities.Requests.MovieRequests")
+                        .WithMany("Issues")
+                        .HasForeignKey("IssueId");
+
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported")
+                        .WithMany()
+                        .HasForeignKey("UserReportedId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
+                        .WithMany()
+                        .HasForeignKey("RequestedUserId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
+                        .WithMany()
+                        .HasForeignKey("UserId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
+                        .WithMany()
+                        .HasForeignKey("UserId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
+                        .WithMany()
+                        .HasForeignKey("UserId");
+                });
+
+            modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
+                {
+                    b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season")
+                        .WithMany("Episodes")
+                        .HasForeignKey("SeasonId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest")
+                        .WithMany("SeasonRequests")
+                        .HasForeignKey("ChildRequestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
diff --git a/src/Ombi.Store/Migrations/20180824152254_MusicRequests.cs b/src/Ombi.Store/Migrations/20180824152254_MusicRequests.cs
new file mode 100644
index 000000000..4810a39eb
--- /dev/null
+++ b/src/Ombi.Store/Migrations/20180824152254_MusicRequests.cs
@@ -0,0 +1,67 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Ombi.Store.Migrations
+{
+    public partial class MusicRequests : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AddColumn<int>(
+                name: "MusicRequestLimit",
+                table: "AspNetUsers",
+                nullable: true);
+
+            migrationBuilder.CreateTable(
+                name: "AlbumRequests",
+                columns: table => new
+                {
+                    Id = table.Column<int>(nullable: false)
+                        .Annotation("Sqlite:Autoincrement", true),
+                    Title = table.Column<string>(nullable: true),
+                    Approved = table.Column<bool>(nullable: false),
+                    MarkedAsApproved = table.Column<DateTime>(nullable: false),
+                    RequestedDate = table.Column<DateTime>(nullable: false),
+                    Available = table.Column<bool>(nullable: false),
+                    MarkedAsAvailable = table.Column<DateTime>(nullable: true),
+                    RequestedUserId = table.Column<string>(nullable: true),
+                    Denied = table.Column<bool>(nullable: true),
+                    MarkedAsDenied = table.Column<DateTime>(nullable: false),
+                    DeniedReason = table.Column<string>(nullable: true),
+                    RequestType = table.Column<int>(nullable: false),
+                    ForeignAlbumId = table.Column<string>(nullable: true),
+                    ForeignArtistId = table.Column<string>(nullable: true),
+                    Disk = table.Column<string>(nullable: true),
+                    Cover = table.Column<string>(nullable: true),
+                    Rating = table.Column<decimal>(nullable: false),
+                    ReleaseDate = table.Column<DateTime>(nullable: false),
+                    ArtistName = table.Column<string>(nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AlbumRequests", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_AlbumRequests_AspNetUsers_RequestedUserId",
+                        column: x => x.RequestedUserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                });
+
+            migrationBuilder.CreateIndex(
+                name: "IX_AlbumRequests_RequestedUserId",
+                table: "AlbumRequests",
+                column: "RequestedUserId");
+        }
+
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropTable(
+                name: "AlbumRequests");
+
+            migrationBuilder.DropColumn(
+                name: "MusicRequestLimit",
+                table: "AspNetUsers");
+        }
+    }
+}
diff --git a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs
index 5a7520005..cf791febb 100644
--- a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs
+++ b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs
@@ -311,6 +311,8 @@ namespace Ombi.Store.Migrations
 
                     b.Property<int?>("MovieRequestLimit");
 
+                    b.Property<int?>("MusicRequestLimit");
+
                     b.Property<string>("NormalizedEmail")
                         .HasMaxLength(256);
 
@@ -460,6 +462,54 @@ namespace Ombi.Store.Migrations
                     b.ToTable("RecentlyAddedLog");
                 });
 
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("Approved");
+
+                    b.Property<string>("ArtistName");
+
+                    b.Property<bool>("Available");
+
+                    b.Property<string>("Cover");
+
+                    b.Property<bool?>("Denied");
+
+                    b.Property<string>("DeniedReason");
+
+                    b.Property<string>("Disk");
+
+                    b.Property<string>("ForeignAlbumId");
+
+                    b.Property<string>("ForeignArtistId");
+
+                    b.Property<DateTime>("MarkedAsApproved");
+
+                    b.Property<DateTime?>("MarkedAsAvailable");
+
+                    b.Property<DateTime>("MarkedAsDenied");
+
+                    b.Property<decimal>("Rating");
+
+                    b.Property<DateTime>("ReleaseDate");
+
+                    b.Property<int>("RequestType");
+
+                    b.Property<DateTime>("RequestedDate");
+
+                    b.Property<string>("RequestedUserId");
+
+                    b.Property<string>("Title");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("RequestedUserId");
+
+                    b.ToTable("AlbumRequests");
+                });
+
             modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
                 {
                     b.Property<int>("Id")
@@ -894,6 +944,13 @@ namespace Ombi.Store.Migrations
                         .HasForeignKey("PlexServerContentId");
                 });
 
+            modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
+                {
+                    b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
+                        .WithMany()
+                        .HasForeignKey("RequestedUserId");
+                });
+
             modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
                 {
                     b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest")
diff --git a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts
index 92c455fc1..736f60aa2 100644
--- a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts
+++ b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts
@@ -20,6 +20,22 @@ export interface IMovieRequests extends IFullBaseRequest {
   qualityOverrideTitle: string;
 }
 
+export interface IAlbumRequest extends IBaseRequest {
+  foreignAlbumId: string;
+  foreignArtistId: string;
+  Disk: string;
+  cover: string;
+  releaseDate: Date;
+  artistName: string;
+
+  subscribed: boolean;
+  showSubscribe: boolean;
+}
+
+export interface IAlbumRequestModel {
+  foreignAlbumId: string;
+}
+
 export interface IRequestsViewModel<T> {
   total: number;
   collection: T[];
@@ -29,6 +45,10 @@ export interface IMovieUpdateModel {
   id: number;
 }
 
+export interface IAlbumUpdateModel {
+  id: number;
+}
+
 export interface IFullBaseRequest extends IBaseRequest {
   imdbId: string;
   overview: string;
diff --git a/src/Ombi/ClientApp/app/interfaces/ISearchMusicResult.ts b/src/Ombi/ClientApp/app/interfaces/ISearchMusicResult.ts
index 4c16ac88b..6afd10b19 100644
--- a/src/Ombi/ClientApp/app/interfaces/ISearchMusicResult.ts
+++ b/src/Ombi/ClientApp/app/interfaces/ISearchMusicResult.ts
@@ -45,6 +45,7 @@ export interface ISearchAlbumResult {
     available: boolean;
    
     // for the UI
+    showSubscribe: boolean;
     requestProcessing: boolean;
     processed: boolean;
     background: any;
diff --git a/src/Ombi/ClientApp/app/recentlyAdded/recentlyAdded.component.ts b/src/Ombi/ClientApp/app/recentlyAdded/recentlyAdded.component.ts
index d2120cdcf..f426a39d1 100644
--- a/src/Ombi/ClientApp/app/recentlyAdded/recentlyAdded.component.ts
+++ b/src/Ombi/ClientApp/app/recentlyAdded/recentlyAdded.component.ts
@@ -1,8 +1,8 @@
 import { Component, OnInit } from "@angular/core";
 import { NguCarouselConfig } from "@ngu/carousel";
 
-import { ImageService, RecentlyAddedService } from "../services";
 import { IRecentlyAddedMovies, IRecentlyAddedTvShows } from "../interfaces";
+import { ImageService, RecentlyAddedService } from "../services";
 
 @Component({
     templateUrl: "recentlyAdded.component.html",
diff --git a/src/Ombi/ClientApp/app/search/music/albumsearch.component.ts b/src/Ombi/ClientApp/app/search/music/albumsearch.component.ts
index 388b3dec0..29824a970 100644
--- a/src/Ombi/ClientApp/app/search/music/albumsearch.component.ts
+++ b/src/Ombi/ClientApp/app/search/music/albumsearch.component.ts
@@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, Output } from "@angular/core";
 import { TranslateService } from "@ngx-translate/core";
 
 import { AuthService } from "../../auth/auth.service";
-import { IRequestEngineResult, ISearchMovieResult } from "../../interfaces";
+import { IRequestEngineResult } from "../../interfaces";
 import { ISearchAlbumResult } from "../../interfaces/ISearchMusicResult";
 import { NotificationService, RequestService } from "../../services";
 
@@ -30,16 +30,16 @@ export class AlbumSearchComponent {
         this.setSearch.emit(artistId);
     }
 
-    public request(searchResult: ISearchMovieResult) {
+    public request(searchResult: ISearchAlbumResult) {
         searchResult.requested = true;
         searchResult.requestProcessing = true;
         searchResult.showSubscribe = false;
-        if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) {
+        if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMusic")) {
             searchResult.approved = true;
         }
 
         try {
-            this.requestService.requestMovie({ theMovieDbId: searchResult.id })
+            this.requestService.requestAlbum({ foreignAlbumId: searchResult.foreignAlbumId })
                 .subscribe(x => {
                     this.engineResult = x;
 
diff --git a/src/Ombi/ClientApp/app/services/request.service.ts b/src/Ombi/ClientApp/app/services/request.service.ts
index 48fa5622d..2a9de8b2a 100644
--- a/src/Ombi/ClientApp/app/services/request.service.ts
+++ b/src/Ombi/ClientApp/app/services/request.service.ts
@@ -5,7 +5,8 @@ import { HttpClient } from "@angular/common/http";
 import { Observable } from "rxjs";
 
 import { TreeNode } from "primeng/primeng";
-import { FilterType, IChildRequests, IFilter, IMovieRequestModel, IMovieRequests, IMovieUpdateModel, IRequestEngineResult, IRequestsViewModel,  ITvRequests, ITvUpdateModel, OrderType } from "../interfaces";
+import { FilterType, IAlbumRequest, IAlbumRequestModel, IAlbumUpdateModel, IChildRequests, IFilter, IMovieRequestModel, IMovieRequests,
+      IMovieUpdateModel, IRequestEngineResult, IRequestsViewModel, ITvRequests, ITvUpdateModel, OrderType } from "../interfaces";
 import { ITvRequestViewModel } from "../interfaces";
 import { ServiceHelpers } from "./service.helpers";
 
@@ -132,4 +133,42 @@ export class RequestService extends ServiceHelpers {
     public setRootFolder(requestId: number, rootFolderId: number): Observable<boolean> {
         return this.http.put<boolean>(`${this.url}tv/root/${requestId}/${rootFolderId}`, {headers: this.headers});
     }
+
+    // Music
+    public requestAlbum(Album: IAlbumRequestModel): Observable<IRequestEngineResult> {
+        return this.http.post<IRequestEngineResult>(`${this.url}music/`, JSON.stringify(Album),  {headers: this.headers});
+    }
+
+    public getTotalAlbums(): Observable<number> {
+        return this.http.get<number>(`${this.url}music/total`, {headers: this.headers});
+    }
+
+    public approveAlbum(Album: IAlbumUpdateModel): Observable<IRequestEngineResult> {
+        return this.http.post<IRequestEngineResult>(`${this.url}music/Approve`, JSON.stringify(Album),  {headers: this.headers});
+    }
+
+    public denyAlbum(Album: IAlbumUpdateModel): Observable<IRequestEngineResult> {
+        return this.http.put<IRequestEngineResult>(`${this.url}music/Deny`, JSON.stringify(Album),  {headers: this.headers});
+    }
+
+    public markAlbumAvailable(Album: IAlbumUpdateModel): Observable<IRequestEngineResult> {
+        return this.http.post<IRequestEngineResult>(`${this.url}music/available`, JSON.stringify(Album),  {headers: this.headers});
+    }
+
+    public markAlbumUnavailable(Album: IAlbumUpdateModel): Observable<IRequestEngineResult> {
+        return this.http.post<IRequestEngineResult>(`${this.url}music/unavailable`, JSON.stringify(Album),  {headers: this.headers});
+    }
+
+    public getAlbumRequests(count: number, position: number, order: OrderType, filter: IFilter): Observable<IRequestsViewModel<IMovieRequests>> {
+        return this.http.get<IRequestsViewModel<IMovieRequests>>(`${this.url}music/${count}/${position}/${order}/${filter.statusFilter}/${filter.availabilityFilter}`, {headers: this.headers});
+    }
+
+    public searchAlbumRequests(search: string): Observable<IAlbumRequest[]> {
+        return this.http.get<IAlbumRequest[]>(`${this.url}music/search/${search}`, {headers: this.headers});
+    }
+
+    public removeAlbumRequest(request: IAlbumRequest) {
+        this.http.delete(`${this.url}music/${request.id}`, {headers: this.headers}).subscribe();
+    }
+
 }
diff --git a/src/Ombi/ClientApp/app/wizard/plex/plexoauth.component.ts b/src/Ombi/ClientApp/app/wizard/plex/plexoauth.component.ts
index 29ecd1a3c..d6ec14a8f 100644
--- a/src/Ombi/ClientApp/app/wizard/plex/plexoauth.component.ts
+++ b/src/Ombi/ClientApp/app/wizard/plex/plexoauth.component.ts
@@ -1,8 +1,8 @@
 import { Component, OnInit } from "@angular/core";
 import { ActivatedRoute, Router } from "@angular/router";
 
-import { IdentityService, PlexOAuthService } from "../../services";
 import { AuthService } from "../../auth/auth.service";
+import { IdentityService, PlexOAuthService } from "../../services";
 
 @Component({
     templateUrl: "./plexoauth.component.html",