!wip started the searching process

pull/2478/head
TidusJar 6 years ago
parent 26d620cf01
commit 9156673f88

@ -22,7 +22,7 @@ namespace Ombi.Api.Lidarr
public Task<List<LidarrProfile>> GetProfiles(string apiKey, string baseUrl)
{
var request = new Request($"{ApiVersion}/profile", baseUrl, HttpMethod.Get);
var request = new Request($"{ApiVersion}/qualityprofile", baseUrl, HttpMethod.Get);
AddHeaders(request, apiKey);
return Api.Request<List<LidarrProfile>>(request);

@ -2,12 +2,6 @@
namespace Ombi.Api.Lidarr.Models
{
public class Cutoff
{
public int id { get; set; }
public string name { get; set; }
}
public class Quality
{
public int id { get; set; }
@ -23,9 +17,7 @@ namespace Ombi.Api.Lidarr.Models
public class LidarrProfile
{
public string name { get; set; }
public Cutoff cutoff { get; set; }
public List<Item> items { get; set; }
public string language { get; set; }
public int id { get; set; }
}
}

@ -7,6 +7,6 @@
public int trackCount { get; set; }
public int totalTrackCount { get; set; }
public int sizeOnDisk { get; set; }
public int percentOfTracks { get; set; }
public decimal percentOfTracks { get; set; }
}
}

@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Api.Lidarr.Models;
using Ombi.Core.Models.Search;
namespace Ombi.Core.Engine
{
public interface IMusicSearchEngine
{
Task<ArtistResult> GetAlbumArtist(string foreignArtistId);
Task<ArtistResult> GetArtist(int artistId);
Task<ArtistResult> GetArtistAlbums(string foreignArtistId);
Task<IEnumerable<AlbumLookup>> SearchAlbum(string search);
Task<IEnumerable<SearchArtistViewModel>> SearchArtist(string search);
}
}

@ -24,7 +24,7 @@ using Ombi.Store.Repository;
namespace Ombi.Core.Engine
{
public class MusicSearchEngine : BaseMediaEngine
public class MusicSearchEngine : BaseMediaEngine, IMusicSearchEngine
{
public MusicSearchEngine(IPrincipal identity, IRequestServiceMain service, ILidarrApi lidarrApi, IMapper mapper,
ILogger<MusicSearchEngine> logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub,
@ -60,12 +60,42 @@ namespace Ombi.Core.Engine
/// </summary>
/// <param name="search">The search.</param>
/// <returns></returns>
public async Task<IEnumerable<ArtistLookup>> SearchArtist(string search)
public async Task<IEnumerable<SearchArtistViewModel>> SearchArtist(string search)
{
var settings = await GetSettings();
var result = await _lidarrApi.ArtistLookup(search, settings.ApiKey, settings.FullUri);
return result;
var vm = new List<SearchArtistViewModel>();
foreach (var r in result)
{
vm.Add(MapIntoArtistVm(r));
}
return vm;
}
private SearchArtistViewModel MapIntoArtistVm(ArtistLookup a)
{
var vm = new SearchArtistViewModel
{
ArtistName = a.artistName,
ArtistType = a.artistType,
Banner = a.images?.FirstOrDefault(x => x.coverType.Equals("banner"))?.url,
Logo = a.images?.FirstOrDefault(x => x.coverType.Equals("logo"))?.url,
CleanName = a.cleanName,
Disambiguation = a.disambiguation,
ForignArtistId = a.foreignArtistId,
Links = a.links,
Overview = a.overview,
};
var poster = a.images?.FirstOrDefault(x => x.coverType.Equals("poaster"));
if (poster == null)
{
vm.Poster = a.remotePoster;
}
return vm;
}
/// <summary>
@ -73,7 +103,7 @@ namespace Ombi.Core.Engine
/// </summary>
/// <param name="artistId"></param>
/// <returns></returns>
public async Task GetArtistAlbums(string foreignArtistId)
public async Task<ArtistResult> GetArtistAlbums(string foreignArtistId)
{
var settings = await GetSettings();
return await _lidarrApi.GetArtistByForignId(foreignArtistId, settings.ApiKey, settings.FullUri);
@ -82,11 +112,12 @@ namespace Ombi.Core.Engine
/// <summary>
/// Returns the artist that produced the album
/// </summary>
/// <param name="albumId"></param>
/// <param name="foreignArtistId"></param>
/// <returns></returns>
public async Task GetAlbumArtist(string foreignArtistId)
public async Task<ArtistResult> GetAlbumArtist(string foreignArtistId)
{
throw new NotImplementedException();
var settings = await GetSettings();
return await _lidarrApi.GetArtistByForignId(foreignArtistId, settings.ApiKey, settings.FullUri);
}
public async Task<ArtistResult> GetArtist(int artistId)

@ -0,0 +1,21 @@
using Ombi.Api.Lidarr.Models;
namespace Ombi.Core.Models.Search
{
public class SearchArtistViewModel
{
public string ArtistName { get; set; }
public string ForignArtistId { get; set; }
public string Overview { get; set; }
public string Disambiguation { get; set; }
public string Banner { get; set; }
public string Poster { get; set; }
public string Logo { get; set; }
public bool Monitored { get; set; }
public bool Available { get; set; }
public bool Requested { get; set; }
public string ArtistType { get; set; }
public string CleanName { get; set; }
public Link[] Links { get; set; } // Couldn't be bothered to map it
}
}

@ -83,6 +83,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<IUserStatsEngine, UserStatsEngine>();
services.AddTransient<IMovieSender, MovieSender>();
services.AddTransient<IRecentlyAddedEngine, RecentlyAddedEngine>();
services.AddTransient<IMusicSearchEngine, MusicSearchEngine>();
services.AddTransient<ITvSender, TvSender>();
services.AddTransient<IMassEmailSender, MassEmailSender>();
services.AddTransient<IPlexOAuthManager, PlexOAuthManager>();

@ -83,7 +83,7 @@
<ng-template #notRequestedBtn>
<button id="{{result.id}}" style="text-align: right" class="btn btn-primary-outline" (click)="request(result)">
<i *ngIf="result.requestProcessing" class="fa fa-circle-o-notch fa-spin fa-fw"></i> <i *ngIf="!result.requestProcessing && !result.processed" class="fa fa-plus"></i>
<i *ngIf="result.processed && !result.requestProcessing" class="fa fa-check"></i>{{ 'Common.Request' | translate }}</button>
<i *ngIf="result.processed && !result.requestProcessing" class="fa fa-check"></i> {{ 'Common.Request' | translate }}</button>
</ng-template>
</div>
<button style="text-align: right" class="btn btn-sm btn-info-outline" (click)="similarMovies(result.id)"> <i class="fa fa-eye"></i> {{ 'Search.Similar' | translate }}</button>

@ -4,13 +4,13 @@ import { TranslateService } from "@ngx-translate/core";
import { Subject } from "rxjs";
import { debounceTime, distinctUntilChanged } from "rxjs/operators";
import { AuthService } from "../auth/auth.service";
import { IIssueCategory, IRequestEngineResult, ISearchMovieResult } from "../interfaces";
import { NotificationService, RequestService, SearchService } from "../services";
import { AuthService } from "../../auth/auth.service";
import { IIssueCategory, IRequestEngineResult, ISearchMovieResult } from "../../interfaces";
import { NotificationService, RequestService, SearchService } from "../../services";
@Component({
selector: "music-search",
templateUrl: "./music.component.html",
templateUrl: "./musicsearch.component.html",
})
export class MusicSearchComponent implements OnInit {
@ -19,6 +19,7 @@ export class MusicSearchComponent implements OnInit {
public movieResults: ISearchMovieResult[];
public result: IRequestEngineResult;
public searchApplied = false;
public searchArtist: boolean;
@Input() public issueCategories: IIssueCategory[];
@Input() public issuesEnabled: boolean;
@ -44,11 +45,20 @@ export class MusicSearchComponent implements OnInit {
this.clearResults();
return;
}
this.searchService.searchMusic(this.searchText)
if(this.searchArtist) {
this.searchService.searchArtist(this.searchText)
.subscribe(x => {
this.movieResults = x;
this.searchApplied = true;
});
} else {
this.searchService.searchAlbum(this.searchText)
.subscribe(x => {
this.movieResults = x;
this.searchApplied = true;
});
}
});
this.defaultPoster = "../../../images/default_movie_poster.png";
const base = this.platformLocation.getBaseHrefFromDOM();
@ -65,7 +75,6 @@ export class MusicSearchComponent implements OnInit {
result: false,
errorMessage: "",
};
this.popularMovies();
}
public search(text: any) {
@ -111,77 +120,6 @@ export class MusicSearchComponent implements OnInit {
}
}
public popularMovies() {
this.clearResults();
this.searchService.popularMovies()
.subscribe(x => {
this.movieResults = x;
});
}
public nowPlayingMovies() {
this.clearResults();
this.searchService.nowPlayingMovies()
.subscribe(x => {
this.movieResults = x;
});
}
public topRatedMovies() {
this.clearResults();
this.searchService.topRatedMovies()
.subscribe(x => {
this.movieResults = x;
});
}
public upcomingMovies() {
this.clearResults();
this.searchService.upcomingMovies()
.subscribe(x => {
this.movieResults = x;
});
}
public reportIssue(catId: IIssueCategory, req: ISearchMovieResult) {
this.issueRequestId = req.id;
this.issueRequestTitle = req.title + `(${req.releaseDate.getFullYear})`;
this.issueCategorySelected = catId;
this.issuesBarVisible = true;
this.issueProviderId = req.id.toString();
}
public similarMovies(theMovieDbId: number) {
this.clearResults();
this.searchService.similarMovies(theMovieDbId)
.subscribe(x => {
this.movieResults = x;
this.getExtraInfo();
});
}
public subscribe(r: ISearchMovieResult) {
r.subscribed = true;
this.requestService.subscribeToMovie(r.requestId)
.subscribe(x => {
this.notificationService.success("Subscribed To Movie!");
});
}
public unSubscribe(r: ISearchMovieResult) {
r.subscribed = false;
this.requestService.unSubscribeToMovie(r.requestId)
.subscribe(x => {
this.notificationService.success("Unsubscribed Movie!");
});
}
private updateItem(key: ISearchMovieResult, updated: ISearchMovieResult) {
const index = this.movieResults.indexOf(key, 0);
if (index > -1) {
const copy = { ...this.movieResults[index] };
this.movieResults[index] = updated;
this.movieResults[index].background = copy.background;
this.movieResults[index].posterPath = copy.posterPath;
}
}
private clearResults() {
this.movieResults = [];
this.searchApplied = false;

@ -13,6 +13,9 @@
<li role="presentation">
<a id="tvTabButton" href="#TvShowTab" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectTvTab()"><i class="fa fa-television"></i> {{ 'Search.TvTab' | translate }}</a>
</li>
<li role="presentation" *ngIf="musicEnabled">
<a id="tvTabButton" href="#MusicTab" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectMusicTab()"><i class="fa fa-music"></i> {{ 'Search.MusicTab' | translate }}</a>
</li>
</ul>
<!-- Tab panes -->
@ -25,6 +28,9 @@
<div [hidden]="!showTv">
<tv-search [issueCategories]="issueCategories" [issuesEnabled]="issuesEnabled"></tv-search>
</div>
<div [hidden]="!showMusic">
<music-search></music-search>
</div>
</div>

@ -9,8 +9,10 @@ import { IssuesService, SettingsService } from "../services";
export class SearchComponent implements OnInit {
public showTv: boolean;
public showMovie: boolean;
public showMusic: boolean;
public issueCategories: IIssueCategory[];
public issuesEnabled = false;
public musicEnabled: boolean;
constructor(private issuesService: IssuesService,
private settingsService: SettingsService) {
@ -18,8 +20,10 @@ export class SearchComponent implements OnInit {
}
public ngOnInit() {
this.settingsService.getLidarr().subscribe(x => this.musicEnabled = x.enabled);
this.showMovie = true;
this.showTv = false;
this.showMusic = false;
this.issuesService.getCategories().subscribe(x => this.issueCategories = x);
this.settingsService.getIssueSettings().subscribe(x => this.issuesEnabled = x.enabled);
}
@ -27,10 +31,17 @@ export class SearchComponent implements OnInit {
public selectMovieTab() {
this.showMovie = true;
this.showTv = false;
this.showMusic = false;
}
public selectTvTab() {
this.showMovie = false;
this.showTv = true;
this.showMusic = false;
}
public selectMusicTab() {
this.showMovie = false;
this.showTv = false;
this.showMusic = true;
}
}

@ -7,6 +7,7 @@ import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
import { MovieSearchComponent } from "./moviesearch.component";
import { MovieSearchGridComponent } from "./moviesearchgrid.component";
import { MusicSearchComponent } from "./music/musicsearch.component";
import { SearchComponent } from "./search.component";
import { SeriesInformationComponent } from "./seriesinformation.component";
import { TvSearchComponent } from "./tvsearch.component";
@ -41,6 +42,7 @@ const routes: Routes = [
TvSearchComponent,
SeriesInformationComponent,
MovieSearchGridComponent,
MusicSearchComponent,
],
exports: [
RouterModule,

@ -69,7 +69,10 @@ export class SearchService extends ServiceHelpers {
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/trending`, {headers: this.headers});
}
// Music
public searchMusic(searchTerm: string): Observable<ISearchMovieResult[]> {
return this.http.get<ISearchMovieResult[]>(`${this.url}/Music/` + searchTerm);
public searchArtist(searchTerm: string): Observable<any> {
return this.http.get<any>(`${this.url}/Music/Artist/` + searchTerm);
}
public searchAlbum(searchTerm: string): Observable<any> {
return this.http.get<any>(`${this.url}/Music/Album/` + searchTerm);
}
}

@ -3,8 +3,7 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { ILidarrSettings, IMinimumAvailability, IRadarrProfile, IRadarrRootFolder } from "../../interfaces";
import { IRadarrSettings } from "../../interfaces";
import { RadarrService } from "../../services";
import { TesterService } from "../../services";
import { LidarrService, TesterService } from "../../services";
import { NotificationService } from "../../services";
import { SettingsService } from "../../services";
@ -22,7 +21,7 @@ export class LidarrComponent implements OnInit {
public form: FormGroup;
constructor(private settingsService: SettingsService,
private radarrService: RadarrService,
private lidarrService: LidarrService,
private notificationService: NotificationService,
private fb: FormBuilder,
private testerService: TesterService) { }
@ -59,7 +58,7 @@ export class LidarrComponent implements OnInit {
public getProfiles(form: FormGroup) {
this.profilesRunning = true;
this.radarrService.getQualityProfiles(form.value).subscribe(x => {
this.lidarrService.getQualityProfiles(form.value).subscribe(x => {
this.qualities = x;
this.qualities.unshift({ name: "Please Select", id: -1 });
@ -70,7 +69,7 @@ export class LidarrComponent implements OnInit {
public getRootFolders(form: FormGroup) {
this.rootFoldersRunning = true;
this.radarrService.getRootFolders(form.value).subscribe(x => {
this.lidarrService.getRootFolders(form.value).subscribe(x => {
this.rootFolders = x;
this.rootFolders.unshift({ path: "Please Select", id: -1 });

@ -50,7 +50,7 @@
<li class="dropdown" [routerLinkActive]="['active']">
<a href="ignore($event)" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-film" aria-hidden="true"></i> Music <span class="caret"></span>
<i class="fa fa-music" aria-hidden="true"></i> Music <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Lidarr']">Lidarr</a></li>

@ -4,7 +4,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Ombi.Api.Lidarr.Models;
using Ombi.Core;
using Ombi.Core.Engine;
using Ombi.Core.Engine.Interfaces;
@ -18,16 +18,18 @@ namespace Ombi.Controllers
[Produces("application/json")]
public class SearchController : Controller
{
public SearchController(IMovieEngine movie, ITvSearchEngine tvEngine, ILogger<SearchController> logger)
public SearchController(IMovieEngine movie, ITvSearchEngine tvEngine, ILogger<SearchController> logger, IMusicSearchEngine music)
{
MovieEngine = movie;
TvEngine = tvEngine;
Logger = logger;
MusicEngine = music;
}
private ILogger<SearchController> Logger { get; }
private IMovieEngine MovieEngine { get; }
private ITvSearchEngine TvEngine { get; }
private IMusicSearchEngine MusicEngine { get; }
/// <summary>
/// Searches for a movie.
@ -182,5 +184,27 @@ namespace Ombi.Controllers
{
return await TvEngine.Trending();
}
/// <summary>
/// Returns the artist information we searched for
/// </summary>
/// <remarks>We use Lidarr as the Provider</remarks>
/// <returns></returns>
[HttpGet("music/artist/{searchTerm}")]
public async Task<IEnumerable<SearchArtistViewModel>> SearchArtist(string searchTerm)
{
return await MusicEngine.SearchArtist(searchTerm);
}
/// <summary>
/// Returns the album information we searched for
/// </summary>
/// <remarks>We use Lidarr as the Provider</remarks>
/// <returns></returns>
[HttpGet("music/album/{searchTerm}")]
public async Task<IEnumerable<AlbumLookup>> SearchAlbum(string searchTerm)
{
return await MusicEngine.SearchAlbum(searchTerm);
}
}
}

@ -333,7 +333,7 @@ namespace Ombi.Controllers
/// </summary>
/// <param name="settings">The settings.</param>
/// <returns></returns>
[HttpPost("sonarr")]
[HttpPost("lidarr")]
public async Task<bool> LidarrSettings([FromBody]LidarrSettings settings)
{
return await Save(settings);

@ -78,6 +78,7 @@
"Want to watch something that is not currently available? No problem, just search for it below and request it!",
"MoviesTab": "Movies",
"TvTab": "TV Shows",
"MusicTab":"Music",
"Suggestions": "Suggestions",
"NoResults": "Sorry, we didn't find any results!",
"DigitalDate": "Digital Release: {{date}}",

Loading…
Cancel
Save