From df74e386726c472057a1e5ebd0a848ff4f0b3c0a Mon Sep 17 00:00:00 2001 From: tidusjar Date: Mon, 11 Jan 2021 14:13:26 +0000 Subject: [PATCH] Fixed the artist search in ombi Make minor improvements to the new search result --- src/Ombi.Api.MusicBrainz/IMusicBrainzApi.cs | 2 + src/Ombi.Api.MusicBrainz/MusicBrainzApi.cs | 7 +++ .../Engine/Interfaces/IMusicSearchEngineV2.cs | 1 + .../Engine/V2/MusicSearchEngineV2.cs | 37 +++++++++--- .../card/discover-card-details.component.ts | 6 +- .../card/discover-card.component.html | 2 +- .../card/discover-card.component.ts | 41 +++++++++++-- .../grid/discover-grid.component.ts | 58 +++++++++---------- .../search-results.component.ts | 18 ++++-- .../ClientApp/src/app/discover/interfaces.ts | 2 +- .../src/app/services/search.service.ts | 3 + .../src/app/services/searchV2.service.ts | 6 +- src/Ombi/Controllers/V2/SearchController.cs | 9 +++ src/Ombi/Program.cs | 2 + 14 files changed, 142 insertions(+), 52 deletions(-) diff --git a/src/Ombi.Api.MusicBrainz/IMusicBrainzApi.cs b/src/Ombi.Api.MusicBrainz/IMusicBrainzApi.cs index 69d8231ad..3b47cdd28 100644 --- a/src/Ombi.Api.MusicBrainz/IMusicBrainzApi.cs +++ b/src/Ombi.Api.MusicBrainz/IMusicBrainzApi.cs @@ -2,6 +2,7 @@ using System.Threading; using System.Threading.Tasks; using Hqub.MusicBrainz.API.Entities; +using Hqub.MusicBrainz.API.Entities.Collections; using Ombi.Api.MusicBrainz.Models; namespace Ombi.Api.MusicBrainz @@ -11,6 +12,7 @@ namespace Ombi.Api.MusicBrainz Task> SearchArtist(string artistQuery); Task> GetReleaseForArtist(string artistId); Task GetArtistInformation(string artistId); + Task GetAlbumInformation(string albumId); Task GetCoverArtForReleaseGroup(string musicBrainzId, CancellationToken token); } } \ No newline at end of file diff --git a/src/Ombi.Api.MusicBrainz/MusicBrainzApi.cs b/src/Ombi.Api.MusicBrainz/MusicBrainzApi.cs index 3c86d7882..e870eb07f 100644 --- a/src/Ombi.Api.MusicBrainz/MusicBrainzApi.cs +++ b/src/Ombi.Api.MusicBrainz/MusicBrainzApi.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Hqub.MusicBrainz.API; using Hqub.MusicBrainz.API.Entities; +using Hqub.MusicBrainz.API.Entities.Collections; using Newtonsoft.Json; using Ombi.Api.MusicBrainz.Models; @@ -20,6 +21,12 @@ namespace Ombi.Api.MusicBrainz _api = api; } + public Task GetAlbumInformation(string albumId) + { + var album = Release.GetAsync(albumId); + return album; + } + public async Task> SearchArtist(string artistQuery) { var artist = await Artist.SearchAsync(artistQuery, 10); diff --git a/src/Ombi.Core/Engine/Interfaces/IMusicSearchEngineV2.cs b/src/Ombi.Core/Engine/Interfaces/IMusicSearchEngineV2.cs index f9889ec9c..efd42dc68 100644 --- a/src/Ombi.Core/Engine/Interfaces/IMusicSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/Interfaces/IMusicSearchEngineV2.cs @@ -9,5 +9,6 @@ namespace Ombi.Core.Engine.Interfaces Task GetArtistInformation(string artistId); Task GetArtistInformationByRequestId(int requestId); Task GetReleaseGroupArt(string musicBrainzId, CancellationToken token); + Task GetAlbum(string albumId); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs index 13256be0a..b7d9575db 100644 --- a/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Security.Principal; using System.Threading; using System.Threading.Tasks; +using Newtonsoft.Json; using Ombi.Api.Lidarr; using Ombi.Api.Lidarr.Models; using Ombi.Api.MusicBrainz; @@ -41,6 +42,21 @@ namespace Ombi.Core.Engine.V2 _lidarrApi = lidarrApi; } + public async Task GetAlbum(string albumId) + { + var g = await _musicBrainzApi.GetAlbumInformation(albumId); + var release = new ReleaseGroup + { + ReleaseType = g.ReleaseGroup.PrimaryType, + Id = g.Id, + Title = g.Title, + ReleaseDate = g.ReleaseGroup.FirstReleaseDate, + }; + + await RunSearchRules(release); + return release; + } + public async Task GetArtistInformation(string artistId) { var artist = await _musicBrainzApi.GetArtistInformation(artistId); @@ -84,12 +100,19 @@ namespace Ombi.Core.Engine.V2 if (lidarrArtistTask != null) { - var artistResult = await lidarrArtistTask; - info.Banner = artistResult.images?.FirstOrDefault(x => x.coverType.Equals("banner", StringComparison.InvariantCultureIgnoreCase))?.url.ToHttpsUrl(); - info.Logo = artistResult.images?.FirstOrDefault(x => x.coverType.Equals("logo", 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.Overview = artistResult.overview; + try + { + var artistResult = await lidarrArtistTask; + info.Banner = artistResult.images?.FirstOrDefault(x => x.coverType.Equals("banner", StringComparison.InvariantCultureIgnoreCase))?.url.ToHttpsUrl(); + info.Logo = artistResult.images?.FirstOrDefault(x => x.coverType.Equals("logo", 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.Overview = artistResult.overview; + } + catch (JsonSerializationException) + { + // swallow, Lidarr probably doesn't have this artist + } } return info; @@ -118,7 +141,7 @@ namespace Ombi.Core.Engine.V2 return new AlbumArt(); } - + public async Task GetArtistInformationByRequestId(int requestId) { var request = await RequestService.MusicRequestRepository.Find(requestId); diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card-details.component.ts b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card-details.component.ts index f3d1276ad..883add54a 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card-details.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card-details.component.ts @@ -31,9 +31,9 @@ export class DiscoverCardDetailsComponent implements OnInit { public async ngOnInit() { this.loading = true; if (this.data.type === RequestType.movie) { - this.movie = await this.searchService.getFullMovieDetailsPromise(this.data.id); + this.movie = await this.searchService.getFullMovieDetailsPromise(+this.data.id); } else if (this.data.type === RequestType.tvShow) { - this.tv = await this.searchService.getTvInfo(this.data.id); + this.tv = await this.searchService.getTvInfo(+this.data.id); const creator = this.tv.crew.filter(tv => { return tv.type === "Creator"; })[0]; @@ -67,7 +67,7 @@ export class DiscoverCardDetailsComponent implements OnInit { public async request() { this.loading = true; if (this.data.type === RequestType.movie) { - const result = await this.requestService.requestMovie({ theMovieDbId: this.data.id, languageCode: "", requestOnBehalf: null }).toPromise(); + const result = await this.requestService.requestMovie({ theMovieDbId: +this.data.id, languageCode: "", requestOnBehalf: null }).toPromise(); this.loading = false; if (result.result) { diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html index 9bbe868ee..b32bb98d8 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html @@ -1,5 +1,5 @@
- +
{{getAvailbilityStatus()}}
diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts index c923de72b..6512ca3a8 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, Input } from "@angular/core"; import { IDiscoverCardResult } from "../../interfaces"; import { RequestType } from "../../../interfaces"; -import { SearchV2Service } from "../../../services"; +import { SearchService, SearchV2Service } from "../../../services"; import { MatDialog } from "@angular/material/dialog"; import { DiscoverCardDetailsComponent } from "./discover-card-details.component"; import { ISearchTvResultV2 } from "../../../interfaces/ISearchTvResultV2"; @@ -18,7 +18,7 @@ export class DiscoverCardComponent implements OnInit { public RequestType = RequestType; public hide: boolean; - constructor(private searchService: SearchV2Service, private dialog: MatDialog) { } + constructor(private searchService: SearchV2Service, private v1Search: SearchService, private dialog: MatDialog) { } public ngOnInit() { if (this.result.type == RequestType.tvShow) { @@ -27,6 +27,9 @@ export class DiscoverCardComponent implements OnInit { if (this.result.type == RequestType.movie) { this.getExtraMovieInfo(); } + if (this.result.type == RequestType.album) { + this.getAlbumInformation(); + } } public openDetails(details: IDiscoverCardResult) { @@ -35,9 +38,9 @@ export class DiscoverCardComponent implements OnInit { public async getExtraTvInfo() { if (this.result.tvMovieDb) { - var result = await this.searchService.getTvInfoWithMovieDbId(this.result.id); + var result = await this.searchService.getTvInfoWithMovieDbId(+this.result.id); } else { - var result = await this.searchService.getTvInfo(this.result.id); + var result = await this.searchService.getTvInfo(+this.result.id); } if(result.status === "404") { this.hide = true; @@ -48,6 +51,34 @@ export class DiscoverCardComponent implements OnInit { } + public async getAlbumInformation() { + this.searchService.getArtistInformation(this.result.id.toString()).subscribe(x => { + if (x.poster) { + this.result.posterPath = x.poster; + } else { + this.searchService.getReleaseGroupArt(this.result.id.toString()).subscribe(art => { + if(art.image) { + this.result.posterPath = art.image; + } + }) + } + this.result.title = x.startYear ? `${x.name} (${x.startYear})` : x.name; + this.result.overview = x.overview; + }); + } + + public generateDetailsLink(): string { + let link = ""; + switch(this.result.type){ + case RequestType.movie: + return `/details/movie/${this.result.id}`; + case RequestType.tvShow: + return `/details/tv/${this.result.id}`; + case RequestType.album: //Actually artist + return `/details/artist/${this.result.id}`; + } + } + public getStatusClass(): string { if (this.result.available) { return "available"; @@ -76,7 +107,7 @@ export class DiscoverCardComponent implements OnInit { private getExtraMovieInfo() { if (!this.result.imdbid) { - this.searchService.getFullMovieDetails(this.result.id) + this.searchService.getFullMovieDetails(+this.result.id) .subscribe(m => { this.updateMovieItem(m); }); diff --git a/src/Ombi/ClientApp/src/app/discover/components/grid/discover-grid.component.ts b/src/Ombi/ClientApp/src/app/discover/components/grid/discover-grid.component.ts index 42f371dc2..51ea7a85f 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/grid/discover-grid.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/grid/discover-grid.component.ts @@ -27,8 +27,8 @@ export class DiscoverGridComponent implements OnInit { public movie: ISearchMovieResultV2; constructor(private searchService: SearchV2Service, private dialog: MatDialog, - private requestService: RequestService, private notification: MatSnackBar, - private router: Router, private sanitizer: DomSanitizer, private imageService: ImageService) { } + private requestService: RequestService, private notification: MatSnackBar, + private router: Router, private sanitizer: DomSanitizer, private imageService: ImageService) { } public ngOnInit() { if (this.result.type == RequestType.tvShow) { @@ -40,7 +40,7 @@ export class DiscoverGridComponent implements OnInit { } public async getExtraTvInfo() { - this.tv = await this.searchService.getTvInfo(this.result.id); + this.tv = await this.searchService.getTvInfo(+this.result.id); this.setTvDefaults(this.tv); this.updateTvItem(this.tv); const creator = this.tv.crew.filter(tv => { @@ -80,35 +80,33 @@ export class DiscoverGridComponent implements OnInit { } private getExtraMovieInfo() { - // if (!this.result.imdbid) { - this.searchService.getFullMovieDetails(this.result.id) - .subscribe(m => { - this.movie = m; - this.updateMovieItem(m); - }); - - this.setMovieBackground() - // } + this.searchService.getFullMovieDetails(+this.result.id) + .subscribe(m => { + this.movie = m; + this.updateMovieItem(m); + }); + + this.setMovieBackground() } private setMovieBackground(): void { - this.result.background = this.sanitizer.bypassSecurityTrustStyle - ("linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url(" + "https://image.tmdb.org/t/p/original" + this.result.background + ")"); - } + this.result.background = this.sanitizer.bypassSecurityTrustStyle + ("linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url(" + "https://image.tmdb.org/t/p/original" + this.result.background + ")"); + } - private setTvBackground(): void { - if (this.result.background != null) { - this.result.background = this.sanitizer.bypassSecurityTrustStyle - ("linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url(https://image.tmdb.org/t/p/original" + this.result.background + ")"); - } else { - this.imageService.getTvBanner(this.result.id).subscribe(x => { - if (x) { - this.result.background = this.sanitizer.bypassSecurityTrustStyle - ("linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url(" + x + ")"); - } - }); - } - } + private setTvBackground(): void { + if (this.result.background != null) { + this.result.background = this.sanitizer.bypassSecurityTrustStyle + ("linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url(https://image.tmdb.org/t/p/original" + this.result.background + ")"); + } else { + this.imageService.getTvBanner(+this.result.id).subscribe(x => { + if (x) { + this.result.background = this.sanitizer.bypassSecurityTrustStyle + ("linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url(" + x + ")"); + } + }); + } + } private updateMovieItem(updated: ISearchMovieResultV2) { this.result.url = "http://www.imdb.com/title/" + updated.imdbId + "/"; @@ -139,7 +137,7 @@ export class DiscoverGridComponent implements OnInit { public async request() { this.requesting = true; if (this.result.type === RequestType.movie) { - const result = await this.requestService.requestMovie({ theMovieDbId: this.result.id, languageCode: "", requestOnBehalf: null }).toPromise(); + const result = await this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: "", requestOnBehalf: null }).toPromise(); if (result.result) { this.result.requested = true; @@ -148,7 +146,7 @@ export class DiscoverGridComponent implements OnInit { this.notification.open(result.errorMessage, "Ok"); } } else if (this.result.type === RequestType.tvShow) { - this.dialog.open(EpisodeRequestComponent, { width: "700px", data: { series: this.tv, requestOnBehalf: null }, panelClass: 'modal-panel' }) + this.dialog.open(EpisodeRequestComponent, { width: "700px", data: { series: this.tv, requestOnBehalf: null }, panelClass: 'modal-panel' }) } this.requesting = false; } diff --git a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts index 995389b2e..0b2aa2030 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts @@ -39,7 +39,7 @@ export class DiscoverSearchResultsComponent implements OnInit { this.filterService.onFilterChange.subscribe(async x => { if (!isEqual(this.filter, x)) { - this.filter = { ...x }; + this.filter = { ...x }; await this.search(); } }); @@ -50,7 +50,7 @@ export class DiscoverSearchResultsComponent implements OnInit { if (filter) { this.filter = Object.assign(new SearchFilter(), JSON.parse(filter)); } else { - this.filter = new SearchFilter({ movies: true, tvShows: true, people: false, music: false}); + this.filter = new SearchFilter({ movies: true, tvShows: true, people: false, music: false }); } this.loading(); await this.search(); @@ -69,12 +69,22 @@ export class DiscoverSearchResultsComponent implements OnInit { mediaType = RequestType.album; } + let poster = `https://image.tmdb.org/t/p/w300/${m.poster}`; + if (!m.poster) { + if (mediaType === RequestType.movie) { + poster = "images/default_movie_poster.png" + } + if (mediaType === RequestType.tvShow) { + poster = "images/default_tv_poster.png" + } + } + this.discoverResults.push({ - posterPath: `https://image.tmdb.org/t/p/w300/${m.poster}`, + posterPath: mediaType !== RequestType.album ? poster : "images/default-music-placeholder.png", requested: false, title: m.title, type: mediaType, - id: +m.id, + id: m.id, url: "", rating: 0, overview: "", diff --git a/src/Ombi/ClientApp/src/app/discover/interfaces.ts b/src/Ombi/ClientApp/src/app/discover/interfaces.ts index bac0faafc..7127f52c5 100644 --- a/src/Ombi/ClientApp/src/app/discover/interfaces.ts +++ b/src/Ombi/ClientApp/src/app/discover/interfaces.ts @@ -1,7 +1,7 @@ import { RequestType } from "../interfaces"; export interface IDiscoverCardResult { - id: number; + id: number | string; posterPath: string; url: string | undefined; title: string; diff --git a/src/Ombi/ClientApp/src/app/services/search.service.ts b/src/Ombi/ClientApp/src/app/services/search.service.ts index 0adfed3ad..3468bede4 100644 --- a/src/Ombi/ClientApp/src/app/services/search.service.ts +++ b/src/Ombi/ClientApp/src/app/services/search.service.ts @@ -89,6 +89,9 @@ export class SearchService extends ServiceHelpers { public searchAlbum(searchTerm: string): Observable { return this.http.get(`${this.url}/Music/Album/` + searchTerm); } + public getAlbumInformation(foreignAlbumId: string): Observable { + return this.http.get(`${this.url}/Music/Album/info/` + foreignAlbumId); + } public getAlbumsForArtist(foreignArtistId: string): Observable { return this.http.get(`${this.url}/Music/Artist/Album/${foreignArtistId}`); } diff --git a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts index fa970313f..383ee18d9 100644 --- a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts +++ b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts @@ -9,7 +9,7 @@ import { ServiceHelpers } from "./service.helpers"; import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2"; import { ISearchTvResultV2, IMovieCollectionsViewModel, IActorCredits } from "../interfaces/ISearchTvResultV2"; -import { IArtistSearchResult, IAlbumArt } from "../interfaces/IMusicSearchResultV2"; +import { IArtistSearchResult, IAlbumArt, IReleaseGroups } from "../interfaces/IMusicSearchResultV2"; import { SearchFilter } from "../my-nav/SearchFilter"; import { IMovieRatings, ITvRatings } from "../interfaces/IRatings"; import { IStreamingData } from "../interfaces/IStreams"; @@ -124,6 +124,10 @@ export class SearchV2Service extends ServiceHelpers { return this.http.get(`${this.url}/releasegroupart/${mbid}`); } + public getAlbum(mbid: string): Observable { + return this.http.get(`${this.url}/artist/album/${mbid}`); + } + public getRottenMovieRatings(name: string, year: number): Observable { return this.http.get(`${this.url}/ratings/movie/${name}/${year}`); } diff --git a/src/Ombi/Controllers/V2/SearchController.cs b/src/Ombi/Controllers/V2/SearchController.cs index 889dc288f..ed831bb1c 100644 --- a/src/Ombi/Controllers/V2/SearchController.cs +++ b/src/Ombi/Controllers/V2/SearchController.cs @@ -16,6 +16,7 @@ using Ombi.Core.Models.Search.V2.Music; using Ombi.Models; using Ombi.Api.RottenTomatoes.Models; using Ombi.Api.RottenTomatoes; +using Hqub.MusicBrainz.API.Entities.Collections; namespace Ombi.Controllers.V2 { @@ -396,6 +397,14 @@ namespace Ombi.Controllers.V2 return await _musicEngine.GetArtistInformationByRequestId(requestId); } + [HttpGet("artist/album/{albumId}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesDefaultResponseType] + public Task GetAlbumInformation(string albumId) + { + return _musicEngine.GetAlbum(albumId); + } + [HttpGet("releasegroupart/{musicBrainzId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesDefaultResponseType] diff --git a/src/Ombi/Program.cs b/src/Ombi/Program.cs index 46b5c8559..f8a45387e 100644 --- a/src/Ombi/Program.cs +++ b/src/Ombi/Program.cs @@ -45,6 +45,8 @@ namespace Ombi } }); + + Console.WriteLine(HelpOutput(result)); UrlArgs = host;