From acc886293dec5a746d2bd5f0bc7a033ef3176b2d Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 26 Apr 2021 08:43:03 +0100 Subject: [PATCH 01/66] Update variables.yml --- .azuredevops/pipelines/templates/variables.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azuredevops/pipelines/templates/variables.yml b/.azuredevops/pipelines/templates/variables.yml index 205e68eaa..e90ecc049 100644 --- a/.azuredevops/pipelines/templates/variables.yml +++ b/.azuredevops/pipelines/templates/variables.yml @@ -27,4 +27,4 @@ variables: value: "4.0.$(Build.BuildId)" - name: isMain - value: $[or(eq(variables['Build.SourceBranch'], 'refs/heads/develop'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))] \ No newline at end of file + value: $[or(eq(variables['Build.SourceBranch'], 'refs/heads/develop'), eq(variables['Build.SourceBranch'], 'refs/heads/master'))] From 69923db39fb9791a0729fce6edb8eef5241f855b Mon Sep 17 00:00:00 2001 From: sirmarv <3598205+sir-marv@users.noreply.github.com> Date: Tue, 27 Apr 2021 07:50:57 -0400 Subject: [PATCH 02/66] Update WebhookApi.cs Fixes #2448. Forward slash is no longer appended to the URL. If a user wants a / at the end of the URL, they will have to enter it in the webhook baseUrl. --- src/Ombi.Api.Webhook/WebhookApi.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Api.Webhook/WebhookApi.cs b/src/Ombi.Api.Webhook/WebhookApi.cs index 8b6b35ca0..f2faaa18b 100644 --- a/src/Ombi.Api.Webhook/WebhookApi.cs +++ b/src/Ombi.Api.Webhook/WebhookApi.cs @@ -19,7 +19,7 @@ namespace Ombi.Api.Webhook public async Task PushAsync(string baseUrl, string accessToken, IDictionary parameters) { - var request = new Request("/", baseUrl, HttpMethod.Post); + var request = new Request("", baseUrl, HttpMethod.Post); if (!string.IsNullOrWhiteSpace(accessToken)) { From a578374588b4ca9df4eadf4c424e9d3d76c06874 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 27 Apr 2021 20:43:08 +0100 Subject: [PATCH 03/66] TV results now respect the users set language --- src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs index 9d97285df..e02ae1c51 100644 --- a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs @@ -50,13 +50,14 @@ namespace Ombi.Core.Engine.V2 public async Task GetShowByRequest(int requestId, CancellationToken token) { var request = await RequestService.TvRequestService.Get().FirstOrDefaultAsync(x => x.Id == requestId); - return await GetShowInformation(request.ExternalProviderId.ToString(), token); // TODO + return await GetShowInformation(request.ExternalProviderId.ToString(), token); } public async Task GetShowInformation(string tvdbid, CancellationToken token) { - var show = await Cache.GetOrAdd(nameof(GetShowInformation) + tvdbid, - async () => await _movieApi.GetTVInfo(tvdbid), DateTime.Now.AddHours(12)); + var langCode = await DefaultLanguageCode(null); + var show = await Cache.GetOrAdd(nameof(GetShowInformation) + langCode + tvdbid, + async () => await _movieApi.GetTVInfo(tvdbid, langCode), DateTime.Now.AddHours(12)); if (show == null || show.name == null) { // We don't have enough information From 264568f3969c7fb3bd85ba3205938eeb6c54cf5e Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 27 Apr 2021 22:17:01 +0100 Subject: [PATCH 04/66] Added the ability to re-process requests --- .../Engine/Interfaces/IRequestEngine.cs | 2 ++ src/Ombi.Core/Engine/MovieRequestEngine.cs | 21 ++++++++++++++++++ src/Ombi.Core/Engine/TvRequestEngine.cs | 22 +++++++++++++++++++ src/Ombi.Store/Repository/BaseRepository.cs | 6 +++++ src/Ombi.Store/Repository/IRepository.cs | 2 ++ .../movie/movie-details.component.html | 1 + .../movie/movie-details.component.ts | 10 +++++++++ .../social-icons/social-icons.component.html | 4 ++++ .../social-icons/social-icons.component.ts | 5 +++++ .../tv-requests-panel.component.html | 1 + .../tv-requests-panel.component.ts | 19 +++++++++++++--- .../src/app/services/request.service.ts | 1 - .../src/app/services/requestV2.service.ts | 6 ++++- src/Ombi/Controllers/V2/RequestsController.cs | 18 +++++++++++++++ src/Ombi/wwwroot/translations/en.json | 3 ++- 15 files changed, 115 insertions(+), 6 deletions(-) diff --git a/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs b/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs index c8b7746f0..f4eeb6fc3 100644 --- a/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Ombi.Core.Models; using Ombi.Core.Models.Requests; @@ -24,5 +25,6 @@ namespace Ombi.Core.Engine.Interfaces Task UnSubscribeRequest(int requestId, RequestType type); Task SubscribeToRequest(int requestId, RequestType type); Task GetRemainingRequests(OmbiUser user = null); + Task ReProcessRequest(int requestId, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index 00a97f766..8d54f0fc3 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -21,6 +21,7 @@ using Ombi.Settings.Settings.Models; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; using Ombi.Core.Models; +using System.Threading; namespace Ombi.Core.Engine { @@ -555,6 +556,11 @@ namespace Ombi.Core.Engine await NotificationHelper.Notify(request, NotificationType.RequestApproved); } + return await ProcessSendingMovie(request); + } + + private async Task ProcessSendingMovie(MovieRequests request) + { if (request.Approved) { var result = await Sender.Send(request); @@ -634,6 +640,21 @@ namespace Ombi.Core.Engine return await MovieRepository.GetAll().AnyAsync(x => x.RequestedUserId == userId); } + public async Task ReProcessRequest(int requestId, CancellationToken cancellationToken) + { + var request = await MovieRepository.Find(requestId); + if (request == null) + { + return new RequestEngineResult + { + Result = false, + ErrorMessage = "Request does not exist" + }; + } + + return await ProcessSendingMovie(request); + } + public async Task MarkUnavailable(int modelId) { var request = await MovieRepository.Find(modelId); diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index e332dde75..5eae0912c 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -25,6 +25,7 @@ using Ombi.Settings.Settings.Models; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; using Ombi.Core.Models; +using System.Threading; namespace Ombi.Core.Engine { @@ -896,6 +897,22 @@ namespace Ombi.Core.Engine } + public async Task ReProcessRequest(int requestId, CancellationToken cancellationToken) + { + var request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == requestId, cancellationToken); + if (request == null) + { + return new RequestEngineResult + { + Result = false, + ErrorMessage = "Request does not exist" + }; + } + + return await ProcessSendingShow(request); + } + + private async Task AfterRequest(ChildRequests model, string requestOnBehalf) { var sendRuleResult = await RunSpecificRule(model, SpecificRules.CanSendNotification); @@ -913,6 +930,11 @@ namespace Ombi.Core.Engine EpisodeCount = model.SeasonRequests.Select(m => m.Episodes.Count).Sum(), }); + return await ProcessSendingShow(model); + } + + private async Task ProcessSendingShow(ChildRequests model) + { if (model.Approved) { // Autosend diff --git a/src/Ombi.Store/Repository/BaseRepository.cs b/src/Ombi.Store/Repository/BaseRepository.cs index 2908309ce..9d7d91447 100644 --- a/src/Ombi.Store/Repository/BaseRepository.cs +++ b/src/Ombi.Store/Repository/BaseRepository.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; @@ -28,6 +29,11 @@ namespace Ombi.Store.Repository return await _db.FindAsync(key); } + public async Task Find(object key, CancellationToken cancellationToken) + { + return await _db.FindAsync(new[] { key }, cancellationToken: cancellationToken); + } + public IQueryable GetAll() { return _db.AsQueryable(); diff --git a/src/Ombi.Store/Repository/IRepository.cs b/src/Ombi.Store/Repository/IRepository.cs index fd7dcc86d..b93b07d45 100644 --- a/src/Ombi.Store/Repository/IRepository.cs +++ b/src/Ombi.Store/Repository/IRepository.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; @@ -12,6 +13,7 @@ namespace Ombi.Store.Repository public interface IRepository where T : Entity { Task Find(object key); + Task Find(object key, CancellationToken cancellationToken); IQueryable GetAll(); Task FirstOrDefaultAsync(Expression> predicate); Task AddRange(IEnumerable content, bool save = true); diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html index 928645f47..c0434980d 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html @@ -24,6 +24,7 @@ [type]="requestType" (openTrailer)="openDialog()" (onAdvancedOptions)="openAdvancedOptions()" + (onReProcessRequest)="reProcessRequest()" > diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts index 3911d64ce..01c8a5783 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts @@ -190,6 +190,16 @@ export class MovieDetailsComponent { }); } + public reProcessRequest() { + this.requestService2.reprocessRequest(this.movieRequest.id, RequestType.movie).subscribe(result => { + if (result.result) { + this.messageService.send(result.message ? result.message : "Successfully Re-processed the request", "Ok"); + } else { + this.messageService.send(result.errorMessage, "Ok"); + } + }); + } + private loadBanner() { this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => { if (!this.movie.backdropPath) { diff --git a/src/Ombi/ClientApp/src/app/media-details/components/shared/social-icons/social-icons.component.html b/src/Ombi/ClientApp/src/app/media-details/components/shared/social-icons/social-icons.component.html index 60cad7bb0..f05792aa9 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/shared/social-icons/social-icons.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/shared/social-icons/social-icons.component.html @@ -35,5 +35,9 @@ {{ 'MediaDetails.RadarrConfiguration' | translate}} {{ 'MediaDetails.SonarrConfiguration' | translate}} + diff --git a/src/Ombi/ClientApp/src/app/media-details/components/shared/social-icons/social-icons.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/shared/social-icons/social-icons.component.ts index 3a27fa723..bc504347b 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/shared/social-icons/social-icons.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/shared/social-icons/social-icons.component.ts @@ -26,6 +26,7 @@ export class SocialIconsComponent { @Output() openTrailer: EventEmitter = new EventEmitter(); @Output() onAdvancedOptions: EventEmitter = new EventEmitter(); + @Output() onReProcessRequest: EventEmitter = new EventEmitter(); public RequestType = RequestType; @@ -37,4 +38,8 @@ export class SocialIconsComponent { public openAdvancedOptions() { this.onAdvancedOptions.emit(); } + + public reProcessRequest() { + this.onReProcessRequest.emit(); + } } diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.html b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.html index 5db522024..8bca28fb5 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.html @@ -70,6 +70,7 @@ + diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts index c7b0711b6..e51414902 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts @@ -4,6 +4,7 @@ import { RequestService } from "../../../../../services/request.service"; import { MessageService } from "../../../../../services"; import { MatDialog } from "@angular/material/dialog"; import { DenyDialogComponent } from "../../../shared/deny-dialog/deny-dialog.component"; +import { RequestServiceV2 } from "../../../../../services/requestV2.service"; @Component({ templateUrl: "./tv-requests-panel.component.html", @@ -16,7 +17,9 @@ export class TvRequestsPanelComponent { public displayedColumns: string[] = ['number', 'title', 'airDate', 'status']; - constructor(private requestService: RequestService, private messageService: MessageService, + constructor(private requestService: RequestService, + private requestService2: RequestServiceV2, + private messageService: MessageService, public dialog: MatDialog) { } @@ -83,9 +86,9 @@ export class TvRequestsPanelComponent { width: '250px', data: {requestId: request.id, requestType: RequestType.tvShow} }); - + dialogRef.afterClosed().subscribe(result => { - request.denied = true; + request.denied = true; request.seasonRequests.forEach((season) => { season.episodes.forEach((ep) => { ep.approved = false; @@ -93,4 +96,14 @@ export class TvRequestsPanelComponent { }); }); } + + public reProcessRequest(request: IChildRequests) { + this.requestService2.reprocessRequest(request.id, RequestType.tvShow).subscribe(result => { + if (result.result) { + this.messageService.send(result.message ? result.message : "Successfully Re-processed the request", "Ok"); + } else { + this.messageService.send(result.errorMessage, "Ok"); + } + }); + } } diff --git a/src/Ombi/ClientApp/src/app/services/request.service.ts b/src/Ombi/ClientApp/src/app/services/request.service.ts index 19a211f93..3fe60e5f3 100644 --- a/src/Ombi/ClientApp/src/app/services/request.service.ts +++ b/src/Ombi/ClientApp/src/app/services/request.service.ts @@ -187,5 +187,4 @@ export class RequestService extends ServiceHelpers { public removeAlbumRequest(request: number): any { return this.http.delete(`${this.url}music/${request}`, {headers: this.headers}); } - } diff --git a/src/Ombi/ClientApp/src/app/services/requestV2.service.ts b/src/Ombi/ClientApp/src/app/services/requestV2.service.ts index c6e155096..a7ebd6d0c 100644 --- a/src/Ombi/ClientApp/src/app/services/requestV2.service.ts +++ b/src/Ombi/ClientApp/src/app/services/requestV2.service.ts @@ -4,7 +4,7 @@ import { Injectable, Inject } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { Observable } from "rxjs"; import { ServiceHelpers } from "./service.helpers"; -import { IRequestsViewModel, IMovieRequests, IChildRequests, IMovieAdvancedOptions as IMediaAdvancedOptions, IRequestEngineResult, IAlbumRequest, ITvRequestViewModelV2 } from "../interfaces"; +import { IRequestsViewModel, IMovieRequests, IChildRequests, IMovieAdvancedOptions as IMediaAdvancedOptions, IRequestEngineResult, IAlbumRequest, ITvRequestViewModelV2, RequestType } from "../interfaces"; @Injectable() @@ -92,4 +92,8 @@ export class RequestServiceV2 extends ServiceHelpers { public requestTv(tv: ITvRequestViewModelV2): Observable { return this.http.post(`${this.url}TV/`, JSON.stringify(tv), {headers: this.headers}); } + + public reprocessRequest(requestId: number, type: RequestType): Observable { + return this.http.post(`${this.url}reprocess/${type}/${requestId}`, undefined, { headers: this.headers }); + } } diff --git a/src/Ombi/Controllers/V2/RequestsController.cs b/src/Ombi/Controllers/V2/RequestsController.cs index 0bbbd4128..67d206e0b 100644 --- a/src/Ombi/Controllers/V2/RequestsController.cs +++ b/src/Ombi/Controllers/V2/RequestsController.cs @@ -11,6 +11,7 @@ using System; using Ombi.Store.Entities; using System.Linq; using Microsoft.Extensions.Logging; +using Ombi.Attributes; namespace Ombi.Controllers.V2 { @@ -134,12 +135,14 @@ namespace Ombi.Controllers.V2 return await _tvRequestEngine.GetUnavailableRequests(count, position, sort, sortOrder); } + [PowerUser] [HttpPost("movie/advancedoptions")] public async Task UpdateAdvancedOptions([FromBody] MediaAdvancedOptions options) { return await _movieRequestEngine.UpdateAdvancedOptions(options); } + [PowerUser] [HttpPost("tv/advancedoptions")] public async Task UpdateTvAdvancedOptions([FromBody] MediaAdvancedOptions options) { @@ -198,6 +201,21 @@ namespace Ombi.Controllers.V2 return result; } + [PowerUser] + [HttpPost("reprocess/{type}/{requestId}")] + public async Task ReProcessRequest(RequestType type, int requestId) + { + switch (type) + { + case RequestType.TvShow: + return Ok(await _tvRequestEngine.ReProcessRequest(requestId, HttpContext.RequestAborted)); + case RequestType.Movie: + return Ok(await _movieRequestEngine.ReProcessRequest(requestId, HttpContext.RequestAborted)); + } + + return BadRequest(); + } + private string GetApiAlias() { // Make sure this only applies when using the API KEY diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json index eab1b18d0..18e864bdd 100644 --- a/src/Ombi/wwwroot/translations/en.json +++ b/src/Ombi/wwwroot/translations/en.json @@ -288,7 +288,8 @@ "RadarrConfiguration": "Radarr Configuration", "RequestOnBehalf": "Request on behalf of", "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On" + "StreamingOn": "Streaming On", + "ReProcessRequest": "Re-Process Request" }, "Discovery": { "PopularTab": "Popular", From 0ad573a98a98f39d05434d28368937037045dd58 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Fri, 30 Apr 2021 20:40:42 +0100 Subject: [PATCH 05/66] Fixed the issue where searching some movies may appear available if they have the same TvDb Id as the result's MovieDbId... --- .../Rule/Rules/Search/PlexAvailabilityRule.cs | 8 +++---- src/Ombi.Helpers.Tests/PlexHelperTests.cs | 1 + .../Jobs/Plex/PlexAvailabilityChecker.cs | 4 ++-- .../Repository/IPlexContentRepository.cs | 3 ++- .../Repository/PlexContentRepository.cs | 22 +++++++++++-------- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs index d0397cc15..7b757802d 100644 --- a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs @@ -29,7 +29,7 @@ namespace Ombi.Core.Rule.Rules.Search var useTvDb = false; if (obj.ImdbId.HasValue()) { - item = await PlexContentRepository.Get(obj.ImdbId); + item = await PlexContentRepository.Get(obj.ImdbId, ProviderType.ImdbId); if (item != null) { useImdb = true; @@ -39,7 +39,7 @@ namespace Ombi.Core.Rule.Rules.Search { if (obj.Id > 0) { - item = await PlexContentRepository.Get(obj.Id.ToString()); + item = await PlexContentRepository.Get(obj.Id.ToString(), ProviderType.TheMovieDbId); if (item != null) { useId = true; @@ -47,7 +47,7 @@ namespace Ombi.Core.Rule.Rules.Search } if (obj.TheMovieDbId.HasValue()) { - item = await PlexContentRepository.Get(obj.TheMovieDbId); + item = await PlexContentRepository.Get(obj.TheMovieDbId, ProviderType.TheMovieDbId); if (item != null) { useTheMovieDb = true; @@ -58,7 +58,7 @@ namespace Ombi.Core.Rule.Rules.Search { if (obj.TheTvDbId.HasValue()) { - item = await PlexContentRepository.Get(obj.TheTvDbId); + item = await PlexContentRepository.Get(obj.TheTvDbId, ProviderType.TvDbId); if (item != null) { useTvDb = true; diff --git a/src/Ombi.Helpers.Tests/PlexHelperTests.cs b/src/Ombi.Helpers.Tests/PlexHelperTests.cs index 82b59fdf7..e7d35a583 100644 --- a/src/Ombi.Helpers.Tests/PlexHelperTests.cs +++ b/src/Ombi.Helpers.Tests/PlexHelperTests.cs @@ -61,6 +61,7 @@ namespace Ombi.Helpers.Tests get { yield return new TestCaseData("plex://movie/5e1632df2d4d84003e48e54e|imdb://tt9178402|tmdb://610201", new ProviderId { ImdbId = "tt9178402", TheMovieDb = "610201" }).SetName("V2 Regular Plex Id"); + yield return new TestCaseData("plex://movie/5e1632df2d4d84003e48e54e|imdb://tt9178402|tmdb://610201|thetvdb://12345", new ProviderId { ImdbId = "tt9178402", TheMovieDb = "610201", TheTvDb = "12345" }).SetName("V2 Regular Plex Id w/ tvdb"); yield return new TestCaseData("plex://movie/5d7768253c3c2a001fbcab72|imdb://tt0119567|tmdb://330", new ProviderId { ImdbId = "tt0119567", TheMovieDb = "330" }).SetName("V2 Regular Plex Id Another"); yield return new TestCaseData("plex://movie/5d7768253c3c2a001fbcab72|imdb://tt0119567", new ProviderId { ImdbId = "tt0119567" }).SetName("V2 Regular Plex Id Single Imdb"); yield return new TestCaseData("plex://movie/5d7768253c3c2a001fbcab72|tmdb://330", new ProviderId { TheMovieDb = "330" }).SetName("V2 Regular Plex Id Single Tmdb"); diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs index d1d26d6e1..f203f297a 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs @@ -183,13 +183,13 @@ namespace Ombi.Schedule.Jobs.Plex PlexServerContent item = null; if (movie.ImdbId.HasValue()) { - item = await _repo.Get(movie.ImdbId); + item = await _repo.Get(movie.ImdbId, ProviderType.ImdbId); } if (item == null) { if (movie.TheMovieDbId.ToString().HasValue()) { - item = await _repo.Get(movie.TheMovieDbId.ToString()); + item = await _repo.Get(movie.TheMovieDbId.ToString(), ProviderType.TheMovieDbId); } } if (item == null) diff --git a/src/Ombi.Store/Repository/IPlexContentRepository.cs b/src/Ombi.Store/Repository/IPlexContentRepository.cs index 7bce2e75a..d1d30a630 100644 --- a/src/Ombi.Store/Repository/IPlexContentRepository.cs +++ b/src/Ombi.Store/Repository/IPlexContentRepository.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; +using Ombi.Helpers; using Ombi.Store.Entities; namespace Ombi.Store.Repository @@ -10,7 +11,7 @@ namespace Ombi.Store.Repository public interface IPlexContentRepository : IExternalRepository { Task ContentExists(string providerId); - Task Get(string providerId); + Task Get(string providerId, ProviderType type); Task GetByKey(int key); Task Update(PlexServerContent existingContent); IQueryable GetAllEpisodes(); diff --git a/src/Ombi.Store/Repository/PlexContentRepository.cs b/src/Ombi.Store/Repository/PlexContentRepository.cs index 1d53874a1..e5c31172e 100644 --- a/src/Ombi.Store/Repository/PlexContentRepository.cs +++ b/src/Ombi.Store/Repository/PlexContentRepository.cs @@ -31,6 +31,7 @@ using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Ombi.Helpers; using Ombi.Store.Context; using Ombi.Store.Entities; @@ -61,18 +62,21 @@ namespace Ombi.Store.Repository return any; } - public async Task Get(string providerId) + public async Task Get(string providerId, ProviderType type) { - var item = await Db.PlexServerContent.FirstOrDefaultAsync(x => x.ImdbId == providerId); - if (item == null) + switch (type) { - item = await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TheMovieDbId == providerId); - if (item == null) - { - item = await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TvDbId == providerId); - } + case ProviderType.ImdbId: + return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.ImdbId == providerId); + case ProviderType.TheMovieDbId: + return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TheMovieDbId == providerId); + case ProviderType.TvDbId: + return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TvDbId == providerId); + default: + break; } - return item; + + return null; } public async Task GetByKey(int key) From 2e316c51d26c93b3defaf9aa951a3cb27020adcf Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sat, 1 May 2021 21:56:06 +0100 Subject: [PATCH 06/66] Fixed build --- src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs b/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs index 7704b78ac..a86afcad0 100644 --- a/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs +++ b/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs @@ -17,6 +17,7 @@ using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; +using Ombi.Helpers; namespace Ombi.Schedule.Tests { @@ -53,7 +54,7 @@ namespace Ombi.Schedule.Tests ImdbId = "test" }; _movie.Setup(x => x.GetAll()).Returns(new List { request }.AsQueryable()); - _repo.Setup(x => x.Get("test")).ReturnsAsync(new PlexServerContent()); + _repo.Setup(x => x.Get("test", ProviderType.ImdbId)).ReturnsAsync(new PlexServerContent()); await Checker.Execute(null); From 8aec700f1194ead922a4f0b68e68f35954720fa6 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 4 May 2021 09:00:27 +0100 Subject: [PATCH 07/66] Added some app store links to the new mobile app --- .../user-preference.component.html | 76 ++++++++++--------- .../user-preference.component.ts | 11 +-- src/Ombi/wwwroot/images/appstore.svg | 46 +++++++++++ 3 files changed, 87 insertions(+), 46 deletions(-) create mode 100644 src/Ombi/wwwroot/images/appstore.svg diff --git a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html index e5fbc6c2f..b809a510d 100644 --- a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html +++ b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html @@ -1,7 +1,7 @@
-

{{username}} +

{{username}} ({{user.emailAddress}})

@@ -34,9 +34,7 @@
- -
{{'UserPreferences.StreamingCountryDescription' | translate}}
@@ -50,47 +48,64 @@
+ +
+ +
+
+ +
+
+ Get it on Google Play +
+
+ Get it on Google Play +
+
- +

Change Details

-
+
You need your current password to make any changes here - - Current Password - - -
+ + Current Password + + +
- - Email Address - - -
+ + Email Address + + +
- - New Password - - -
+ + New Password + + +
- - New Password Confirm - - -
+ + New Password Confirm + + +
@@ -103,17 +118,6 @@ - -
-
- -
- - -
-
-
diff --git a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts index 50753dfc8..ae68055a6 100644 --- a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts +++ b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts @@ -86,15 +86,6 @@ export class UserPreferenceComponent implements OnInit { this.identityService.updateStreamingCountry(this.selectedCountry).subscribe(x => this.notification.success(this.translate.instant("UserPreferences.Updated"))); } - public openMobileApp(event: any) { - event.preventDefault(); - - this.identityService.getAccessToken().subscribe(x => { - const url = `ombi://${this.customizationSettings.applicationUrl}_${x}`; - window.location.assign(url); - }); - } - public getProfileImage(): string { let emailHash: string|Int32Array; if (this.user.emailAddress) { @@ -131,7 +122,7 @@ export class UserPreferenceComponent implements OnInit { private welcomeText: string; - private setWelcomeText() { + private setWelcomeText() { var d = new Date(); var hour = d.getHours(); diff --git a/src/Ombi/wwwroot/images/appstore.svg b/src/Ombi/wwwroot/images/appstore.svg new file mode 100644 index 000000000..072b425a1 --- /dev/null +++ b/src/Ombi/wwwroot/images/appstore.svg @@ -0,0 +1,46 @@ + + Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f18aa778e6d376a19010e753988f30280a095ae8 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 6 May 2021 19:59:06 +0100 Subject: [PATCH 08/66] Added the ability to hide the user in the discord notification --- .../Agents/DiscordNotification.cs | 22 ++++++++++--------- .../Agents/EmailNotification.cs | 4 ++-- .../Agents/LegacyMobileNotification.cs | 4 ++-- .../Agents/MobileNotification.cs | 4 ++-- src/Ombi.Notifications/BaseNotification.cs | 4 ++-- .../DiscordNotificationSettings.cs | 1 + .../app/interfaces/INotificationSettings.ts | 1 + .../notifications/discord.component.html | 3 +++ .../notifications/discord.component.ts | 3 ++- 9 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/Ombi.Notifications/Agents/DiscordNotification.cs b/src/Ombi.Notifications/Agents/DiscordNotification.cs index dda10f210..4a0c369fc 100644 --- a/src/Ombi.Notifications/Agents/DiscordNotification.cs +++ b/src/Ombi.Notifications/Agents/DiscordNotification.cs @@ -106,21 +106,23 @@ namespace Ombi.Notifications.Agents }; var fields = new List(); - - if (model.Data.TryGetValue("Alias", out var alias)) + if (!settings.HideUser) { - if (alias.HasValue()) + if (model.Data.TryGetValue("Alias", out var alias)) { - fields.Add(new DiscordField { name = "Requested By", value = alias, inline = true }); + if (alias.HasValue()) + { + fields.Add(new DiscordField { name = "Requested By", value = alias, inline = true }); + } } - } - else - { - if (model.Data.TryGetValue("RequestedUser", out var requestedUser)) + else { - if (requestedUser.HasValue()) + if (model.Data.TryGetValue("RequestedUser", out var requestedUser)) { - fields.Add(new DiscordField { name = "Requested By", value = requestedUser, inline = true }); + if (requestedUser.HasValue()) + { + fields.Add(new DiscordField { name = "Requested By", value = requestedUser, inline = true }); + } } } } diff --git a/src/Ombi.Notifications/Agents/EmailNotification.cs b/src/Ombi.Notifications/Agents/EmailNotification.cs index a7f9334fb..b6d03305b 100644 --- a/src/Ombi.Notifications/Agents/EmailNotification.cs +++ b/src/Ombi.Notifications/Agents/EmailNotification.cs @@ -240,9 +240,9 @@ namespace Ombi.Notifications.Agents private async Task SendToSubscribers(EmailNotificationSettings settings, NotificationMessage message) { - if (await SubsribedUsers.AnyAsync()) + if (await Subscribed.AnyAsync()) { - foreach (var user in SubsribedUsers) + foreach (var user in Subscribed) { if (user.Email.IsNullOrEmpty()) { diff --git a/src/Ombi.Notifications/Agents/LegacyMobileNotification.cs b/src/Ombi.Notifications/Agents/LegacyMobileNotification.cs index 5ac92d5bf..33cec783c 100644 --- a/src/Ombi.Notifications/Agents/LegacyMobileNotification.cs +++ b/src/Ombi.Notifications/Agents/LegacyMobileNotification.cs @@ -304,9 +304,9 @@ namespace Ombi.Notifications.Agents private async Task AddSubscribedUsers(List playerIds) { - if (await SubsribedUsers.AnyAsync()) + if (await Subscribed.AnyAsync()) { - foreach (var user in SubsribedUsers) + foreach (var user in Subscribed) { var notificationId = user.NotificationUserIds; if (notificationId.Any()) diff --git a/src/Ombi.Notifications/Agents/MobileNotification.cs b/src/Ombi.Notifications/Agents/MobileNotification.cs index 864453b71..bb6454bfc 100644 --- a/src/Ombi.Notifications/Agents/MobileNotification.cs +++ b/src/Ombi.Notifications/Agents/MobileNotification.cs @@ -346,9 +346,9 @@ namespace Ombi.Notifications.Agents private async Task AddSubscribedUsers(List playerIds) { - if (await SubsribedUsers.AnyAsync()) + if (await Subscribed.AnyAsync()) { - foreach (var user in SubsribedUsers) + foreach (var user in Subscribed) { var notificationIds = await _notifications.GetAll().Where(x => x.UserId == user.Id).ToListAsync(); diff --git a/src/Ombi.Notifications/BaseNotification.cs b/src/Ombi.Notifications/BaseNotification.cs index 9d8bbb776..46db5d467 100644 --- a/src/Ombi.Notifications/BaseNotification.cs +++ b/src/Ombi.Notifications/BaseNotification.cs @@ -48,7 +48,7 @@ namespace Ombi.Notifications protected ChildRequests TvRequest { get; set; } protected AlbumRequest AlbumRequest { get; set; } protected MovieRequests MovieRequest { get; set; } - protected IQueryable SubsribedUsers { get; private set; } + protected IQueryable Subscribed { get; private set; } public abstract string NotificationName { get; } @@ -75,7 +75,7 @@ namespace Ombi.Notifications if (model.RequestId > 0) { await LoadRequest(model.RequestId, model.RequestType); - SubsribedUsers = GetSubscriptions(model.RequestId, model.RequestType); + Subscribed = GetSubscriptions(model.RequestId, model.RequestType); } Customization = await CustomizationSettings.GetSettingsAsync(); diff --git a/src/Ombi.Settings/Settings/Models/Notifications/DiscordNotificationSettings.cs b/src/Ombi.Settings/Settings/Models/Notifications/DiscordNotificationSettings.cs index 45dc17ee1..0ec81a6d8 100644 --- a/src/Ombi.Settings/Settings/Models/Notifications/DiscordNotificationSettings.cs +++ b/src/Ombi.Settings/Settings/Models/Notifications/DiscordNotificationSettings.cs @@ -9,6 +9,7 @@ namespace Ombi.Settings.Settings.Models.Notifications public string WebhookUrl { get; set; } public string Username { get; set; } public string Icon { get; set; } + public bool HideUser { get; set; } [JsonIgnore] public string WebHookId => SplitWebUrl(4); diff --git a/src/Ombi/ClientApp/src/app/interfaces/INotificationSettings.ts b/src/Ombi/ClientApp/src/app/interfaces/INotificationSettings.ts index d08778e2a..e1c52103c 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/INotificationSettings.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/INotificationSettings.ts @@ -59,6 +59,7 @@ export interface IDiscordNotifcationSettings extends INotificationSettings { webhookUrl: string; username: string; icon: string; + hideUser: boolean; notificationTemplates: INotificationTemplates[]; } diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.html b/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.html index 140198c94..9f19ae9a2 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.html +++ b/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.html @@ -24,6 +24,8 @@ Username + Hide Users in notification +
@@ -34,6 +36,7 @@
+
diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.ts index 73f271894..e2e92e55c 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.ts @@ -29,7 +29,8 @@ export class DiscordComponent implements OnInit { enabled: [x.enabled], username: [x.username], webhookUrl: [x.webhookUrl, [Validators.required]], - icon: [x.icon] + icon: [x.icon], + hideUser: [x.hideUser] }); }); From 5d8a2123120bcb79f58de4e8b882a454b05d1e98 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 6 May 2021 20:15:58 +0100 Subject: [PATCH 09/66] Improved the Plex OAuth flow --- .../src/app/login/login.component.ts | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Ombi/ClientApp/src/app/login/login.component.ts b/src/Ombi/ClientApp/src/app/login/login.component.ts index 5245b8239..e9260d685 100644 --- a/src/Ombi/ClientApp/src/app/login/login.component.ts +++ b/src/Ombi/ClientApp/src/app/login/login.component.ts @@ -146,6 +146,9 @@ export class LoginComponent implements OnDestroy, OnInit { } public oauth() { + if (this.oAuthWindow) { + this.oAuthWindow.close(); + } this.oAuthWindow = window.open(window.location.toString(), "_blank", `toolbar=0, location=0, status=0, @@ -159,16 +162,22 @@ export class LoginComponent implements OnDestroy, OnInit { this.authService.login({ usePlexOAuth: true, password: "", rememberMe: true, username: "", plexTvPin: pin }).subscribe(x => { this.oAuthWindow!.location.replace(x.url); - this.pinTimer = setInterval(() => { + if (this.pinTimer) { + clearInterval(this.pinTimer); + } - this.oauthLoading = true; - this.getPinResult(x.pinId); - }, 4000); + this.pinTimer = setInterval(() => { + if(this.oAuthWindow.closed) { + this.oauthLoading = true; + this.getPinResult(x.pinId); + } + }, 1000); }); }); } public getPinResult(pinId: number) { + clearInterval(this.pinTimer); this.authService.oAuth(pinId).subscribe(x => { if(x.access_token) { this.store.save("id_token", x.access_token); @@ -176,7 +185,7 @@ export class LoginComponent implements OnDestroy, OnInit { if (this.authService.loggedIn()) { this.ngOnDestroy(); - if(this.oAuthWindow) { + if (this.oAuthWindow) { this.oAuthWindow.close(); } this.oauthLoading = false; @@ -184,6 +193,10 @@ export class LoginComponent implements OnDestroy, OnInit { return; } } + this.notify.open("Could not log you in!", "OK", { + duration: 3000 + }); + this.oauthLoading = false; }, err => { console.log(err); From 7c79e28d5c0a3d884ddec862dc7a87b2ff51c582 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 6 May 2021 20:29:44 +0100 Subject: [PATCH 10/66] Added a message on the application url field to better explain what it does --- .../app/settings/customization/customization.component.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Ombi/ClientApp/src/app/settings/customization/customization.component.html b/src/Ombi/ClientApp/src/app/settings/customization/customization.component.html index c98cf65fc..3b3044780 100644 --- a/src/Ombi/ClientApp/src/app/settings/customization/customization.component.html +++ b/src/Ombi/ClientApp/src/app/settings/customization/customization.component.html @@ -12,6 +12,10 @@
+ The application url should be your Externally Accessible URL for example, your internal URL is http://192.168.1.50/ but your Externally + Accessible URL is 'https://mydomain.com/requests' Please ensure this field is correct as it drives a lot of functionality include the QR code for the + mobile app and it affects the way email notifications are sent. + Application URL From 8dd00e9e9935038754fad1202652fd5ad9575114 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 6 May 2021 20:31:36 +0100 Subject: [PATCH 11/66] Improved the message on the admin request popup --- src/Ombi/wwwroot/translations/en.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json index 18e864bdd..5e24656fe 100644 --- a/src/Ombi/wwwroot/translations/en.json +++ b/src/Ombi/wwwroot/translations/en.json @@ -254,9 +254,9 @@ "ViewCollection":"View Collection", "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", "AdvancedOptions":"Advanced Options", - "AutoApproveOptions":"You can configure the request here, once requested it will be send to your DVR application and will be auto approved!", - "AutoApproveOptionsTv":"You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it!", - "AutoApproveOptionsTvShort":"You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it!", + "AutoApproveOptions":"You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv":"You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort":"You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", "QualityProfilesSelect":"Select A Quality Profile", "RootFolderSelect":"Select A Root Folder", "LanguageProfileSelect":"Select A Language Profile", From 4071b2e8a215e5e5dfe60b617080c7e4c48d7e36 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Fri, 7 May 2021 14:41:10 +0100 Subject: [PATCH 12/66] Added the open on mobile back in, this will be available in the next app update --- .../Rules/Search/AvailabilityRuleHelper.cs | 2 +- .../Rule/Rules/Search/PlexAvailabilityRule.cs | 4 +-- .../user-preference.component.html | 28 +++++++++++-------- .../user-preference.component.ts | 7 +++++ 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs index 71331c51d..c3de20798 100644 --- a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs +++ b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs @@ -13,7 +13,7 @@ namespace Ombi.Core.Rule.Rules.Search { public static void CheckForUnairedEpisodes(SearchTvShowViewModel search) { - foreach (var season in search.SeasonRequests) + foreach (var season in search.SeasonRequests.ToList()) { // If we have all the episodes for this season, then this season is available if (season.Episodes.All(x => x.Available)) diff --git a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs index 7b757802d..68551aac4 100644 --- a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs @@ -85,9 +85,9 @@ namespace Ombi.Core.Rule.Rules.Search if (search.SeasonRequests.Any()) { var allEpisodes = PlexContentRepository.GetAllEpisodes(); - foreach (var season in search.SeasonRequests) + foreach (var season in search.SeasonRequests.ToList()) { - foreach (var episode in season.Episodes) + foreach (var episode in season.Episodes.ToList()) { await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb, Log); } diff --git a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html index b809a510d..ab9f7bf0c 100644 --- a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html +++ b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html @@ -52,19 +52,25 @@
-
-
-
- Get it on Google Play + +
+
+ Get it on Google Play +
+
+ Get it on Google Play +
+
+ +
+
-
- Get it on Google Play -
-
+
diff --git a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts index ae68055a6..eb504065c 100644 --- a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts +++ b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts @@ -120,6 +120,13 @@ export class UserPreferenceComponent implements OnInit { }) } + public openMobileApp(event: any) { + event.preventDefault(); + + const url = `ombi://${this.qrCode}`; + window.location.assign(url); + } + private welcomeText: string; private setWelcomeText() { From 50af2b84821ce39d316194c0a14e7ebb4f507d1e Mon Sep 17 00:00:00 2001 From: tidusjar Date: Fri, 7 May 2021 19:36:07 +0100 Subject: [PATCH 13/66] Fixed the issue where you couldn't remove a legacy user from the notifications --- src/Ombi/Controllers/V1/MobileController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi/Controllers/V1/MobileController.cs b/src/Ombi/Controllers/V1/MobileController.cs index 2ca640769..485535816 100644 --- a/src/Ombi/Controllers/V1/MobileController.cs +++ b/src/Ombi/Controllers/V1/MobileController.cs @@ -92,7 +92,7 @@ namespace Ombi.Controllers.V1 [Admin] public async Task RemoveUser([FromBody] RemoveUserModel userId) { - var user = await _userManager.Users.Include(x => x.NotificationUserIds).FirstOrDefaultAsync(x => x.Id.Equals(userId.UserId, StringComparison.InvariantCultureIgnoreCase)); + var user = await _userManager.Users.Include(x => x.NotificationUserIds).FirstOrDefaultAsync(x => x.Id == userId.UserId); try { await _notification.DeleteRange(user.NotificationUserIds); From 64c0fc17cc56c1484a33a8dc2a715843bcab82b9 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sun, 9 May 2021 19:58:36 +0100 Subject: [PATCH 14/66] Fixed #4152 --- src/Ombi.Core/Engine/Interfaces/BaseEngine.cs | 4 ++-- src/Ombi.Core/Engine/MovieRequestEngine.cs | 4 ++-- src/Ombi.Core/Rule/Interfaces/IRuleEvaluator.cs | 2 +- src/Ombi.Core/Rule/Interfaces/ISpecificRule.cs | 2 +- src/Ombi.Core/Rule/RuleEvaluator.cs | 4 ++-- .../Rule/Rules/Search/AvailabilityRuleHelper.cs | 2 +- .../Rule/Rules/Search/LidarrArtistCacheRule.cs | 3 ++- .../Rule/Rules/Specific/SendNotificationRule.cs | 11 ++++++++++- 8 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs index 6fd22bced..68a4335cb 100644 --- a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs @@ -59,9 +59,9 @@ namespace Ombi.Core.Engine.Interfaces var ruleResults = await Rules.StartSearchRules(model); return ruleResults; } - public async Task RunSpecificRule(object model, SpecificRules rule) + public async Task RunSpecificRule(object model, SpecificRules rule, string requestOnBehalf) { - var ruleResults = await Rules.StartSpecificRules(model, rule); + var ruleResults = await Rules.StartSpecificRules(model, rule, requestOnBehalf); return ruleResults; } } diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index 8d54f0fc3..a2380be81 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -71,7 +71,7 @@ namespace Ombi.Core.Engine var canRequestOnBehalf = model.RequestOnBehalf.HasValue(); var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin); - if (model.RequestOnBehalf.HasValue() && !isAdmin) + if (canRequestOnBehalf && !isAdmin) { return new RequestEngineResult { @@ -703,7 +703,7 @@ namespace Ombi.Core.Engine { await MovieRepository.Add(model); - var result = await RunSpecificRule(model, SpecificRules.CanSendNotification); + var result = await RunSpecificRule(model, SpecificRules.CanSendNotification, requestOnBehalf); if (result.Success) { await NotificationHelper.NewRequest(model); diff --git a/src/Ombi.Core/Rule/Interfaces/IRuleEvaluator.cs b/src/Ombi.Core/Rule/Interfaces/IRuleEvaluator.cs index c32342146..5b438124e 100644 --- a/src/Ombi.Core/Rule/Interfaces/IRuleEvaluator.cs +++ b/src/Ombi.Core/Rule/Interfaces/IRuleEvaluator.cs @@ -9,6 +9,6 @@ namespace Ombi.Core.Rule.Interfaces { Task> StartRequestRules(BaseRequest obj); Task> StartSearchRules(SearchViewModel obj); - Task StartSpecificRules(object obj, SpecificRules selectedRule); + Task StartSpecificRules(object obj, SpecificRules selectedRule, string requestOnBehalf); } } \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Interfaces/ISpecificRule.cs b/src/Ombi.Core/Rule/Interfaces/ISpecificRule.cs index 065b2f990..f76464888 100644 --- a/src/Ombi.Core/Rule/Interfaces/ISpecificRule.cs +++ b/src/Ombi.Core/Rule/Interfaces/ISpecificRule.cs @@ -5,7 +5,7 @@ namespace Ombi.Core.Rule.Interfaces { public interface ISpecificRule where T : new() { - Task Execute(T obj); + Task Execute(T obj, string requestOnBehalf); SpecificRules Rule { get; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Rule/RuleEvaluator.cs b/src/Ombi.Core/Rule/RuleEvaluator.cs index a0c272c00..712d6031e 100644 --- a/src/Ombi.Core/Rule/RuleEvaluator.cs +++ b/src/Ombi.Core/Rule/RuleEvaluator.cs @@ -58,13 +58,13 @@ namespace Ombi.Core.Rule return results; } - public async Task StartSpecificRules(object obj, SpecificRules selectedRule) + public async Task StartSpecificRules(object obj, SpecificRules selectedRule, string requestOnBehalf) { foreach (var rule in SpecificRules) { if (selectedRule == rule.Rule) { - var result = await rule.Execute(obj); + var result = await rule.Execute(obj, requestOnBehalf); return result; } } diff --git a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs index c3de20798..fe062e851 100644 --- a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs +++ b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs @@ -18,7 +18,7 @@ namespace Ombi.Core.Rule.Rules.Search // If we have all the episodes for this season, then this season is available if (season.Episodes.All(x => x.Available)) { - season.SeasonAvailable = true; + season.SeasonAvailable = true; } } if (search.SeasonRequests.All(x => x.Episodes.All(e => e.Available))) diff --git a/src/Ombi.Core/Rule/Rules/Search/LidarrArtistCacheRule.cs b/src/Ombi.Core/Rule/Rules/Search/LidarrArtistCacheRule.cs index a254ea2d3..b0e9af1ec 100644 --- a/src/Ombi.Core/Rule/Rules/Search/LidarrArtistCacheRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/LidarrArtistCacheRule.cs @@ -8,7 +8,7 @@ using Ombi.Store.Repository; namespace Ombi.Core.Rule.Rules.Search { - public class LidarrArtistCacheRule : SpecificRule, ISpecificRule + public class LidarrArtistCacheRule : SpecificRule, IRules { public LidarrArtistCacheRule(IExternalRepository db) { @@ -30,6 +30,7 @@ namespace Ombi.Core.Rule.Rules.Search return Task.FromResult(Success()); } + public override SpecificRules Rule => SpecificRules.LidarrArtist; } } \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Specific/SendNotificationRule.cs b/src/Ombi.Core/Rule/Rules/Specific/SendNotificationRule.cs index 30ec9b14a..af71df9ac 100644 --- a/src/Ombi.Core/Rule/Rules/Specific/SendNotificationRule.cs +++ b/src/Ombi.Core/Rule/Rules/Specific/SendNotificationRule.cs @@ -22,11 +22,20 @@ namespace Ombi.Core.Rule.Rules.Specific private OmbiUserManager UserManager { get; } private ISettingsService Settings { get; } - public async Task Execute(object obj) + public async Task Execute(object obj, string requestOnBehalf) { var req = (BaseRequest)obj; + var canRequestonBehalf = requestOnBehalf.HasValue(); var settings = await Settings.GetSettingsAsync(); var sendNotification = true; + + if (settings.DoNotSendNotificationsForAutoApprove && canRequestonBehalf) + { + return new RuleResult + { + Success = false + }; + } var requestedUser = await UserManager.Users.FirstOrDefaultAsync(x => x.Id == req.RequestedUserId); if (req.RequestType == RequestType.Movie) { From 6e32bd33f5418070d9616152e31309e84c3b4489 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sun, 9 May 2021 21:15:56 +0100 Subject: [PATCH 15/66] Fixed build --- .../Rule/Search/LidarrAlbumCacheRuleTests.cs | 10 +++++----- .../Rule/Search/LidarrArtistCacheRuleTests.cs | 6 +++--- src/Ombi.Core/Engine/MovieRequestEngine.cs | 2 +- src/Ombi.Core/Engine/MusicRequestEngine.cs | 4 ++-- src/Ombi.Core/Engine/MusicSearchEngine.cs | 8 ++++---- src/Ombi.Core/Engine/TvRequestEngine.cs | 2 +- .../Rule/Rules/Search/LidarrAlbumCacheRule.cs | 6 ++++-- .../Rule/Rules/Search/LidarrArtistCacheRule.cs | 4 ++-- 8 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/Ombi.Core.Tests/Rule/Search/LidarrAlbumCacheRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/LidarrAlbumCacheRuleTests.cs index 27dbee614..7bf84d05f 100644 --- a/src/Ombi.Core.Tests/Rule/Search/LidarrAlbumCacheRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/LidarrAlbumCacheRuleTests.cs @@ -30,7 +30,7 @@ namespace Ombi.Core.Tests.Rule.Search public async Task Should_Not_Be_Monitored_Or_Available() { var request = new SearchAlbumViewModel { ForeignAlbumId = "abc" }; - var result = await Rule.Execute(request); + var result = await Rule.Execute(request, string.Empty); Assert.True(result.Success); Assert.False(request.Approved); @@ -49,7 +49,7 @@ namespace Ombi.Core.Tests.Rule.Search } }.AsQueryable()); var request = new SearchAlbumViewModel { ForeignAlbumId = "abc" }; - var result = await Rule.Execute(request); + var result = await Rule.Execute(request, string.Empty); Assert.True(result.Success); Assert.False(request.Approved); @@ -71,7 +71,7 @@ namespace Ombi.Core.Tests.Rule.Search } }.AsQueryable()); var request = new SearchAlbumViewModel { ForeignAlbumId = "abc" }; - var result = await Rule.Execute(request); + var result = await Rule.Execute(request, string.Empty); Assert.True(result.Success); Assert.False(request.Approved); @@ -93,7 +93,7 @@ namespace Ombi.Core.Tests.Rule.Search } }.AsQueryable()); var request = new SearchAlbumViewModel { ForeignAlbumId = "abc" }; - var result = await Rule.Execute(request); + var result = await Rule.Execute(request, string.Empty); Assert.True(result.Success); Assert.False(request.Approved); @@ -114,7 +114,7 @@ namespace Ombi.Core.Tests.Rule.Search } }.AsQueryable()); var request = new SearchAlbumViewModel { ForeignAlbumId = "abc" }; - var result = await Rule.Execute(request); + var result = await Rule.Execute(request, string.Empty); Assert.True(result.Success); Assert.False(request.Approved); diff --git a/src/Ombi.Core.Tests/Rule/Search/LidarrArtistCacheRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/LidarrArtistCacheRuleTests.cs index c17400acb..e13d8d1cd 100644 --- a/src/Ombi.Core.Tests/Rule/Search/LidarrArtistCacheRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/LidarrArtistCacheRuleTests.cs @@ -29,7 +29,7 @@ namespace Ombi.Core.Tests.Rule.Search public async Task Should_Not_Be_Monitored() { var request = new SearchArtistViewModel { ForignArtistId = "abc" }; - var result = await Rule.Execute(request); + var result = await Rule.Execute(request, string.Empty); Assert.True(result.Success); Assert.False(request.Monitored); @@ -46,7 +46,7 @@ namespace Ombi.Core.Tests.Rule.Search } }.AsQueryable()); var request = new SearchArtistViewModel { ForignArtistId = "abc" }; - var result = await Rule.Execute(request); + var result = await Rule.Execute(request, string.Empty); Assert.True(result.Success); Assert.True(request.Monitored); @@ -64,7 +64,7 @@ namespace Ombi.Core.Tests.Rule.Search } }.AsQueryable()); var request = new SearchArtistViewModel { ForignArtistId = "abc" }; - var result = await Rule.Execute(request); + var result = await Rule.Execute(request, string.Empty); Assert.True(result.Success); Assert.True(request.Monitored); diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index a2380be81..d37983d21 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -550,7 +550,7 @@ namespace Ombi.Core.Engine request.Denied = false; await MovieRepository.Update(request); - var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification); + var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification, string.Empty); if (canNotify.Success) { await NotificationHelper.Notify(request, NotificationType.RequestApproved); diff --git a/src/Ombi.Core/Engine/MusicRequestEngine.cs b/src/Ombi.Core/Engine/MusicRequestEngine.cs index e473c1fb1..032b2ae7d 100644 --- a/src/Ombi.Core/Engine/MusicRequestEngine.cs +++ b/src/Ombi.Core/Engine/MusicRequestEngine.cs @@ -362,7 +362,7 @@ namespace Ombi.Core.Engine await MusicRepository.Update(request); - var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification); + var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification, string.Empty); if (canNotify.Success) { await NotificationHelper.Notify(request, NotificationType.RequestApproved); @@ -506,7 +506,7 @@ namespace Ombi.Core.Engine { await MusicRepository.Add(model); - var result = await RunSpecificRule(model, SpecificRules.CanSendNotification); + var result = await RunSpecificRule(model, SpecificRules.CanSendNotification, string.Empty); if (result.Success) { await NotificationHelper.NewRequest(model); diff --git a/src/Ombi.Core/Engine/MusicSearchEngine.cs b/src/Ombi.Core/Engine/MusicSearchEngine.cs index a9af03ecf..89bae7069 100644 --- a/src/Ombi.Core/Engine/MusicSearchEngine.cs +++ b/src/Ombi.Core/Engine/MusicSearchEngine.cs @@ -151,7 +151,7 @@ namespace Ombi.Core.Engine } - await Rules.StartSpecificRules(vm, SpecificRules.LidarrArtist); + await Rules.StartSpecificRules(vm, SpecificRules.LidarrArtist, string.Empty); return vm; } @@ -190,7 +190,7 @@ namespace Ombi.Core.Engine vm.Cover = a.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url?.ToHttpsUrl(); - await Rules.StartSpecificRules(vm, SpecificRules.LidarrAlbum); + await Rules.StartSpecificRules(vm, SpecificRules.LidarrAlbum, string.Empty); await RunSearchRules(vm); @@ -230,7 +230,7 @@ namespace Ombi.Core.Engine vm.Cover = a.remoteCover; } - await Rules.StartSpecificRules(vm, SpecificRules.LidarrAlbum); + await Rules.StartSpecificRules(vm, SpecificRules.LidarrAlbum, string.Empty); await RunSearchRules(vm); @@ -258,7 +258,7 @@ namespace Ombi.Core.Engine vm.Cover = fullAlbum.remoteCover; } - await Rules.StartSpecificRules(vm, SpecificRules.LidarrAlbum); + await Rules.StartSpecificRules(vm, SpecificRules.LidarrAlbum, string.Empty); await RunSearchRules(vm); diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index 5eae0912c..00655e921 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -915,7 +915,7 @@ namespace Ombi.Core.Engine private async Task AfterRequest(ChildRequests model, string requestOnBehalf) { - var sendRuleResult = await RunSpecificRule(model, SpecificRules.CanSendNotification); + var sendRuleResult = await RunSpecificRule(model, SpecificRules.CanSendNotification, requestOnBehalf); if (sendRuleResult.Success) { await NotificationHelper.NewRequest(model); diff --git a/src/Ombi.Core/Rule/Rules/Search/LidarrAlbumCacheRule.cs b/src/Ombi.Core/Rule/Rules/Search/LidarrAlbumCacheRule.cs index 3ca57d635..ca0c0cd97 100644 --- a/src/Ombi.Core/Rule/Rules/Search/LidarrAlbumCacheRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/LidarrAlbumCacheRule.cs @@ -9,7 +9,7 @@ using Ombi.Store.Repository; namespace Ombi.Core.Rule.Rules.Search { - public class LidarrAlbumCacheRule : BaseSearchRule, IRules + public class LidarrAlbumCacheRule : SpecificRule, ISpecificRule { public LidarrAlbumCacheRule(IExternalRepository db) { @@ -18,7 +18,9 @@ namespace Ombi.Core.Rule.Rules.Search private readonly IExternalRepository _db; - public Task Execute(SearchViewModel objec) + public override SpecificRules Rule => SpecificRules.LidarrAlbum; + + public Task Execute(object objec, string requestOnBehalf) { if (objec is SearchAlbumViewModel obj) { diff --git a/src/Ombi.Core/Rule/Rules/Search/LidarrArtistCacheRule.cs b/src/Ombi.Core/Rule/Rules/Search/LidarrArtistCacheRule.cs index b0e9af1ec..06ca3f06c 100644 --- a/src/Ombi.Core/Rule/Rules/Search/LidarrArtistCacheRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/LidarrArtistCacheRule.cs @@ -8,7 +8,7 @@ using Ombi.Store.Repository; namespace Ombi.Core.Rule.Rules.Search { - public class LidarrArtistCacheRule : SpecificRule, IRules + public class LidarrArtistCacheRule : SpecificRule, ISpecificRule { public LidarrArtistCacheRule(IExternalRepository db) { @@ -17,7 +17,7 @@ namespace Ombi.Core.Rule.Rules.Search private readonly IExternalRepository _db; - public Task Execute(object objec) + public Task Execute(object objec, string requestOnBehalf) { var obj = (SearchArtistViewModel) objec; // Check if it's in Lidarr From 900ec20e42d31c0f290a04d71268065b9e6a0cc7 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sun, 9 May 2021 21:44:21 +0100 Subject: [PATCH 16/66] Fixed #4057 #4180 --- .../src/app/usermanagement/usermanagement.component.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.ts b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.ts index c2245957c..d119c8961 100644 --- a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.ts +++ b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.ts @@ -1,7 +1,7 @@ import { AfterViewInit, Component, OnInit, ViewChild } from "@angular/core"; - import { ICheckbox, ICustomizationSettings, IEmailNotificationSettings, IUser } from "../interfaces"; import { IdentityService, NotificationService, SettingsService } from "../services"; + import { MatSort } from "@angular/material/sort"; import { MatTableDataSource } from "@angular/material/table"; import { SelectionModel } from "@angular/cdk/collections"; @@ -90,6 +90,9 @@ export class UserManagementComponent implements OnInit { if (this.bulkMusicLimit) { x.musicRequestLimit = this.bulkMusicLimit; } + if (this.bulkStreaming) { + x.streamingCountry = this.bulkStreaming; + } this.identityService.updateUser(x).subscribe(y => { if (!y.successful) { this.notificationService.error(`Could not update user ${x.userName}. Reason ${y.errors[0]}`); @@ -102,6 +105,7 @@ export class UserManagementComponent implements OnInit { this.bulkMovieLimit = undefined; this.bulkEpisodeLimit = undefined; this.bulkMusicLimit = undefined; + this.bulkStreaming = undefined; } public isAllSelected() { From b8076e2e655958522ed4974ea1cdc88dfe63f798 Mon Sep 17 00:00:00 2001 From: Dyson Parkes Date: Mon, 10 May 2021 13:43:00 +1200 Subject: [PATCH 17/66] Adjust app store string --- .../components/user-preference/user-preference.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html index ab9f7bf0c..6954030de 100644 --- a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html +++ b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.html @@ -62,7 +62,7 @@
Get it on Google Play
@@ -128,4 +128,4 @@ -
\ No newline at end of file + From 21b8bf76d28b4b232f1fb74f86d2fc82da8edb24 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 11 May 2021 09:51:18 +0100 Subject: [PATCH 18/66] Fixed an issue where for Available Emby content, the service ID was not being passed --- src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs index 3fe11cbc4..7f6718a6b 100644 --- a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs @@ -67,7 +67,7 @@ namespace Ombi.Core.Rule.Rules.Search var s = await EmbySettings.GetSettingsAsync(); if (s.Enable) { - var server = s.Servers.FirstOrDefault(x => x.ServerHostname != null); + var server = s.Servers.FirstOrDefault(); if ((server?.ServerHostname ?? string.Empty).HasValue()) { obj.EmbyUrl = EmbyHelper.GetEmbyMediaUrl(item.EmbyId, server?.ServerId, server?.ServerHostname); From 65879acb8d2abc981409a5bd3419b064417aef98 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sun, 16 May 2021 11:52:37 +0100 Subject: [PATCH 19/66] Fixed the deseralizing issue #4181 --- src/Ombi.Api.Radarr/Models/V2/RadarrAddMovie.cs | 1 + src/Ombi.Api.Radarr/RadarrApi.cs | 3 ++- src/Ombi.Api.Radarr/RadarrV3Api.cs | 3 ++- src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Ombi.Api.Radarr/Models/V2/RadarrAddMovie.cs b/src/Ombi.Api.Radarr/Models/V2/RadarrAddMovie.cs index b56049c9a..09e985f43 100644 --- a/src/Ombi.Api.Radarr/Models/V2/RadarrAddMovie.cs +++ b/src/Ombi.Api.Radarr/Models/V2/RadarrAddMovie.cs @@ -28,5 +28,6 @@ namespace Ombi.Api.Radarr.Models public string titleSlug { get; set; } public int year { get; set; } public string minimumAvailability { get; set; } + public long sizeOnDisk { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Api.Radarr/RadarrApi.cs b/src/Ombi.Api.Radarr/RadarrApi.cs index b461ccda8..e1879bba3 100644 --- a/src/Ombi.Api.Radarr/RadarrApi.cs +++ b/src/Ombi.Api.Radarr/RadarrApi.cs @@ -82,7 +82,8 @@ namespace Ombi.Api.Radarr titleSlug = title + year, monitored = true, year = year, - minimumAvailability = minimumAvailability + minimumAvailability = minimumAvailability, + sizeOnDisk = 0 }; if (searchNow) diff --git a/src/Ombi.Api.Radarr/RadarrV3Api.cs b/src/Ombi.Api.Radarr/RadarrV3Api.cs index dd1d0b279..21f95b3e1 100644 --- a/src/Ombi.Api.Radarr/RadarrV3Api.cs +++ b/src/Ombi.Api.Radarr/RadarrV3Api.cs @@ -85,7 +85,8 @@ namespace Ombi.Api.Radarr titleSlug = title + year, monitored = true, year = year, - minimumAvailability = minimumAvailability + minimumAvailability = minimumAvailability, + sizeOnDisk = 0 }; if (searchNow) diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts index d4c5a9883..256f0a75e 100644 --- a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts @@ -43,7 +43,7 @@ export class RadarrComponent implements OnInit { addOnly: [x.addOnly], minimumAvailability: [x.minimumAvailability, [Validators.required]], scanForAvailability: [x.scanForAvailability], - v3: [x.v3] + v3: [x.v3 ?? true] }); if (x.defaultQualityProfile) { From d23c4c38594d96e28c8bf6de0e6e69b7f84276b4 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sun, 16 May 2021 12:03:39 +0100 Subject: [PATCH 20/66] removed the ripple from the navmenu #4192 --- .../ClientApp/src/app/my-nav/my-nav.component.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html index c1b69b303..f73c9bbc8 100644 --- a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html +++ b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html @@ -6,12 +6,12 @@ {{applicationName}} - + -