mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-16 02:02:55 -07:00
fix(sonarr): 🐛 Sonarr V4 should work now (#4810)
* fix(sonarr): 🐛 Sonarr V4 should work now
Auto detect the sonarr version and adjust the UI depending on V3 or V4 (Lang profiles)
* fix: Fixed the load error
This commit is contained in:
parent
5ad6ea3d70
commit
37655aff9d
16 changed files with 219 additions and 59 deletions
|
@ -1,5 +1,5 @@
|
|||
import { APP_BASE_HREF, CommonModule, PlatformLocation } from "@angular/common";
|
||||
import { CustomPageService, ImageService, RequestService, SettingsService } from "./services";
|
||||
import { CustomPageService, ImageService, RequestService, SettingsService, SonarrService } from "./services";
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { HTTP_INTERCEPTORS, HttpClient, HttpClientModule } from "@angular/common/http";
|
||||
import { IdentityService, IssuesService, JobService, MessageService, PlexTvService, SearchService, StatusService } from "./services";
|
||||
|
@ -13,6 +13,7 @@ import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
|||
import { BrowserModule } from "@angular/platform-browser";
|
||||
import { ButtonModule } from "primeng/button";
|
||||
import { CUSTOMIZATION_INITIALIZER } from "./state/customization/customization-initializer";
|
||||
import { SONARR_INITIALIZER } from "./state/sonarr/sonarr-initializer";
|
||||
import { ConfirmDialogModule } from "primeng/confirmdialog";
|
||||
import { CookieComponent } from "./auth/cookie.component";
|
||||
import { CookieService } from "ng2-cookies";
|
||||
|
@ -22,6 +23,7 @@ import { DataViewModule } from "primeng/dataview";
|
|||
import { DialogModule } from "primeng/dialog";
|
||||
import { FEATURES_INITIALIZER } from "./state/features/features-initializer";
|
||||
import { FeatureState } from "./state/features";
|
||||
import { SonarrSettingsState } from "./state/sonarr";
|
||||
import { JwtModule } from "@auth0/angular-jwt";
|
||||
import { LandingPageComponent } from "./landingpage/landingpage.component";
|
||||
import { LandingPageService } from "./services";
|
||||
|
@ -161,7 +163,7 @@ export function JwtTokenGetter() {
|
|||
}),
|
||||
SidebarModule,
|
||||
MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, LayoutModule, MatSlideToggleModule,
|
||||
NgxsModule.forRoot([CustomizationState, FeatureState], {
|
||||
NgxsModule.forRoot([CustomizationState, FeatureState, SonarrSettingsState], {
|
||||
developmentMode: !environment.production,
|
||||
}),
|
||||
...environment.production ? [] :
|
||||
|
@ -205,8 +207,10 @@ export function JwtTokenGetter() {
|
|||
MessageService,
|
||||
StorageService,
|
||||
RequestService,
|
||||
SonarrService,
|
||||
SignalRNotificationService,
|
||||
FEATURES_INITIALIZER,
|
||||
SONARR_INITIALIZER,
|
||||
CUSTOMIZATION_INITIALIZER,
|
||||
{
|
||||
provide: APP_BASE_HREF,
|
||||
|
|
|
@ -13,6 +13,7 @@ import { StatusService } from "../services";
|
|||
import { StorageService } from "../shared/storage/storage-service";
|
||||
import { MatSnackBar } from "@angular/material/snack-bar";
|
||||
import { CustomizationFacade } from "../state/customization";
|
||||
import { SonarrFacade } from "app/state/sonarr";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./login.component.html",
|
||||
|
@ -60,6 +61,7 @@ export class LoginComponent implements OnDestroy, OnInit {
|
|||
private translate: TranslateService,
|
||||
private plexTv: PlexTvService,
|
||||
private store: StorageService,
|
||||
private sonarrFacade: SonarrFacade,
|
||||
private readonly notify: MatSnackBar
|
||||
) {
|
||||
this.href = href;
|
||||
|
@ -142,6 +144,7 @@ export class LoginComponent implements OnDestroy, OnInit {
|
|||
|
||||
if (this.authService.loggedIn()) {
|
||||
this.ngOnDestroy();
|
||||
this.sonarrFacade.load().subscribe();
|
||||
this.router.navigate(["/"]);
|
||||
} else {
|
||||
this.notify.open(this.errorBody, "OK", {
|
||||
|
@ -218,6 +221,7 @@ export class LoginComponent implements OnDestroy, OnInit {
|
|||
this.oAuthWindow.close();
|
||||
}
|
||||
this.oauthLoading = false;
|
||||
this.sonarrFacade.load().subscribe();
|
||||
this.router.navigate(["search"]);
|
||||
return;
|
||||
}
|
||||
|
@ -248,6 +252,7 @@ export class LoginComponent implements OnDestroy, OnInit {
|
|||
|
||||
if (this.authService.loggedIn()) {
|
||||
this.ngOnDestroy();
|
||||
this.sonarrFacade.load().subscribe();
|
||||
this.router.navigate(["/"]);
|
||||
} else {
|
||||
this.notify.open(this.errorBody, "OK", {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, ViewEncapsulation, OnInit } from "@angular/core";
|
||||
import { ImageService, SearchV2Service, MessageService, RequestService, SonarrService, SettingsStateService } from "../../../services";
|
||||
import { SearchV2Service, MessageService, RequestService, SonarrService, SettingsStateService } from "../../../services";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { DomSanitizer } from "@angular/platform-browser";
|
||||
import { ISearchTvResultV2 } from "../../../interfaces/ISearchTvResultV2";
|
||||
|
@ -11,9 +11,8 @@ import { AuthService } from "../../../auth/auth.service";
|
|||
import { NewIssueComponent } from "../shared/new-issue/new-issue.component";
|
||||
import { TvAdvancedOptionsComponent } from "./panels/tv-advanced-options/tv-advanced-options.component";
|
||||
import { RequestServiceV2 } from "../../../services/requestV2.service";
|
||||
import { RequestBehalfComponent } from "../shared/request-behalf/request-behalf.component";
|
||||
import { forkJoin } from "rxjs";
|
||||
import { TopBannerComponent } from "../shared/top-banner/top-banner.component";
|
||||
import { SonarrFacade } from "app/state/sonarr";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./tv-details.component.html",
|
||||
|
@ -36,10 +35,15 @@ export class TvDetailsComponent implements OnInit {
|
|||
private tvdbId: number;
|
||||
|
||||
constructor(private searchService: SearchV2Service, private route: ActivatedRoute,
|
||||
private sanitizer: DomSanitizer, private imageService: ImageService,
|
||||
public dialog: MatDialog, public messageService: MessageService, private requestService: RequestService,
|
||||
private sanitizer: DomSanitizer,
|
||||
public dialog: MatDialog,
|
||||
public messageService: MessageService,
|
||||
private requestService: RequestService,
|
||||
private requestService2: RequestServiceV2,
|
||||
private auth: AuthService, private sonarrService: SonarrService, private settingsState: SettingsStateService) {
|
||||
private auth: AuthService,
|
||||
private sonarrService: SonarrService,
|
||||
private sonarrFacade: SonarrFacade,
|
||||
private settingsState: SettingsStateService) {
|
||||
this.route.params.subscribe((params: any) => {
|
||||
this.tvdbId = params.tvdbId;
|
||||
this.fromSearch = params.search;
|
||||
|
@ -58,7 +62,7 @@ export class TvDetailsComponent implements OnInit {
|
|||
this.manageOwnRequests = this.auth.hasRole('ManageOwnRequests');
|
||||
|
||||
if (this.isAdmin) {
|
||||
this.showAdvanced = await this.sonarrService.isEnabled();
|
||||
this.showAdvanced = this.sonarrFacade.isEnabled();
|
||||
}
|
||||
|
||||
// if (this.fromSearch) {
|
||||
|
@ -138,6 +142,7 @@ export class TvDetailsComponent implements OnInit {
|
|||
this.tv.images.original = 'https://image.tmdb.org/t/p/w300/' + this.tv.images.original
|
||||
};
|
||||
}
|
||||
|
||||
private loadAdvancedInfo() {
|
||||
const profile = this.sonarrService.getQualityProfilesWithoutSettings();
|
||||
const folders = this.sonarrService.getRootFoldersWithoutSettings();
|
||||
|
|
|
@ -40,7 +40,11 @@ export class SonarrService extends ServiceHelpers {
|
|||
return this.http.post<ITag[]>(`${this.url}/tags/`, JSON.stringify(settings), {headers: this.headers});
|
||||
}
|
||||
|
||||
public isEnabled(): Promise<boolean> {
|
||||
return this.http.get<boolean>(`${this.url}/enabled/`, { headers: this.headers }).toPromise();
|
||||
public isEnabled(): Observable<boolean> {
|
||||
return this.http.get<boolean>(`${this.url}/enabled/`, { headers: this.headers });
|
||||
}
|
||||
|
||||
public getVersion(): Observable<string> {
|
||||
return this.http.get<string>(`${this.url}/version/`, { headers: this.headers });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@
|
|||
</div>
|
||||
</div></div>
|
||||
|
||||
<div class="form-group col-md-12" *ngIf="sonarrVersion === '3'">
|
||||
<div class="form-group col-md-12" *ngIf="sonarrVersion == '3'">
|
||||
<label for="select" class="control-label">Language Profiles
|
||||
<i *ngIf="form.get('languageProfile').hasError('required')" class="fas fa-exclamation-circle error-text" pTooltip="A Language Profile is required"></i>
|
||||
</label>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Component, OnInit } from "@angular/core";
|
||||
import { UntypedFormBuilder, FormControl, UntypedFormGroup, Validators } from "@angular/forms";
|
||||
import { SonarrFacade } from "app/state/sonarr/sonarr.facade";
|
||||
import { finalize, map } from "rxjs";
|
||||
|
||||
import { ILanguageProfiles, ISonarrProfile, ISonarrRootFolder, ITag } from "../../interfaces";
|
||||
|
@ -8,7 +9,6 @@ import { ISonarrSettings } from "../../interfaces";
|
|||
import { SonarrService } from "../../services";
|
||||
import { TesterService } from "../../services";
|
||||
import { NotificationService } from "../../services";
|
||||
import { SettingsService } from "../../services";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./sonarr.component.html",
|
||||
|
@ -22,7 +22,7 @@ export class SonarrComponent implements OnInit {
|
|||
public rootFoldersAnime: ISonarrRootFolder[];
|
||||
public languageProfiles: ILanguageProfiles[];
|
||||
public languageProfilesAnime: ILanguageProfiles[];
|
||||
|
||||
|
||||
public tags: ITag[];
|
||||
public animeTags: ITag[];
|
||||
|
||||
|
@ -38,11 +38,13 @@ export class SonarrComponent implements OnInit {
|
|||
public sonarrVersion: string;
|
||||
formErrors: any;
|
||||
|
||||
constructor(private settingsService: SettingsService,
|
||||
private sonarrService: SonarrService,
|
||||
public sonarrState$ = this.sonarrFacade.sonarrState$();
|
||||
|
||||
constructor(private sonarrService: SonarrService,
|
||||
private notificationService: NotificationService,
|
||||
private testerService: TesterService,
|
||||
private fb: UntypedFormBuilder){}
|
||||
private fb: UntypedFormBuilder,
|
||||
private sonarrFacade: SonarrFacade){}
|
||||
|
||||
onFormValuesChanged()
|
||||
{
|
||||
|
@ -64,27 +66,27 @@ export class SonarrComponent implements OnInit {
|
|||
}
|
||||
|
||||
public ngOnInit() {
|
||||
this.settingsService.getSonarr()
|
||||
.subscribe(x => {
|
||||
this.sonarrFacade.sonarrState$()
|
||||
.subscribe(({settings, version}) => {
|
||||
this.form = this.fb.group({
|
||||
enabled: [x.enabled],
|
||||
apiKey: [x.apiKey, [Validators.required]],
|
||||
qualityProfile: [x.qualityProfile, [Validators.required, validateProfile]],
|
||||
rootPath: [x.rootPath, [Validators.required, validateProfile]],
|
||||
qualityProfileAnime: [x.qualityProfileAnime],
|
||||
rootPathAnime: [x.rootPathAnime],
|
||||
ssl: [x.ssl],
|
||||
subDir: [x.subDir],
|
||||
ip: [x.ip, [Validators.required]],
|
||||
port: [x.port, [Validators.required]],
|
||||
addOnly: [x.addOnly],
|
||||
seasonFolders: [x.seasonFolders],
|
||||
languageProfile: [x.languageProfile],
|
||||
languageProfileAnime: [x.languageProfileAnime],
|
||||
scanForAvailability: [x.scanForAvailability],
|
||||
sendUserTags: [x.sendUserTags],
|
||||
tag: [x.tag],
|
||||
animeTag: [x.animeTag]
|
||||
enabled: [settings.enabled],
|
||||
apiKey: [settings.apiKey, [Validators.required]],
|
||||
qualityProfile: [settings.qualityProfile, [Validators.required, validateProfile]],
|
||||
rootPath: [settings.rootPath, [Validators.required, validateProfile]],
|
||||
qualityProfileAnime: [settings.qualityProfileAnime],
|
||||
rootPathAnime: [settings.rootPathAnime],
|
||||
ssl: [settings.ssl],
|
||||
subDir: [settings.subDir],
|
||||
ip: [settings.ip, [Validators.required]],
|
||||
port: [settings.port, [Validators.required]],
|
||||
addOnly: [settings.addOnly],
|
||||
seasonFolders: [settings.seasonFolders],
|
||||
languageProfile: [settings.languageProfile],
|
||||
languageProfileAnime: [settings.languageProfileAnime],
|
||||
scanForAvailability: [settings.scanForAvailability],
|
||||
sendUserTags: [settings.sendUserTags],
|
||||
tag: [settings.tag],
|
||||
animeTag: [settings.animeTag]
|
||||
});
|
||||
|
||||
this.rootFolders = [];
|
||||
|
@ -93,25 +95,20 @@ export class SonarrComponent implements OnInit {
|
|||
this.tags = [];
|
||||
this.animeTags = [];
|
||||
|
||||
if (x.enabled && this.form.valid) {
|
||||
this.testerService.sonarrTest(x).subscribe(result => {
|
||||
this.sonarrVersion = result.version[0];
|
||||
if (this.sonarrVersion === '3') {
|
||||
this.form.controls.languageProfile.addValidators([Validators.required, validateProfile]);
|
||||
}
|
||||
});
|
||||
if (version.length > 0) {
|
||||
this.sonarrVersion = version[0];
|
||||
}
|
||||
|
||||
if (x.qualityProfile) {
|
||||
if (settings.qualityProfile) {
|
||||
this.getProfiles(this.form);
|
||||
}
|
||||
if (x.rootPath) {
|
||||
if (settings.rootPath) {
|
||||
this.getRootFolders(this.form);
|
||||
}
|
||||
if (x.languageProfile) {
|
||||
if (settings.languageProfile) {
|
||||
this.getLanguageProfiles(this.form);
|
||||
}
|
||||
if (x.tag || x.animeTag) {
|
||||
if (settings.tag || settings.animeTag) {
|
||||
this.getTags(this.form);
|
||||
}
|
||||
|
||||
|
@ -226,7 +223,7 @@ export class SonarrComponent implements OnInit {
|
|||
form.controls.tag.setValue(null);
|
||||
}
|
||||
|
||||
this.settingsService.saveSonarr(form.value)
|
||||
this.sonarrFacade.updateSettings(form.value)
|
||||
.subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Successfully saved Sonarr settings");
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field appearance="outline" floatLabel=auto>
|
||||
<mat-form-field *ngIf="sonarrLanguageProfiles" appearance="outline" floatLabel=auto>
|
||||
<mat-label>{{'MediaDetails.LanguageProfileSelect' | translate }}</mat-label>
|
||||
<mat-select id="sonarrLanguageId" formControlName="sonarrLanguageId">
|
||||
<mat-option id="sonarrLanguageId{{profile.id}}" *ngFor="let profile of sonarrLanguageProfiles" value="{{profile.id}}">{{profile.name}}</mat-option>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms";
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
|
||||
import { SonarrFacade } from "app/state/sonarr";
|
||||
import { firstValueFrom, Observable } from "rxjs";
|
||||
import { startWith, map } from "rxjs/operators";
|
||||
import { ILanguageProfiles, IRadarrProfile, IRadarrRootFolder, ISonarrProfile, ISonarrRootFolder, ISonarrSettings, IUserDropdown, RequestType } from "../../interfaces";
|
||||
import { IdentityService, MessageService, RadarrService, RequestService, SettingsService, SonarrService } from "../../services";
|
||||
import { RequestServiceV2 } from "../../services/requestV2.service";
|
||||
import { ILanguageProfiles, IRadarrProfile, IRadarrRootFolder, ISonarrProfile, ISonarrRootFolder, IUserDropdown, RequestType } from "../../interfaces";
|
||||
import { IdentityService, RadarrService, SonarrService } from "../../services";
|
||||
|
||||
export interface IAdminRequestDialogData {
|
||||
type: RequestType,
|
||||
|
@ -23,9 +23,9 @@ export class AdminRequestDialogComponent implements OnInit {
|
|||
@Inject(MAT_DIALOG_DATA) public data: IAdminRequestDialogData,
|
||||
private identityService: IdentityService,
|
||||
private sonarrService: SonarrService,
|
||||
private settingsService: SettingsService,
|
||||
private radarrService: RadarrService,
|
||||
private fb: UntypedFormBuilder
|
||||
private fb: UntypedFormBuilder,
|
||||
private sonarrFacade: SonarrFacade
|
||||
) {}
|
||||
|
||||
public form: UntypedFormGroup;
|
||||
|
@ -63,11 +63,14 @@ export class AdminRequestDialogComponent implements OnInit {
|
|||
);
|
||||
|
||||
if (this.data.type === RequestType.tvShow) {
|
||||
this.sonarrEnabled = await this.sonarrService.isEnabled();
|
||||
this.sonarrEnabled = this.sonarrFacade.isEnabled();
|
||||
if (this.sonarrEnabled) {
|
||||
this.sonarrService.getV3LanguageProfilesWithoutSettings().subscribe((profiles: ILanguageProfiles[]) => {
|
||||
this.sonarrLanguageProfiles = profiles;
|
||||
})
|
||||
console.log(this.sonarrFacade.version());
|
||||
if (this.sonarrFacade.version()[0] === "3") {
|
||||
this.sonarrService.getV3LanguageProfilesWithoutSettings().subscribe((profiles: ILanguageProfiles[]) => {
|
||||
this.sonarrLanguageProfiles = profiles;
|
||||
})
|
||||
}
|
||||
this.sonarrService.getQualityProfilesWithoutSettings().subscribe(c => {
|
||||
this.sonarrProfiles = c;
|
||||
});
|
||||
|
|
4
src/Ombi/ClientApp/src/app/state/sonarr/index.ts
Normal file
4
src/Ombi/ClientApp/src/app/state/sonarr/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export * from './sonarr.state';
|
||||
export * from './sonarr.actions';
|
||||
export * from './sonarr.facade';
|
||||
export * from './sonarr.selectors';
|
|
@ -0,0 +1,12 @@
|
|||
import { APP_INITIALIZER } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { SonarrFacade } from "./sonarr.facade";
|
||||
|
||||
export const SONARR_INITIALIZER = {
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: (sonarrFacade: SonarrFacade) => (): Observable<unknown> => {
|
||||
return sonarrFacade.load();
|
||||
},
|
||||
multi: true,
|
||||
deps: [SonarrFacade],
|
||||
};
|
10
src/Ombi/ClientApp/src/app/state/sonarr/sonarr.actions.ts
Normal file
10
src/Ombi/ClientApp/src/app/state/sonarr/sonarr.actions.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { ISonarrSettings } from "../../interfaces";
|
||||
|
||||
export class LoadSettings {
|
||||
public static readonly type = '[Sonarr] LoadSettings';
|
||||
}
|
||||
|
||||
export class UpdateSettings {
|
||||
public static readonly type = '[Sonarr] UpdateSettings';
|
||||
constructor(public settings: ISonarrSettings) { }
|
||||
}
|
28
src/Ombi/ClientApp/src/app/state/sonarr/sonarr.facade.ts
Normal file
28
src/Ombi/ClientApp/src/app/state/sonarr/sonarr.facade.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import { ISonarrSettings } from "../../interfaces";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { Store } from "@ngxs/store";
|
||||
import { SonarrState } from "./types";
|
||||
import { SonarrSelectors } from "./sonarr.selectors";
|
||||
import { LoadSettings, UpdateSettings } from "./sonarr.actions";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class SonarrFacade {
|
||||
|
||||
public constructor(private store: Store) {}
|
||||
|
||||
public sonarrState$ = (): Observable<SonarrState> => this.store.select(SonarrSelectors.state);
|
||||
|
||||
public updateSettings = (settings: ISonarrSettings): Observable<unknown> => this.store.dispatch(new UpdateSettings(settings));
|
||||
|
||||
public load = (): Observable<unknown> => this.store.dispatch(new LoadSettings());
|
||||
|
||||
public version = (): string => this.store.selectSnapshot(SonarrSelectors.version);
|
||||
|
||||
public settings = (): ISonarrSettings => this.store.selectSnapshot(SonarrSelectors.settings);
|
||||
|
||||
public isEnabled = (): boolean => this.store.selectSnapshot(SonarrSelectors.isEnabled);
|
||||
|
||||
}
|
26
src/Ombi/ClientApp/src/app/state/sonarr/sonarr.selectors.ts
Normal file
26
src/Ombi/ClientApp/src/app/state/sonarr/sonarr.selectors.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { SonarrState, SONARR_STATE_TOKEN } from "./types";
|
||||
import { Selector } from "@ngxs/store";
|
||||
import { ISonarrSettings } from "../../interfaces";
|
||||
|
||||
export class SonarrSelectors {
|
||||
|
||||
@Selector([SONARR_STATE_TOKEN])
|
||||
public static state(state: SonarrState): SonarrState {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Selector([SonarrSelectors.state])
|
||||
public static version(state: SonarrState): string {
|
||||
return state.version;
|
||||
}
|
||||
|
||||
@Selector([SonarrSelectors.state])
|
||||
public static settings(state: SonarrState): ISonarrSettings {
|
||||
return state.settings;
|
||||
}
|
||||
|
||||
@Selector([SonarrSelectors.state])
|
||||
public static isEnabled(state: SonarrState): boolean {
|
||||
return state.settings?.enabled ?? false;
|
||||
}
|
||||
}
|
41
src/Ombi/ClientApp/src/app/state/sonarr/sonarr.state.ts
Normal file
41
src/Ombi/ClientApp/src/app/state/sonarr/sonarr.state.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { Action, State, StateContext } from "@ngxs/store";
|
||||
|
||||
import { SonarrState, SONARR_STATE_TOKEN } from "./types";
|
||||
import { SettingsService, SonarrService } from "../../services";
|
||||
import { AuthService } from "../../auth/auth.service";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { combineLatest, Observable, of } from "rxjs";
|
||||
import { map, tap } from "rxjs/operators";
|
||||
import { LoadSettings, UpdateSettings } from "./sonarr.actions";
|
||||
import { ISonarrSettings } from "../../interfaces";
|
||||
|
||||
@State({
|
||||
name: SONARR_STATE_TOKEN
|
||||
})
|
||||
@Injectable()
|
||||
export class SonarrSettingsState {
|
||||
constructor(private sonarrService: SonarrService, private settingsService: SettingsService, private authService: AuthService) { }
|
||||
|
||||
@Action(LoadSettings)
|
||||
public load({ setState }: StateContext<SonarrState>): Observable<SonarrState> {
|
||||
const isAdmin = this.authService.isAdmin();
|
||||
const calls = isAdmin ? [this.sonarrService.getVersion(), this.settingsService.getSonarr()] : [of(""), of({})];
|
||||
|
||||
return combineLatest(calls).pipe(
|
||||
tap(([version, settings]) =>
|
||||
{
|
||||
setState({settings: settings as ISonarrSettings, version: version as string});
|
||||
}),
|
||||
map((result) => <SonarrState>{settings: result[1], version: result[0]})
|
||||
);
|
||||
}
|
||||
|
||||
@Action(UpdateSettings)
|
||||
public enable(ctx: StateContext<SonarrState>, { settings }: UpdateSettings): Observable<SonarrState> {
|
||||
const state = ctx.getState();
|
||||
return this.settingsService.saveSonarr(settings).pipe(
|
||||
tap((_) => ctx.setState({...state, settings})),
|
||||
map(_ => <SonarrState>{...state, settings})
|
||||
);
|
||||
}
|
||||
}
|
9
src/Ombi/ClientApp/src/app/state/sonarr/types.ts
Normal file
9
src/Ombi/ClientApp/src/app/state/sonarr/types.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { ISonarrSettings } from "../../interfaces";
|
||||
import { StateToken } from "@ngxs/store";
|
||||
|
||||
export const SONARR_STATE_TOKEN = new StateToken<SonarrState>('SonarrState');
|
||||
|
||||
export interface SonarrState {
|
||||
settings: ISonarrSettings;
|
||||
version: string;
|
||||
}
|
|
@ -151,5 +151,17 @@ namespace Ombi.Controllers.V1.External
|
|||
return settings.Enabled;
|
||||
}
|
||||
|
||||
[HttpGet("version")]
|
||||
[PowerUser]
|
||||
public async Task<string> SonarrVersion()
|
||||
{
|
||||
var settings = await SonarrSettings.GetSettingsAsync();
|
||||
if (!settings.Enabled)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
var status = await SonarrV3Api.SystemStatus(settings.ApiKey, settings.FullUri);
|
||||
return status.version;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue