mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 21:33:15 -07:00
Merge branch 'feature/music-rework' into merge-music
This commit is contained in:
commit
296e739b0e
70 changed files with 6475 additions and 661 deletions
|
@ -9,6 +9,7 @@ namespace Ombi.Api.Lidarr
|
||||||
{
|
{
|
||||||
Task<List<AlbumLookup>> AlbumLookup(string searchTerm, string apiKey, string baseUrl);
|
Task<List<AlbumLookup>> AlbumLookup(string searchTerm, string apiKey, string baseUrl);
|
||||||
Task<List<ArtistLookup>> ArtistLookup(string searchTerm, string apiKey, string baseUrl);
|
Task<List<ArtistLookup>> ArtistLookup(string searchTerm, string apiKey, string baseUrl);
|
||||||
|
Task<List<Search>> Search(string searchTerm, string apiKey, string baseUrl);
|
||||||
Task<List<LidarrProfile>> GetProfiles(string apiKey, string baseUrl);
|
Task<List<LidarrProfile>> GetProfiles(string apiKey, string baseUrl);
|
||||||
Task<List<LidarrRootFolder>> GetRootFolders(string apiKey, string baseUrl);
|
Task<List<LidarrRootFolder>> GetRootFolders(string apiKey, string baseUrl);
|
||||||
Task<ArtistResult> GetArtist(int artistId, string apiKey, string baseUrl);
|
Task<ArtistResult> GetArtist(int artistId, string apiKey, string baseUrl);
|
||||||
|
|
|
@ -36,6 +36,15 @@ namespace Ombi.Api.Lidarr
|
||||||
return _api.Request<List<LidarrRootFolder>>(request);
|
return _api.Request<List<LidarrRootFolder>>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<Search>> Search(string searchTerm, string apiKey, string baseUrl)
|
||||||
|
{
|
||||||
|
var request = new Request($"{ApiVersion}/search", baseUrl, HttpMethod.Get);
|
||||||
|
request.AddQueryString("term", searchTerm);
|
||||||
|
|
||||||
|
AddHeaders(request, apiKey);
|
||||||
|
return await _api.Request<List<Search>>(request);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<List<ArtistLookup>> ArtistLookup(string searchTerm, string apiKey, string baseUrl)
|
public async Task<List<ArtistLookup>> ArtistLookup(string searchTerm, string apiKey, string baseUrl)
|
||||||
{
|
{
|
||||||
var request = new Request($"{ApiVersion}/Artist/lookup", baseUrl, HttpMethod.Get);
|
var request = new Request($"{ApiVersion}/Artist/lookup", baseUrl, HttpMethod.Get);
|
||||||
|
@ -83,7 +92,7 @@ namespace Ombi.Api.Lidarr
|
||||||
|
|
||||||
public Task<AlbumByArtistResponse> GetAlbumsByArtist(string foreignArtistId)
|
public Task<AlbumByArtistResponse> GetAlbumsByArtist(string foreignArtistId)
|
||||||
{
|
{
|
||||||
var request = new Request(string.Empty, $"https://api.lidarr.audio/api/v0.4/artist/{foreignArtistId}",
|
var request = new Request(string.Empty, $"https://api.lidarr.audio/api/v1/artist/{foreignArtistId}",
|
||||||
HttpMethod.Get) {IgnoreBaseUrlAppend = true};
|
HttpMethod.Get) {IgnoreBaseUrlAppend = true};
|
||||||
return _api.Request<AlbumByArtistResponse>(request);
|
return _api.Request<AlbumByArtistResponse>(request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Ombi.Api.Lidarr.Models
|
||||||
public string title { get; set; }
|
public string title { get; set; }
|
||||||
public string status { get; set; }
|
public string status { get; set; }
|
||||||
public string artistType { get; set; }
|
public string artistType { get; set; }
|
||||||
|
public string overview { get; set; }
|
||||||
public string disambiguation { get; set; }
|
public string disambiguation { get; set; }
|
||||||
public List<LidarrLinks> links { get; set; }
|
public List<LidarrLinks> links { get; set; }
|
||||||
public int artistId { get; set; }
|
public int artistId { get; set; }
|
||||||
|
|
|
@ -32,21 +32,9 @@ namespace Ombi.Api.Lidarr.Models
|
||||||
|
|
||||||
public class Addoptions
|
public class Addoptions
|
||||||
{
|
{
|
||||||
public MonitorTypes monitor { get; set; }
|
public string monitor { get; set; }
|
||||||
public bool monitored { get; set; }
|
public bool monitored { get; set; }
|
||||||
public bool searchForMissingAlbums { get; set; } // Only for Artists add
|
public bool searchForMissingAlbums { get; set; } // Only for Artists add
|
||||||
public string[] AlbumsToMonitor { get; set; } // Uses the MusicBrainzAlbumId!
|
public string[] AlbumsToMonitor { get; set; } // Uses the MusicBrainzAlbumId!
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MonitorTypes
|
|
||||||
{
|
|
||||||
All,
|
|
||||||
Future,
|
|
||||||
Missing,
|
|
||||||
Existing,
|
|
||||||
Latest,
|
|
||||||
First,
|
|
||||||
None,
|
|
||||||
Unknown
|
|
||||||
}
|
|
||||||
}
|
}
|
13
src/Ombi.Api.Lidarr/Models/Search.cs
Normal file
13
src/Ombi.Api.Lidarr/Models/Search.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using System.Net.Mime;
|
||||||
|
|
||||||
|
namespace Ombi.Api.Lidarr.Models
|
||||||
|
{
|
||||||
|
public class Search
|
||||||
|
{
|
||||||
|
public ArtistLookup artist { get; set; }
|
||||||
|
public AlbumLookup album { get; set; }
|
||||||
|
public string foreignId { get; set; }
|
||||||
|
public string id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -5,12 +5,10 @@ using System.Threading.Tasks;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using AutoFixture;
|
using AutoFixture;
|
||||||
using Hqub.MusicBrainz.API.Entities;
|
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Ombi.Api.Lidarr;
|
using Ombi.Api.Lidarr;
|
||||||
using Ombi.Api.Lidarr.Models;
|
using Ombi.Api.Lidarr.Models;
|
||||||
using Ombi.Api.MusicBrainz;
|
|
||||||
using Ombi.Core.Engine.V2;
|
using Ombi.Core.Engine.V2;
|
||||||
using Ombi.Core.Models.Requests;
|
using Ombi.Core.Models.Requests;
|
||||||
using Ombi.Core.Models.Search.V2.Music;
|
using Ombi.Core.Models.Search.V2.Music;
|
||||||
|
@ -22,7 +20,6 @@ using Ombi.Settings.Settings.Models.External;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
using Ombi.Test.Common;
|
using Ombi.Test.Common;
|
||||||
using Artist = Hqub.MusicBrainz.API.Entities.Artist;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Tests.Engine.V2
|
namespace Ombi.Core.Tests.Engine.V2
|
||||||
{
|
{
|
||||||
|
@ -32,7 +29,6 @@ namespace Ombi.Core.Tests.Engine.V2
|
||||||
|
|
||||||
private MusicSearchEngineV2 _engine;
|
private MusicSearchEngineV2 _engine;
|
||||||
|
|
||||||
private Mock<IMusicBrainzApi> _musicApi;
|
|
||||||
private Mock<ILidarrApi> _lidarrApi;
|
private Mock<ILidarrApi> _lidarrApi;
|
||||||
private Mock<ISettingsService<LidarrSettings>> _lidarrSettings;
|
private Mock<ISettingsService<LidarrSettings>> _lidarrSettings;
|
||||||
private Fixture F;
|
private Fixture F;
|
||||||
|
@ -52,118 +48,14 @@ namespace Ombi.Core.Tests.Engine.V2
|
||||||
var cache = new Mock<ICacheService>();
|
var cache = new Mock<ICacheService>();
|
||||||
var ombiSettings = new Mock<ISettingsService<OmbiSettings>>();
|
var ombiSettings = new Mock<ISettingsService<OmbiSettings>>();
|
||||||
var requestSub = new Mock<IRepository<RequestSubscription>>();
|
var requestSub = new Mock<IRepository<RequestSubscription>>();
|
||||||
_musicApi = new Mock<IMusicBrainzApi>();
|
|
||||||
_lidarrSettings = new Mock<ISettingsService<LidarrSettings>>();
|
_lidarrSettings = new Mock<ISettingsService<LidarrSettings>>();
|
||||||
_lidarrApi = new Mock<ILidarrApi>();
|
_lidarrApi = new Mock<ILidarrApi>();
|
||||||
_lidarrSettings.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new LidarrSettings());
|
_lidarrSettings.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new LidarrSettings());
|
||||||
_engine = new MusicSearchEngineV2(principle.Object, requestService.Object, ruleEval.Object,
|
_engine = new MusicSearchEngineV2(principle.Object, requestService.Object, ruleEval.Object,
|
||||||
um.Object, cache.Object, ombiSettings.Object, requestSub.Object, _musicApi.Object,
|
um.Object, cache.Object, ombiSettings.Object, requestSub.Object,
|
||||||
_lidarrSettings.Object, _lidarrApi.Object);
|
_lidarrSettings.Object, _lidarrApi.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public async Task GetBasicArtistInformation_SingleArtist_Test()
|
|
||||||
{
|
|
||||||
_musicApi.Setup(x => x.GetArtistInformation("pretend-artist-id")).ReturnsAsync(F.Create<Artist>());
|
|
||||||
|
|
||||||
var result = await _engine.GetArtistInformation("pretend-artist-id");
|
|
||||||
|
|
||||||
Assert.That(result, Is.Not.Null);
|
|
||||||
Assert.That(result.ReleaseGroups.Any(), Is.True, "Release Groups are null");
|
|
||||||
Assert.That(result.Members.Any(), Is.False, "Members somehow populated?");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public async Task GetBasicArtistInformation_Group_Test()
|
|
||||||
{
|
|
||||||
var musicReturnVal = F.Build<Artist>().With(x => x.Relations, new List<Relation>
|
|
||||||
{
|
|
||||||
new Relation
|
|
||||||
{
|
|
||||||
TypeId = RelationLinks.BandMember,
|
|
||||||
Artist = new Artist
|
|
||||||
{
|
|
||||||
Name = "Mr Artist"
|
|
||||||
},
|
|
||||||
Attributes = new []{"a nobody"},
|
|
||||||
Begin = "1992",
|
|
||||||
End = "2019",
|
|
||||||
Ended = true
|
|
||||||
},
|
|
||||||
new Relation
|
|
||||||
{
|
|
||||||
TypeId = RelationLinks.BandMember,
|
|
||||||
Artist = new Artist
|
|
||||||
{
|
|
||||||
Name = "Mr Artist2"
|
|
||||||
},
|
|
||||||
Attributes = new []{"a nobody2"},
|
|
||||||
Begin = "1993",
|
|
||||||
}
|
|
||||||
});
|
|
||||||
_musicApi.Setup(x => x.GetArtistInformation("pretend-artist-id")).ReturnsAsync(musicReturnVal.Create());
|
|
||||||
|
|
||||||
var result = await _engine.GetArtistInformation("pretend-artist-id");
|
|
||||||
|
|
||||||
Assert.That(result, Is.Not.Null);
|
|
||||||
Assert.That(result.ReleaseGroups.Any(), Is.True, "Release Groups are null");
|
|
||||||
Assert.That(result.Members.Any(), Is.True, "Members IS NULL!");
|
|
||||||
|
|
||||||
Assert.That(result.Members.FirstOrDefault(x => x.Name == "Mr Artist").End, Is.EqualTo("2019"));
|
|
||||||
Assert.That(result.Members.FirstOrDefault(x => x.Name == "Mr Artist").Attributes.Length, Is.EqualTo(1));
|
|
||||||
Assert.That(result.Members.FirstOrDefault(x => x.Name == "Mr Artist").IsCurrentMember, Is.EqualTo(false));
|
|
||||||
Assert.That(result.Members.FirstOrDefault(x => x.Name == "Mr Artist").Start, Is.EqualTo("1992"));
|
|
||||||
|
|
||||||
Assert.That(result.Members.FirstOrDefault(x => x.Name == "Mr Artist2").IsCurrentMember, Is.EqualTo(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCaseSource(nameof(LinksData))]
|
|
||||||
public async Task<string> GetBasicArtistInformation_Links_Test(string url, string typeId, Func<ArtistInformation, string> func)
|
|
||||||
{
|
|
||||||
var musicReturnVal = F.Build<Artist>().With(x => x.Relations, new List<Relation>
|
|
||||||
{
|
|
||||||
new Relation
|
|
||||||
{
|
|
||||||
TypeId = typeId,
|
|
||||||
Url = new Url
|
|
||||||
{
|
|
||||||
Resource = url
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
|
||||||
_musicApi.Setup(x => x.GetArtistInformation("pretend-artist-id")).ReturnsAsync(musicReturnVal.Create());
|
|
||||||
|
|
||||||
var result = await _engine.GetArtistInformation("pretend-artist-id");
|
|
||||||
|
|
||||||
Assert.That(result, Is.Not.Null);
|
|
||||||
return func(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<TestCaseData> LinksData
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
yield return new TestCaseData("twitter.com", RelationLinks.SocialNetwork, new Func<ArtistInformation, string>(artist => artist.Links.Twitter)).Returns("twitter.com").SetName("ArtistInformation_Links_Twitter");
|
|
||||||
yield return new TestCaseData("allmusic", RelationLinks.AllMusic, new Func<ArtistInformation, string>(artist => artist.Links.AllMusic)).Returns("allmusic").SetName("ArtistInformation_Links_AllMusic");
|
|
||||||
yield return new TestCaseData("bbcmusic", RelationLinks.BbcMusic, new Func<ArtistInformation, string>(artist => artist.Links.BbcMusic)).Returns("bbcmusic").SetName("ArtistInformation_Links_BbcMusic");
|
|
||||||
yield return new TestCaseData("discogs", RelationLinks.Discogs, new Func<ArtistInformation, string>(artist => artist.Links.Discogs)).Returns("discogs").SetName("ArtistInformation_Links_Discogs");
|
|
||||||
yield return new TestCaseData("homepage", RelationLinks.Homepage, new Func<ArtistInformation, string>(artist => artist.Links.HomePage)).Returns("homepage").SetName("ArtistInformation_Links_Homepage");
|
|
||||||
yield return new TestCaseData("imdb", RelationLinks.Imdb, new Func<ArtistInformation, string>(artist => artist.Links.Imdb)).Returns("imdb").SetName("ArtistInformation_Links_Imdb");
|
|
||||||
yield return new TestCaseData("lastfm", RelationLinks.LastFm, new Func<ArtistInformation, string>(artist => artist.Links.LastFm)).Returns("lastfm").SetName("ArtistInformation_Links_LastFm");
|
|
||||||
yield return new TestCaseData("myspace", RelationLinks.MySpace, new Func<ArtistInformation, string>(artist => artist.Links.MySpace)).Returns("myspace").SetName("ArtistInformation_Links_MySpace");
|
|
||||||
yield return new TestCaseData("onlinecommunity", RelationLinks.OnlineCommunity, new Func<ArtistInformation, string>(artist => artist.Links.OnlineCommunity)).Returns("onlinecommunity").SetName("ArtistInformation_Links_OnlineCommunity");
|
|
||||||
yield return new TestCaseData("www.facebook.com", RelationLinks.SocialNetwork, new Func<ArtistInformation, string>(artist => artist.Links.Facebook)).Returns("www.facebook.com").SetName("ArtistInformation_Links_Facebook");
|
|
||||||
yield return new TestCaseData("www.instagram.com", RelationLinks.SocialNetwork, new Func<ArtistInformation, string>(artist => artist.Links.Instagram)).Returns("www.instagram.com").SetName("ArtistInformation_Links_insta");
|
|
||||||
yield return new TestCaseData("www.vk.com", RelationLinks.SocialNetwork, new Func<ArtistInformation, string>(artist => artist.Links.Vk)).Returns("www.vk.com").SetName("ArtistInformation_Links_vk");
|
|
||||||
yield return new TestCaseData("app.spotify.com", RelationLinks.Streams, new Func<ArtistInformation, string>(artist => artist.Links.Spotify)).Returns("app.spotify.com").SetName("ArtistInformation_Links_Spotify");
|
|
||||||
yield return new TestCaseData("deezer.com", RelationLinks.Streams, new Func<ArtistInformation, string>(artist => artist.Links.Deezer)).Returns("deezer.com").SetName("ArtistInformation_Links_Deezer");
|
|
||||||
yield return new TestCaseData("play.google.com", RelationLinks.Download, new Func<ArtistInformation, string>(artist => artist.Links.Google)).Returns("play.google.com").SetName("ArtistInformation_Links_Google");
|
|
||||||
yield return new TestCaseData("itunes.apple.com", RelationLinks.Download, new Func<ArtistInformation, string>(artist => artist.Links.Apple)).Returns("itunes.apple.com").SetName("ArtistInformation_Links_Apple");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task GetArtistInformation_WithPosters()
|
public async Task GetArtistInformation_WithPosters()
|
||||||
{
|
{
|
||||||
|
@ -200,7 +92,6 @@ namespace Ombi.Core.Tests.Engine.V2
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_musicApi.Setup(x => x.GetArtistInformation("pretend-artist-id")).ReturnsAsync(F.Create<Artist>());
|
|
||||||
|
|
||||||
var result = await _engine.GetArtistInformation("pretend-artist-id");
|
var result = await _engine.GetArtistInformation("pretend-artist-id");
|
||||||
|
|
||||||
|
|
|
@ -10,19 +10,24 @@ namespace Ombi.Core.Engine
|
||||||
{
|
{
|
||||||
public interface IMusicRequestEngine
|
public interface IMusicRequestEngine
|
||||||
{
|
{
|
||||||
Task<RequestEngineResult>ApproveAlbum(AlbumRequest request);
|
Task<RequestEngineResult>ApproveAlbum(MusicRequests request);
|
||||||
Task<RequestEngineResult> ApproveAlbumById(int requestId);
|
Task<RequestEngineResult> ApproveAlbumById(int requestId);
|
||||||
Task<RequestEngineResult> DenyAlbumById(int modelId, string reason);
|
Task<RequestEngineResult> DenyAlbumById(int modelId, string reason);
|
||||||
Task<IEnumerable<AlbumRequest>> GetRequests();
|
Task<IEnumerable<MusicRequests>> GetRequests();
|
||||||
Task<RequestsViewModel<AlbumRequest>> GetRequests(int count, int position, OrderFilterModel orderFilter);
|
Task<RequestsViewModel<MusicRequests>> GetRequests(int count, int position, OrderFilterModel orderFilter);
|
||||||
Task<int> GetTotal();
|
Task<int> GetTotal();
|
||||||
Task<RequestEngineResult> MarkAvailable(int modelId);
|
Task<RequestEngineResult> MarkAvailable(int modelId);
|
||||||
Task<RequestEngineResult> MarkUnavailable(int modelId);
|
Task<RequestEngineResult> MarkUnavailable(int modelId);
|
||||||
Task<RequestEngineResult> RemoveAlbumRequest(int requestId);
|
Task<RequestEngineResult> RemoveAlbumRequest(int requestId);
|
||||||
Task<RequestEngineResult> RequestAlbum(MusicAlbumRequestViewModel model);
|
Task<RequestEngineResult> RequestAlbum(MusicAlbumRequestViewModel model);
|
||||||
Task<IEnumerable<AlbumRequest>> SearchAlbumRequest(string search);
|
Task<RequestEngineResult> RequestArtist(MusicArtistRequestViewModel model);
|
||||||
|
Task<IEnumerable<MusicRequests>> SearchAlbumRequest(string search);
|
||||||
Task<bool> UserHasRequest(string userId);
|
Task<bool> UserHasRequest(string userId);
|
||||||
Task<RequestsViewModel<AlbumRequest>> GetRequestsByStatus(int count, int position, string sort, string sortOrder, RequestStatus available);
|
Task<RequestsViewModel<AlbumRequest>> GetRequestsByStatus(int count, int position, string sort, string sortOrder, RequestStatus available);
|
||||||
Task<RequestsViewModel<AlbumRequest>> GetRequests(int count, int position, string sort, string sortOrder);
|
Task<RequestsViewModel<AlbumRequest>> GetRequests(int count, int position, string sort, string sortOrder);
|
||||||
|
|
||||||
|
Task<RequestQuotaCountModel> GetRemainingRequests(OmbiUser user = null);
|
||||||
|
Task<RequestsViewModel<MusicRequests>> GetRequestsByStatus(int count, int position, string sort, string sortOrder, RequestStatus available);
|
||||||
|
Task<RequestsViewModel<MusicRequests>> GetRequests(int count, int position, string sort, string sortOrder);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,6 +9,6 @@ namespace Ombi.Core.Engine.Interfaces
|
||||||
Task<ArtistInformation> GetArtistInformation(string artistId);
|
Task<ArtistInformation> GetArtistInformation(string artistId);
|
||||||
Task<ArtistInformation> GetArtistInformationByRequestId(int requestId);
|
Task<ArtistInformation> GetArtistInformationByRequestId(int requestId);
|
||||||
Task<AlbumArt> GetReleaseGroupArt(string musicBrainzId, CancellationToken token);
|
Task<AlbumArt> GetReleaseGroupArt(string musicBrainzId, CancellationToken token);
|
||||||
Task<ReleaseGroup> GetAlbum(string albumId);
|
Task<AlbumInformation> GetAlbumInformation(string albumId);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -73,7 +73,7 @@ namespace Ombi.Core.Engine
|
||||||
|
|
||||||
var userDetails = await GetUser();
|
var userDetails = await GetUser();
|
||||||
|
|
||||||
var requestModel = new AlbumRequest
|
var requestModel = new MusicRequests
|
||||||
{
|
{
|
||||||
ForeignAlbumId = model.ForeignAlbumId,
|
ForeignAlbumId = model.ForeignAlbumId,
|
||||||
ArtistName = album.artist?.artistName,
|
ArtistName = album.artist?.artistName,
|
||||||
|
@ -85,8 +85,10 @@ namespace Ombi.Core.Engine
|
||||||
Title = album.title,
|
Title = album.title,
|
||||||
Disk = album.images?.FirstOrDefault(x => x.coverType.Equals("disc"))?.url,
|
Disk = album.images?.FirstOrDefault(x => x.coverType.Equals("disc"))?.url,
|
||||||
Cover = album.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url,
|
Cover = album.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url,
|
||||||
ForeignArtistId = album?.artist?.foreignArtistId ?? string.Empty, // This needs to be populated to send to Lidarr for new requests
|
ForeignArtistId = album.artist?.foreignArtistId,
|
||||||
RequestedByAlias = model.RequestedByAlias
|
RequestedByAlias = model.RequestedByAlias,
|
||||||
|
Monitor = model.Monitor,
|
||||||
|
SearchForMissingAlbums = model.SearchForMissingAlbums
|
||||||
};
|
};
|
||||||
if (requestModel.Cover.IsNullOrEmpty())
|
if (requestModel.Cover.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
|
@ -128,6 +130,58 @@ namespace Ombi.Core.Engine
|
||||||
return await AddAlbumRequest(requestModel);
|
return await AddAlbumRequest(requestModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<RequestEngineResult> RequestArtist(MusicArtistRequestViewModel model)
|
||||||
|
{
|
||||||
|
var s = await _lidarrSettings.GetSettingsAsync();
|
||||||
|
var artist = await _lidarrApi.GetArtistByForeignId(model.ForeignArtistId, s.ApiKey, s.FullUri);
|
||||||
|
var userDetails = await GetUser();
|
||||||
|
var requestModel = new MusicRequests
|
||||||
|
{
|
||||||
|
ForeignArtistId = model.ForeignArtistId,
|
||||||
|
Monitored = model.Monitored,
|
||||||
|
Title = artist.artistName,
|
||||||
|
ArtistName = artist.artistName,
|
||||||
|
RequestedDate = DateTime.Now,
|
||||||
|
RequestType = RequestType.Artist,
|
||||||
|
RequestedUserId = userDetails.Id,
|
||||||
|
Monitor = model.Monitor,
|
||||||
|
SearchForMissingAlbums = model.SearchForMissingAlbums
|
||||||
|
};
|
||||||
|
|
||||||
|
var ruleResults = (await RunRequestRules(requestModel)).ToList();
|
||||||
|
if (ruleResults.Any(x => !x.Success))
|
||||||
|
{
|
||||||
|
return new RequestEngineResult
|
||||||
|
{
|
||||||
|
ErrorMessage = ruleResults.FirstOrDefault(x => x.Message.HasValue()).Message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (requestModel.Approved) // The rules have auto approved this
|
||||||
|
{
|
||||||
|
var requestEngineResult = await AddArtistRequest(requestModel);
|
||||||
|
if (requestEngineResult.Result)
|
||||||
|
{
|
||||||
|
var result = await ApproveArtist(requestModel);
|
||||||
|
if (result.IsError)
|
||||||
|
{
|
||||||
|
Logger.LogWarning("Tried auto sending Album but failed. Message: {0}", result.Message);
|
||||||
|
return new RequestEngineResult
|
||||||
|
{
|
||||||
|
Message = result.Message,
|
||||||
|
ErrorMessage = result.Message,
|
||||||
|
Result = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestEngineResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are no providers then it's successful but album has not been sent
|
||||||
|
}
|
||||||
|
|
||||||
|
return await AddArtistRequest(requestModel);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the requests.
|
/// Gets the requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -135,11 +189,11 @@ namespace Ombi.Core.Engine
|
||||||
/// <param name="position">The position.</param>
|
/// <param name="position">The position.</param>
|
||||||
/// <param name="orderFilter">The order/filter type.</param>
|
/// <param name="orderFilter">The order/filter type.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<RequestsViewModel<AlbumRequest>> GetRequests(int count, int position,
|
public async Task<RequestsViewModel<MusicRequests>> GetRequests(int count, int position,
|
||||||
OrderFilterModel orderFilter)
|
OrderFilterModel orderFilter)
|
||||||
{
|
{
|
||||||
var shouldHide = await HideFromOtherUsers();
|
var shouldHide = await HideFromOtherUsers();
|
||||||
IQueryable<AlbumRequest> allRequests;
|
IQueryable<MusicRequests> allRequests;
|
||||||
if (shouldHide.Hide)
|
if (shouldHide.Hide)
|
||||||
{
|
{
|
||||||
allRequests =
|
allRequests =
|
||||||
|
@ -193,14 +247,86 @@ namespace Ombi.Core.Engine
|
||||||
{
|
{
|
||||||
await CheckForSubscription(shouldHide, x);
|
await CheckForSubscription(shouldHide, x);
|
||||||
});
|
});
|
||||||
return new RequestsViewModel<AlbumRequest>
|
return new RequestsViewModel<MusicRequests>
|
||||||
{
|
{
|
||||||
Collection = requests,
|
Collection = requests,
|
||||||
Total = total
|
Total = total
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private IQueryable<AlbumRequest> OrderAlbums(IQueryable<AlbumRequest> allRequests, OrderType type)
|
/// <summary>
|
||||||
|
/// Gets the requests.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="count">The count.</param>
|
||||||
|
/// <param name="position">The position.</param>
|
||||||
|
/// <param name="orderFilter">The order/filter type.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<RequestsViewModel<MusicRequests>> GetRequestArtist(int count, int position,
|
||||||
|
OrderFilterModel orderFilter)
|
||||||
|
{
|
||||||
|
var shouldHide = await HideFromOtherUsers();
|
||||||
|
IQueryable<MusicRequests> allRequests;
|
||||||
|
if (shouldHide.Hide)
|
||||||
|
{
|
||||||
|
allRequests =
|
||||||
|
MusicRepository.GetWithUser(shouldHide
|
||||||
|
.UserId); //.Skip(position).Take(count).OrderByDescending(x => x.ReleaseDate).ToListAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
allRequests =
|
||||||
|
MusicRepository
|
||||||
|
.GetWithUser(); //.Skip(position).Take(count).OrderByDescending(x => x.ReleaseDate).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (orderFilter.AvailabilityFilter)
|
||||||
|
{
|
||||||
|
case FilterType.None:
|
||||||
|
break;
|
||||||
|
case FilterType.Available:
|
||||||
|
allRequests = allRequests.Where(x => x.Available);
|
||||||
|
break;
|
||||||
|
case FilterType.NotAvailable:
|
||||||
|
allRequests = allRequests.Where(x => !x.Available);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (orderFilter.StatusFilter)
|
||||||
|
{
|
||||||
|
case FilterType.None:
|
||||||
|
break;
|
||||||
|
case FilterType.Approved:
|
||||||
|
allRequests = allRequests.Where(x => x.Approved);
|
||||||
|
break;
|
||||||
|
case FilterType.Processing:
|
||||||
|
allRequests = allRequests.Where(x => x.Approved && !x.Available);
|
||||||
|
break;
|
||||||
|
case FilterType.PendingApproval:
|
||||||
|
allRequests = allRequests.Where(x => !x.Approved && !x.Available && !(x.Denied ?? false));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
var total = allRequests.Count();
|
||||||
|
|
||||||
|
var requests = await (OrderAlbums(allRequests, orderFilter.OrderType)).Skip(position).Take(count)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
requests.ForEach(async x =>
|
||||||
|
{
|
||||||
|
await CheckForSubscription(shouldHide, x);
|
||||||
|
});
|
||||||
|
return new RequestsViewModel<MusicRequests>
|
||||||
|
{
|
||||||
|
Collection = requests,
|
||||||
|
Total = total
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private IQueryable<MusicRequests> OrderAlbums(IQueryable<MusicRequests> allRequests, OrderType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -234,10 +360,10 @@ namespace Ombi.Core.Engine
|
||||||
/// Gets the requests.
|
/// Gets the requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<IEnumerable<AlbumRequest>> GetRequests()
|
public async Task<IEnumerable<MusicRequests>> GetRequests()
|
||||||
{
|
{
|
||||||
var shouldHide = await HideFromOtherUsers();
|
var shouldHide = await HideFromOtherUsers();
|
||||||
List<AlbumRequest> allRequests;
|
List<MusicRequests> allRequests;
|
||||||
if (shouldHide.Hide)
|
if (shouldHide.Hide)
|
||||||
{
|
{
|
||||||
allRequests = await MusicRepository.GetWithUser(shouldHide.UserId).ToListAsync();
|
allRequests = await MusicRepository.GetWithUser(shouldHide.UserId).ToListAsync();
|
||||||
|
@ -254,8 +380,28 @@ namespace Ombi.Core.Engine
|
||||||
return allRequests;
|
return allRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<MusicRequests>> GetRequestsArtist()
|
||||||
|
{
|
||||||
|
var shouldHide = await HideFromOtherUsers();
|
||||||
|
List<MusicRequests> allRequests;
|
||||||
|
if (shouldHide.Hide)
|
||||||
|
{
|
||||||
|
allRequests = await MusicRepository.GetWithUser(shouldHide.UserId).ToListAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
allRequests = await MusicRepository.GetWithUser().ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task CheckForSubscription(HideResult shouldHide, List<AlbumRequest> albumRequests)
|
allRequests.ForEach(async x =>
|
||||||
|
{
|
||||||
|
await CheckForArtistSubscription(shouldHide, x);
|
||||||
|
});
|
||||||
|
return allRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task CheckForSubscription(HideResult shouldHide, List<MusicRequests> albumRequests)
|
||||||
{
|
{
|
||||||
var requestIds = albumRequests.Select(x => x.Id);
|
var requestIds = albumRequests.Select(x => x.Id);
|
||||||
var sub = await _subscriptionRepository.GetAll().Where(s =>
|
var sub = await _subscriptionRepository.GetAll().Where(s =>
|
||||||
|
@ -276,7 +422,22 @@ namespace Ombi.Core.Engine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckForSubscription(HideResult shouldHide, AlbumRequest x)
|
private async Task CheckForArtistSubscription(HideResult shouldHide, MusicRequests artistRequest)
|
||||||
|
{
|
||||||
|
if (shouldHide.UserId == artistRequest.RequestedUserId)
|
||||||
|
{
|
||||||
|
artistRequest.ShowSubscribe = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
artistRequest.ShowSubscribe = true;
|
||||||
|
var sub = await _subscriptionRepository.GetAll().FirstOrDefaultAsync(s =>
|
||||||
|
s.UserId == shouldHide.UserId && s.RequestId == artistRequest.Id && s.RequestType == RequestType.Artist);
|
||||||
|
artistRequest.Subscribed = sub != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task CheckForSubscription(HideResult shouldHide, MusicRequests x)
|
||||||
{
|
{
|
||||||
if (shouldHide.UserId == x.RequestedUserId)
|
if (shouldHide.UserId == x.RequestedUserId)
|
||||||
{
|
{
|
||||||
|
@ -296,10 +457,10 @@ namespace Ombi.Core.Engine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="search">The search.</param>
|
/// <param name="search">The search.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<IEnumerable<AlbumRequest>> SearchAlbumRequest(string search)
|
public async Task<IEnumerable<MusicRequests>> SearchAlbumRequest(string search)
|
||||||
{
|
{
|
||||||
var shouldHide = await HideFromOtherUsers();
|
var shouldHide = await HideFromOtherUsers();
|
||||||
List<AlbumRequest> allRequests;
|
List<MusicRequests> allRequests;
|
||||||
if (shouldHide.Hide)
|
if (shouldHide.Hide)
|
||||||
{
|
{
|
||||||
allRequests = await MusicRepository.GetWithUser(shouldHide.UserId).ToListAsync();
|
allRequests = await MusicRepository.GetWithUser(shouldHide.UserId).ToListAsync();
|
||||||
|
@ -346,7 +507,7 @@ namespace Ombi.Core.Engine
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestEngineResult> ApproveAlbum(AlbumRequest request)
|
public async Task<RequestEngineResult> ApproveAlbum(MusicRequests request)
|
||||||
{
|
{
|
||||||
if (request == null)
|
if (request == null)
|
||||||
{
|
{
|
||||||
|
@ -370,7 +531,60 @@ namespace Ombi.Core.Engine
|
||||||
|
|
||||||
if (request.Approved)
|
if (request.Approved)
|
||||||
{
|
{
|
||||||
var result = await _musicSender.Send(request);
|
var result = await _musicSender.SendAlbum(request);
|
||||||
|
if (result.Success && result.Sent)
|
||||||
|
{
|
||||||
|
return new RequestEngineResult
|
||||||
|
{
|
||||||
|
Result = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.Success)
|
||||||
|
{
|
||||||
|
Logger.LogWarning("Tried auto sending album but failed. Message: {0}", result.Message);
|
||||||
|
return new RequestEngineResult
|
||||||
|
{
|
||||||
|
Message = result.Message,
|
||||||
|
ErrorMessage = result.Message,
|
||||||
|
Result = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are no providers then it's successful but movie has not been sent
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RequestEngineResult
|
||||||
|
{
|
||||||
|
Result = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestEngineResult> ApproveArtist(MusicRequests request)
|
||||||
|
{
|
||||||
|
if (request == null)
|
||||||
|
{
|
||||||
|
return new RequestEngineResult
|
||||||
|
{
|
||||||
|
ErrorMessage = "Request does not exist"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
request.MarkedAsApproved = DateTime.Now;
|
||||||
|
request.Approved = true;
|
||||||
|
request.Denied = false;
|
||||||
|
await MusicRepository.Update(request);
|
||||||
|
|
||||||
|
|
||||||
|
var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification, string.Empty);
|
||||||
|
if (canNotify.Success)
|
||||||
|
{
|
||||||
|
await NotificationHelper.Notify(request, NotificationType.RequestApproved);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.Approved)
|
||||||
|
{
|
||||||
|
var result = await _musicSender.SendArtist(request);
|
||||||
if (result.Success && result.Sent)
|
if (result.Success && result.Sent)
|
||||||
{
|
{
|
||||||
return new RequestEngineResult
|
return new RequestEngineResult
|
||||||
|
@ -469,7 +683,7 @@ namespace Ombi.Core.Engine
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<RequestEngineResult> AddAlbumRequest(AlbumRequest model)
|
private async Task<RequestEngineResult> AddAlbumRequest(MusicRequests model)
|
||||||
{
|
{
|
||||||
await MusicRepository.Add(model);
|
await MusicRepository.Add(model);
|
||||||
|
|
||||||
|
@ -490,10 +704,32 @@ namespace Ombi.Core.Engine
|
||||||
return new RequestEngineResult { Result = true, Message = $"{model.Title} has been successfully added!", RequestId = model.Id };
|
return new RequestEngineResult { Result = true, Message = $"{model.Title} has been successfully added!", RequestId = model.Id };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestsViewModel<AlbumRequest>> GetRequestsByStatus(int count, int position, string sortProperty, string sortOrder, RequestStatus status)
|
private async Task<RequestEngineResult> AddArtistRequest(MusicRequests model)
|
||||||
|
{
|
||||||
|
// Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(MusicRepository));
|
||||||
|
await MusicRepository.Add(model);
|
||||||
|
|
||||||
|
var result = await RunSpecificRule(model, SpecificRules.CanSendNotification, string.Empty);
|
||||||
|
if (result.Success)
|
||||||
|
{
|
||||||
|
await NotificationHelper.NewRequest(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
await _requestLog.Add(new RequestLog
|
||||||
|
{
|
||||||
|
UserId = (await GetUser()).Id,
|
||||||
|
RequestDate = DateTime.UtcNow,
|
||||||
|
RequestId = model.Id,
|
||||||
|
RequestType = RequestType.Artist,
|
||||||
|
});
|
||||||
|
|
||||||
|
return new RequestEngineResult { Result = true, Message = $"{model.Title} has been successfully added!", RequestId = model.Id };
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestsViewModel<MusicRequests>> GetRequestsByStatus(int count, int position, string sortProperty, string sortOrder, RequestStatus status)
|
||||||
{
|
{
|
||||||
var shouldHide = await HideFromOtherUsers();
|
var shouldHide = await HideFromOtherUsers();
|
||||||
IQueryable<AlbumRequest> allRequests;
|
IQueryable<MusicRequests> allRequests;
|
||||||
if (shouldHide.Hide)
|
if (shouldHide.Hide)
|
||||||
{
|
{
|
||||||
allRequests =
|
allRequests =
|
||||||
|
@ -525,12 +761,12 @@ namespace Ombi.Core.Engine
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var prop = TypeDescriptor.GetProperties(typeof(AlbumRequest)).Find(sortProperty, true);
|
var prop = TypeDescriptor.GetProperties(typeof(MusicRequests)).Find(sortProperty, true);
|
||||||
|
|
||||||
if (sortProperty.Contains('.'))
|
if (sortProperty.Contains('.'))
|
||||||
{
|
{
|
||||||
// This is a navigation property currently not supported
|
// This is a navigation property currently not supported
|
||||||
prop = TypeDescriptor.GetProperties(typeof(AlbumRequest)).Find("RequestedDate", true);
|
prop = TypeDescriptor.GetProperties(typeof(MusicRequests)).Find("RequestedDate", true);
|
||||||
//var properties = sortProperty.Split(new []{'.'}, StringSplitOptions.RemoveEmptyEntries);
|
//var properties = sortProperty.Split(new []{'.'}, StringSplitOptions.RemoveEmptyEntries);
|
||||||
//var firstProp = TypeDescriptor.GetProperties(typeof(MovieRequests)).Find(properties[0], true);
|
//var firstProp = TypeDescriptor.GetProperties(typeof(MovieRequests)).Find(properties[0], true);
|
||||||
//var propType = firstProp.PropertyType;
|
//var propType = firstProp.PropertyType;
|
||||||
|
@ -545,17 +781,17 @@ namespace Ombi.Core.Engine
|
||||||
requests = requests.Skip(position).Take(count).ToList();
|
requests = requests.Skip(position).Take(count).ToList();
|
||||||
|
|
||||||
await CheckForSubscription(shouldHide, requests);
|
await CheckForSubscription(shouldHide, requests);
|
||||||
return new RequestsViewModel<AlbumRequest>
|
return new RequestsViewModel<MusicRequests>
|
||||||
{
|
{
|
||||||
Collection = requests,
|
Collection = requests,
|
||||||
Total = total
|
Total = total
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestsViewModel<AlbumRequest>> GetRequests(int count, int position, string sortProperty, string sortOrder)
|
public async Task<RequestsViewModel<MusicRequests>> GetRequests(int count, int position, string sortProperty, string sortOrder)
|
||||||
{
|
{
|
||||||
var shouldHide = await HideFromOtherUsers();
|
var shouldHide = await HideFromOtherUsers();
|
||||||
IQueryable<AlbumRequest> allRequests;
|
IQueryable<MusicRequests> allRequests;
|
||||||
if (shouldHide.Hide)
|
if (shouldHide.Hide)
|
||||||
{
|
{
|
||||||
allRequests =
|
allRequests =
|
||||||
|
@ -589,7 +825,7 @@ namespace Ombi.Core.Engine
|
||||||
requests = requests.Skip(position).Take(count).ToList();
|
requests = requests.Skip(position).Take(count).ToList();
|
||||||
|
|
||||||
await CheckForSubscription(shouldHide, requests);
|
await CheckForSubscription(shouldHide, requests);
|
||||||
return new RequestsViewModel<AlbumRequest>
|
return new RequestsViewModel<MusicRequests>
|
||||||
{
|
{
|
||||||
Collection = requests,
|
Collection = requests,
|
||||||
Total = total
|
Total = total
|
||||||
|
|
|
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ombi.Api.MusicBrainz;
|
|
||||||
using Ombi.Api.TheMovieDb;
|
using Ombi.Api.TheMovieDb;
|
||||||
using Ombi.Api.TheMovieDb.Models;
|
using Ombi.Api.TheMovieDb.Models;
|
||||||
|
using Ombi.Api.Lidarr;
|
||||||
using Ombi.Core.Authentication;
|
using Ombi.Core.Authentication;
|
||||||
using Ombi.Core.Models.Requests;
|
using Ombi.Core.Models.Requests;
|
||||||
using Ombi.Core.Models.Search.V2;
|
using Ombi.Core.Models.Search.V2;
|
||||||
|
@ -23,17 +23,18 @@ namespace Ombi.Core.Engine.V2
|
||||||
{
|
{
|
||||||
public MultiSearchEngine(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules,
|
public MultiSearchEngine(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules,
|
||||||
OmbiUserManager um, ICacheService cache, ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub,
|
OmbiUserManager um, ICacheService cache, ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub,
|
||||||
IMovieDbApi movieDbApi, ISettingsService<LidarrSettings> lidarrSettings, IMusicBrainzApi musicApi)
|
IMovieDbApi movieDbApi, ISettingsService<LidarrSettings> lidarrSettings, ILidarrApi lidarrApi)
|
||||||
: base(identity, requestService, rules, um, cache, ombiSettings, sub)
|
: base(identity, requestService, rules, um, cache, ombiSettings, sub)
|
||||||
{
|
{
|
||||||
_movieDbApi = movieDbApi;
|
_movieDbApi = movieDbApi;
|
||||||
_lidarrSettings = lidarrSettings;
|
_lidarrSettings = lidarrSettings;
|
||||||
_musicApi = musicApi;
|
_lidarrApi = lidarrApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IMovieDbApi _movieDbApi;
|
private readonly IMovieDbApi _movieDbApi;
|
||||||
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
||||||
private readonly IMusicBrainzApi _musicApi;
|
|
||||||
|
private readonly ILidarrApi _lidarrApi;
|
||||||
|
|
||||||
private bool _demo = DemoSingleton.Instance.Demo;
|
private bool _demo = DemoSingleton.Instance.Demo;
|
||||||
|
|
||||||
|
@ -43,22 +44,41 @@ namespace Ombi.Core.Engine.V2
|
||||||
var lang = await DefaultLanguageCode(null);
|
var lang = await DefaultLanguageCode(null);
|
||||||
var model = new List<MultiSearchResult>();
|
var model = new List<MultiSearchResult>();
|
||||||
|
|
||||||
var movieDbData = (await _movieDbApi.MultiSearch(searchTerm, lang, cancellationToken)).results;
|
|
||||||
|
|
||||||
var lidarrSettings = await _lidarrSettings.GetSettingsAsync();
|
var lidarrSettings = await _lidarrSettings.GetSettingsAsync();
|
||||||
if (lidarrSettings.Enabled && filter.Music)
|
if (lidarrSettings.Enabled && filter.Music)
|
||||||
{
|
{
|
||||||
var artistResult = await _musicApi.SearchArtist(searchTerm);
|
var lidarSearchResult = await _lidarrApi.Search(searchTerm, lidarrSettings.ApiKey, lidarrSettings.FullUri);
|
||||||
foreach (var artist in artistResult)
|
foreach (var search_result in lidarSearchResult)
|
||||||
|
{
|
||||||
|
if (search_result.artist != null)
|
||||||
{
|
{
|
||||||
model.Add(new MultiSearchResult
|
model.Add(new MultiSearchResult
|
||||||
{
|
{
|
||||||
MediaType = "Artist",
|
MediaType = "Artist",
|
||||||
Title = artist.Name,
|
Title = search_result.artist.artistName,
|
||||||
Id = artist.Id
|
Id = search_result.artist.foreignArtistId,
|
||||||
|
Poster = search_result.artist.remotePoster,
|
||||||
|
Monitored = search_result.artist.monitored
|
||||||
|
|
||||||
|
});
|
||||||
|
} else if (search_result.album != null)
|
||||||
|
{
|
||||||
|
model.Add(new MultiSearchResult
|
||||||
|
{
|
||||||
|
MediaType = "Album",
|
||||||
|
Title = search_result.album.title,
|
||||||
|
Id = search_result.album.foreignAlbumId,
|
||||||
|
Poster = search_result.album.remoteCover,
|
||||||
|
Monitored = search_result.album.monitored
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.Movies || filter.TvShows)
|
||||||
|
{
|
||||||
|
var movieDbData = (await _movieDbApi.MultiSearch(searchTerm, lang, cancellationToken)).results;
|
||||||
|
|
||||||
foreach (var multiSearch in movieDbData)
|
foreach (var multiSearch in movieDbData)
|
||||||
{
|
{
|
||||||
|
@ -110,6 +130,7 @@ namespace Ombi.Core.Engine.V2
|
||||||
result.Id = multiSearch.id.ToString();
|
result.Id = multiSearch.id.ToString();
|
||||||
model.Add(result);
|
model.Add(result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ombi.Api.Lidarr;
|
using Ombi.Api.Lidarr;
|
||||||
using Ombi.Api.Lidarr.Models;
|
using Ombi.Api.Lidarr.Models;
|
||||||
using Ombi.Api.MusicBrainz;
|
|
||||||
using Ombi.Core.Authentication;
|
using Ombi.Core.Authentication;
|
||||||
using Ombi.Core.Engine.Interfaces;
|
using Ombi.Core.Engine.Interfaces;
|
||||||
using Ombi.Core.Models.Requests;
|
using Ombi.Core.Models.Requests;
|
||||||
|
@ -20,83 +19,57 @@ using Ombi.Settings.Settings.Models;
|
||||||
using Ombi.Settings.Settings.Models.External;
|
using Ombi.Settings.Settings.Models.External;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
using Artist = Hqub.MusicBrainz.API.Entities.Artist;
|
|
||||||
using ReleaseGroup = Ombi.Core.Models.Search.V2.Music.ReleaseGroup;
|
using ReleaseGroup = Ombi.Core.Models.Search.V2.Music.ReleaseGroup;
|
||||||
|
|
||||||
namespace Ombi.Core.Engine.V2
|
namespace Ombi.Core.Engine.V2
|
||||||
{
|
{
|
||||||
public class MusicSearchEngineV2 : BaseMediaEngine, IMusicSearchEngineV2
|
public class MusicSearchEngineV2 : BaseMediaEngine, IMusicSearchEngineV2
|
||||||
{
|
{
|
||||||
private readonly IMusicBrainzApi _musicBrainzApi;
|
|
||||||
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
||||||
private readonly ILidarrApi _lidarrApi;
|
private readonly ILidarrApi _lidarrApi;
|
||||||
|
|
||||||
public MusicSearchEngineV2(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules,
|
public MusicSearchEngineV2(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules,
|
||||||
OmbiUserManager um, ICacheService cache, ISettingsService<OmbiSettings> ombiSettings,
|
OmbiUserManager um, ICacheService cache, ISettingsService<OmbiSettings> ombiSettings,
|
||||||
IRepository<RequestSubscription> sub, IMusicBrainzApi musicBrainzApi, ISettingsService<LidarrSettings> lidarrSettings,
|
IRepository<RequestSubscription> sub, ISettingsService<LidarrSettings> lidarrSettings,
|
||||||
ILidarrApi lidarrApi)
|
ILidarrApi lidarrApi)
|
||||||
: base(identity, requestService, rules, um, cache, ombiSettings, sub)
|
: base(identity, requestService, rules, um, cache, ombiSettings, sub)
|
||||||
{
|
{
|
||||||
_musicBrainzApi = musicBrainzApi;
|
|
||||||
_lidarrSettings = lidarrSettings;
|
_lidarrSettings = lidarrSettings;
|
||||||
_lidarrApi = lidarrApi;
|
_lidarrApi = lidarrApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ReleaseGroup> GetAlbum(string albumId)
|
public async Task<ReleaseGroup> GetAlbum(string albumId)
|
||||||
{
|
{
|
||||||
var g = await _musicBrainzApi.GetAlbumInformation(albumId);
|
var lidarrSettings = await GetLidarrSettings();
|
||||||
var release = new ReleaseGroup
|
Task<AlbumLookup> lidarrAlbumTask = null;
|
||||||
|
var release = new ReleaseGroup{};
|
||||||
|
if (lidarrSettings.Enabled)
|
||||||
{
|
{
|
||||||
ReleaseType = g.ReleaseGroup.PrimaryType,
|
lidarrAlbumTask = _lidarrApi.GetAlbumByForeignId(albumId, lidarrSettings.ApiKey, lidarrSettings.FullUri);
|
||||||
Id = g.Id,
|
var albumResult = await lidarrAlbumTask;
|
||||||
Title = g.Title,
|
release = new ReleaseGroup
|
||||||
ReleaseDate = g.ReleaseGroup.FirstReleaseDate,
|
{
|
||||||
|
ReleaseType = albumResult.artistType,
|
||||||
|
Id = albumResult.artistId.ToString(),
|
||||||
|
Title = albumResult.title,
|
||||||
|
ReleaseDate = albumResult.releaseDate.ToString(),
|
||||||
};
|
};
|
||||||
|
|
||||||
await RunSearchRules(release);
|
await RunSearchRules(release);
|
||||||
|
}
|
||||||
|
|
||||||
return release;
|
return release;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ArtistInformation> GetArtistInformation(string artistId)
|
public async Task<ArtistInformation> GetArtistInformation(string artistId)
|
||||||
{
|
{
|
||||||
var artist = await _musicBrainzApi.GetArtistInformation(artistId);
|
|
||||||
var lidarrSettings = await GetLidarrSettings();
|
var lidarrSettings = await GetLidarrSettings();
|
||||||
Task<ArtistResult> lidarrArtistTask = null;
|
Task<ArtistResult> lidarrArtistTask = null;
|
||||||
|
var info = new ArtistInformation { };
|
||||||
if (lidarrSettings.Enabled)
|
if (lidarrSettings.Enabled)
|
||||||
{
|
{
|
||||||
lidarrArtistTask = _lidarrApi.GetArtistByForeignId(artistId, lidarrSettings.ApiKey, lidarrSettings.FullUri);
|
lidarrArtistTask = _lidarrApi.GetArtistByForeignId(artistId, lidarrSettings.ApiKey, lidarrSettings.FullUri);
|
||||||
}
|
info = new ArtistInformation { };
|
||||||
|
|
||||||
var info = new ArtistInformation
|
|
||||||
{
|
|
||||||
Id = artistId,
|
|
||||||
Name = artist.Name,
|
|
||||||
Country = artist.Country,
|
|
||||||
Region = artist.Area?.Name,
|
|
||||||
Type = artist.Type,
|
|
||||||
StartYear = artist.LifeSpan?.Begin ?? "",
|
|
||||||
EndYear = artist.LifeSpan?.End ?? "",
|
|
||||||
Disambiguation = artist.Disambiguation,
|
|
||||||
ReleaseGroups = new List<ReleaseGroup>(),
|
|
||||||
Members = new List<BandMember>()
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var g in artist.ReleaseGroups)
|
|
||||||
{
|
|
||||||
var release = new ReleaseGroup
|
|
||||||
{
|
|
||||||
ReleaseType = g.PrimaryType,
|
|
||||||
Id = g.Id,
|
|
||||||
Title = g.Title,
|
|
||||||
ReleaseDate = g.FirstReleaseDate,
|
|
||||||
};
|
|
||||||
|
|
||||||
await RunSearchRules(release);
|
|
||||||
info.ReleaseGroups.Add(release);
|
|
||||||
}
|
|
||||||
|
|
||||||
info.Links = GetLinksForArtist(artist);
|
|
||||||
info.Members = GetBandMembers(artist);
|
|
||||||
|
|
||||||
if (lidarrArtistTask != null)
|
if (lidarrArtistTask != null)
|
||||||
{
|
{
|
||||||
|
@ -108,36 +81,72 @@ namespace Ombi.Core.Engine.V2
|
||||||
info.Poster = artistResult.images?.FirstOrDefault(x => x.coverType.Equals("poster", StringComparison.InvariantCultureIgnoreCase))?.url.ToHttpsUrl();
|
info.Poster = artistResult.images?.FirstOrDefault(x => x.coverType.Equals("poster", StringComparison.InvariantCultureIgnoreCase))?.url.ToHttpsUrl();
|
||||||
info.FanArt = artistResult.images?.FirstOrDefault(x => x.coverType.Equals("fanart", StringComparison.InvariantCultureIgnoreCase))?.url.ToHttpsUrl();
|
info.FanArt = artistResult.images?.FirstOrDefault(x => x.coverType.Equals("fanart", StringComparison.InvariantCultureIgnoreCase))?.url.ToHttpsUrl();
|
||||||
info.Overview = artistResult.overview;
|
info.Overview = artistResult.overview;
|
||||||
|
info.Name = artistResult.artistName;
|
||||||
|
info.Monitored = artistResult.monitored;
|
||||||
}
|
}
|
||||||
catch (JsonSerializationException)
|
catch (JsonSerializationException)
|
||||||
{
|
{
|
||||||
// swallow, Lidarr probably doesn't have this artist
|
// swallow, Lidarr probably doesn't have this artist
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<AlbumInformation> GetAlbumInformation(string albumId)
|
||||||
|
{
|
||||||
|
var lidarrSettings = await GetLidarrSettings();
|
||||||
|
Task<AlbumLookup> lidarrAlbumTask = null;
|
||||||
|
var info = new AlbumInformation { };
|
||||||
|
if (lidarrSettings.Enabled)
|
||||||
|
{
|
||||||
|
lidarrAlbumTask = _lidarrApi.GetAlbumByForeignId(albumId, lidarrSettings.ApiKey, lidarrSettings.FullUri);
|
||||||
|
|
||||||
|
if (lidarrAlbumTask != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var albumResult = await lidarrAlbumTask;
|
||||||
|
info.Cover = albumResult.images?.FirstOrDefault(x => x.coverType.Equals("cover", StringComparison.InvariantCultureIgnoreCase))?.url.ToHttpsUrl();
|
||||||
|
info.Title = albumResult.title;
|
||||||
|
info.Disambiguation = albumResult.disambiguation;
|
||||||
|
info.Overview = albumResult.overview;
|
||||||
|
info.Monitored = albumResult.monitored;
|
||||||
|
info.Id = albumResult.foreignAlbumId;
|
||||||
|
}
|
||||||
|
catch (JsonSerializationException)
|
||||||
|
{
|
||||||
|
// swallow, Lidarr probably doesn't have this album
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AlbumArt> GetReleaseGroupArt(string musicBrainzId, CancellationToken token)
|
public async Task<AlbumArt> GetReleaseGroupArt(string musicBrainzId, CancellationToken token)
|
||||||
{
|
{
|
||||||
var art = await _musicBrainzApi.GetCoverArtForReleaseGroup(musicBrainzId, token);
|
// var art = await _musicBrainzApi.GetCoverArtForReleaseGroup(musicBrainzId, token);
|
||||||
|
|
||||||
if (art == null || !art.images.Any())
|
// if (art == null || !art.images.Any())
|
||||||
{
|
// {
|
||||||
return new AlbumArt();
|
// return new AlbumArt();
|
||||||
}
|
// }
|
||||||
|
|
||||||
foreach (var cover in art.images)
|
// foreach (var cover in art.images)
|
||||||
{
|
// {
|
||||||
if ((cover.thumbnails?.small ?? string.Empty).HasValue())
|
// if ((cover.thumbnails?.small ?? string.Empty).HasValue())
|
||||||
{
|
// {
|
||||||
return new AlbumArt(cover.thumbnails.small.ToHttpsUrl());
|
// return new AlbumArt(cover.thumbnails.small.ToHttpsUrl());
|
||||||
}
|
// }
|
||||||
if ((cover.thumbnails?.large ?? string.Empty).HasValue())
|
// if ((cover.thumbnails?.large ?? string.Empty).HasValue())
|
||||||
{
|
// {
|
||||||
return new AlbumArt(cover.thumbnails.large.ToHttpsUrl());
|
// return new AlbumArt(cover.thumbnails.large.ToHttpsUrl());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return new AlbumArt();
|
return new AlbumArt();
|
||||||
}
|
}
|
||||||
|
@ -151,18 +160,18 @@ namespace Ombi.Core.Engine.V2
|
||||||
private List<BandMember> GetBandMembers(Artist artist)
|
private List<BandMember> GetBandMembers(Artist artist)
|
||||||
{
|
{
|
||||||
var members = new List<BandMember>();
|
var members = new List<BandMember>();
|
||||||
var membersOfBand = artist.Relations.Where(x => x.TypeId == RelationLinks.BandMember);
|
// var membersOfBand = artist.Relations.Where(x => x.TypeId == RelationLinks.BandMember);
|
||||||
foreach (var member in membersOfBand)
|
// foreach (var member in membersOfBand)
|
||||||
{
|
// {
|
||||||
members.Add(new BandMember
|
// members.Add(new BandMember
|
||||||
{
|
// {
|
||||||
Name = member.Artist?.Name,
|
// Name = member.Artist?.Name,
|
||||||
Attributes = member.Attributes,
|
// Attributes = member.Attributes,
|
||||||
IsCurrentMember = member.Ended == null,
|
// IsCurrentMember = member.Ended == null,
|
||||||
End = member.End,
|
// End = member.End,
|
||||||
Start = member.Begin
|
// Start = member.Begin
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
@ -170,79 +179,79 @@ namespace Ombi.Core.Engine.V2
|
||||||
private ArtistLinks GetLinksForArtist(Artist artist)
|
private ArtistLinks GetLinksForArtist(Artist artist)
|
||||||
{
|
{
|
||||||
var links = new ArtistLinks();
|
var links = new ArtistLinks();
|
||||||
foreach (var relation in artist.Relations)
|
// foreach (var relation in artist.Relations)
|
||||||
{
|
// {
|
||||||
switch (relation.TypeId)
|
// switch (relation.TypeId)
|
||||||
{
|
// {
|
||||||
case RelationLinks.AllMusic:
|
// case RelationLinks.AllMusic:
|
||||||
links.AllMusic = relation.Url?.Resource.ToHttpsUrl();
|
// links.AllMusic = relation.Url?.Resource.ToHttpsUrl();
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.BbcMusic:
|
// case RelationLinks.BbcMusic:
|
||||||
links.BbcMusic = relation.Url?.Resource.ToHttpsUrl();
|
// links.BbcMusic = relation.Url?.Resource.ToHttpsUrl();
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.Discogs:
|
// case RelationLinks.Discogs:
|
||||||
links.Discogs = relation.Url?.Resource.ToHttpsUrl();
|
// links.Discogs = relation.Url?.Resource.ToHttpsUrl();
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.Homepage:
|
// case RelationLinks.Homepage:
|
||||||
links.HomePage = relation.Url?.Resource.ToHttpsUrl();
|
// links.HomePage = relation.Url?.Resource.ToHttpsUrl();
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.Imdb:
|
// case RelationLinks.Imdb:
|
||||||
links.Imdb = relation.Url?.Resource.ToHttpsUrl();
|
// links.Imdb = relation.Url?.Resource.ToHttpsUrl();
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.LastFm:
|
// case RelationLinks.LastFm:
|
||||||
links.LastFm = relation.Url?.Resource.ToHttpsUrl();
|
// links.LastFm = relation.Url?.Resource.ToHttpsUrl();
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.MySpace:
|
// case RelationLinks.MySpace:
|
||||||
links.MySpace = relation.Url?.Resource.ToHttpsUrl();
|
// links.MySpace = relation.Url?.Resource.ToHttpsUrl();
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.OnlineCommunity:
|
// case RelationLinks.OnlineCommunity:
|
||||||
links.OnlineCommunity = relation.Url?.Resource.ToHttpsUrl();
|
// links.OnlineCommunity = relation.Url?.Resource.ToHttpsUrl();
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.SocialNetwork:
|
// case RelationLinks.SocialNetwork:
|
||||||
if ((relation.Url?.Resource ?? string.Empty).Contains("twitter", CompareOptions.IgnoreCase))
|
// if ((relation.Url?.Resource ?? string.Empty).Contains("twitter", CompareOptions.IgnoreCase))
|
||||||
{
|
// {
|
||||||
links.Twitter = relation.Url?.Resource.ToHttpsUrl();
|
// links.Twitter = relation.Url?.Resource.ToHttpsUrl();
|
||||||
}
|
// }
|
||||||
if ((relation.Url?.Resource ?? string.Empty).Contains("facebook", CompareOptions.IgnoreCase))
|
// if ((relation.Url?.Resource ?? string.Empty).Contains("facebook", CompareOptions.IgnoreCase))
|
||||||
{
|
// {
|
||||||
links.Facebook = relation.Url?.Resource.ToHttpsUrl();
|
// links.Facebook = relation.Url?.Resource.ToHttpsUrl();
|
||||||
}
|
// }
|
||||||
if ((relation.Url?.Resource ?? string.Empty).Contains("instagram", CompareOptions.IgnoreCase))
|
// if ((relation.Url?.Resource ?? string.Empty).Contains("instagram", CompareOptions.IgnoreCase))
|
||||||
{
|
// {
|
||||||
links.Instagram = relation.Url?.Resource.ToHttpsUrl();
|
// links.Instagram = relation.Url?.Resource.ToHttpsUrl();
|
||||||
}
|
// }
|
||||||
if ((relation.Url?.Resource ?? string.Empty).Contains("vk", CompareOptions.IgnoreCase))
|
// if ((relation.Url?.Resource ?? string.Empty).Contains("vk", CompareOptions.IgnoreCase))
|
||||||
{
|
// {
|
||||||
links.Vk = relation.Url?.Resource.ToHttpsUrl();
|
// links.Vk = relation.Url?.Resource.ToHttpsUrl();
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.Streams:
|
// case RelationLinks.Streams:
|
||||||
if ((relation.Url?.Resource ?? string.Empty).Contains("spotify", CompareOptions.IgnoreCase))
|
// if ((relation.Url?.Resource ?? string.Empty).Contains("spotify", CompareOptions.IgnoreCase))
|
||||||
{
|
// {
|
||||||
links.Spotify = relation.Url?.Resource.ToHttpsUrl();
|
// links.Spotify = relation.Url?.Resource.ToHttpsUrl();
|
||||||
}
|
// }
|
||||||
if ((relation.Url?.Resource ?? string.Empty).Contains("deezer", CompareOptions.IgnoreCase))
|
// if ((relation.Url?.Resource ?? string.Empty).Contains("deezer", CompareOptions.IgnoreCase))
|
||||||
{
|
// {
|
||||||
links.Deezer = relation.Url?.Resource.ToHttpsUrl();
|
// links.Deezer = relation.Url?.Resource.ToHttpsUrl();
|
||||||
}
|
// }
|
||||||
|
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.YouTube:
|
// case RelationLinks.YouTube:
|
||||||
links.YouTube = relation.Url?.Resource.ToHttpsUrl();
|
// links.YouTube = relation.Url?.Resource.ToHttpsUrl();
|
||||||
break;
|
// break;
|
||||||
case RelationLinks.Download:
|
// case RelationLinks.Download:
|
||||||
if ((relation.Url?.Resource ?? string.Empty).Contains("google", CompareOptions.IgnoreCase))
|
// if ((relation.Url?.Resource ?? string.Empty).Contains("google", CompareOptions.IgnoreCase))
|
||||||
{
|
// {
|
||||||
links.Google = relation.Url?.Resource.ToHttpsUrl();
|
// links.Google = relation.Url?.Resource.ToHttpsUrl();
|
||||||
}
|
// }
|
||||||
if ((relation.Url?.Resource ?? string.Empty).Contains("apple", CompareOptions.IgnoreCase))
|
// if ((relation.Url?.Resource ?? string.Empty).Contains("apple", CompareOptions.IgnoreCase))
|
||||||
{
|
// {
|
||||||
links.Apple = relation.Url?.Resource.ToHttpsUrl();
|
// links.Apple = relation.Url?.Resource.ToHttpsUrl();
|
||||||
}
|
// }
|
||||||
|
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return links;
|
return links;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace Ombi.Core
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task NewRequest(AlbumRequest model)
|
public async Task NewRequest(MusicRequests model)
|
||||||
{
|
{
|
||||||
var notificationModel = new NotificationOptions
|
var notificationModel = new NotificationOptions
|
||||||
{
|
{
|
||||||
|
@ -55,7 +55,6 @@ namespace Ombi.Core
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task Notify(MovieRequests model, NotificationType type)
|
public async Task Notify(MovieRequests model, NotificationType type)
|
||||||
{
|
{
|
||||||
var notificationModel = new NotificationOptions
|
var notificationModel = new NotificationOptions
|
||||||
|
@ -88,7 +87,7 @@ namespace Ombi.Core
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Notify(AlbumRequest model, NotificationType type)
|
public async Task Notify(MusicRequests model, NotificationType type)
|
||||||
{
|
{
|
||||||
var notificationModel = new NotificationOptions
|
var notificationModel = new NotificationOptions
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,5 +4,16 @@
|
||||||
{
|
{
|
||||||
public string ForeignAlbumId { get; set; }
|
public string ForeignAlbumId { get; set; }
|
||||||
public string RequestedByAlias { get; set; }
|
public string RequestedByAlias { get; set; }
|
||||||
|
public string Monitor { get; set; }
|
||||||
|
public bool SearchForMissingAlbums { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MusicArtistRequestViewModel
|
||||||
|
{
|
||||||
|
public string ForeignArtistId { get; set; }
|
||||||
|
public bool Monitored { get; set; }
|
||||||
|
public string RequestedByAlias { get; set; }
|
||||||
|
public string Monitor { get; set; }
|
||||||
|
public bool SearchForMissingAlbums { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,5 +7,6 @@
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string Poster { get; set; }
|
public string Poster { get; set; }
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
|
public bool Monitored { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
20
src/Ombi.Core/Models/Search/V2/Music/AlbumInformation.cs
Normal file
20
src/Ombi.Core/Models/Search/V2/Music/AlbumInformation.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Models.Search.V2.Music
|
||||||
|
{
|
||||||
|
public class AlbumInformation
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string StartYear { get; set; }
|
||||||
|
public string EndYear { get; set; }
|
||||||
|
public bool IsEnded => string.IsNullOrEmpty(EndYear);
|
||||||
|
public bool Monitored { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
public string Country { get; set; }
|
||||||
|
public string Region { get; set; }
|
||||||
|
public string Disambiguation { get; set; }
|
||||||
|
public string Cover { get; set; }
|
||||||
|
public string Overview { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ namespace Ombi.Core.Models.Search.V2.Music
|
||||||
public string Poster { get; set; }
|
public string Poster { get; set; }
|
||||||
public string FanArt { get; set; }
|
public string FanArt { get; set; }
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
|
public bool Monitored { get; set; }
|
||||||
public List<ReleaseGroup> ReleaseGroups { get; set; }
|
public List<ReleaseGroup> ReleaseGroups { get; set; }
|
||||||
public ArtistLinks Links { get; set; }
|
public ArtistLinks Links { get; set; }
|
||||||
public List<BandMember> Members { get; set; }
|
public List<BandMember> Members { get; set; }
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
<ProjectReference Include="..\Ombi.Api.Jellyfin\Ombi.Api.Jellyfin.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Jellyfin\Ombi.Api.Jellyfin.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.FanartTv\Ombi.Api.FanartTv.csproj" />
|
<ProjectReference Include="..\Ombi.Api.FanartTv\Ombi.Api.FanartTv.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.MusicBrainz\Ombi.Api.MusicBrainz.csproj" />
|
|
||||||
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.Radarr\Ombi.Api.Radarr.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Radarr\Ombi.Api.Radarr.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.SickRage\Ombi.Api.SickRage.csproj" />
|
<ProjectReference Include="..\Ombi.Api.SickRage\Ombi.Api.SickRage.csproj" />
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Ombi.Core.Senders
|
||||||
{
|
{
|
||||||
public interface IMusicSender
|
public interface IMusicSender
|
||||||
{
|
{
|
||||||
Task<SenderResult> Send(AlbumRequest model);
|
Task<SenderResult> SendAlbum(MusicRequests model);
|
||||||
|
Task<SenderResult> SendArtist(MusicRequests model);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,10 +10,10 @@ namespace Ombi.Core
|
||||||
{
|
{
|
||||||
Task NewRequest(FullBaseRequest model);
|
Task NewRequest(FullBaseRequest model);
|
||||||
Task NewRequest(ChildRequests model);
|
Task NewRequest(ChildRequests model);
|
||||||
Task NewRequest(AlbumRequest model);
|
Task NewRequest(MusicRequests model);
|
||||||
Task Notify(MovieRequests model, NotificationType type);
|
Task Notify(MovieRequests model, NotificationType type);
|
||||||
Task Notify(ChildRequests model, NotificationType type);
|
Task Notify(ChildRequests model, NotificationType type);
|
||||||
Task Notify(AlbumRequest model, NotificationType type);
|
Task Notify(MusicRequests model, NotificationType type);
|
||||||
Task Notify(NotificationOptions model);
|
Task Notify(NotificationOptions model);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,14 +33,14 @@ namespace Ombi.Core.Senders
|
||||||
private readonly IRepository<RequestQueue> _requestQueueRepository;
|
private readonly IRepository<RequestQueue> _requestQueueRepository;
|
||||||
private readonly INotificationHelper _notificationHelper;
|
private readonly INotificationHelper _notificationHelper;
|
||||||
|
|
||||||
public async Task<SenderResult> Send(AlbumRequest model)
|
public async Task<SenderResult> SendAlbum(MusicRequests model)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var settings = await _lidarrSettings.GetSettingsAsync();
|
var settings = await _lidarrSettings.GetSettingsAsync();
|
||||||
if (settings.Enabled)
|
if (settings.Enabled)
|
||||||
{
|
{
|
||||||
return await SendToLidarr(model, settings);
|
return await SendAlbumToLidarr(model, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SenderResult { Success = false, Sent = false, Message = "Lidarr is not enabled" };
|
return new SenderResult { Success = false, Sent = false, Message = "Lidarr is not enabled" };
|
||||||
|
@ -73,7 +73,47 @@ namespace Ombi.Core.Senders
|
||||||
return new SenderResult { Success = false, Sent = false, Message = "Something went wrong!" };
|
return new SenderResult { Success = false, Sent = false, Message = "Something went wrong!" };
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<SenderResult> SendToLidarr(AlbumRequest model, LidarrSettings settings)
|
public async Task<SenderResult> SendArtist(MusicRequests model)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var settings = await _lidarrSettings.GetSettingsAsync();
|
||||||
|
if (settings.Enabled)
|
||||||
|
{
|
||||||
|
return await SendArtistToLidarr(model, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SenderResult { Success = false, Sent = false, Message = "Lidarr is not enabled" };
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_log.LogError(e, "Exception thrown when sending a music to DVR app, added to the request queue");
|
||||||
|
var existingQueue = await _requestQueueRepository.FirstOrDefaultAsync(x => x.RequestId == model.Id);
|
||||||
|
if (existingQueue != null)
|
||||||
|
{
|
||||||
|
existingQueue.RetryCount++;
|
||||||
|
existingQueue.Error = e.Message;
|
||||||
|
await _requestQueueRepository.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _requestQueueRepository.Add(new RequestQueue
|
||||||
|
{
|
||||||
|
Dts = DateTime.UtcNow,
|
||||||
|
Error = e.Message,
|
||||||
|
RequestId = model.Id,
|
||||||
|
Type = RequestType.Album,
|
||||||
|
RetryCount = 0
|
||||||
|
});
|
||||||
|
await _notificationHelper.Notify(model, NotificationType.ItemAddedToFaultQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new SenderResult { Success = false, Sent = false, Message = "Something went wrong!" };
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<SenderResult> SendAlbumToLidarr(MusicRequests model, LidarrSettings settings)
|
||||||
{
|
{
|
||||||
var qualityToUse = int.Parse(settings.DefaultQualityProfile);
|
var qualityToUse = int.Parse(settings.DefaultQualityProfile);
|
||||||
//if (model.QualityOverride > 0)
|
//if (model.QualityOverride > 0)
|
||||||
|
@ -99,9 +139,9 @@ namespace Ombi.Core.Senders
|
||||||
foreignArtistId = model.ForeignArtistId,
|
foreignArtistId = model.ForeignArtistId,
|
||||||
addOptions = new Addoptions
|
addOptions = new Addoptions
|
||||||
{
|
{
|
||||||
monitored = true,
|
monitored = model.Monitored,
|
||||||
monitor = MonitorTypes.None,
|
monitor = model.Monitor,
|
||||||
searchForMissingAlbums = false,
|
searchForMissingAlbums = model.SearchForMissingAlbums,
|
||||||
AlbumsToMonitor = new[] {model.ForeignAlbumId}
|
AlbumsToMonitor = new[] {model.ForeignAlbumId}
|
||||||
},
|
},
|
||||||
added = DateTime.Now,
|
added = DateTime.Now,
|
||||||
|
@ -160,7 +200,46 @@ namespace Ombi.Core.Senders
|
||||||
return new SenderResult { Success = false, Sent = false, Message = "Album is already monitored" };
|
return new SenderResult { Success = false, Sent = false, Message = "Album is already monitored" };
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<SenderResult> SetupAlbum(AlbumRequest model, ArtistResult artist, LidarrSettings settings)
|
private async Task<SenderResult> SendArtistToLidarr(MusicRequests model, LidarrSettings settings)
|
||||||
|
{
|
||||||
|
var qualityToUse = int.Parse(settings.DefaultQualityProfile);
|
||||||
|
//if (model.QualityOverride > 0)
|
||||||
|
//{
|
||||||
|
// qualityToUse = model.QualityOverride;
|
||||||
|
//}
|
||||||
|
|
||||||
|
var rootFolderPath = /*model.RootPathOverride <= 0 ?*/ settings.DefaultRootPath /*: await RadarrRootPath(model.RootPathOverride, settings)*/;
|
||||||
|
|
||||||
|
EnsureArg.IsNotNullOrEmpty(model.ForeignArtistId, nameof(model.ForeignArtistId));
|
||||||
|
EnsureArg.IsNotNullOrEmpty(rootFolderPath, nameof(rootFolderPath));
|
||||||
|
|
||||||
|
// Create artist
|
||||||
|
var newArtist = new ArtistAdd
|
||||||
|
{
|
||||||
|
foreignArtistId = model.ForeignArtistId,
|
||||||
|
addOptions = new Addoptions
|
||||||
|
{
|
||||||
|
monitor = model.Monitor,
|
||||||
|
searchForMissingAlbums = model.SearchForMissingAlbums
|
||||||
|
},
|
||||||
|
artistName = model.ArtistName,
|
||||||
|
added = DateTime.Now,
|
||||||
|
monitored = model.Monitored,
|
||||||
|
metadataProfileId = settings.MetadataProfileId,
|
||||||
|
qualityProfileId = qualityToUse,
|
||||||
|
rootFolderPath = rootFolderPath,
|
||||||
|
};
|
||||||
|
// Console.Write(newArtist);
|
||||||
|
var result = await _lidarrApi.AddArtist(newArtist, settings.ApiKey, settings.FullUri);
|
||||||
|
if (result != null && result.id > 0)
|
||||||
|
{
|
||||||
|
return new SenderResult { Message = "Artist has been requested!", Sent = true, Success = true };
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SenderResult { Success = false, Sent = false, Message = "Artist is already monitored" };
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<SenderResult> SetupAlbum(MusicRequests model, ArtistResult artist, LidarrSettings settings)
|
||||||
{
|
{
|
||||||
// Get the album id
|
// Get the album id
|
||||||
var albums = await _lidarrApi.GetAllAlbumsByArtistId(artist.id, settings.ApiKey, settings.FullUri);
|
var albums = await _lidarrApi.GetAllAlbumsByArtistId(artist.id, settings.ApiKey, settings.FullUri);
|
||||||
|
|
|
@ -261,7 +261,7 @@ namespace Ombi.Core.Senders
|
||||||
qualityProfileId = qualityToUse,
|
qualityProfileId = qualityToUse,
|
||||||
titleSlug = model.ParentRequest.Title,
|
titleSlug = model.ParentRequest.Title,
|
||||||
seriesType = seriesType,
|
seriesType = seriesType,
|
||||||
addOptions = new AddOptions
|
addOptions = new Ombi.Api.Sonarr.Models.AddOptions
|
||||||
{
|
{
|
||||||
ignoreEpisodesWithFiles = false, // There shouldn't be any episodes with files, this is a new season
|
ignoreEpisodesWithFiles = false, // There shouldn't be any episodes with files, this is a new season
|
||||||
ignoreEpisodesWithoutFiles = false, // We want all missing
|
ignoreEpisodesWithoutFiles = false, // We want all missing
|
||||||
|
|
|
@ -63,7 +63,6 @@ using Ombi.Schedule.Jobs.Plex.Interfaces;
|
||||||
using Ombi.Schedule.Jobs.SickRage;
|
using Ombi.Schedule.Jobs.SickRage;
|
||||||
using Ombi.Schedule.Processor;
|
using Ombi.Schedule.Processor;
|
||||||
using Quartz.Spi;
|
using Quartz.Spi;
|
||||||
using Ombi.Api.MusicBrainz;
|
|
||||||
using Ombi.Api.Twilio;
|
using Ombi.Api.Twilio;
|
||||||
using Ombi.Api.CloudService;
|
using Ombi.Api.CloudService;
|
||||||
using Ombi.Api.RottenTomatoes;
|
using Ombi.Api.RottenTomatoes;
|
||||||
|
@ -167,7 +166,6 @@ namespace Ombi.DependencyInjection
|
||||||
services.AddTransient<IOneSignalApi, OneSignalApi>();
|
services.AddTransient<IOneSignalApi, OneSignalApi>();
|
||||||
services.AddTransient<ILidarrApi, LidarrApi>();
|
services.AddTransient<ILidarrApi, LidarrApi>();
|
||||||
services.AddTransient<IGroupMeApi, GroupMeApi>();
|
services.AddTransient<IGroupMeApi, GroupMeApi>();
|
||||||
services.AddTransient<IMusicBrainzApi, MusicBrainzApi>();
|
|
||||||
services.AddTransient<IWhatsAppApi, WhatsAppApi>();
|
services.AddTransient<IWhatsAppApi, WhatsAppApi>();
|
||||||
services.AddTransient<ICloudMobileNotification, CloudMobileNotification>();
|
services.AddTransient<ICloudMobileNotification, CloudMobileNotification>();
|
||||||
services.AddTransient<IEmbyApiFactory, EmbyApiFactory>();
|
services.AddTransient<IEmbyApiFactory, EmbyApiFactory>();
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
<ProjectReference Include="..\Ombi.Api.GroupMe\Ombi.Api.GroupMe.csproj" />
|
<ProjectReference Include="..\Ombi.Api.GroupMe\Ombi.Api.GroupMe.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.MusicBrainz\Ombi.Api.MusicBrainz.csproj" />
|
|
||||||
<ProjectReference Include="..\Ombi.Api.Notifications\Ombi.Api.Notifications.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Notifications\Ombi.Api.Notifications.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj" />
|
||||||
|
|
|
@ -197,7 +197,7 @@ namespace Ombi.Notifications.Tests
|
||||||
public void MusicNotificationTests()
|
public void MusicNotificationTests()
|
||||||
{
|
{
|
||||||
var notificationOptions = new NotificationOptions();
|
var notificationOptions = new NotificationOptions();
|
||||||
var req = F.Build<AlbumRequest>()
|
var req = F.Build<MusicRequests>()
|
||||||
.With(x => x.RequestType, RequestType.Album)
|
.With(x => x.RequestType, RequestType.Album)
|
||||||
.With(x => x.Available, true)
|
.With(x => x.Available, true)
|
||||||
.Create();
|
.Create();
|
||||||
|
@ -232,7 +232,7 @@ namespace Ombi.Notifications.Tests
|
||||||
public string MusicNotificationTests_RequestStatus(bool available, bool denied, bool approved)
|
public string MusicNotificationTests_RequestStatus(bool available, bool denied, bool approved)
|
||||||
{
|
{
|
||||||
var notificationOptions = new NotificationOptions();
|
var notificationOptions = new NotificationOptions();
|
||||||
var req = F.Build<AlbumRequest>()
|
var req = F.Build<MusicRequests>()
|
||||||
.With(x => x.RequestType, RequestType.Album)
|
.With(x => x.RequestType, RequestType.Album)
|
||||||
.With(x => x.Available, available)
|
.With(x => x.Available, available)
|
||||||
.With(x => x.Denied, denied)
|
.With(x => x.Denied, denied)
|
||||||
|
|
|
@ -46,7 +46,8 @@ namespace Ombi.Notifications
|
||||||
|
|
||||||
|
|
||||||
protected ChildRequests TvRequest { get; set; }
|
protected ChildRequests TvRequest { get; set; }
|
||||||
protected AlbumRequest AlbumRequest { get; set; }
|
protected MusicRequests AlbumRequest { get; set; }
|
||||||
|
protected MusicRequests ArtistRequest { get; set; }
|
||||||
protected MovieRequests MovieRequest { get; set; }
|
protected MovieRequests MovieRequest { get; set; }
|
||||||
protected IQueryable<OmbiUser> Subscribed { get; private set; }
|
protected IQueryable<OmbiUser> Subscribed { get; private set; }
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace Ombi.Notifications
|
||||||
CalculateRequestStatus(req);
|
CalculateRequestStatus(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Setup(NotificationOptions opts, AlbumRequest req, CustomizationSettings s,
|
public void Setup(NotificationOptions opts, MusicRequests req, CustomizationSettings s,
|
||||||
UserNotificationPreferences pref)
|
UserNotificationPreferences pref)
|
||||||
{
|
{
|
||||||
LoadIssues(opts);
|
LoadIssues(opts);
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace Ombi.Schedule.Jobs.Lidarr
|
||||||
await _notification.Clients.Clients(NotificationHub.AdminConnectionIds)
|
await _notification.Clients.Clients(NotificationHub.AdminConnectionIds)
|
||||||
.SendAsync(NotificationHub.NotificationEvent, "Lidarr Availability Check Started");
|
.SendAsync(NotificationHub.NotificationEvent, "Lidarr Availability Check Started");
|
||||||
var allAlbumRequests = _requestRepository.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available);
|
var allAlbumRequests = _requestRepository.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available);
|
||||||
var albumsToUpdate = new List<AlbumRequest>();
|
var albumsToUpdate = new List<MusicRequests>();
|
||||||
foreach (var request in allAlbumRequests)
|
foreach (var request in allAlbumRequests)
|
||||||
{
|
{
|
||||||
// Check if we have it cached
|
// Check if we have it cached
|
||||||
|
|
|
@ -81,7 +81,23 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
await _requestQueue.SaveChangesAsync();
|
await _requestQueue.SaveChangesAsync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var result = await _musicSender.Send(musicRequest);
|
var result = await _musicSender.SendAlbum(musicRequest);
|
||||||
|
if (result.Success)
|
||||||
|
{
|
||||||
|
request.Completed = DateTime.UtcNow;
|
||||||
|
await _requestQueue.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (request.Type == RequestType.Artist)
|
||||||
|
{
|
||||||
|
var musicRequest = await _musicRequestRepository.GetAll().FirstOrDefaultAsync(x => x.Id == request.RequestId);
|
||||||
|
if (musicRequest == null)
|
||||||
|
{
|
||||||
|
await _requestQueue.Delete(request);
|
||||||
|
await _requestQueue.SaveChangesAsync();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var result = await _musicSender.SendArtist(musicRequest);
|
||||||
if (result.Success)
|
if (result.Success)
|
||||||
{
|
{
|
||||||
request.Completed = DateTime.UtcNow;
|
request.Completed = DateTime.UtcNow;
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace Ombi.Store.Context
|
||||||
public DbSet<NotificationTemplates> NotificationTemplates { get; set; }
|
public DbSet<NotificationTemplates> NotificationTemplates { get; set; }
|
||||||
|
|
||||||
public DbSet<MovieRequests> MovieRequests { get; set; }
|
public DbSet<MovieRequests> MovieRequests { get; set; }
|
||||||
public DbSet<AlbumRequest> AlbumRequests { get; set; }
|
public DbSet<MusicRequests> MusicRequests { get; set; }
|
||||||
public DbSet<TvRequests> TvRequests { get; set; }
|
public DbSet<TvRequests> TvRequests { get; set; }
|
||||||
public DbSet<ChildRequests> ChildRequests { get; set; }
|
public DbSet<ChildRequests> ChildRequests { get; set; }
|
||||||
public DbSet<EpisodeRequests> EpisodeRequests { get; set; }
|
public DbSet<EpisodeRequests> EpisodeRequests { get; set; }
|
||||||
|
|
|
@ -5,5 +5,6 @@
|
||||||
TvShow = 0,
|
TvShow = 0,
|
||||||
Movie = 1,
|
Movie = 1,
|
||||||
Album = 2,
|
Album = 2,
|
||||||
|
Artist = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Ombi.Store.Entities.Requests
|
namespace Ombi.Store.Entities.Requests
|
||||||
{
|
{
|
||||||
[Table("AlbumRequests")]
|
[Table("MusicRequests")]
|
||||||
public class AlbumRequest : BaseRequest
|
public class MusicRequests : BaseRequest
|
||||||
{
|
{
|
||||||
public string ForeignAlbumId { get; set; }
|
public string ForeignAlbumId { get; set; }
|
||||||
public string ForeignArtistId { get; set; }
|
public string ForeignArtistId { get; set; }
|
||||||
|
@ -17,6 +17,9 @@ namespace Ombi.Store.Entities.Requests
|
||||||
public bool Subscribed { get; set; }
|
public bool Subscribed { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public bool ShowSubscribe { get; set; }
|
public bool ShowSubscribe { get; set; }
|
||||||
|
public bool Monitored { get; set; }
|
||||||
|
public string Monitor { get; set; }
|
||||||
|
public bool SearchForMissingAlbums { get; set; }
|
||||||
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
1243
src/Ombi.Store/Migrations/OmbiMySql/20210802192907_RenameAlbumRequests.Designer.cs
generated
Normal file
1243
src/Ombi.Store/Migrations/OmbiMySql/20210802192907_RenameAlbumRequests.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,17 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations.OmbiMySql
|
||||||
|
{
|
||||||
|
public partial class RenameAlbumRequests : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameTable("AlbumRequests", null, "MusicRequests");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1243
src/Ombi.Store/Migrations/OmbiMySql/20210802193833_MusicRequestsMonitor.Designer.cs
generated
Normal file
1243
src/Ombi.Store/Migrations/OmbiMySql/20210802193833_MusicRequestsMonitor.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,46 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations.OmbiMySql
|
||||||
|
{
|
||||||
|
public partial class MusicRequestsMonitor : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "Monitored",
|
||||||
|
table: "MusicRequests",
|
||||||
|
type: "BOOLEAN",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "Monitor",
|
||||||
|
table: "MusicRequests",
|
||||||
|
type: "longtext",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "SearchForMissingAlbums",
|
||||||
|
table: "MusicRequests",
|
||||||
|
type: "longtext",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Monitored",
|
||||||
|
table: "MusicRequests");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Monitor",
|
||||||
|
table: "MusicRequests");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "SearchForMissingAlbums",
|
||||||
|
table: "MusicRequests");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1243
src/Ombi.Store/Migrations/OmbiSqlite/20210802192907_RenameAlbumRequests.Designer.cs
generated
Normal file
1243
src/Ombi.Store/Migrations/OmbiSqlite/20210802192907_RenameAlbumRequests.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,17 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations.OmbiSqlite
|
||||||
|
{
|
||||||
|
public partial class RenameAlbumRequests : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameTable("AlbumRequests", null, "MusicRequests");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1243
src/Ombi.Store/Migrations/OmbiSqlite/20210802193833_MusicRequestsMonitor.Designer.cs
generated
Normal file
1243
src/Ombi.Store/Migrations/OmbiSqlite/20210802193833_MusicRequestsMonitor.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,46 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations.OmbiSqlite
|
||||||
|
{
|
||||||
|
public partial class MusicRequestsMonitor : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "Monitored",
|
||||||
|
table: "MusicRequests",
|
||||||
|
type: "BOOLEAN",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "Monitor",
|
||||||
|
table: "MusicRequests",
|
||||||
|
type: "longtext",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "SearchForMissingAlbums",
|
||||||
|
table: "MusicRequests",
|
||||||
|
type: "longtext",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Monitored",
|
||||||
|
table: "MusicRequests");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Monitor",
|
||||||
|
table: "MusicRequests");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "SearchForMissingAlbums",
|
||||||
|
table: "MusicRequests");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -427,76 +427,6 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
||||||
b.ToTable("RequestSubscription");
|
b.ToTable("RequestSubscription");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<bool>("Approved")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<string>("ArtistName")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<bool>("Available")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<string>("Cover")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<bool?>("Denied")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<string>("DeniedReason")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("Disk")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("ForeignAlbumId")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("ForeignArtistId")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<DateTime>("MarkedAsApproved")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("MarkedAsAvailable")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<DateTime>("MarkedAsDenied")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<decimal>("Rating")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<DateTime>("ReleaseDate")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<int>("RequestType")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<string>("RequestedByAlias")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<DateTime>("RequestedDate")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("RequestedUserId")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RequestedUserId");
|
|
||||||
|
|
||||||
b.ToTable("AlbumRequests");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
@ -736,6 +666,85 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
||||||
b.ToTable("MovieRequests");
|
b.ToTable("MovieRequests");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.MusicRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Approved")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ArtistName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Available")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Cover")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool?>("Denied")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("DeniedReason")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Disk")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ForeignAlbumId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ForeignArtistId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsApproved")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("MarkedAsAvailable")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsDenied")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Monitor")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Monitored")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<decimal>("Rating")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ReleaseDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("RequestedByAlias")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("RequestedDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RequestedUserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("SearchForMissingAlbums")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RequestedUserId");
|
||||||
|
|
||||||
|
b.ToTable("MusicRequests");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
@ -1060,15 +1069,6 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
||||||
b.Navigation("User");
|
b.Navigation("User");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RequestedUserId");
|
|
||||||
|
|
||||||
b.Navigation("RequestedUser");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest")
|
b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest")
|
||||||
|
@ -1135,6 +1135,15 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
||||||
b.Navigation("RequestedUser");
|
b.Navigation("RequestedUser");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.MusicRequests", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RequestedUserId");
|
||||||
|
|
||||||
|
b.Navigation("RequestedUser");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
|
|
@ -4,14 +4,14 @@ using Ombi.Store.Entities.Requests;
|
||||||
|
|
||||||
namespace Ombi.Store.Repository.Requests
|
namespace Ombi.Store.Repository.Requests
|
||||||
{
|
{
|
||||||
public interface IMusicRequestRepository : IRepository<AlbumRequest>
|
public interface IMusicRequestRepository : IRepository<MusicRequests>
|
||||||
{
|
{
|
||||||
IQueryable<AlbumRequest> GetAll(string userId);
|
IQueryable<MusicRequests> GetAll(string userId);
|
||||||
AlbumRequest GetRequest(string foreignAlbumId);
|
MusicRequests GetRequest(string foreignAlbumId);
|
||||||
Task<AlbumRequest> GetRequestAsync(string foreignAlbumId);
|
Task<MusicRequests> GetRequestAsync(string foreignAlbumId);
|
||||||
IQueryable<AlbumRequest> GetWithUser();
|
IQueryable<MusicRequests> GetWithUser();
|
||||||
IQueryable<AlbumRequest> GetWithUser(string userId);
|
IQueryable<MusicRequests> GetWithUser(string userId);
|
||||||
Task Save();
|
Task Save();
|
||||||
Task Update(AlbumRequest request);
|
Task Update(MusicRequests request);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,7 +9,7 @@ using Ombi.Store.Entities.Requests;
|
||||||
|
|
||||||
namespace Ombi.Store.Repository.Requests
|
namespace Ombi.Store.Repository.Requests
|
||||||
{
|
{
|
||||||
public class MusicRequestRepository : Repository<AlbumRequest>, IMusicRequestRepository
|
public class MusicRequestRepository : Repository<MusicRequests>, IMusicRequestRepository
|
||||||
{
|
{
|
||||||
public MusicRequestRepository(OmbiContext ctx) : base(ctx)
|
public MusicRequestRepository(OmbiContext ctx) : base(ctx)
|
||||||
{
|
{
|
||||||
|
@ -18,48 +18,58 @@ namespace Ombi.Store.Repository.Requests
|
||||||
|
|
||||||
private OmbiContext Db { get; }
|
private OmbiContext Db { get; }
|
||||||
|
|
||||||
public Task<AlbumRequest> GetRequestAsync(string foreignAlbumId)
|
public Task<MusicRequests> GetRequestAsync(string foreignAlbumId)
|
||||||
{
|
{
|
||||||
return Db.AlbumRequests.Where(x => x.ForeignAlbumId == foreignAlbumId)
|
return Db.MusicRequests.Where(x => x.ForeignAlbumId == foreignAlbumId)
|
||||||
.Include(x => x.RequestedUser)
|
.Include(x => x.RequestedUser)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueryable<AlbumRequest> GetAll(string userId)
|
public IQueryable<MusicRequests> GetAll(string userId)
|
||||||
{
|
{
|
||||||
return GetWithUser().Where(x => x.RequestedUserId == userId);
|
return GetWithUser().Where(x => x.RequestedUserId == userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlbumRequest GetRequest(string foreignAlbumId)
|
public MusicRequests GetRequest(string foreignAlbumId)
|
||||||
{
|
{
|
||||||
return Db.AlbumRequests.Where(x => x.ForeignAlbumId == foreignAlbumId)
|
return Db.MusicRequests.Where(x => x.ForeignAlbumId == foreignAlbumId)
|
||||||
.Include(x => x.RequestedUser)
|
.Include(x => x.RequestedUser)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueryable<AlbumRequest> GetWithUser()
|
public IQueryable<MusicRequests> GetWithUser()
|
||||||
{
|
{
|
||||||
return Db.AlbumRequests
|
return Db.MusicRequests
|
||||||
.Include(x => x.RequestedUser)
|
.Include(x => x.RequestedUser)
|
||||||
.ThenInclude(x => x.NotificationUserIds)
|
.ThenInclude(x => x.NotificationUserIds)
|
||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IQueryable<AlbumRequest> GetWithUser(string userId)
|
public IQueryable<MusicRequests> GetWithUser(string userId)
|
||||||
{
|
{
|
||||||
return Db.AlbumRequests
|
return Db.MusicRequests
|
||||||
.Where(x => x.RequestedUserId == userId)
|
.Where(x => x.RequestedUserId == userId)
|
||||||
.Include(x => x.RequestedUser)
|
.Include(x => x.RequestedUser)
|
||||||
.ThenInclude(x => x.NotificationUserIds)
|
.ThenInclude(x => x.NotificationUserIds)
|
||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Update(AlbumRequest request)
|
public async Task Update(MusicRequests request)
|
||||||
{
|
{
|
||||||
if (Db.Entry(request).State == EntityState.Detached)
|
if (Db.Entry(request).State == EntityState.Detached)
|
||||||
{
|
{
|
||||||
Db.AlbumRequests.Attach(request);
|
Db.MusicRequests.Attach(request);
|
||||||
|
Db.Update(request);
|
||||||
|
}
|
||||||
|
await InternalSaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateArtist(MusicRequests request)
|
||||||
|
{
|
||||||
|
if (Db.Entry(request).State == EntityState.Detached)
|
||||||
|
{
|
||||||
|
Db.MusicRequests.Attach(request);
|
||||||
Db.Update(request);
|
Db.Update(request);
|
||||||
}
|
}
|
||||||
await InternalSaveChanges();
|
await InternalSaveChanges();
|
||||||
|
|
|
@ -112,8 +112,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Hubs", "Ombi.Hubs\Ombi
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.GroupMe", "Ombi.Api.GroupMe\Ombi.Api.GroupMe.csproj", "{9266403C-B04D-4C0F-AC39-82F12C781949}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.GroupMe", "Ombi.Api.GroupMe\Ombi.Api.GroupMe.csproj", "{9266403C-B04D-4C0F-AC39-82F12C781949}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.MusicBrainz", "Ombi.Api.MusicBrainz\Ombi.Api.MusicBrainz.csproj", "{C5C1769B-4197-4410-A160-0EEF39EDDC98}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Twilio", "Ombi.Api.Twilio\Ombi.Api.Twilio.csproj", "{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Twilio", "Ombi.Api.Twilio\Ombi.Api.Twilio.csproj", "{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.HealthChecks", "Ombi.HealthChecks\Ombi.HealthChecks.csproj", "{59D19538-0496-44EE-936E-EBBC22CF7B27}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.HealthChecks", "Ombi.HealthChecks\Ombi.HealthChecks.csproj", "{59D19538-0496-44EE-936E-EBBC22CF7B27}"
|
||||||
|
@ -431,6 +429,10 @@ Global
|
||||||
{8F19C701-7881-4BC7-8BBA-B068A6B954AD}.NonUiBuild|Any CPU.Build.0 = NonUiBuild|Any CPU
|
{8F19C701-7881-4BC7-8BBA-B068A6B954AD}.NonUiBuild|Any CPU.Build.0 = NonUiBuild|Any CPU
|
||||||
{8F19C701-7881-4BC7-8BBA-B068A6B954AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{8F19C701-7881-4BC7-8BBA-B068A6B954AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{8F19C701-7881-4BC7-8BBA-B068A6B954AD}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8F19C701-7881-4BC7-8BBA-B068A6B954AD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{0C81C423-25CC-4A91-ABE7-9C3F97770F69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{0C81C423-25CC-4A91-ABE7-9C3F97770F69}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0C81C423-25CC-4A91-ABE7-9C3F97770F69}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{0C81C423-25CC-4A91-ABE7-9C3F97770F69}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
<i *ngIf="loading" class="fas fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
|
<i *ngIf="loading" class="fas fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
|
||||||
{{'Common.Request' | translate }}
|
{{'Common.Request' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
<button id="requestButton{{result.id}}{{result.type}}{{discoverType}}" *ngIf="monitored" mat-raised-button
|
||||||
|
class="btn-spacing full-width poster-request-btn" color="accent" [disabled]>
|
||||||
|
<i class="fa-lg fas fa-check"></i> {{'Common.Monitored' | translate }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -27,6 +27,7 @@ export class DiscoverCardComponent implements OnInit {
|
||||||
public loading: boolean;
|
public loading: boolean;
|
||||||
|
|
||||||
public requestable: boolean;
|
public requestable: boolean;
|
||||||
|
public monitored: boolean;
|
||||||
|
|
||||||
// This data is needed to open the dialog
|
// This data is needed to open the dialog
|
||||||
private tvSearchResult: ISearchTvResultV2;
|
private tvSearchResult: ISearchTvResultV2;
|
||||||
|
@ -42,6 +43,9 @@ export class DiscoverCardComponent implements OnInit {
|
||||||
if (this.result.type == RequestType.movie) {
|
if (this.result.type == RequestType.movie) {
|
||||||
this.getExtraMovieInfo();
|
this.getExtraMovieInfo();
|
||||||
}
|
}
|
||||||
|
if (this.result.type == RequestType.artist) {
|
||||||
|
this.getArtistInformation();
|
||||||
|
}
|
||||||
if (this.result.type == RequestType.album) {
|
if (this.result.type == RequestType.album) {
|
||||||
this.getAlbumInformation();
|
this.getAlbumInformation();
|
||||||
}
|
}
|
||||||
|
@ -54,7 +58,7 @@ export class DiscoverCardComponent implements OnInit {
|
||||||
this.updateTvItem(this.tvSearchResult);
|
this.updateTvItem(this.tvSearchResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAlbumInformation() {
|
public async getArtistInformation() {
|
||||||
this.searchService.getArtistInformation(this.result.id.toString()).subscribe(x => {
|
this.searchService.getArtistInformation(this.result.id.toString()).subscribe(x => {
|
||||||
if (x.poster) {
|
if (x.poster) {
|
||||||
this.result.posterPath = x.poster;
|
this.result.posterPath = x.poster;
|
||||||
|
@ -63,14 +67,38 @@ export class DiscoverCardComponent implements OnInit {
|
||||||
this.searchService.getReleaseGroupArt(this.result.id.toString()).subscribe(art => {
|
this.searchService.getReleaseGroupArt(this.result.id.toString()).subscribe(art => {
|
||||||
if (art.image) {
|
if (art.image) {
|
||||||
this.result.posterPath = art.image;
|
this.result.posterPath = art.image;
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.result.title = x.startYear ? `${x.name} (${x.startYear})` : x.name;
|
this.result.title = x.name;
|
||||||
this.result.overview = x.overview;
|
this.result.overview = x.overview;
|
||||||
this.fullyLoaded = true;
|
this.fullyLoaded = true;
|
||||||
|
if (x.monitored) {
|
||||||
|
this.requestable = false;
|
||||||
|
this.monitored = true;
|
||||||
|
} else {
|
||||||
this.requestable = true;
|
this.requestable = true;
|
||||||
|
this.monitored = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getAlbumInformation() {
|
||||||
|
this.searchService.getAlbumInformation(this.result.id.toString()).subscribe(x => {
|
||||||
|
if (x.cover) {
|
||||||
|
this.result.posterPath = x.cover;
|
||||||
|
this.fullyLoaded = true;
|
||||||
|
}
|
||||||
|
this.result.title = x.title;
|
||||||
|
this.result.overview = x.overview;
|
||||||
|
this.fullyLoaded = true;
|
||||||
|
if (x.monitored) {
|
||||||
|
this.requestable = false;
|
||||||
|
this.monitored = true;
|
||||||
|
} else {
|
||||||
|
this.requestable = true;
|
||||||
|
this.monitored = false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,8 +108,10 @@ export class DiscoverCardComponent implements OnInit {
|
||||||
return `/details/movie/${this.result.id}`;
|
return `/details/movie/${this.result.id}`;
|
||||||
case RequestType.tvShow:
|
case RequestType.tvShow:
|
||||||
return `/details/tv/${this.result.id}`;
|
return `/details/tv/${this.result.id}`;
|
||||||
case RequestType.album: //Actually artist
|
case RequestType.artist: //Actually artist
|
||||||
return `/details/artist/${this.result.id}`;
|
return `/details/artist/${this.result.id}`;
|
||||||
|
case RequestType.album:
|
||||||
|
return `/details/album/${this.result.id}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +145,27 @@ export class DiscoverCardComponent implements OnInit {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
switch (this.result.type) {
|
switch (this.result.type) {
|
||||||
|
case RequestType.artist:
|
||||||
|
this.requestService.requestArtist({ foreignArtistId: this.result.id.toString(), monitored: true, monitor: "all", searchForMissingAlbums: true }).subscribe(x => {
|
||||||
|
if (x.result) {
|
||||||
|
this.result.requested = true;
|
||||||
|
this.messageService.send(x.message, "Ok");
|
||||||
|
} else {
|
||||||
|
this.messageService.send(x.errorMessage, "Ok");
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
case RequestType.album:
|
||||||
|
this.requestService.requestAlbum({foreignAlbumId: this.result.id.toString(), monitor: 'all', monitored: true, searchForMissingAlbums: false}).subscribe(x => {
|
||||||
|
if (x.result) {
|
||||||
|
this.result.requested = true;
|
||||||
|
this.messageService.send(x.message, "Ok");
|
||||||
|
} else {
|
||||||
|
this.messageService.send(x.errorMessage, "Ok");
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
case RequestType.tvShow:
|
case RequestType.tvShow:
|
||||||
const dia = this.dialog.open(EpisodeRequestComponent, { width: "700px", data: { series: this.tvSearchResult, isAdmin: this.isAdmin }, panelClass: 'modal-panel' });
|
const dia = this.dialog.open(EpisodeRequestComponent, { width: "700px", data: { series: this.tvSearchResult, isAdmin: this.isAdmin }, panelClass: 'modal-panel' });
|
||||||
dia.afterClosed().subscribe(x => this.loading = false);
|
dia.afterClosed().subscribe(x => this.loading = false);
|
||||||
|
|
|
@ -87,6 +87,8 @@ export class DiscoverSearchResultsComponent implements OnInit {
|
||||||
} else if (m.mediaType == "tv") {
|
} else if (m.mediaType == "tv") {
|
||||||
mediaType = RequestType.tvShow;
|
mediaType = RequestType.tvShow;
|
||||||
} else if (m.mediaType == "Artist") {
|
} else if (m.mediaType == "Artist") {
|
||||||
|
mediaType = RequestType.artist;
|
||||||
|
} else if (m.mediaType == "Album") {
|
||||||
mediaType = RequestType.album;
|
mediaType = RequestType.album;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,10 +100,13 @@ export class DiscoverSearchResultsComponent implements OnInit {
|
||||||
if (mediaType === RequestType.tvShow) {
|
if (mediaType === RequestType.tvShow) {
|
||||||
poster = "images/default_tv_poster.png"
|
poster = "images/default_tv_poster.png"
|
||||||
}
|
}
|
||||||
|
if (mediaType === RequestType.album || mediaType === RequestType.artist) {
|
||||||
|
poster = "images/default-music-placeholder.png";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.discoverResults.push({
|
this.discoverResults.push({
|
||||||
posterPath: mediaType !== RequestType.album ? poster : "images/default-music-placeholder.png",
|
posterPath: poster,
|
||||||
requested: false,
|
requested: false,
|
||||||
title: m.title,
|
title: m.title,
|
||||||
type: mediaType,
|
type: mediaType,
|
||||||
|
@ -154,6 +159,9 @@ export class DiscoverSearchResultsComponent implements OnInit {
|
||||||
if (mediaType === RequestType.tvShow) {
|
if (mediaType === RequestType.tvShow) {
|
||||||
poster = "images/default_tv_poster.png"
|
poster = "images/default_tv_poster.png"
|
||||||
}
|
}
|
||||||
|
if (mediaType === RequestType.album || mediaType === RequestType.artist) {
|
||||||
|
poster = "images/default-music-placeholder.png";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.discoverResults.push({
|
this.discoverResults.push({
|
||||||
|
|
|
@ -15,6 +15,29 @@ export interface IArtistSearchResult {
|
||||||
links: IArtistLinks;
|
links: IArtistLinks;
|
||||||
members: IBandMembers[];
|
members: IBandMembers[];
|
||||||
overview: string;
|
overview: string;
|
||||||
|
monitored: boolean;
|
||||||
|
|
||||||
|
background: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IAlbumSearchResult {
|
||||||
|
title: string;
|
||||||
|
id: string;
|
||||||
|
startYear: string;
|
||||||
|
endYear: string;
|
||||||
|
type: string;
|
||||||
|
country: string;
|
||||||
|
region: string;
|
||||||
|
disambiguation: string;
|
||||||
|
banner: string;
|
||||||
|
logo: string;
|
||||||
|
cover: string;
|
||||||
|
fanArt: string;
|
||||||
|
releaseGroups: IReleaseGroups[];
|
||||||
|
links: IArtistLinks;
|
||||||
|
members: IBandMembers[];
|
||||||
|
overview: string;
|
||||||
|
monitored: boolean;
|
||||||
|
|
||||||
background: any;
|
background: any;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
export enum RequestType {
|
export enum RequestType {
|
||||||
tvShow = 0,
|
tvShow = 0,
|
||||||
movie = 1,
|
movie = 1,
|
||||||
album = 2,
|
artist = 2,
|
||||||
|
album = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
// NEW WORLD
|
// NEW WORLD
|
||||||
|
@ -44,6 +45,16 @@ export interface IAlbumRequest extends IBaseRequest {
|
||||||
|
|
||||||
export interface IAlbumRequestModel {
|
export interface IAlbumRequestModel {
|
||||||
foreignAlbumId: string;
|
foreignAlbumId: string;
|
||||||
|
monitored: boolean;
|
||||||
|
monitor: string;
|
||||||
|
searchForMissingAlbums: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IArtistRequestModel {
|
||||||
|
foreignArtistId: string;
|
||||||
|
monitored: boolean;
|
||||||
|
monitor: string;
|
||||||
|
searchForMissingAlbums: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRequestsViewModel<T> {
|
export interface IRequestsViewModel<T> {
|
||||||
|
|
|
@ -80,8 +80,9 @@ export class IssuesDetailsComponent implements OnInit {
|
||||||
this.router.navigate(['/details/movie/', this.providerId]);
|
this.router.navigate(['/details/movie/', this.providerId]);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RequestType.album:
|
|
||||||
this.router.navigate(['/details/artist/', this.providerId]);
|
case RequestType.artist:
|
||||||
|
this.router.navigate(['/details/artist/', firstIssue.providerId]);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RequestType.tvShow:
|
case RequestType.tvShow:
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
<div *ngIf="!album" class="justify-content-md-center top-spacing loading-spinner">
|
||||||
|
<mat-spinner [color]="'accent'"></mat-spinner>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="album" class="dark-theme">
|
||||||
|
|
||||||
|
<top-banner [title]="album.title" [background]="getBackground()" [tagline]="album.disambiguation"></top-banner>
|
||||||
|
|
||||||
|
<section id="info-wrapper">
|
||||||
|
<div class="small-middle-container">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<media-poster [posterPath]="album.cover"></media-poster>
|
||||||
|
|
||||||
|
<!--Next to poster-->
|
||||||
|
<!-- <div class="col-12 col-lg-3 col-xl-3 media-row">
|
||||||
|
|
||||||
|
<social-icons [homepage]="artist.links?.homePage" [doNotAppend]="true" [imdbId]="artist.links?.imdb" [twitter]="artist.links?.twitter" [facebook]="artist.links?.facebook" [instagram]="artist.links?.instagram"></social-icons>
|
||||||
|
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<div class="col-12 col-lg-6 col-xl-6 media-row">
|
||||||
|
|
||||||
|
<button *ngIf="!album.monitored" mat-raised-button class="btn-spacing" color="primary" (click)="requestAlbum()">
|
||||||
|
<i class="fas fa-plus"></i> {{ 'MediaDetails.RequestAlbum' | translate }}</button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<button mat-raised-button class="btn-green btn-spacing" *ngIf="album.monitored"> {{
|
||||||
|
'Common.Requested' | translate }}</button>
|
||||||
|
<span *ngIf="!album.monitored">
|
||||||
|
<span *ngIf="album.monitored; then requestedBtn else notRequestedBtn"></span>
|
||||||
|
|
||||||
|
<!-- <ng-template #requestedBtn>
|
||||||
|
<button mat-raised-button *ngIf="!hasRequest || hasRequest && movieRequest && !movieRequest.denied"
|
||||||
|
class="btn-spacing" color="warn" [disabled]><i class="fas fa-check"></i>
|
||||||
|
{{ 'Common.Requested' | translate }}</button>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #notRequestedBtn>
|
||||||
|
<button mat-raised-button class="btn-spacing" color="primary" (click)="request()">
|
||||||
|
<i *ngIf="movie.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i> <i
|
||||||
|
*ngIf="!movie.requestProcessing && !movie.processed" class="fas fa-plus"></i>
|
||||||
|
<i *ngIf="movie.processed && !movie.requestProcessing" class="fas fa-check"></i> {{
|
||||||
|
'Common.Request' | translate }}</button>
|
||||||
|
<!-- </ng-template> -->
|
||||||
|
</span>
|
||||||
|
<!-- <span *ngIf="isAdmin && hasRequest">
|
||||||
|
<button (click)="approve()" mat-raised-button class="btn-spacing" color="accent">
|
||||||
|
<i class="fas fa-plus"></i> {{ 'Common.Approve' | translate }}
|
||||||
|
</button>
|
||||||
|
<button *ngIf="!movie.available" (click)="markAvailable()" mat-raised-button class="btn-spacing"
|
||||||
|
color="accent">
|
||||||
|
<i class="fas fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button *ngIf="movieRequest && !movieRequest.denied" mat-raised-button class="btn-spacing" color="warn"
|
||||||
|
(click)="deny()">
|
||||||
|
<i class="fas fa-times"></i> {{
|
||||||
|
'Requests.Deny' | translate }}</button>
|
||||||
|
<button *ngIf="movieRequest && movieRequest.denied" [matTooltip]="movieRequest.deniedReason"
|
||||||
|
mat-raised-button class="btn-spacing" color="warn">
|
||||||
|
<i class="fas fa-times"></i> {{
|
||||||
|
'MediaDetails.Denied' | translate }}</button>
|
||||||
|
</span> -->
|
||||||
|
|
||||||
|
<!-- <button *ngIf="(hasRequest && movieRequest) || movie.available" mat-raised-button class="btn-spacing"
|
||||||
|
color="danger" (click)="issue()">
|
||||||
|
<i class="fas fa-exclamation"></i> {{
|
||||||
|
'Requests.ReportIssue' | translate }}</button> -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<!-- <div class="col-12 col-md-2">
|
||||||
|
|
||||||
|
<mat-card class="mat-elevation-z8">
|
||||||
|
<mat-card-content class="medium-font">
|
||||||
|
<album-information-panel [album]="album"></album-information-panel>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
|
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<div class="col-12 col-md-10">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<mat-card class=" mat-elevation-z8 spacing-below">
|
||||||
|
<mat-card-content>
|
||||||
|
<h1>{{album.title}} - {{album.disambiguation}}</h1>
|
||||||
|
<br />
|
||||||
|
{{album.overview}}
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="issuesPanel" *ngIf="album.requestId">
|
||||||
|
<issues-panel [requestId]="album.requestId" [isAdmin]="isAdmin"></issues-panel>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!-- <div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<mat-accordion class="mat-elevation-z8 spacing-below">
|
||||||
|
<mat-expansion-panel>
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
<mat-panel-title>
|
||||||
|
{{'MediaDetails.RecommendationsTitle' | translate}}
|
||||||
|
</mat-panel-title>
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<div class="row card-spacer" *ngIf="movie.recommendations.results.length > 0">
|
||||||
|
|
||||||
|
<div class="col-md-2" *ngFor="let r of movie.recommendations.results">
|
||||||
|
<div class="sidebar affixable affix-top preview-poster">
|
||||||
|
<div class="poster">
|
||||||
|
<a [routerLink]="'/details/movie/'+r.id">
|
||||||
|
<img class="real grow" matTooltip="{{r.title}}"
|
||||||
|
src="https://image.tmdb.org/t/p/w300/{{r.poster_path}}" alt="Poster"
|
||||||
|
style="display: block;">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mat-expansion-panel>
|
||||||
|
<mat-expansion-panel>
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
<mat-panel-title>
|
||||||
|
{{'MediaDetails.SimilarTitle' | translate}}
|
||||||
|
</mat-panel-title>
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<div class="row card-spacer" *ngIf="movie.similar.results.length > 0">
|
||||||
|
|
||||||
|
<div class="col-md-2" *ngFor="let r of movie.similar.results">
|
||||||
|
<div class="sidebar affixable affix-top preview-poster">
|
||||||
|
<div class="poster ">
|
||||||
|
<a [routerLink]="'/details/movie/'+r.id">
|
||||||
|
<img class="real grow" matTooltip="{{r.title}}"
|
||||||
|
src="https://image.tmdb.org/t/p/w300/{{r.poster_path}}" alt="Poster"
|
||||||
|
style="display: block;">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mat-expansion-panel>
|
||||||
|
<mat-expansion-panel>
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
<mat-panel-title>
|
||||||
|
{{'MediaDetails.VideosTitle' | translate}}
|
||||||
|
</mat-panel-title>
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<div class="row card-spacer" *ngIf="movie.videos.results.length > 0">
|
||||||
|
|
||||||
|
<div class="col-md-6" *ngFor="let video of movie.videos.results">
|
||||||
|
<iframe width="100%" height="315px" [src]="'https://www.youtube.com/embed/' + video.key | safe"
|
||||||
|
frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
|
||||||
|
allowfullscreen></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mat-expansion-panel>
|
||||||
|
</mat-accordion>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="bottom-page-gap">
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
|
@ -0,0 +1,126 @@
|
||||||
|
import { Component, ViewEncapsulation } from "@angular/core";
|
||||||
|
import { ImageService, SearchV2Service, RequestService, MessageService } from "../../../services";
|
||||||
|
import { ActivatedRoute } from "@angular/router";
|
||||||
|
import { DomSanitizer } from "@angular/platform-browser";
|
||||||
|
import { MatDialog } from "@angular/material/dialog";
|
||||||
|
import { YoutubeTrailerComponent } from "../shared/youtube-trailer.component";
|
||||||
|
import { AuthService } from "../../../auth/auth.service";
|
||||||
|
import { DenyDialogComponent } from "../shared/deny-dialog/deny-dialog.component";
|
||||||
|
import { NewIssueComponent } from "../shared/new-issue/new-issue.component";
|
||||||
|
import { IAlbumSearchResult, IReleaseGroups } from "../../../interfaces/IMusicSearchResultV2";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: "./album-details.component.html",
|
||||||
|
styleUrls: ["../../media-details.component.scss"],
|
||||||
|
encapsulation: ViewEncapsulation.None
|
||||||
|
})
|
||||||
|
export class AlbumDetailsComponent {
|
||||||
|
private albumId: string;
|
||||||
|
|
||||||
|
public album: IAlbumSearchResult = null;
|
||||||
|
private selectedAlbums: IReleaseGroups[] = [];
|
||||||
|
|
||||||
|
public isAdmin: boolean;
|
||||||
|
|
||||||
|
constructor(private searchService: SearchV2Service, private route: ActivatedRoute,
|
||||||
|
private sanitizer: DomSanitizer, private imageService: ImageService,
|
||||||
|
public dialog: MatDialog, private requestService: RequestService,
|
||||||
|
public messageService: MessageService, private auth: AuthService) {
|
||||||
|
this.route.params.subscribe((params: any) => {
|
||||||
|
this.albumId = params.albumId;
|
||||||
|
this.load();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public load() {
|
||||||
|
this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser");
|
||||||
|
this.searchService.getAlbumInformation(this.albumId).subscribe(x => this.album = x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getBackground(): string {
|
||||||
|
if (this.album.cover) {
|
||||||
|
this.album.background = this.sanitizer.bypassSecurityTrustStyle
|
||||||
|
("url(" + this.album.cover + ")");
|
||||||
|
return this.album.background
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.album.background
|
||||||
|
}
|
||||||
|
|
||||||
|
public async requestAlbum() {
|
||||||
|
if (this.album.monitored) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.requestService.requestAlbum({
|
||||||
|
foreignAlbumId: this.album.id,
|
||||||
|
monitored: true,
|
||||||
|
monitor: "existing",
|
||||||
|
searchForMissingAlbums: true
|
||||||
|
}).toPromise()
|
||||||
|
.then(r => {
|
||||||
|
if (r.result) {
|
||||||
|
this.album.monitored = true;
|
||||||
|
this.messageService.send(r.message);
|
||||||
|
} else {
|
||||||
|
this.messageService.send(r.errorMessage);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(r => {
|
||||||
|
console.log(r);
|
||||||
|
this.messageService.send("Error when requesting album");
|
||||||
|
});
|
||||||
|
// const
|
||||||
|
}
|
||||||
|
|
||||||
|
public openDialog() {
|
||||||
|
this.dialog.open(YoutubeTrailerComponent, {
|
||||||
|
width: '560px',
|
||||||
|
// data: this.movie.videos.results[0].key
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async deny() {
|
||||||
|
const dialogRef = this.dialog.open(DenyDialogComponent, {
|
||||||
|
width: '250px',
|
||||||
|
// data: {requestId: this.movieRequest.id, requestType: RequestType.movie}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
|
// this.movieRequest.denied = result;
|
||||||
|
// if(this.movieRequest.denied) {
|
||||||
|
// this.movie.approved = false;
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async issue() {
|
||||||
|
const dialogRef = this.dialog.open(NewIssueComponent, {
|
||||||
|
width: '500px',
|
||||||
|
// data: {requestId: this.movieRequest ? this.movieRequest.id : null, requestType: RequestType.movie, imdbid: this.movie.imdbId}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async approve() {
|
||||||
|
// const result = await this.requestService.approveMovie({ id: this.movieRequest.id }).toPromise();
|
||||||
|
// if (result.result) {
|
||||||
|
// this.movie.approved = false;
|
||||||
|
// this.messageService.send("Successfully Approved", "Ok");
|
||||||
|
// } else {
|
||||||
|
// this.messageService.send(result.errorMessage, "Ok");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public async markAvailable() {
|
||||||
|
// const result = await this.requestService.markMovieAvailable({id: this.movieRequest.id}).toPromise();
|
||||||
|
// if (result.result) {
|
||||||
|
// // this.movie.available = true;
|
||||||
|
// this.messageService.send(result.message, "Ok");
|
||||||
|
// } else {
|
||||||
|
// this.messageService.send(result.errorMessage, "Ok");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public setAdvancedOptions(data: any) {
|
||||||
|
// this.advancedOptions = data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<div *ngIf="album">
|
||||||
|
<div>
|
||||||
|
<strong>Type:</strong>
|
||||||
|
<div>{{album.type}}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Country</strong>
|
||||||
|
<div>{{album.country}}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Release Date</strong>
|
||||||
|
<div>{{album.startYear}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { Component, Input, ViewEncapsulation } from "@angular/core";
|
||||||
|
import { ISearchArtistResult } from "../../../../../interfaces";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: "./album-information-panel.component.html",
|
||||||
|
styleUrls: ["../../../../media-details.component.scss"],
|
||||||
|
selector: "album-information-panel",
|
||||||
|
encapsulation: ViewEncapsulation.None
|
||||||
|
})
|
||||||
|
export class AlbumInformationPanel {
|
||||||
|
@Input() public album: ISearchAlbumResult;
|
||||||
|
}
|
|
@ -16,73 +16,22 @@
|
||||||
<!--Next to poster-->
|
<!--Next to poster-->
|
||||||
<div class="col-12 col-lg-3 col-xl-3 media-row">
|
<div class="col-12 col-lg-3 col-xl-3 media-row">
|
||||||
|
|
||||||
<social-icons [homepage]="artist.links.homePage" [doNotAppend]="true" [imdbId]="artist.links.imdb" [twitter]="artist.links.twitter" [facebook]="artist.links.facebook" [instagram]="artist.links.instagram"></social-icons>
|
<!-- <social-icons [homepage]="artist.links.homePage" [doNotAppend]="true" [imdbId]="artist.links.imdb" [twitter]="artist.links.twitter" [facebook]="artist.links.facebook" [instagram]="artist.links.instagram"></social-icons> -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-lg-6 col-xl-6 media-row">
|
<div class="col-12 col-lg-6 col-xl-6 media-row">
|
||||||
|
<button mat-raised-button *ngIf="artist.monitored" class="btn-spacing" color="primary"
|
||||||
<button mat-raised-button *ngIf="selectedAlbums.length === 0" class="btn-spacing" color="primary" (click)="requestAllAlbums()">
|
color="accent" [disabled]>
|
||||||
<i class="fas fa-plus"></i> {{ 'MediaDetails.RequestAllAlbums' | translate }}</button>
|
<i class="fa-lg fas fa-check"></i> {{'Common.Monitored' | translate }}</button>
|
||||||
<button mat-raised-button *ngIf="selectedAlbums.length > 0" class="btn-spacing" color="primary" (click)="requestAllAlbums()">
|
<button mat-raised-button *ngIf="!artist.monitored && selectedAlbums.length === 0" class="btn-spacing" color="primary" (click)="requestAllAlbums()">
|
||||||
<i class="fas fa-plus"></i> {{ 'MediaDetails.RequestSelectedAlbums' | translate }}</button>
|
<i class="fas fa-plus"></i> {{ 'Common.Request' | translate }}</button>
|
||||||
|
|
||||||
<button mat-raised-button *ngIf="selectedAlbums.length > 0" class="btn-spacing" color="accent" (click)="clearSelection()">
|
|
||||||
<i class="fas fa-minus"></i> {{ 'MediaDetails.ClearSelection' | translate }}</button>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <button mat-raised-button class="btn-green btn-spacing" *ngIf="movie.available"> {{
|
|
||||||
'Common.Available' | translate }}</button> -->
|
|
||||||
<!-- <span *ngIf="!movie.available">
|
|
||||||
<span *ngIf="movie.requested || movie.approved; then requestedBtn else notRequestedBtn"></span>
|
|
||||||
|
|
||||||
<ng-template #requestedBtn>
|
|
||||||
<button mat-raised-button *ngIf="!hasRequest || hasRequest && movieRequest && !movieRequest.denied"
|
|
||||||
class="btn-spacing" color="warn" [disabled]><i class="fas fa-check"></i>
|
|
||||||
{{ 'Common.Requested' | translate }}</button>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template #notRequestedBtn>
|
|
||||||
<button mat-raised-button class="btn-spacing" color="primary" (click)="request()">
|
|
||||||
<i *ngIf="movie.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i> <i
|
|
||||||
*ngIf="!movie.requestProcessing && !movie.processed" class="fas fa-plus"></i>
|
|
||||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fas fa-check"></i> {{
|
|
||||||
'Common.Request' | translate }}</button>
|
|
||||||
</ng-template>
|
|
||||||
</span> -->
|
|
||||||
<!-- <span *ngIf="isAdmin && hasRequest">
|
|
||||||
<button (click)="approve()" mat-raised-button class="btn-spacing" color="accent">
|
|
||||||
<i class="fas fa-plus"></i> {{ 'Common.Approve' | translate }}
|
|
||||||
</button>
|
|
||||||
<button *ngIf="!movie.available" (click)="markAvailable()" mat-raised-button class="btn-spacing"
|
|
||||||
color="accent">
|
|
||||||
<i class="fas fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button *ngIf="movieRequest && !movieRequest.denied" mat-raised-button class="btn-spacing" color="warn"
|
|
||||||
(click)="deny()">
|
|
||||||
<i class="fas fa-times"></i> {{
|
|
||||||
'Requests.Deny' | translate }}</button>
|
|
||||||
<button *ngIf="movieRequest && movieRequest.denied" [matTooltip]="movieRequest.deniedReason"
|
|
||||||
mat-raised-button class="btn-spacing" color="warn">
|
|
||||||
<i class="fas fa-times"></i> {{
|
|
||||||
'MediaDetails.Denied' | translate }}</button>
|
|
||||||
</span> -->
|
|
||||||
|
|
||||||
<!-- <button *ngIf="(hasRequest && movieRequest) || movie.available" mat-raised-button class="btn-spacing"
|
|
||||||
color="danger" (click)="issue()">
|
|
||||||
<i class="fas fa-exclamation"></i> {{
|
|
||||||
'Requests.ReportIssue' | translate }}</button> -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-12 col-md-2">
|
<!-- <div class="col-12 col-md-2">
|
||||||
|
|
||||||
<mat-card class="mat-elevation-z8">
|
<mat-card class="mat-elevation-z8">
|
||||||
<mat-card-content class="medium-font">
|
<mat-card-content class="medium-font">
|
||||||
|
@ -91,7 +40,7 @@
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<div class="col-12 col-md-10">
|
<div class="col-12 col-md-10">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -106,7 +55,7 @@
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<artist-release-panel (onAlbumSelect)="albumSelected($event)" (albumLoad)="albumLoad($event)" *ngIf="artist.releaseGroups.length > 0" [releases]="artist.releaseGroups"></artist-release-panel>
|
<artist-release-panel (onAlbumSelect)="albumSelected($event)" (albumLoad)="albumLoad($event)" *ngIf="artist.releaseGroups?.length > 0" [releases]="artist.releaseGroups"></artist-release-panel>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -119,78 +68,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<mat-accordion class="mat-elevation-z8 spacing-below">
|
|
||||||
<mat-expansion-panel>
|
|
||||||
<mat-expansion-panel-header>
|
|
||||||
<mat-panel-title>
|
|
||||||
{{'MediaDetails.RecommendationsTitle' | translate}}
|
|
||||||
</mat-panel-title>
|
|
||||||
</mat-expansion-panel-header>
|
|
||||||
|
|
||||||
<div class="row card-spacer" *ngIf="movie.recommendations.results.length > 0">
|
|
||||||
|
|
||||||
<div class="col-md-2" *ngFor="let r of movie.recommendations.results">
|
|
||||||
<div class="sidebar affixable affix-top preview-poster">
|
|
||||||
<div class="poster">
|
|
||||||
<a [routerLink]="'/details/movie/'+r.id">
|
|
||||||
<img class="real grow" matTooltip="{{r.title}}"
|
|
||||||
src="https://image.tmdb.org/t/p/w300/{{r.poster_path}}" alt="Poster"
|
|
||||||
style="display: block;">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-expansion-panel>
|
|
||||||
<mat-expansion-panel>
|
|
||||||
<mat-expansion-panel-header>
|
|
||||||
<mat-panel-title>
|
|
||||||
{{'MediaDetails.SimilarTitle' | translate}}
|
|
||||||
</mat-panel-title>
|
|
||||||
</mat-expansion-panel-header>
|
|
||||||
|
|
||||||
<div class="row card-spacer" *ngIf="movie.similar.results.length > 0">
|
|
||||||
|
|
||||||
<div class="col-md-2" *ngFor="let r of movie.similar.results">
|
|
||||||
<div class="sidebar affixable affix-top preview-poster">
|
|
||||||
<div class="poster ">
|
|
||||||
<a [routerLink]="'/details/movie/'+r.id">
|
|
||||||
<img class="real grow" matTooltip="{{r.title}}"
|
|
||||||
src="https://image.tmdb.org/t/p/w300/{{r.poster_path}}" alt="Poster"
|
|
||||||
style="display: block;">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-expansion-panel>
|
|
||||||
<mat-expansion-panel>
|
|
||||||
<mat-expansion-panel-header>
|
|
||||||
<mat-panel-title>
|
|
||||||
{{'MediaDetails.VideosTitle' | translate}}
|
|
||||||
</mat-panel-title>
|
|
||||||
</mat-expansion-panel-header>
|
|
||||||
|
|
||||||
<div class="row card-spacer" *ngIf="movie.videos.results.length > 0">
|
|
||||||
|
|
||||||
<div class="col-md-6" *ngFor="let video of movie.videos.results">
|
|
||||||
<iframe width="100%" height="315px" [src]="'https://www.youtube.com/embed/' + video.key | safe"
|
|
||||||
frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
|
|
||||||
allowfullscreen></iframe>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-expansion-panel>
|
|
||||||
</mat-accordion>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component } from "@angular/core";
|
import { Component, ViewEncapsulation } from "@angular/core";
|
||||||
import { ImageService, SearchV2Service, RequestService, MessageService } from "../../../services";
|
import { ImageService, SearchV2Service, RequestService, MessageService } from "../../../services";
|
||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute } from "@angular/router";
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
import { DomSanitizer } from "@angular/platform-browser";
|
||||||
|
@ -13,6 +13,7 @@ import { TranslateService } from "@ngx-translate/core";
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./artist-details.component.html",
|
templateUrl: "./artist-details.component.html",
|
||||||
styleUrls: ["../../media-details.component.scss"],
|
styleUrls: ["../../media-details.component.scss"],
|
||||||
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class ArtistDetailsComponent {
|
export class ArtistDetailsComponent {
|
||||||
private artistId: string;
|
private artistId: string;
|
||||||
|
@ -89,7 +90,10 @@ export class ArtistDetailsComponent {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.requestService.requestAlbum({
|
this.requestService.requestAlbum({
|
||||||
foreignAlbumId : a.id
|
foreignAlbumId : a.id,
|
||||||
|
monitored: true,
|
||||||
|
monitor: "all",
|
||||||
|
searchForMissingAlbums: true
|
||||||
}).toPromise()
|
}).toPromise()
|
||||||
.then(r => {
|
.then(r => {
|
||||||
if (r.result) {
|
if (r.result) {
|
||||||
|
@ -112,7 +116,10 @@ export class ArtistDetailsComponent {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.requestService.requestAlbum({
|
this.requestService.requestAlbum({
|
||||||
foreignAlbumId : a.id
|
foreignAlbumId : a.id,
|
||||||
|
monitored: true,
|
||||||
|
monitor: "all",
|
||||||
|
searchForMissingAlbums: true
|
||||||
}).toPromise()
|
}).toPromise()
|
||||||
.then(r => {
|
.then(r => {
|
||||||
if (r.result) {
|
if (r.result) {
|
||||||
|
|
|
@ -1,4 +1,20 @@
|
||||||
import { IssuesService, RadarrService, RequestService, SearchService, SonarrService } from "../../services";
|
|
||||||
|
import { MovieDetailsComponent } from "./movie/movie-details.component";
|
||||||
|
import { YoutubeTrailerComponent } from "./shared/youtube-trailer.component";
|
||||||
|
import { TvDetailsComponent } from "./tv/tv-details.component";
|
||||||
|
import { MovieInformationPanelComponent } from "./movie/panels/movie-information-panel.component";
|
||||||
|
import { TvInformationPanelComponent } from "./tv/panels/tv-information-panel/tv-information-panel.component";
|
||||||
|
import { TopBannerComponent } from "./shared/top-banner/top-banner.component";
|
||||||
|
import { SocialIconsComponent } from "./shared/social-icons/social-icons.component";
|
||||||
|
import { MediaPosterComponent } from "./shared/media-poster/media-poster.component";
|
||||||
|
import { CastCarouselComponent } from "./shared/cast-carousel/cast-carousel.component";
|
||||||
|
import { DenyDialogComponent } from "./shared/deny-dialog/deny-dialog.component";
|
||||||
|
import { TvRequestsPanelComponent } from "./tv/panels/tv-requests/tv-requests-panel.component";
|
||||||
|
import { MovieAdvancedOptionsComponent } from "./movie/panels/movie-advanced-options/movie-advanced-options.component";
|
||||||
|
import { SearchService, RequestService, RadarrService, IssuesService, SonarrService } from "../../services";
|
||||||
|
import { RequestServiceV2 } from "../../services/requestV2.service";
|
||||||
|
import { NewIssueComponent } from "./shared/new-issue/new-issue.component";
|
||||||
|
import { AlbumDetailsComponent } from "./album/album-details.component";
|
||||||
|
|
||||||
import { ArtistDetailsComponent } from "./artist/artist-details.component";
|
import { ArtistDetailsComponent } from "./artist/artist-details.component";
|
||||||
import { ArtistInformationPanel } from "./artist/panels/artist-information-panel/artist-information-panel.component";
|
import { ArtistInformationPanel } from "./artist/panels/artist-information-panel/artist-information-panel.component";
|
||||||
|
@ -37,6 +53,7 @@ export const components: any[] = [
|
||||||
MovieAdvancedOptionsComponent,
|
MovieAdvancedOptionsComponent,
|
||||||
TvAdvancedOptionsComponent,
|
TvAdvancedOptionsComponent,
|
||||||
NewIssueComponent,
|
NewIssueComponent,
|
||||||
|
AlbumDetailsComponent,
|
||||||
ArtistDetailsComponent,
|
ArtistDetailsComponent,
|
||||||
ArtistInformationPanel,
|
ArtistInformationPanel,
|
||||||
ArtistReleasePanel,
|
ArtistReleasePanel,
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class DenyDialogComponent {
|
||||||
if(this.data.requestType == RequestType.tvShow) {
|
if(this.data.requestType == RequestType.tvShow) {
|
||||||
result = await this.requestService.denyChild({id: this.data.requestId, reason: this.denyReason }).toPromise();
|
result = await this.requestService.denyChild({id: this.data.requestId, reason: this.denyReason }).toPromise();
|
||||||
}
|
}
|
||||||
if(this.data.requestType == RequestType.album) {
|
if(this.data.requestType == RequestType.artist) {
|
||||||
result = await this.requestService.denyAlbum({id: this.data.requestId, reason: this.denyReason }).toPromise();
|
result = await this.requestService.denyAlbum({id: this.data.requestId, reason: this.denyReason }).toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="sidebar sidebar-poster affixable affix-top">
|
<div class="sidebar sidebar-poster affixable affix-top">
|
||||||
<div class="poster mobile-poster">
|
<div class="poster mobile-poster">
|
||||||
<img class="real" src="{{posterPath}}" alt="Poster"
|
<img class="real" src="{{posterPath}}" alt="Poster"
|
||||||
style="display: block;">
|
style="display: block; max-width: 400px;">
|
||||||
</div>
|
</div>
|
||||||
<!--Underneith poster-->
|
<!--Underneith poster-->
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -95,6 +95,10 @@
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#summary-wrapper .row {
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
#info-wrapper {
|
#info-wrapper {
|
||||||
min-height: 600px;
|
min-height: 600px;
|
||||||
}
|
}
|
||||||
|
@ -256,10 +260,6 @@
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#info-wrapper{
|
|
||||||
margin-top:-200px;
|
|
||||||
}
|
|
||||||
.full-screenshot.enabled.overlay{
|
.full-screenshot.enabled.overlay{
|
||||||
background-image: linear-gradient(to bottom, transparent, 50%, $ombi-background-primary);
|
background-image: linear-gradient(to bottom, transparent, 50%, $ombi-background-primary);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { PipeModule } from "../pipes/pipe.module";
|
||||||
import * as fromComponents from './components';
|
import * as fromComponents from './components';
|
||||||
import { AuthGuard } from "../auth/auth.guard";
|
import { AuthGuard } from "../auth/auth.guard";
|
||||||
import { ArtistDetailsComponent } from "./components/artist/artist-details.component";
|
import { ArtistDetailsComponent } from "./components/artist/artist-details.component";
|
||||||
|
import { AlbumDetailsComponent } from "./components/album/album-details.component";
|
||||||
import { ReactiveFormsModule } from "@angular/forms";
|
import { ReactiveFormsModule } from "@angular/forms";
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ const routes: Routes = [
|
||||||
{ path: "tv/:tvdbId/:search", component: TvDetailsComponent, canActivate: [AuthGuard] },
|
{ path: "tv/:tvdbId/:search", component: TvDetailsComponent, canActivate: [AuthGuard] },
|
||||||
{ path: "tv/:tvdbId", component: TvDetailsComponent, canActivate: [AuthGuard] },
|
{ path: "tv/:tvdbId", component: TvDetailsComponent, canActivate: [AuthGuard] },
|
||||||
{ path: "artist/:artistId", component: ArtistDetailsComponent, canActivate: [AuthGuard] },
|
{ path: "artist/:artistId", component: ArtistDetailsComponent, canActivate: [AuthGuard] },
|
||||||
|
{ path: "album/:albumId", component: AlbumDetailsComponent, canActivate: [AuthGuard] },
|
||||||
];
|
];
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
|
|
@ -28,8 +28,9 @@ export class RequestOptionsComponent {
|
||||||
if (this.data.type === RequestType.tvShow) {
|
if (this.data.type === RequestType.tvShow) {
|
||||||
request = this.requestService.deleteChild(this.data.id);
|
request = this.requestService.deleteChild(this.data.id);
|
||||||
}
|
}
|
||||||
if (this.data.type === RequestType.album) {
|
|
||||||
request = this.requestService.removeAlbumRequest(this.data.id);
|
if (this.data.type === RequestType.artist) {
|
||||||
|
await this.requestService.removeAlbumRequest(this.data.id).toPromise();
|
||||||
}
|
}
|
||||||
request.subscribe(result => {
|
request.subscribe(result => {
|
||||||
if (result.result) {
|
if (result.result) {
|
||||||
|
@ -49,7 +50,7 @@ export class RequestOptionsComponent {
|
||||||
if (this.data.type === RequestType.tvShow) {
|
if (this.data.type === RequestType.tvShow) {
|
||||||
await this.requestService.approveChild({id: this.data.id}).toPromise();
|
await this.requestService.approveChild({id: this.data.id}).toPromise();
|
||||||
}
|
}
|
||||||
if (this.data.type === RequestType.album) {
|
if (this.data.type === RequestType.artist) {
|
||||||
await this.requestService.approveAlbum({id: this.data.id}).toPromise();
|
await this.requestService.approveAlbum({id: this.data.id}).toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ export class RequestOptionsComponent {
|
||||||
if (this.data.type === RequestType.movie) {
|
if (this.data.type === RequestType.movie) {
|
||||||
await this.requestService.markMovieAvailable({id: this.data.id}).toPromise();
|
await this.requestService.markMovieAvailable({id: this.data.id}).toPromise();
|
||||||
}
|
}
|
||||||
if (this.data.type === RequestType.album) {
|
if (this.data.type === RequestType.artist) {
|
||||||
await this.requestService.markAlbumAvailable({id: this.data.id}).toPromise();
|
await this.requestService.markAlbumAvailable({id: this.data.id}).toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ import { HttpClient } from "@angular/common/http";
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
import { UITreeNode } from "primeng/tree";
|
import { UITreeNode } from "primeng/tree";
|
||||||
import { FilterType, IAlbumRequest, IAlbumRequestModel, IAlbumUpdateModel, IChildRequests, IDenyAlbumModel, IDenyMovieModel, IFilter,
|
import {
|
||||||
|
FilterType, IAlbumRequest, IAlbumRequestModel, IArtistRequestModel, IAlbumUpdateModel, IChildRequests, IDenyAlbumModel, IDenyMovieModel, IFilter,
|
||||||
IMovieRequestModel, IMovieRequests, IMovieUpdateModel, IRequestEngineResult, IRequestsViewModel, ITvDenyModel, ITvRequests, ITvUpdateModel, OrderType } from "../interfaces";
|
IMovieRequestModel, IMovieRequests, IMovieUpdateModel, IRequestEngineResult, IRequestsViewModel, ITvDenyModel, ITvRequests, ITvUpdateModel, OrderType } from "../interfaces";
|
||||||
import { ServiceHelpers } from "./service.helpers";
|
import { ServiceHelpers } from "./service.helpers";
|
||||||
|
|
||||||
|
@ -154,7 +155,10 @@ export class RequestService extends ServiceHelpers {
|
||||||
|
|
||||||
// Music
|
// Music
|
||||||
public requestAlbum(Album: IAlbumRequestModel): Observable<IRequestEngineResult> {
|
public requestAlbum(Album: IAlbumRequestModel): Observable<IRequestEngineResult> {
|
||||||
return this.http.post<IRequestEngineResult>(`${this.url}music/`, JSON.stringify(Album), {headers: this.headers});
|
return this.http.post<IRequestEngineResult>(`${this.url}album/`, JSON.stringify(Album), {headers: this.headers});
|
||||||
|
}
|
||||||
|
public requestArtist(Artist: IArtistRequestModel): Observable<IRequestEngineResult> {
|
||||||
|
return this.http.post<IRequestEngineResult>(`${this.url}artist/`, JSON.stringify(Artist), { headers: this.headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTotalAlbums(): Observable<number> {
|
public getTotalAlbums(): Observable<number> {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { ServiceHelpers } from "./service.helpers";
|
||||||
|
|
||||||
import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2";
|
import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2";
|
||||||
import { ISearchTvResultV2, IMovieCollectionsViewModel, IActorCredits } from "../interfaces/ISearchTvResultV2";
|
import { ISearchTvResultV2, IMovieCollectionsViewModel, IActorCredits } from "../interfaces/ISearchTvResultV2";
|
||||||
import { IArtistSearchResult, IAlbumArt, IReleaseGroups } from "../interfaces/IMusicSearchResultV2";
|
import { IArtistSearchResult, IAlbumSearchResult, IAlbumArt, IReleaseGroups } from "../interfaces/IMusicSearchResultV2";
|
||||||
import { SearchFilter } from "../my-nav/SearchFilter";
|
import { SearchFilter } from "../my-nav/SearchFilter";
|
||||||
import { IMovieRatings, ITvRatings } from "../interfaces/IRatings";
|
import { IMovieRatings, ITvRatings } from "../interfaces/IRatings";
|
||||||
import { IStreamingData } from "../interfaces/IStreams";
|
import { IStreamingData } from "../interfaces/IStreams";
|
||||||
|
@ -140,6 +140,10 @@ export class SearchV2Service extends ServiceHelpers {
|
||||||
return this.http.get<IArtistSearchResult>(`${this.url}/artist/${artistId}`);
|
return this.http.get<IArtistSearchResult>(`${this.url}/artist/${artistId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getAlbumInformation(albumId: string): Observable<IAlbumSearchResult> {
|
||||||
|
return this.http.get<IAlbumSearchResult>(`${this.url}/artist/album/${albumId}`);
|
||||||
|
}
|
||||||
|
|
||||||
public getReleaseGroupArt(mbid: string): Observable<IAlbumArt> {
|
public getReleaseGroupArt(mbid: string): Observable<IAlbumArt> {
|
||||||
return this.http.get<IAlbumArt>(`${this.url}/releasegroupart/${mbid}`);
|
return this.http.get<IAlbumArt>(`${this.url}/releasegroupart/${mbid}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ export class RemainingRequestsComponent implements OnInit {
|
||||||
this.matIcon = "fas fa-tv";
|
this.matIcon = "fas fa-tv";
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case RequestType.album:
|
case RequestType.artist:
|
||||||
this.requestService.getRemainingMusicRequests().subscribe(callback);
|
this.requestService.getRemainingMusicRequests().subscribe(callback);
|
||||||
this.matIcon = "fas fa-music";
|
this.matIcon = "fas fa-music";
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
"no-internal-module": false,
|
"no-internal-module": false,
|
||||||
"quotemark": [ true, "double", "avoid-template" ],
|
"quotemark": [ true, "double", "avoid-template" ],
|
||||||
"no-console": false,
|
"no-console": false,
|
||||||
"no-non-null-assertion": false,
|
"no-non-null-assertion": false
|
||||||
},
|
},
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"experimentalDecorators":true,
|
"experimentalDecorators":false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ using ILogger = Microsoft.Extensions.Logging.ILogger;
|
||||||
namespace Ombi.Controllers.V1
|
namespace Ombi.Controllers.V1
|
||||||
{
|
{
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/v1/request/music")]
|
[Route("api/v1/request")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class MusicRequestController : ControllerBase
|
public class MusicRequestController : ControllerBase
|
||||||
|
@ -45,7 +45,7 @@ namespace Ombi.Controllers.V1
|
||||||
/// <param name="statusType"></param>
|
/// <param name="statusType"></param>
|
||||||
/// <param name="availabilityType"></param>
|
/// <param name="availabilityType"></param>
|
||||||
[HttpGet("{count:int}/{position:int}/{orderType:int}/{statusType:int}/{availabilityType:int}")]
|
[HttpGet("{count:int}/{position:int}/{orderType:int}/{statusType:int}/{availabilityType:int}")]
|
||||||
public async Task<RequestsViewModel<AlbumRequest>> GetRequests(int count, int position, int orderType, int statusType, int availabilityType)
|
public async Task<RequestsViewModel<MusicRequests>> GetRequests(int count, int position, int orderType, int statusType, int availabilityType)
|
||||||
{
|
{
|
||||||
return await _engine.GetRequests(count, position, new OrderFilterModel
|
return await _engine.GetRequests(count, position, new OrderFilterModel
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ namespace Ombi.Controllers.V1
|
||||||
/// Gets all album requests.
|
/// Gets all album requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IEnumerable<AlbumRequest>> GetRequests()
|
public async Task<IEnumerable<MusicRequests>> GetRequests()
|
||||||
{
|
{
|
||||||
return await _engine.GetRequests();
|
return await _engine.GetRequests();
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ namespace Ombi.Controllers.V1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="album">The album.</param>
|
/// <param name="album">The album.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost("album")]
|
||||||
public async Task<RequestEngineResult> RequestAlbum([FromBody] MusicAlbumRequestViewModel album)
|
public async Task<RequestEngineResult> RequestAlbum([FromBody] MusicAlbumRequestViewModel album)
|
||||||
{
|
{
|
||||||
album.RequestedByAlias = GetApiAlias();
|
album.RequestedByAlias = GetApiAlias();
|
||||||
|
@ -95,13 +95,36 @@ namespace Ombi.Controllers.V1
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Requests a artist.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="artist">The artist.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("artist")]
|
||||||
|
public async Task<RequestEngineResult> RequestArtist([FromBody] MusicArtistRequestViewModel artist)
|
||||||
|
{
|
||||||
|
Console.Write(artist);
|
||||||
|
artist.RequestedByAlias = GetApiAlias();
|
||||||
|
var result = await _engine.RequestArtist(artist);
|
||||||
|
if (result.Result)
|
||||||
|
{
|
||||||
|
var voteResult = await _voteEngine.UpVote(result.RequestId, RequestType.Artist);
|
||||||
|
if (voteResult.IsError)
|
||||||
|
{
|
||||||
|
_log.LogError("Couldn't automatically add the vote for the artist {0} because {1}", artist.ForeignArtistId, voteResult.ErrorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for a specific album request
|
/// Searches for a specific album request
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="searchTerm">The search term.</param>
|
/// <param name="searchTerm">The search term.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("search/{searchTerm}")]
|
[HttpGet("search/{searchTerm}")]
|
||||||
public async Task<IEnumerable<AlbumRequest>> Search(string searchTerm)
|
public async Task<IEnumerable<MusicRequests>> Search(string searchTerm)
|
||||||
{
|
{
|
||||||
return await _engine.SearchAlbumRequest(searchTerm);
|
return await _engine.SearchAlbumRequest(searchTerm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,31 +151,31 @@ namespace Ombi.Controllers.V2
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("album/available/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
[HttpGet("album/available/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
||||||
public async Task<RequestsViewModel<AlbumRequest>> GetAvailableAlbumRequests(int count, int position, string sort, string sortOrder)
|
public async Task<RequestsViewModel<MusicRequests>> GetAvailableAlbumRequests(int count, int position, string sort, string sortOrder)
|
||||||
{
|
{
|
||||||
return await _musicRequestEngine.GetRequestsByStatus(count, position, sort, sortOrder, RequestStatus.Available);
|
return await _musicRequestEngine.GetRequestsByStatus(count, position, sort, sortOrder, RequestStatus.Available);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("album/processing/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
[HttpGet("album/processing/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
||||||
public async Task<RequestsViewModel<AlbumRequest>> GetProcessingAlbumRequests(int count, int position, string sort, string sortOrder)
|
public async Task<RequestsViewModel<MusicRequests>> GetProcessingAlbumRequests(int count, int position, string sort, string sortOrder)
|
||||||
{
|
{
|
||||||
return await _musicRequestEngine.GetRequestsByStatus(count, position, sort, sortOrder, RequestStatus.ProcessingRequest);
|
return await _musicRequestEngine.GetRequestsByStatus(count, position, sort, sortOrder, RequestStatus.ProcessingRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("album/pending/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
[HttpGet("album/pending/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
||||||
public async Task<RequestsViewModel<AlbumRequest>> GetPendingAlbumRequests(int count, int position, string sort, string sortOrder)
|
public async Task<RequestsViewModel<MusicRequests>> GetPendingAlbumRequests(int count, int position, string sort, string sortOrder)
|
||||||
{
|
{
|
||||||
return await _musicRequestEngine.GetRequestsByStatus(count, position, sort, sortOrder, RequestStatus.PendingApproval);
|
return await _musicRequestEngine.GetRequestsByStatus(count, position, sort, sortOrder, RequestStatus.PendingApproval);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("album/denied/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
[HttpGet("album/denied/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
||||||
public async Task<RequestsViewModel<AlbumRequest>> GetDeniedAlbumRequests(int count, int position, string sort, string sortOrder)
|
public async Task<RequestsViewModel<MusicRequests>> GetDeniedAlbumRequests(int count, int position, string sort, string sortOrder)
|
||||||
{
|
{
|
||||||
return await _musicRequestEngine.GetRequestsByStatus(count, position, sort, sortOrder, RequestStatus.Denied);
|
return await _musicRequestEngine.GetRequestsByStatus(count, position, sort, sortOrder, RequestStatus.Denied);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("album/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
[HttpGet("album/{count:int}/{position:int}/{sort}/{sortOrder}")]
|
||||||
public async Task<RequestsViewModel<AlbumRequest>> GetAlbumRequests(int count, int position, string sort, string sortOrder)
|
public async Task<RequestsViewModel<MusicRequests>> GetAlbumRequests(int count, int position, string sort, string sortOrder)
|
||||||
{
|
{
|
||||||
return await _musicRequestEngine.GetRequests(count, position, sort, sortOrder);
|
return await _musicRequestEngine.GetRequests(count, position, sort, sortOrder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -429,9 +429,9 @@ namespace Ombi.Controllers.V2
|
||||||
[HttpGet("artist/album/{albumId}")]
|
[HttpGet("artist/album/{albumId}")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesDefaultResponseType]
|
[ProducesDefaultResponseType]
|
||||||
public Task<ReleaseGroup> GetAlbumInformation(string albumId)
|
public Task<AlbumInformation> GetAlbumInformation(string albumId)
|
||||||
{
|
{
|
||||||
return _musicEngine.GetAlbum(albumId);
|
return _musicEngine.GetAlbumInformation(albumId);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("releasegroupart/{musicBrainzId}")]
|
[HttpGet("releasegroupart/{musicBrainzId}")]
|
||||||
|
|
|
@ -38,7 +38,8 @@
|
||||||
"Update": "Update",
|
"Update": "Update",
|
||||||
"tvShow": "TV Show",
|
"tvShow": "TV Show",
|
||||||
"movie": "Movie",
|
"movie": "Movie",
|
||||||
"album": "Album"
|
"album": "Album",
|
||||||
|
"artist": "Artist"
|
||||||
},
|
},
|
||||||
"PasswordReset": {
|
"PasswordReset": {
|
||||||
"EmailAddressPlaceholder": "Email Address",
|
"EmailAddressPlaceholder": "Email Address",
|
||||||
|
@ -298,6 +299,7 @@
|
||||||
"RequestAllAlbums": "Request All Albums",
|
"RequestAllAlbums": "Request All Albums",
|
||||||
"ClearSelection": "Clear Selection",
|
"ClearSelection": "Clear Selection",
|
||||||
"RequestSelectedAlbums": "Request Selected Albums",
|
"RequestSelectedAlbums": "Request Selected Albums",
|
||||||
|
"RequestAlbum": "Request Album",
|
||||||
"ViewCollection":"View Collection",
|
"ViewCollection":"View Collection",
|
||||||
"NotEnoughInfo": "Unfortunately there is not enough information about this show yet!",
|
"NotEnoughInfo": "Unfortunately there is not enough information about this show yet!",
|
||||||
"AdvancedOptions":"Advanced Options",
|
"AdvancedOptions":"Advanced Options",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue