mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-16 02:02:55 -07:00
stuffffffffff including searchbar and new navbar !wip
This commit is contained in:
parent
c0a4b20152
commit
33cefe1a62
50 changed files with 397 additions and 196 deletions
11
src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs
Normal file
11
src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
|
||||
namespace Ombi.Core.Engine.V2
|
||||
{
|
||||
public interface IMultiSearchEngine
|
||||
{
|
||||
Task<List<MultiSearch>> MultiSearch(string searchTerm, string lang = "en");
|
||||
}
|
||||
}
|
35
src/Ombi.Core/Engine/V2/MultiSearchEngine.cs
Normal file
35
src/Ombi.Core/Engine/V2/MultiSearchEngine.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
|
||||
namespace Ombi.Core.Engine.V2
|
||||
{
|
||||
public class MultiSearchEngine : BaseMediaEngine, IMultiSearchEngine
|
||||
{
|
||||
public MultiSearchEngine(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules,
|
||||
OmbiUserManager um, ICacheService cache, ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub,
|
||||
IMovieDbApi movieDbApi)
|
||||
: base(identity, requestService, rules, um, cache, ombiSettings, sub)
|
||||
{
|
||||
_movieDbApi = movieDbApi;
|
||||
}
|
||||
|
||||
private readonly IMovieDbApi _movieDbApi;
|
||||
|
||||
|
||||
public async Task<List<MultiSearch>> MultiSearch(string searchTerm, string lang = "en")
|
||||
{
|
||||
return (await _movieDbApi.MultiSearch(searchTerm, lang)).results;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,6 +53,7 @@ using Ombi.Updater;
|
|||
using PlexContentCacher = Ombi.Schedule.Jobs.Plex;
|
||||
using Ombi.Api.Telegram;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine.V2;
|
||||
using Ombi.Core.Processor;
|
||||
using Ombi.Schedule.Jobs.Lidarr;
|
||||
using Ombi.Schedule.Jobs.Plex.Interfaces;
|
||||
|
@ -68,6 +69,7 @@ namespace Ombi.DependencyInjection
|
|||
public static void RegisterApplicationDependencies(this IServiceCollection services)
|
||||
{
|
||||
services.RegisterEngines();
|
||||
services.RegisterEnginesV2();
|
||||
services.RegisterApi();
|
||||
services.RegisterServices();
|
||||
services.RegisterStore();
|
||||
|
@ -93,6 +95,11 @@ namespace Ombi.DependencyInjection
|
|||
services.AddTransient<IPlexOAuthManager, PlexOAuthManager>();
|
||||
services.AddTransient<IVoteEngine, VoteEngine>();
|
||||
}
|
||||
|
||||
public static void RegisterEnginesV2(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<IMultiSearchEngine, MultiSearchEngine>();
|
||||
}
|
||||
public static void RegisterHttp(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
|
|
|
@ -21,5 +21,6 @@ namespace Ombi.Api.TheMovieDb
|
|||
Task<TvInfo> GetTVInfo(string themoviedbid);
|
||||
Task<TheMovieDbContainer<ActorResult>> SearchByActor(string searchTerm, string langCode);
|
||||
Task<ActorCredits> GetActorMovieCredits(int actorId, string langCode);
|
||||
Task<TheMovieDbContainer<MultiSearch>> MultiSearch(string searchTerm, string languageCode);
|
||||
}
|
||||
}
|
27
src/Ombi.TheMovieDbApi/Models/MultiSearch.cs
Normal file
27
src/Ombi.TheMovieDbApi/Models/MultiSearch.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
namespace Ombi.Api.TheMovieDb.Models
|
||||
{
|
||||
public class MultiSearch
|
||||
{
|
||||
public string original_name { get; set; }
|
||||
public int id { get; set; }
|
||||
public string media_type { get; set; }
|
||||
public string name { get; set; }
|
||||
public int vote_count { get; set; }
|
||||
public float vote_average { get; set; }
|
||||
public string poster_path { get; set; }
|
||||
public string first_air_date { get; set; }
|
||||
public float popularity { get; set; }
|
||||
public int?[] genre_ids { get; set; }
|
||||
public string original_language { get; set; }
|
||||
public string backdrop_path { get; set; }
|
||||
public string overview { get; set; }
|
||||
public string[] origin_country { get; set; }
|
||||
public bool video { get; set; }
|
||||
public string title { get; set; }
|
||||
public string original_title { get; set; }
|
||||
public bool adult { get; set; }
|
||||
public string release_date { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -171,6 +171,17 @@ namespace Ombi.Api.TheMovieDb
|
|||
|
||||
return await Api.Request<TvInfo>(request);
|
||||
}
|
||||
|
||||
public async Task<TheMovieDbContainer<MultiSearch>> MultiSearch(string searchTerm, string languageCode)
|
||||
{
|
||||
var request = new Request("search/multi", BaseUri, HttpMethod.Get);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("language", languageCode);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("query", searchTerm);
|
||||
var result = await Api.Request<TheMovieDbContainer<MultiSearch>>(request);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void AddRetry(Request request)
|
||||
{
|
||||
request.Retry = true;
|
||||
|
|
14
src/Ombi/Attributes/ApiV2Attribute.cs
Normal file
14
src/Ombi/Attributes/ApiV2Attribute.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
{
|
||||
[Route(ApiBase)]
|
||||
public class ApiV2Attribute : RouteAttribute
|
||||
{
|
||||
protected const string ApiBase = "api/v2/[controller]";
|
||||
|
||||
public ApiV2Attribute() : base(ApiBase)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -165,9 +165,7 @@
|
|||
</nav> -->
|
||||
|
||||
|
||||
<app-nav></app-nav>
|
||||
<app-my-nav [showNav]="showNav"></app-my-nav>
|
||||
|
||||
|
||||
<div [ngClass]="{'container top-spacing': showNav}" id="{{currentUrl}}">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</div>
|
|
@ -1,10 +0,0 @@
|
|||
@media (max-width: 978px) {
|
||||
.top-spacing {
|
||||
padding-top: 10%
|
||||
}
|
||||
}
|
||||
@media (min-width: 979px) {
|
||||
.top-spacing {
|
||||
padding-top: 5%
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ import { ButtonModule, CaptchaModule, ConfirmationService, ConfirmDialogModule,
|
|||
TooltipModule } from "primeng/primeng";
|
||||
|
||||
import {
|
||||
MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule} from '@angular/material';
|
||||
MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, MatAutocompleteModule} from '@angular/material';
|
||||
import { MatCardModule, MatInputModule, MatTabsModule } from "@angular/material";
|
||||
|
||||
import { MDBBootstrapModule, CardsFreeModule, NavbarModule } from "angular-bootstrap-md";
|
||||
|
@ -44,11 +44,13 @@ import { LandingPageService } from "./services";
|
|||
import { NotificationService } from "./services";
|
||||
import { SettingsService } from "./services";
|
||||
import { IssuesService, JobService, PlexTvService, StatusService, SearchService, IdentityService } from "./services";
|
||||
import { NavComponent } from "./nav/nav.component";
|
||||
import { MyNavComponent } from './my-nav/my-nav.component';
|
||||
import { LayoutModule } from '@angular/cdk/layout';
|
||||
import { SearchV2Service } from "./services/searchV2.service";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "*", component: PageNotFoundComponent },
|
||||
{ path: "", redirectTo: "/home", pathMatch: "full" },
|
||||
{ path: "", redirectTo: "/discover", pathMatch: "full" },
|
||||
{ path: "login", component: LoginComponent },
|
||||
{ path: "Login/OAuth/:pin", component: LoginOAuthComponent },
|
||||
{ path: "Custom", component: CustomPageComponent },
|
||||
|
@ -57,7 +59,7 @@ const routes: Routes = [
|
|||
{ path: "token", component: TokenResetPasswordComponent },
|
||||
{ path: "landingpage", component: LandingPageComponent },
|
||||
{ path: "auth/cookie", component: CookieComponent },
|
||||
{ loadChildren: "./discover/discover.module#DiscoverModule", path: "home" },
|
||||
{ loadChildren: "./discover/discover.module#DiscoverModule", path: "discover" },
|
||||
{ loadChildren: "./issues/issues.module#IssuesModule", path: "issues" },
|
||||
{ loadChildren: "./settings/settings.module#SettingsModule", path: "Settings" },
|
||||
{ loadChildren: "./wizard/wizard.module#WizardModule", path: "Wizard" },
|
||||
|
@ -107,6 +109,7 @@ export function JwtTokenGetter() {
|
|||
MatInputModule,
|
||||
MatTabsModule,
|
||||
ReactiveFormsModule,
|
||||
MatAutocompleteModule,
|
||||
CaptchaModule,
|
||||
TooltipModule,
|
||||
ConfirmDialogModule,
|
||||
|
@ -127,7 +130,7 @@ export function JwtTokenGetter() {
|
|||
},
|
||||
}),
|
||||
SidebarModule,
|
||||
MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule,
|
||||
MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, LayoutModule,
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
|
@ -139,7 +142,8 @@ export function JwtTokenGetter() {
|
|||
CustomPageComponent,
|
||||
CookieComponent,
|
||||
LoginOAuthComponent,
|
||||
NavComponent,
|
||||
MyNavComponent,
|
||||
|
||||
],
|
||||
providers: [
|
||||
NotificationService,
|
||||
|
@ -156,6 +160,7 @@ export function JwtTokenGetter() {
|
|||
IssuesService,
|
||||
PlexTvService,
|
||||
SearchService,
|
||||
SearchV2Service,
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
|
|
|
@ -22,7 +22,6 @@ export class DiscoverComponent implements OnInit {
|
|||
this.tvShows = await this.searchService.popularTv().toPromise();
|
||||
|
||||
this.movies.forEach(m => {
|
||||
debugger;
|
||||
this.discoverResults.push({
|
||||
available: m.available,
|
||||
posterPath: `https://image.tmdb.org/t/p/w300/${m.posterPath}`,
|
||||
|
|
|
@ -3,14 +3,13 @@ import { RouterModule, Routes } from "@angular/router";
|
|||
|
||||
import { SearchService } from "../services";
|
||||
|
||||
import { AuthGuard } from "../auth/auth.guard";
|
||||
|
||||
import { SharedModule } from "../shared/shared.module";
|
||||
import { DiscoverComponent } from "./discover.component";
|
||||
import { DiscoverCardComponent } from "./card/discover-card.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "", component: DiscoverComponent, canActivate: [AuthGuard] },
|
||||
{ path: "", component: DiscoverComponent },
|
||||
{ path: "discover", component: DiscoverComponent },
|
||||
];
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
|
|
@ -34,6 +34,28 @@
|
|||
background: any;
|
||||
}
|
||||
|
||||
export interface IMultiSearchResult {
|
||||
original_name: string;
|
||||
id: number;
|
||||
media_type: string;
|
||||
name: string;
|
||||
vote_count: number;
|
||||
vote_average: number;
|
||||
poster_path: string;
|
||||
first_air_date: string;
|
||||
popularity: number;
|
||||
genre_ids: number[];
|
||||
original_language: string;
|
||||
backdrop_path: string;
|
||||
overview: string;
|
||||
origin_country: string[];
|
||||
video: true;
|
||||
title: string;
|
||||
original_title: string;
|
||||
adult: true;
|
||||
release_date: string;
|
||||
}
|
||||
|
||||
export interface ILanguageRefine {
|
||||
code: string;
|
||||
name: string;
|
||||
|
|
52
src/Ombi/ClientApp/src/app/my-nav/my-nav.component.css
Normal file
52
src/Ombi/ClientApp/src/app/my-nav/my-nav.component.css
Normal file
|
@ -0,0 +1,52 @@
|
|||
.sidenav-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sidenav {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.sidenav .mat-toolbar {
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
.mat-toolbar.mat-primary {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
.spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
@media (max-width: 978px) {
|
||||
.top-spacing {
|
||||
padding-top: 10%
|
||||
}
|
||||
}
|
||||
@media (min-width: 979px) {
|
||||
.top-spacing {
|
||||
padding-top: 4%
|
||||
}
|
||||
}
|
||||
|
||||
.example-form {
|
||||
min-width: 150px;
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.quater-width {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.autocomplete-img {
|
||||
vertical-align: middle;
|
||||
height: 63px;
|
||||
}
|
||||
|
||||
.mat-option {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
padding: 0px 5px;
|
||||
}
|
39
src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html
Normal file
39
src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html
Normal file
|
@ -0,0 +1,39 @@
|
|||
<mat-sidenav-container class="sidenav-container">
|
||||
<mat-sidenav #drawer class="sidenav" fixedInViewport="true" [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
|
||||
[mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)">
|
||||
<mat-toolbar>Ombi</mat-toolbar>
|
||||
<mat-nav-list>
|
||||
<a mat-list-item [routerLinkActive]="['active']" routerLink="/discover">Discover</a>
|
||||
<a mat-list-item [routerLinkActive]="['active']" routerLink="/search">Search</a>
|
||||
<a mat-list-item [routerLinkActive]="['active']" routerLink="/requests">Requests</a>
|
||||
<a mat-list-item [routerLinkActive]="['active']" routerLink="/settings">Settings</a>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
<mat-sidenav-content>
|
||||
<mat-toolbar color="primary" class="sticky-header">
|
||||
<button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()" *ngIf="isHandset$ | async">
|
||||
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<span class="spacer"></span>
|
||||
<mat-form-field class="quater-width">
|
||||
<input [(ngModel)]="searchText" (keyup)="search($event)" matInput [matAutocomplete]="auto">
|
||||
<mat-autocomplete #auto="matAutocomplete">
|
||||
<mat-option *ngFor="let option of searchResult" [value]="option">
|
||||
<img src="https://image.tmdb.org/t/p/w300/{{option.poster_path}}" class="autocomplete-img" aria-hidden/>
|
||||
<span *ngIf="option.media_type == 'tv'">
|
||||
{{option.name}}
|
||||
</span>
|
||||
<span *ngIf="option.media_type == 'movie'">
|
||||
{{option.title}}
|
||||
</span>
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
</mat-toolbar>
|
||||
<!-- Add Content Here -->
|
||||
<div [ngClass]="{'container top-spacing': showNav}">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
42
src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts
Normal file
42
src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { map, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
||||
|
||||
import { SearchV2Service } from '../services/searchV2.service';
|
||||
import { IMultiSearchResult } from '../interfaces';
|
||||
|
||||
@Component({
|
||||
selector: 'app-my-nav',
|
||||
templateUrl: './my-nav.component.html',
|
||||
styleUrls: ['./my-nav.component.css']
|
||||
})
|
||||
export class MyNavComponent {
|
||||
|
||||
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
|
||||
.pipe(
|
||||
map(result => result.matches)
|
||||
);
|
||||
|
||||
@Input() public showNav: boolean;
|
||||
public searchChanged: Subject<string> = new Subject<string>();
|
||||
public searchText: string;
|
||||
public searchResult: IMultiSearchResult[];
|
||||
public option: IMultiSearchResult;
|
||||
|
||||
constructor(private breakpointObserver: BreakpointObserver,
|
||||
private searchService: SearchV2Service) {
|
||||
this.searchChanged.pipe(
|
||||
debounceTime(600), // Wait Xms after the last event before emitting last event
|
||||
distinctUntilChanged(), // only emit if value is different from previous value
|
||||
).subscribe(x => {
|
||||
this.searchText = x as string;
|
||||
this.searchService.multiSearch(this.searchText).subscribe(x => this.searchResult = x)
|
||||
});
|
||||
}
|
||||
|
||||
public search(text: any) {
|
||||
this.searchChanged.next(text.target.value);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<mat-sidenav-container class="sidenav-container">
|
||||
<mat-sidenav #drawer class="sidenav" fixedInViewport="true" [attr.role]="isHandset ? 'dialog' : 'navigation'"
|
||||
[mode]="(isHandset | async)!.matches ? 'over' : 'side'" [opened]="!(isHandset | async)!.matches">
|
||||
<mat-toolbar color="primary">Ombi</mat-toolbar>
|
||||
<mat-nav-list>
|
||||
<a mat-list-item routerLink="/">Discover</a>
|
||||
<a mat-list-item routerLink="/search">Search</a>
|
||||
<a mat-list-item routerLink="/settings">Settings</a>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
<mat-sidenav-content>
|
||||
<mat-toolbar color="primary">
|
||||
<button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()" *ngIf="(isHandset | async)!.matches">
|
||||
<mat-icon aria-label="Side nav toggle icon"></mat-icon>
|
||||
</button>
|
||||
|
||||
|
||||
<span class="example-fill-remaining-space"></span>
|
||||
|
||||
</mat-toolbar>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
|
@ -1,17 +0,0 @@
|
|||
.sidenav-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sidenav {
|
||||
width: 200px;
|
||||
box-shadow: 3px 0 6px rgba(0,0,0,.24);
|
||||
}
|
||||
.example-fill-remaining-space {
|
||||
/* This fills the remaining space, by using flexbox.
|
||||
Every toolbar row uses a flexbox row layout. */
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.right-spacing {
|
||||
margin-right:2%;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import { BreakpointObserver, Breakpoints, BreakpointState } from "@angular/cdk/layout";
|
||||
import { Component } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
@Component({
|
||||
selector: "app-nav",
|
||||
templateUrl: "./nav.component.html",
|
||||
styleUrls: ["./nav.component.scss"],
|
||||
})
|
||||
export class NavComponent {
|
||||
public isHandset: Observable<BreakpointState> = this.breakpointObserver.observe(Breakpoints.HandsetPortrait);
|
||||
|
||||
constructor(private breakpointObserver: BreakpointObserver) {
|
||||
// this.checkLogin();
|
||||
// this.authService.userLoggedIn.subscribe(x => {
|
||||
// this.checkLogin();
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,24 +1,6 @@
|
|||
<mdb-card>
|
||||
<!--Card image-->
|
||||
<mdb-card-img src="https://mdbootstrap.com/img/Photos/Lightbox/Thumbnail/img%20(97).jpg" alt="Card image cap"></mdb-card-img>
|
||||
<!--Card content-->
|
||||
<mdb-card-body>
|
||||
|
||||
|
||||
<!--Title-->
|
||||
<mdb-card-title>
|
||||
<h4>Card Title</h4>
|
||||
</mdb-card-title>
|
||||
|
||||
<!--Text-->
|
||||
<mdb-card-text> Some quick example text to build on the card title and make up the bulk of the card's
|
||||
content.
|
||||
</mdb-card-text>
|
||||
|
||||
<a href="#" mdbBtn color="primary" mdbWavesEffect>Button</a>
|
||||
</mdb-card-body>
|
||||
</mdb-card>
|
||||
|
||||
<!-- Movie tab
|
||||
<div role="tabpanel" class="tab-pane active" id="MoviesTab">
|
||||
|
||||
<div class="input-group search-bar-background">
|
||||
|
@ -199,4 +181,4 @@
|
|||
|
||||
|
||||
<issue-report [movie]="true" [visible]="issuesBarVisible" (visibleChange)="issuesBarVisible = $event;" [title]="issueRequestTitle"
|
||||
[issueCategory]="issueCategorySelected" [id]="issueRequestId" [providerId]="issueProviderId"></issue-report> -->
|
||||
[issueCategory]="issueCategorySelected" [id]="issueRequestId" [providerId]="issueProviderId"></issue-report>
|
19
src/Ombi/ClientApp/src/app/services/searchV2.service.ts
Normal file
19
src/Ombi/ClientApp/src/app/services/searchV2.service.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { PlatformLocation } from "@angular/common";
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { IMultiSearchResult } from "../interfaces";
|
||||
import { ServiceHelpers } from "./service.helpers";
|
||||
|
||||
@Injectable()
|
||||
export class SearchV2Service extends ServiceHelpers {
|
||||
constructor(http: HttpClient, public platformLocation: PlatformLocation) {
|
||||
super(http, "/api/v2/search", platformLocation);
|
||||
}
|
||||
|
||||
public multiSearch(searchTerm: string): Observable<IMultiSearchResult[]> {
|
||||
return this.http.get<IMultiSearchResult[]>(`${this.url}/multi/${searchTerm}`);
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ import { InputSwitchModule, SidebarModule } from "primeng/primeng";
|
|||
|
||||
import {
|
||||
MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, MatTooltipModule} from '@angular/material';
|
||||
import { MatCardModule, MatInputModule, MatTabsModule } from "@angular/material";
|
||||
import { MatCardModule, MatInputModule, MatTabsModule, MatAutocompleteModule } from "@angular/material";
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -25,6 +25,7 @@ import {
|
|||
TruncateModule,
|
||||
MomentModule,
|
||||
MatCardModule,
|
||||
MatAutocompleteModule,
|
||||
MatInputModule,
|
||||
MatTabsModule,
|
||||
MatButtonModule,
|
||||
|
@ -52,6 +53,7 @@ import {
|
|||
MatListModule,
|
||||
MatToolbarModule,
|
||||
MatTooltipModule,
|
||||
MatAutocompleteModule,
|
||||
],
|
||||
})
|
||||
export class SharedModule {}
|
||||
|
|
|
@ -5,7 +5,7 @@ using Ombi.Api.CouchPotato.Models;
|
|||
using Ombi.Attributes;
|
||||
using Ombi.Settings.Settings.Models.External;
|
||||
|
||||
namespace Ombi.Controllers.External
|
||||
namespace Ombi.Controllers.V1.External
|
||||
{
|
||||
[Admin]
|
||||
[ApiV1]
|
|
@ -4,14 +4,13 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Api.Emby;
|
||||
using Ombi.Api.Plex;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Models.External;
|
||||
|
||||
namespace Ombi.Controllers.External
|
||||
namespace Ombi.Controllers.V1.External
|
||||
{
|
||||
[Admin]
|
||||
[ApiV1]
|
|
@ -9,7 +9,7 @@ using Ombi.Core.Settings;
|
|||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models.External;
|
||||
|
||||
namespace Ombi.Controllers.External
|
||||
namespace Ombi.Controllers.V1.External
|
||||
{
|
||||
[PowerUser]
|
||||
[ApiV1]
|
|
@ -15,7 +15,7 @@ using Ombi.Helpers;
|
|||
using Ombi.Models;
|
||||
using Ombi.Models.External;
|
||||
|
||||
namespace Ombi.Controllers.External
|
||||
namespace Ombi.Controllers.V1.External
|
||||
{
|
||||
[Admin]
|
||||
[ApiV1]
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
@ -10,7 +9,7 @@ using Ombi.Core.Settings;
|
|||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models.External;
|
||||
|
||||
namespace Ombi.Controllers.External
|
||||
namespace Ombi.Controllers.V1.External
|
||||
{
|
||||
[Authorize]
|
||||
[ApiV1]
|
|
@ -7,10 +7,9 @@ using Ombi.Api.Sonarr.Models;
|
|||
using Ombi.Api.Sonarr.Models.V3;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Settings.Settings.Models.External;
|
||||
|
||||
namespace Ombi.Controllers.External
|
||||
namespace Ombi.Controllers.V1.External
|
||||
{
|
||||
[Authorize]
|
||||
[ApiV1]
|
|
@ -23,7 +23,7 @@ using Ombi.Schedule.Jobs.Ombi;
|
|||
using Ombi.Settings.Settings.Models.External;
|
||||
using Ombi.Settings.Settings.Models.Notifications;
|
||||
|
||||
namespace Ombi.Controllers.External
|
||||
namespace Ombi.Controllers.V1.External
|
||||
{
|
||||
/// <summary>
|
||||
/// The Tester Controller
|
|
@ -34,7 +34,7 @@ using Ombi.Store.Repository.Requests;
|
|||
using IdentityResult = Microsoft.AspNetCore.Identity.IdentityResult;
|
||||
using OmbiIdentityResult = Ombi.Models.Identity.IdentityResult;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
|
@ -1,18 +1,14 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Api.FanartTv;
|
||||
using Ombi.Store.Repository;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Api.FanartTv;
|
||||
using Ombi.Config;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Repository;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Produces("application/json")]
|
|
@ -1,24 +1,22 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Hangfire;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Core;
|
||||
using Ombi.Core.Notifications;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Models;
|
||||
using Ombi.Notifications.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using StackExchange.Profiling.Helpers;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Authorize]
|
|
@ -2,8 +2,6 @@
|
|||
using System.Threading.Tasks;
|
||||
using Hangfire;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Ombi.Api.Service;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Schedule.Jobs;
|
||||
|
@ -11,7 +9,7 @@ using Ombi.Schedule.Jobs.Emby;
|
|||
using Ombi.Schedule.Jobs.Ombi;
|
||||
using Ombi.Schedule.Jobs.Plex;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Admin]
|
|
@ -9,7 +9,7 @@ using Ombi.Core.Settings;
|
|||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Models;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[AllowAnonymous]
|
|
@ -1,10 +1,10 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Models;
|
||||
using System;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[Authorize]
|
||||
[ApiV1]
|
|
@ -12,7 +12,7 @@ using Ombi.Models;
|
|||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Authorize]
|
|
@ -1,20 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.UI;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[Authorize]
|
||||
[Route("api/v1/request/music")]
|
|
@ -31,7 +31,7 @@ using Ombi.Attributes;
|
|||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Senders;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[Admin]
|
||||
[ApiV1]
|
|
@ -1,13 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Api.Plex;
|
||||
using Ombi.Core.Authentication;
|
||||
|
@ -15,7 +11,7 @@ using Ombi.Core.Settings;
|
|||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Helpers;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
[ApiV1]
|
|
@ -1,13 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Models;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Produces("application/json")]
|
|
@ -1,24 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.UI;
|
||||
using Ombi.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[Authorize]
|
||||
[ApiV1]
|
|
@ -1,17 +1,15 @@
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Admin]
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Core;
|
||||
|
@ -9,9 +10,8 @@ using Ombi.Core.Engine.Interfaces;
|
|||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Models;
|
||||
using StackExchange.Profiling;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[Authorize]
|
||||
[ApiV1]
|
|
@ -12,7 +12,9 @@ using Microsoft.AspNetCore.Authorization;
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using NCrontab;
|
||||
using Ombi.Api.Emby;
|
||||
using Ombi.Api.Github;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Models.UI;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models;
|
||||
|
@ -25,10 +27,8 @@ using Ombi.Settings.Settings.Models.External;
|
|||
using Ombi.Settings.Settings.Models.Notifications;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
using Ombi.Api.Github;
|
||||
using Ombi.Core.Engine;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
|
@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||
using Ombi.Attributes;
|
||||
using Ombi.Core.Engine;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Admin]
|
|
@ -33,7 +33,7 @@ using Ombi.Core.Settings;
|
|||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Produces("application/json")]
|
|
@ -2,11 +2,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
@ -18,7 +16,7 @@ using Ombi.Models.Identity;
|
|||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Produces("application/json")]
|
|
@ -1,12 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Core.Processor;
|
||||
using Ombi.Helpers;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Produces("application/json")]
|
|
@ -1,14 +1,14 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Models.UI;
|
||||
using Ombi.Store.Entities;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
[ApiV1]
|
||||
[Authorize]
|
32
src/Ombi/Controllers/V2/SearchController.cs
Normal file
32
src/Ombi/Controllers/V2/SearchController.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Core.Engine.V2;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Controllers.V2
|
||||
{
|
||||
[ApiV2]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class SearchController : ControllerBase
|
||||
{
|
||||
public SearchController(IMultiSearchEngine multiSearchEngine)
|
||||
{
|
||||
_multiSearchEngine = multiSearchEngine;
|
||||
}
|
||||
|
||||
private readonly IMultiSearchEngine _multiSearchEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Runs the update job
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("multi/{searchTerm}")]
|
||||
public async Task<List<MultiSearch>> ForceUpdate(string searchTerm)
|
||||
{
|
||||
return await _multiSearchEngine.MultiSearch(searchTerm);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue