From 6756ee688a0f7d77f94189f6fbe40b04739540b1 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Thu, 14 Apr 2022 12:59:36 +0200 Subject: [PATCH 001/270] Remove dead code --- .../tv-request-grid.component.ts | 64 ------------------- 1 file changed, 64 deletions(-) diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts index 7d1304eff1..123e24f110 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts @@ -80,70 +80,6 @@ export class TvRequestGridComponent { } } - public async approve(request: IChildRequests) { - const result = await this.requestService.approveChild({ - id: request.id - }).toPromise(); - - if (result.result) { - request.approved = true; - request.denied = false; - request.seasonRequests.forEach((season) => { - season.episodes.forEach((ep) => { - ep.approved = true; - }); - }); - this.notificationService.send("Request has been approved", "Ok"); - } else { - this.notificationService.send(result.errorMessage, "Ok"); - } - } - - public changeAvailability(request: IChildRequests, available: boolean) { - request.available = available; - request.seasonRequests.forEach((season) => { - season.episodes.forEach((ep) => { - ep.available = available; - }); - }); - if (available) { - this.requestService.markTvAvailable({ id: request.id }).subscribe(x => { - if (x.result) { - this.notificationService.send( - `This request is now available`); - } else { - this.notificationService.send("Request Available", x.message ? x.message : x.errorMessage); - request.approved = false; - } - }); - } else { - this.requestService.markTvUnavailable({ id: request.id }).subscribe(x => { - if (x.result) { - this.notificationService.send( - `This request is now unavailable`); - } else { - this.notificationService.send("Request Available", x.message ? x.message : x.errorMessage); - request.approved = false; - } - }); - } - } - public async deny(request: IChildRequests) { - const dialogRef = this.dialog.open(DenyDialogComponent, { - width: '250px', - data: {requestId: request.id, requestType: RequestType.tvShow} - }); - - dialogRef.afterClosed().subscribe(result => { - request.denied = true; - request.seasonRequests.forEach((season) => { - season.episodes.forEach((ep) => { - ep.approved = false; - }); - }); - }); - } - public async requestAllSeasons() { this.tv.requestAll = true; await this.submitRequests(); From fc202f5337930f98133f15592ed5c54ca9b15740 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Thu, 14 Apr 2022 13:54:04 +0200 Subject: [PATCH 002/270] Localize TV requests messages on TV details page --- src/Ombi.Core/Senders/MusicSender.cs | 2 +- src/Ombi.Core/Senders/TvSender.cs | 3 +-- .../tv-request-grid.component.ts | 2 +- .../tv-requests-panel.component.ts | 24 ++++++++++--------- .../src/app/services/message.service.ts | 14 +++++++---- src/Ombi/wwwroot/translations/en.json | 3 ++- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/Ombi.Core/Senders/MusicSender.cs b/src/Ombi.Core/Senders/MusicSender.cs index 6390578ddd..260b008feb 100644 --- a/src/Ombi.Core/Senders/MusicSender.cs +++ b/src/Ombi.Core/Senders/MusicSender.cs @@ -70,7 +70,7 @@ await _requestQueueRepository.Add(new RequestQueue } - return new SenderResult { Success = false, Sent = false, Message = "Something went wrong!" }; + return new SenderResult { Success = false, Sent = false }; } private async Task SendToLidarr(AlbumRequest model, LidarrSettings settings) diff --git a/src/Ombi.Core/Senders/TvSender.cs b/src/Ombi.Core/Senders/TvSender.cs index 3676d05ee6..c076b2d130 100644 --- a/src/Ombi.Core/Senders/TvSender.cs +++ b/src/Ombi.Core/Senders/TvSender.cs @@ -133,8 +133,7 @@ await _requestQueueRepository.Add(new RequestQueue return new SenderResult { - Success = false, - Message = "Something went wrong!" + Success = false }; } diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts index 123e24f110..bac88756e1 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts @@ -36,7 +36,7 @@ export class TvRequestGridComponent { // Make sure something has been selected const selected = this.selection.hasValue(); if (!selected && !this.tv.requestAll && !this.tv.firstSeason && !this.tv.latestSeason) { - this.notificationService.send("You need to select some episodes!", "OK"); + this.notificationService.send(this.translate.instant("Requests.NeedToSelectEpisodes")); return; } 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 e397e60ea3..1aa7958504 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 @@ -6,6 +6,7 @@ import { MatDialog } from "@angular/material/dialog"; import { MessageService } from "../../../../../services"; import { RequestService } from "../../../../../services/request.service"; import { RequestServiceV2 } from "../../../../../services/requestV2.service"; +import { TranslateService } from "@ngx-translate/core"; @Component({ templateUrl: "./tv-requests-panel.component.html", @@ -24,7 +25,8 @@ export class TvRequestsPanelComponent { constructor(private requestService: RequestService, private requestService2: RequestServiceV2, private messageService: MessageService, - public dialog: MatDialog) { + public dialog: MatDialog, + private translateService: TranslateService) { } @@ -41,7 +43,7 @@ export class TvRequestsPanelComponent { ep.approved = true; }); }); - this.messageService.send("Request has been approved", "Ok"); + this.messageService.send(this.translateService.instant("Requests.SuccessfullyApproved")); } else { this.messageService.sendRequestEngineResultError(result); } @@ -52,7 +54,7 @@ export class TvRequestsPanelComponent { if (result) { this.tvRequest.splice(this.tvRequest.indexOf(request),1); - this.messageService.send("Request has been Deleted", "Ok"); + this.messageService.send(this.translateService.instant("Requests.SuccessfullyDeleted")); } } @@ -67,9 +69,9 @@ export class TvRequestsPanelComponent { this.requestService.markTvAvailable({ id: request.id }).subscribe(x => { if (x.result) { this.messageService.send( - `This request is now available`); + this.translateService.instant("Requests.NowAvailable")); } else { - this.messageService.send("Request Available", x.message ? x.message : x.errorMessage); + this.messageService.sendRequestEngineResultError(x); request.approved = false; } }); @@ -77,9 +79,9 @@ export class TvRequestsPanelComponent { this.requestService.markTvUnavailable({ id: request.id }).subscribe(x => { if (x.result) { this.messageService.send( - `This request is now unavailable`); + this.translateService.instant("Requests.NowUnavailable")); } else { - this.messageService.send("Request Available", x.message ? x.message : x.errorMessage); + this.messageService.sendRequestEngineResultError(x); request.approved = false; } }); @@ -102,11 +104,11 @@ export class TvRequestsPanelComponent { } public reProcessRequest(request: IChildRequests) { - this.requestService2.reprocessRequest(request.id, RequestType.tvShow, false).subscribe(result => { - if (result.result) { - this.messageService.send(result.message ? result.message : "Successfully Re-processed the request", "Ok"); + this.requestService2.reprocessRequest(request.id, RequestType.tvShow, false).subscribe(x => { + if (x.result) { + this.messageService.send(this.translateService.instant("Requests.SuccessfullyReprocessed")); } else { - this.messageService.sendRequestEngineResultError(result); + this.messageService.sendRequestEngineResultError(x); } }); } diff --git a/src/Ombi/ClientApp/src/app/services/message.service.ts b/src/Ombi/ClientApp/src/app/services/message.service.ts index be1df37be6..995bc0f896 100644 --- a/src/Ombi/ClientApp/src/app/services/message.service.ts +++ b/src/Ombi/ClientApp/src/app/services/message.service.ts @@ -22,11 +22,15 @@ export class MessageService { } public sendRequestEngineResultError(result: IRequestEngineResult, action: string = "Ok") { const textKey = 'Requests.ErrorCodes.' + result.errorCode; - const text = this.translate.instant(textKey); - if (text !== textKey) { - this.send(text, action); - } else { - this.send(result.errorMessage ? result.errorMessage : result.message, action); + var text = this.translate.instant(textKey); + if (text === textKey) { // Error code on backend may not exist in frontend + if (result.errorMessage || result.message) { + text = result.errorMessage ? result.errorMessage : result.message; + } else { + text = this.translate.instant('ErrorPages.SomethingWentWrong'); + } } + + this.send(text, action); } } diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json index a9c40c1971..3611b02494 100644 --- a/src/Ombi/wwwroot/translations/en.json +++ b/src/Ombi/wwwroot/translations/en.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Check this page for continuous site updates." }, "ErrorPages": { - "NotFound": "Page not found" + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Discover", From e8fb74de031e1e61a558bd86fbf38fbcf45b102a Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Thu, 14 Apr 2022 18:24:08 +0200 Subject: [PATCH 003/270] Transform buttons with link into anchors --- src/Ombi/ClientApp/src/app/issues/issuestable.component.html | 2 +- .../components/albums-grid/albums-grid.component.html | 2 +- .../components/movies-grid/movies-grid.component.html | 2 +- .../requests-list/components/tv-grid/tv-grid.component.html | 2 +- .../src/app/usermanagement/usermanagement.component.html | 4 ++-- src/Ombi/ClientApp/src/styles/Styles.scss | 4 ++++ 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Ombi/ClientApp/src/app/issues/issuestable.component.html b/src/Ombi/ClientApp/src/app/issues/issuestable.component.html index 8e22d3e515..99b297b60f 100644 --- a/src/Ombi/ClientApp/src/app/issues/issuestable.component.html +++ b/src/Ombi/ClientApp/src/app/issues/issuestable.component.html @@ -14,7 +14,7 @@ - + {{ 'Issues.Details' | translate}} diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/albums-grid/albums-grid.component.html b/src/Ombi/ClientApp/src/app/requests-list/components/albums-grid/albums-grid.component.html index 977b55a175..7e06a73364 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/albums-grid/albums-grid.component.html +++ b/src/Ombi/ClientApp/src/app/requests-list/components/albums-grid/albums-grid.component.html @@ -59,7 +59,7 @@ - + {{ 'Requests.Details' | translate}} diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html index d95460b401..77dacd1e9a 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html +++ b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html @@ -83,7 +83,7 @@ - + {{ 'Requests.Details' | translate}} diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.html b/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.html index 8cb00d3bb7..7eb4b56340 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.html +++ b/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.html @@ -63,7 +63,7 @@ - + {{'Requests.Details' | translate}} diff --git a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html index f79188ae90..0d51717411 100644 --- a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html +++ b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html @@ -2,7 +2,7 @@
- + Add User To Ombi @@ -105,7 +105,7 @@ - + Edit diff --git a/src/Ombi/ClientApp/src/styles/Styles.scss b/src/Ombi/ClientApp/src/styles/Styles.scss index 115555410f..5b466c3a27 100644 --- a/src/Ombi/ClientApp/src/styles/Styles.scss +++ b/src/Ombi/ClientApp/src/styles/Styles.scss @@ -142,6 +142,10 @@ background-color: $ombi-active; } + a.mat-raised-button { + text-decoration:none; + } + hr { border-top: 1px solid $accent-dark; } From d41dd7210bacedd84cb48036391edc483ce5f02f Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Sat, 16 Apr 2022 09:39:06 +0200 Subject: [PATCH 004/270] Sonarr sync: stop using seasonpass API --- src/Ombi.Core/Senders/TvSender.cs | 76 ++++++++----------------------- 1 file changed, 19 insertions(+), 57 deletions(-) diff --git a/src/Ombi.Core/Senders/TvSender.cs b/src/Ombi.Core/Senders/TvSender.cs index 3676d05ee6..960e37edfe 100644 --- a/src/Ombi.Core/Senders/TvSender.cs +++ b/src/Ombi.Core/Senders/TvSender.cs @@ -343,8 +343,6 @@ private async Task SendToSonarr(ChildRequests model, SonarrSeries result, Sonarr await Task.Delay(500); } - var seriesChanges = false; - foreach (var season in model.SeasonRequests) { foreach (var ep in season.Episodes) @@ -359,72 +357,36 @@ private async Task SendToSonarr(ChildRequests model, SonarrSeries result, Sonarr } existingSeason = result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber); - var sonarrEpisodeList = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber).ToList(); - var sonarrEpCount = sonarrEpisodeList.Count; - var ourRequestCount = season.Episodes.Count; - - var ourEpisodes = season.Episodes.Select(x => x.EpisodeNumber).ToList(); - var unairedEpisodes = sonarrEpisodeList.Where(x => x.airDateUtc > DateTime.UtcNow).Select(x => x.episodeNumber).ToList(); - //// Check if we have requested all the latest episodes, if we have then monitor - //// NOTE, not sure if needed since ombi ui displays future episodes anyway... - //ourEpisodes.AddRange(unairedEpisodes); - //var distinctEpisodes = ourEpisodes.Distinct().ToList(); - //var missingEpisodes = Enumerable.Range(distinctEpisodes.Min(), distinctEpisodes.Count).Except(distinctEpisodes); - - if (sonarrEpCount == ourRequestCount /*|| !missingEpisodes.Any()*/) + // Make sure this season is set to monitored + if (!existingSeason.monitored) { - // We have the same amount of requests as all of the episodes in the season. + // We need to monitor it, problem being is all episodes will now be monitored + // So we need to monitor the series but unmonitor every episode existingSeason.monitored = true; - seriesChanges = true; + var sea = result.seasons.FirstOrDefault(x => x.seasonNumber == existingSeason.seasonNumber); + sea.monitored = true; - // We do not need to update the episodes as marking the season as monitored will mark the episodes as monitored. - var seasonToUpdate = result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber); - seasonToUpdate.monitored = true; // Update by ref - } - else - { - // Make sure this season is set to monitored - if (!existingSeason.monitored) + result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri); + var epToUnmonitored = new List(); + var newEpList = sonarrEpList.ConvertAll(ep => new Episode(ep)); // Clone it so we don't modify the original member + foreach (var ep in newEpList.Where(x => x.seasonNumber == existingSeason.seasonNumber).ToList()) { - // We need to monitor it, problem being is all episodes will now be monitored - // So we need to monitor the series but unmonitor every episode - // Except the episodes that are already monitored before we update the series (we do not want to unmonitored episodes that are monitored beforehand) - existingSeason.monitored = true; - var sea = result.seasons.FirstOrDefault(x => x.seasonNumber == existingSeason.seasonNumber); - sea.monitored = true; - //var previouslyMonitoredEpisodes = sonarrEpList.Where(x => - // x.seasonNumber == existingSeason.seasonNumber && x.monitored).Select(x => x.episodeNumber).ToList(); // We probably don't actually care about this - result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri); - var epToUnmonitored = new List(); - var newEpList = sonarrEpList.ConvertAll(ep => new Episode(ep)); // Clone it so we don't modify the original member - foreach (var ep in newEpList.Where(x => x.seasonNumber == existingSeason.seasonNumber).ToList()) - { - //if (previouslyMonitoredEpisodes.Contains(ep.episodeNumber)) - //{ - // // This was previously monitored. - // continue; - //} - ep.monitored = false; - epToUnmonitored.Add(ep); - } - - foreach (var epToUpdate in epToUnmonitored) - { - await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri); - } + ep.monitored = false; + epToUnmonitored.Add(ep); } - // Now update the episodes that need updating - foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber)) + + foreach (var epToUpdate in epToUnmonitored) { await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri); } } - } - if (seriesChanges) - { - await SonarrApi.SeasonPass(s.ApiKey, s.FullUri, result); + // Now update the episodes that need updating + foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber)) + { + await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri); + } } if (!s.AddOnly) From 59f962550775950815d284159482082b8a231ba6 Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Tue, 19 Apr 2022 08:12:27 +0000 Subject: [PATCH 005/270] chore(release): :rocket: v4.16.13 --- CHANGELOG.md | 13 ++++--------- version.json | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2915d98bba..8e42ab73ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [4.16.13](https://github.com/Ombi-app/Ombi/compare/v4.16.12...v4.16.13) (2022-04-19) + + + ## [4.16.12](https://github.com/Ombi-app/Ombi/compare/v4.16.11...v4.16.12) (2022-04-19) @@ -349,12 +353,3 @@ -## [4.11.5](https://github.com/Ombi-app/Ombi/compare/v4.11.4...v4.11.5) (2022-02-05) - - -### Bug Fixes - -* **sonarr:** Fixed where requesting all seasons would only mark the latest as monitored [#4496](https://github.com/Ombi-app/Ombi/issues/4496) ([cfb85c2](https://github.com/Ombi-app/Ombi/commit/cfb85c23d77626b9ec1d99a6cf76497c438d0338)) - - - diff --git a/version.json b/version.json index e21952327d..d3e43f7731 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.16.12" + "version": "4.16.13" } \ No newline at end of file From 809202be5f730e20b2407e1305519da7d5c42878 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Tue, 19 Apr 2022 10:31:13 +0200 Subject: [PATCH 006/270] Fix requests when 4k available and 4k disabled Fixes #4610 --- .../Jobs/Emby/EmbyAvaliabilityChecker.cs | 11 ++++++++--- .../Jobs/Jellyfin/JellyfinAvaliabilityChecker.cs | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs index 9d88c59075..8e8b75e451 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs @@ -7,10 +7,12 @@ using Microsoft.Extensions.Logging; using Ombi.Core; using Ombi.Core.Notifications; +using Ombi.Core.Services; using Ombi.Helpers; using Ombi.Hubs; using Ombi.Notifications.Models; using Ombi.Schedule.Jobs.Ombi; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; @@ -21,7 +23,7 @@ namespace Ombi.Schedule.Jobs.Emby public class EmbyAvaliabilityChecker : IEmbyAvaliabilityChecker { public EmbyAvaliabilityChecker(IEmbyContentRepository repo, ITvRequestRepository t, IMovieRequestRepository m, - INotificationHelper n, ILogger log, IHubContext notification) + INotificationHelper n, ILogger log, IHubContext notification, IFeatureService featureService) { _repo = repo; _tvRepo = t; @@ -29,6 +31,7 @@ public EmbyAvaliabilityChecker(IEmbyContentRepository repo, ITvRequestRepository _notificationService = n; _log = log; _notification = notification; + _featureService = featureService; } private readonly ITvRequestRepository _tvRepo; @@ -37,6 +40,7 @@ public EmbyAvaliabilityChecker(IEmbyContentRepository repo, ITvRequestRepository private readonly INotificationHelper _notificationService; private readonly ILogger _log; private readonly IHubContext _notification; + private readonly IFeatureService _featureService; public async Task Execute(IJobExecutionContext job) { @@ -53,6 +57,7 @@ await _notification.Clients.Clients(NotificationHub.AdminConnectionIds) private async Task ProcessMovies() { + var feature4kEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available || (!x.Available4K && x.Has4KRequest)); foreach (var movie in movies) @@ -85,8 +90,8 @@ private async Task ProcessMovies() notify = true; } - // If we have a non-4k versison then mark as available - if (embyContent.Quality != null && !movie.Available) + // If we have a non-4k version or we don't care about versions, then mark as available + if (!movie.Available && ( !feature4kEnabled || embyContent.Quality != null )) { movie.Available = true; movie.MarkedAsAvailable = DateTime.Now; diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinAvaliabilityChecker.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinAvaliabilityChecker.cs index b1dafa71fb..79eb5d6a4f 100644 --- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinAvaliabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinAvaliabilityChecker.cs @@ -33,9 +33,11 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Ombi.Core; +using Ombi.Core.Services; using Ombi.Helpers; using Ombi.Hubs; using Ombi.Notifications.Models; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; @@ -46,7 +48,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin public class JellyfinAvaliabilityChecker : IJellyfinAvaliabilityChecker { public JellyfinAvaliabilityChecker(IJellyfinContentRepository repo, ITvRequestRepository t, IMovieRequestRepository m, - INotificationHelper n, ILogger log, IHubContext notification) + INotificationHelper n, ILogger log, IHubContext notification, IFeatureService featureService) { _repo = repo; _tvRepo = t; @@ -54,6 +56,7 @@ public JellyfinAvaliabilityChecker(IJellyfinContentRepository repo, ITvRequestRe _notificationService = n; _log = log; _notification = notification; + _featureService = featureService; } private readonly ITvRequestRepository _tvRepo; @@ -62,6 +65,7 @@ public JellyfinAvaliabilityChecker(IJellyfinContentRepository repo, ITvRequestRe private readonly INotificationHelper _notificationService; private readonly ILogger _log; private readonly IHubContext _notification; + private readonly IFeatureService _featureService; public async Task Execute(IJobExecutionContext job) { @@ -78,6 +82,7 @@ await _notification.Clients.Clients(NotificationHub.AdminConnectionIds) private async Task ProcessMovies() { + var feature4kEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available || (!x.Available4K && x.Has4KRequest)); foreach (var movie in movies) @@ -110,8 +115,8 @@ private async Task ProcessMovies() notify = true; } - // If we have a non-4k versison then mark as available - if (jellyfinContent.Quality != null && !movie.Available) + // If we have a non-4k version or we don't care about versions, then mark as available + if (!movie.Available && ( !feature4kEnabled || jellyfinContent.Quality != null )) { movie.Available = true; movie.MarkedAsAvailable = DateTime.Now; From eea8663f7d09cc1b50bb4ab95e30a8dff076da90 Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Tue, 19 Apr 2022 08:49:14 +0000 Subject: [PATCH 007/270] chore(release): :rocket: v4.16.14 --- CHANGELOG.md | 13 ++++--------- version.json | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e42ab73ea..9ca246ad91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [4.16.14](https://github.com/Ombi-app/Ombi/compare/v4.16.13...v4.16.14) (2022-04-19) + + + ## [4.16.13](https://github.com/Ombi-app/Ombi/compare/v4.16.12...v4.16.13) (2022-04-19) @@ -344,12 +348,3 @@ -## [4.11.6](https://github.com/Ombi-app/Ombi/compare/v4.11.5...v4.11.6) (2022-02-10) - - -### Bug Fixes - -* **plex:** Fixed an issue where in a rare case we couldn't sync the data [#4502](https://github.com/Ombi-app/Ombi/issues/4502) ([191318d](https://github.com/Ombi-app/Ombi/commit/191318ddad5a8148422955bf928f1c49b890e3eb)) - - - diff --git a/version.json b/version.json index d3e43f7731..13e40434e6 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.16.13" + "version": "4.16.14" } \ No newline at end of file From a0e0ae1da35bbc16dbd3c496f7443026c717926d Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Tue, 19 Apr 2022 11:49:15 +0200 Subject: [PATCH 008/270] Hide subscribe button when request is available --- src/Ombi.Core/Engine/MovieRequestEngine.cs | 5 ++++- src/Ombi.Core/Engine/MusicRequestEngine.cs | 5 ++++- src/Ombi.Core/Engine/TvRequestEngine.cs | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index cb4cb4ba65..b290633d58 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -533,7 +533,10 @@ private async Task CheckForSubscription(string UserId, List movie } else { - x.ShowSubscribe = true; + if (!x.Available && !x.Available4K) + { + x.ShowSubscribe = true; + } var hasSub = sub.FirstOrDefault(r => r.RequestId == x.Id); x.Subscribed = hasSub != null; } diff --git a/src/Ombi.Core/Engine/MusicRequestEngine.cs b/src/Ombi.Core/Engine/MusicRequestEngine.cs index 640d2ade34..e6fc1dad8c 100644 --- a/src/Ombi.Core/Engine/MusicRequestEngine.cs +++ b/src/Ombi.Core/Engine/MusicRequestEngine.cs @@ -270,7 +270,10 @@ private async Task CheckForSubscription(HideResult shouldHide, List r.RequestId == x.Id); x.Subscribed = hasSub != null; } diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index 5664d276f6..a684f903c5 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -886,7 +886,10 @@ private async Task CheckForSubscription(HideResult shouldHide, List s.RequestId == x.Id); x.Subscribed = result != null; } From 8daf8e0c7f988e48a9b2ea520ef184411e0f7bb9 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Tue, 19 Apr 2022 12:00:40 +0200 Subject: [PATCH 009/270] Hide subscribe button when request is denied --- src/Ombi.Core/Engine/MovieRequestEngine.cs | 2 +- src/Ombi.Core/Engine/MusicRequestEngine.cs | 2 +- src/Ombi.Core/Engine/TvRequestEngine.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index b290633d58..9403fdcaec 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -533,7 +533,7 @@ private async Task CheckForSubscription(string UserId, List movie } else { - if (!x.Available && !x.Available4K) + if (!x.Available && !x.Available4K && (!x.Denied ?? true) && (!x.Denied4K ?? true)) { x.ShowSubscribe = true; } diff --git a/src/Ombi.Core/Engine/MusicRequestEngine.cs b/src/Ombi.Core/Engine/MusicRequestEngine.cs index e6fc1dad8c..67caa81a2f 100644 --- a/src/Ombi.Core/Engine/MusicRequestEngine.cs +++ b/src/Ombi.Core/Engine/MusicRequestEngine.cs @@ -270,7 +270,7 @@ private async Task CheckForSubscription(HideResult shouldHide, List Date: Tue, 19 Apr 2022 21:26:11 +0200 Subject: [PATCH 010/270] Add Title to Partially Available Message If the Title of the show is not menitoned it can be unclear what Episodes are now available. --- src/Ombi.Store/Context/OmbiContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index 0681d9ca0d..77298e7199 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -212,7 +212,7 @@ public void Seed() notificationToAdd = new NotificationTemplates { NotificationType = notificationType, - Message = "Your TV request is now partially available! Season {PartiallyAvailableSeasonNumber} Episodes {PartiallyAvailableEpisodeNumbers}!", + Message = "Your TV request for {Title} is now partially available! Season {PartiallyAvailableSeasonNumber} Episodes {PartiallyAvailableEpisodeNumbers}!", Subject = "{ApplicationName}: Partially Available Request!", Agent = agent, Enabled = true, From 4fa71f71a09dfc3a313bfd8f276960ff560c3e33 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Wed, 20 Apr 2022 13:30:03 +0200 Subject: [PATCH 011/270] Better error message when test email fails due to missing recipient --- src/Ombi/Controllers/V1/External/TesterController.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Ombi/Controllers/V1/External/TesterController.cs b/src/Ombi/Controllers/V1/External/TesterController.cs index f18547e0fe..6ee0ebe226 100644 --- a/src/Ombi/Controllers/V1/External/TesterController.cs +++ b/src/Ombi/Controllers/V1/External/TesterController.cs @@ -282,11 +282,18 @@ public async Task Email([FromBody] EmailNotificationSettings settings) { try { + var currentUser = await GetCurrentUserAsync(); + + if (!currentUser.Email.HasValue()) + { + throw new Exception($"User '{currentUser.UserName}' has no email address set on their user profile."); + } + var message = new NotificationMessage { Message = "This is just a test! Success!", Subject = $"Ombi: Test", - To = (await GetCurrentUserAsync()).Email, + To = currentUser.Email, }; message.Other.Add("PlainTextBody", "This is just a test! Success!"); @@ -539,7 +546,7 @@ public async Task WhatsAppTest([FromBody] WhatsAppSettingsViewModel settin { var user = await UserManager.Users.Include(x => x.UserNotificationPreferences).FirstOrDefaultAsync(x => x.UserName == HttpContext.User.Identity.Name); - + var status = await WhatsAppApi.SendMessage(new WhatsAppModel { From = settings.From, From ef7ec861d8aede2a4817752c990617f583805391 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Sat, 23 Apr 2022 12:42:30 +0200 Subject: [PATCH 012/270] feat(discover): Add original language filter --- src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs | 2 + src/Ombi.Core/Engine/V2/MultiSearchEngine.cs | 5 ++ .../Models/External/TheMovieDbSettings.cs | 2 + src/Ombi.TheMovieDbApi/IMovieDbApi.cs | 1 + src/Ombi.TheMovieDbApi/Models/Language.cs | 14 +++++ src/Ombi.TheMovieDbApi/TheMovieDbApi.cs | 14 +++++ .../ClientApp/src/app/interfaces/IMovieDb.ts | 5 ++ .../ClientApp/src/app/interfaces/ISettings.ts | 3 +- .../src/app/services/searchV2.service.ts | 8 ++- .../themoviedb/themoviedb.component.html | 12 ++++- .../themoviedb/themoviedb.component.ts | 53 +++++++++++-------- src/Ombi/Controllers/V2/SearchController.cs | 7 +++ 12 files changed, 100 insertions(+), 26 deletions(-) create mode 100644 src/Ombi.TheMovieDbApi/Models/Language.cs diff --git a/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs b/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs index 7ad8c509a2..7666db6fe6 100644 --- a/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs +++ b/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Models.Search.V2; +using Ombi.TheMovieDbApi.Models; // Due to conflicting Genre models in // Ombi.TheMovieDbApi.Models and Ombi.Api.TheMovieDb.Models @@ -14,5 +15,6 @@ public interface IMultiSearchEngine { Task> MultiSearch(string searchTerm, MultiSearchFilter filter, CancellationToken cancellationToken); Task> GetGenres(string media, CancellationToken requestAborted); + Task> GetLanguages(CancellationToken requestAborted); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs b/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs index 362a79e43d..3f96f15986 100644 --- a/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs +++ b/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs @@ -17,6 +17,7 @@ using Ombi.Settings.Settings.Models.External; using Ombi.Store.Entities; using Ombi.Store.Repository; +using Ombi.TheMovieDbApi.Models; // Due to conflicting Genre models in // Ombi.TheMovieDbApi.Models and Ombi.Api.TheMovieDb.Models @@ -124,5 +125,9 @@ public async Task> GetGenres(string media, CancellationToken var lang = await DefaultLanguageCode(null); return await _movieDbApi.GetGenres(media, cancellationToken, lang); } + public async Task> GetLanguages(CancellationToken cancellationToken) + { + return await _movieDbApi.GetLanguages(cancellationToken); + } } } diff --git a/src/Ombi.Settings/Settings/Models/External/TheMovieDbSettings.cs b/src/Ombi.Settings/Settings/Models/External/TheMovieDbSettings.cs index c2df1b9b35..cbb0233a0e 100644 --- a/src/Ombi.Settings/Settings/Models/External/TheMovieDbSettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/TheMovieDbSettings.cs @@ -11,5 +11,7 @@ public sealed class TheMovieDbSettings : Ombi.Settings.Settings.Models.Settings public List ExcludedMovieGenreIds { get; set; } public List ExcludedTvGenreIds { get; set; } + + public List OriginalLanguages { get; set; } } } diff --git a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs index dc2e5525c6..51da958b62 100644 --- a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs @@ -41,6 +41,7 @@ public interface IMovieDbApi Task GetMovieWatchProviders(int theMoviedbId, CancellationToken token); Task GetTvWatchProviders(int theMoviedbId, CancellationToken token); Task> GetGenres(string media, CancellationToken cancellationToken, string languageCode); + Task> GetLanguages(CancellationToken cancellationToken); Task> SearchWatchProviders(string media, string searchTerm, CancellationToken cancellationToken); Task> AdvancedSearch(DiscoverModel model, CancellationToken cancellationToken); } diff --git a/src/Ombi.TheMovieDbApi/Models/Language.cs b/src/Ombi.TheMovieDbApi/Models/Language.cs new file mode 100644 index 0000000000..c6b14a6549 --- /dev/null +++ b/src/Ombi.TheMovieDbApi/Models/Language.cs @@ -0,0 +1,14 @@ +ο»Ώusing Newtonsoft.Json; + +namespace Ombi.TheMovieDbApi.Models +{ + public class Language + { + [JsonProperty("iso_639_1")] + public string Id { get; set; } + [JsonProperty("english_name")] + public string EnglishName { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs index 335ea7da3a..02862fb7d8 100644 --- a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs @@ -438,6 +438,16 @@ public async Task> GetGenres(string media, CancellationToken cancell return result.genres ?? new List(); } + public async Task> GetLanguages(CancellationToken cancellationToken) + { + var request = new Request($"/configuration/languages", BaseUri, HttpMethod.Get); + request.AddQueryString("api_key", ApiToken); + AddRetry(request); + + var result = await Api.Request>(request, cancellationToken); + return result ?? new List(); + } + public Task> MultiSearch(string searchTerm, string languageCode, CancellationToken cancellationToken) { var request = new Request("search/multi", BaseUri, HttpMethod.Get); @@ -472,6 +482,10 @@ private async Task AddDiscoverSettings(Request request) { request.AddQueryString("without_keywords", string.Join(",", settings.ExcludedKeywordIds)); } + if (settings.OriginalLanguages?.Any() == true) + { + request.AddQueryString("with_original_language", string.Join("|", settings.OriginalLanguages)); + } } private async Task AddGenreFilter(Request request, string media_type) diff --git a/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts b/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts index f82225434c..77352de4bb 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts @@ -17,3 +17,8 @@ export interface IDiscoverModel { watchProviders?: number[]; companies?: number[]; } +export interface ILanguage { + iso_639_1 : string; + english_name : string; + name : string; +} diff --git a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts index 95b1fba00a..4594d2a2f7 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts @@ -339,7 +339,8 @@ export interface ITheMovieDbSettings extends ISettings { showAdultMovies: boolean; excludedKeywordIds: number[]; excludedMovieGenreIds: number[]; - excludedTvGenreIds: number[] + excludedTvGenreIds: number[]; + originalLanguages: string[]; } export interface IUpdateModel diff --git a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts index c806553706..56b1057c60 100644 --- a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts +++ b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts @@ -4,7 +4,7 @@ import { Injectable, Inject } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { Observable } from "rxjs"; -import { IDiscoverModel, IMovieDbKeyword, IMultiSearchResult, ISearchMovieResult, ISearchTvResult } from "../interfaces"; +import { IDiscoverModel, ILanguage, IMovieDbKeyword, IMultiSearchResult, ISearchMovieResult, ISearchTvResult } from "../interfaces"; import { ServiceHelpers } from "./service.helpers"; import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2"; @@ -23,11 +23,15 @@ export class SearchV2Service extends ServiceHelpers { public multiSearch(searchTerm: string, filter: SearchFilter): Observable { return this.http.post(`${this.url}/multi/${encodeURIComponent(searchTerm)}`, filter); } - + public getGenres(media: string): Observable { return this.http.get(`${this.url}/Genres/${media}`, { headers: this.headers }) } + public getLanguages(): Observable { + return this.http.get(`${this.url}/Languages`, { headers: this.headers }) + } + public getFullMovieDetails(theMovieDbId: number): Observable { return this.http.get(`${this.url}/Movie/${theMovieDbId}`); } diff --git a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.html b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.html index fb10cc142f..d017689475 100644 --- a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.html +++ b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.html @@ -13,6 +13,14 @@
+ + Original languages + + + {{language.english_name}} + + + - +
Movie Genres @@ -51,7 +59,7 @@ {{key.name}} - +
diff --git a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts index 512f603635..7f4076e87b 100644 --- a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts @@ -1,7 +1,7 @@ ο»Ώimport {COMMA, ENTER} from "@angular/cdk/keycodes"; import { Component, ElementRef, OnInit, ViewChild } from "@angular/core"; import { FormBuilder, FormGroup } from "@angular/forms"; -import { IMovieDbKeyword, ITheMovieDbSettings } from "../../interfaces"; +import { ILanguage, IMovieDbKeyword, ITheMovieDbSettings } from "../../interfaces"; import { debounceTime, switchMap } from "rxjs/operators"; import { MatAutocomplete } from "@angular/material/autocomplete"; @@ -22,14 +22,17 @@ interface IKeywordTag { export class TheMovieDbComponent implements OnInit { public settings: ITheMovieDbSettings; + public originalLanguages: ILanguage[]; public excludedKeywords: IKeywordTag[]; public excludedMovieGenres: IKeywordTag[]; public excludedTvGenres: IKeywordTag[]; public tagForm: FormGroup; + public languages: ILanguage[]; public filteredTags: IMovieDbKeyword[]; public filteredMovieGenres: IMovieDbKeyword[]; public filteredTvGenres: IMovieDbKeyword[]; + constructor(private settingsService: SettingsService, private notificationService: NotificationService, private tmdbService: TheMovieDbService, @@ -37,14 +40,30 @@ export class TheMovieDbComponent implements OnInit { private fb: FormBuilder) { } public ngOnInit() { - this.tagForm = this.fb.group({ - input: null, - excludedMovieGenres: null, - excludedTvGenres: null, - }); this.settingsService.getTheMovieDbSettings().subscribe(settings => { this.settings = settings; + this.tagForm = this.fb.group({ + input: null, + originalLanguages: [this.settings.originalLanguages], + excludedMovieGenres: null, + excludedTvGenres: null, + }); + + this.tagForm + .get("input") + .valueChanges.pipe( + debounceTime(600), + switchMap((value: string) => { + if (value) { + return this.tmdbService.getKeywords(value); + } + return []; + }) + ) + .subscribe((r) => (this.filteredTags = r)); + + // Map Keyword ids -> keyword name this.excludedKeywords = settings.excludedKeywordIds ? settings.excludedKeywordIds.map(id => ({ @@ -82,8 +101,12 @@ export class TheMovieDbComponent implements OnInit { } }); }); - }); - + }); + + this.searchService.getLanguages().subscribe((results) => { + this.languages = results.sort((a: ILanguage, b: ILanguage) => (a.english_name > b.english_name) ? 1 : -1);; + }); + // Map Tv Genre ids -> genre name this.excludedTvGenres = settings.excludedTvGenreIds ? settings.excludedTvGenreIds.map(id => ({ @@ -102,22 +125,10 @@ export class TheMovieDbComponent implements OnInit { genre.name = result.name; } }); - }); + }); }); }); - this.tagForm - .get("input") - .valueChanges.pipe( - debounceTime(600), - switchMap((value: string) => { - if (value) { - return this.tmdbService.getKeywords(value); - } - return []; - }) - ) - .subscribe((r) => (this.filteredTags = r)); } public remove(tag: IKeywordTag, tag_type: string): void { diff --git a/src/Ombi/Controllers/V2/SearchController.cs b/src/Ombi/Controllers/V2/SearchController.cs index fc970b793d..5227f06ec8 100644 --- a/src/Ombi/Controllers/V2/SearchController.cs +++ b/src/Ombi/Controllers/V2/SearchController.cs @@ -19,6 +19,7 @@ // Due to conflicting Genre models in // Ombi.TheMovieDbApi.Models and Ombi.Api.TheMovieDb.Models using Genre = Ombi.TheMovieDbApi.Models.Genre; +using Ombi.TheMovieDbApi.Models; namespace Ombi.Controllers.V2 { @@ -69,6 +70,12 @@ public Task> GetGenres(string media) return _multiSearchEngine.GetGenres(media, HttpContext.RequestAborted); } + [HttpGet("Languages")] + public Task> GetLanguages() + { + return _multiSearchEngine.GetLanguages(HttpContext.RequestAborted); + } + /// /// Returns details for a single movie /// From 1027fcf1f3d2a109a32edd38825870046dc50e67 Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Sun, 24 Apr 2022 20:51:46 +0000 Subject: [PATCH 013/270] chore(release): :rocket: v4.16.15 --- CHANGELOG.md | 13 ++++--------- version.json | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ca246ad91..1bcd20e552 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [4.16.15](https://github.com/Ombi-app/Ombi/compare/v4.16.14...v4.16.15) (2022-04-24) + + + ## [4.16.14](https://github.com/Ombi-app/Ombi/compare/v4.16.13...v4.16.14) (2022-04-19) @@ -339,12 +343,3 @@ -## [4.11.7](https://github.com/Ombi-app/Ombi/compare/v4.11.6...v4.11.7) (2022-02-12) - - -### Bug Fixes - -* **notifications:** :bug: This is a fix for some of the duplicate notification issues [#3825](https://github.com/Ombi-app/Ombi/issues/3825) ([22bb422](https://github.com/Ombi-app/Ombi/commit/22bb4226ead2d62e8c2c2c05be47d7da621402e2)) - - - diff --git a/version.json b/version.json index 13e40434e6..ca01d90f9d 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.16.14" + "version": "4.16.15" } \ No newline at end of file From d8f2260c7ae3ed48386743b7adbd06e284487034 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sun, 24 Apr 2022 22:10:44 +0100 Subject: [PATCH 014/270] fix(4616): :bug: fixed mandatory fields --- .../movies-grid/movies-grid.component.html | 4 ++-- .../radarr/components/radarr-form.component.ts | 6 +++--- .../app/settings/radarr/radarr.component.html | 2 ++ .../src/app/settings/radarr/radarr.component.ts | 16 +++++++++++++++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html index 77dacd1e9a..26da475241 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html +++ b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html @@ -84,7 +84,7 @@ {{ 'Requests.Details' | translate}} - + {{ 'Requests.Options' | translate}} @@ -103,4 +103,4 @@ - \ No newline at end of file + diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts index e85bfc08b7..7b331e5ebe 100644 --- a/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts @@ -9,7 +9,7 @@ import { TesterService, NotificationService, RadarrService } from "../../../serv selector: "ombi-settings-radarr-form", templateUrl: "./radarr-form.component.html", styleUrls: ["./radarr-form.component.scss"], - // changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush }) export class RadarrFormComponent implements OnInit { @@ -23,11 +23,11 @@ export class RadarrFormComponent implements OnInit { constructor(private radarrService: RadarrService, private notificationService: NotificationService, private testerService: TesterService, - private controlContainer: ControlContainer) { } + private controlContainer: ControlContainer) { + } public ngOnInit() { this.form = this.controlContainer.control; - // this.toggleValidators(); this.qualities = []; this.qualities.push({ name: "Please Select", id: -1 }); diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.html b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.html index 724beccf1a..5a3e24e901 100644 --- a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.html +++ b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.html @@ -8,11 +8,13 @@ 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 1e2925f13e..87f83efcce 100644 --- a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts @@ -1,9 +1,10 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit, QueryList, ViewChild, ViewChildren } from "@angular/core"; import { FormBuilder, FormGroup } from "@angular/forms"; import { IMinimumAvailability, IRadarrCombined, IRadarrProfile, IRadarrRootFolder } from "../../interfaces"; import { NotificationService, SettingsService } from "../../services"; import { FeaturesFacade } from "../../state/features/features.facade"; +import { RadarrFormComponent } from "./components/radarr-form.component"; @Component({ templateUrl: "./radarr.component.html", @@ -19,11 +20,15 @@ export class RadarrComponent implements OnInit { public form: FormGroup; public is4kEnabled: boolean = false; + @ViewChildren('4kForm') public form4k: QueryList; + @ViewChildren('normalForm') public normalForm: QueryList; + constructor(private settingsService: SettingsService, private notificationService: NotificationService, private featureFacade: FeaturesFacade, private fb: FormBuilder) { } + public ngOnInit() { this.is4kEnabled = this.featureFacade.is4kEnabled(); this.settingsService.getRadarr() @@ -56,7 +61,16 @@ export class RadarrComponent implements OnInit { scanForAvailability: [x.radarr4K.scanForAvailability] }), }); + this.normalForm.changes.forEach((comp => { + comp.first.toggleValidators(); + })) + if (this.is4kEnabled) { + this.form4k.changes.forEach((comp => { + comp.first.toggleValidators(); + })) + } }); + } From da8251c4f2e9c40d8589ef8dbc9563d6f84bba17 Mon Sep 17 00:00:00 2001 From: contrib-readme-bot Date: Mon, 25 Apr 2022 07:05:57 +0000 Subject: [PATCH 015/270] chore: :busts_in_silhouette: Updated Contributors [skip ci] --- README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 32552817ea..a8360d6c87 100644 --- a/README.md +++ b/README.md @@ -665,14 +665,21 @@ Here are some of the features Ombi has: Shoghi + + + Teifun2 +
+ Teifun2 +
+ + thomasvt1
Thomas Van Tilburg
- - + Tim-Trott @@ -707,15 +714,15 @@ Here are some of the features Ombi has:
Xirg
- + + bazhip
Tim OBrien
- - + x-limitless-x @@ -750,15 +757,15 @@ Here are some of the features Ombi has:
M4tta
- + + maartenheebink
Maartenheebink
- - + masterhuck From 8f30fbe69041126df30a998fd8816ada752cabbb Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Mon, 25 Apr 2022 07:09:07 +0000 Subject: [PATCH 016/270] chore(release): :rocket: v4.16.16 --- CHANGELOG.md | 18 +++++++++--------- version.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bcd20e552..466e6b68d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [4.16.16](https://github.com/Ombi-app/Ombi/compare/v4.16.15...v4.16.16) (2022-04-25) + + +### Bug Fixes + +* **4616:** :bug: fixed mandatory fields ([d8f2260](https://github.com/Ombi-app/Ombi/commit/d8f2260c7ae3ed48386743b7adbd06e284487034)) + + + ## [4.16.15](https://github.com/Ombi-app/Ombi/compare/v4.16.14...v4.16.15) (2022-04-24) @@ -334,12 +343,3 @@ -## [4.11.8](https://github.com/Ombi-app/Ombi/compare/v4.11.7...v4.11.8) (2022-02-13) - - -### Bug Fixes - -* **settings:** :bug: Fixed an issue where we were not displaying the excluded keyworks correctly in the TheMovieDbSettings page ([d3b3316](https://github.com/Ombi-app/Ombi/commit/d3b3316cbac18356b2f6b0912a3deb2c183e6534)) - - - diff --git a/version.json b/version.json index ca01d90f9d..dd731e41b7 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.16.15" + "version": "4.16.16" } \ No newline at end of file From 5d58db3a94f61ab3ed0a95729f37be4f29e7ec7f Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 25 Apr 2022 10:54:39 +0100 Subject: [PATCH 017/270] added test results into the PR pipeline --- .github/workflows/pr.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 961871f8af..97ff5f305c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -45,7 +45,16 @@ jobs: - name: Run Unit Tests run: | cd src - dotnet test --logger trx --results-directory "TestResults" + dotnet test --logger "trx;LogFileName=test-results.trx" || true + + - name: Test Report + uses: dorny/test-reporter@v1 + if: always() + with: + name: DotNET Tests + path: "**/test-results.trx" + reporter: dotnet-trx + fail-on-error: true analysis: runs-on: ubuntu-latest From 651fcedcabc0d69f1032290a1ba8c1787bea48bc Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Mon, 25 Apr 2022 10:26:23 +0000 Subject: [PATCH 018/270] chore(release): :rocket: v4.16.17 --- CHANGELOG.md | 13 ++++--------- version.json | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 466e6b68d3..2e14fa33f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [4.16.17](https://github.com/Ombi-app/Ombi/compare/v4.16.16...v4.16.17) (2022-04-25) + + + ## [4.16.16](https://github.com/Ombi-app/Ombi/compare/v4.16.15...v4.16.16) (2022-04-25) @@ -334,12 +338,3 @@ -# [4.12.0](https://github.com/Ombi-app/Ombi/compare/v4.11.8...v4.12.0) (2022-02-14) - - -### Features - -* **radarr:** 4K Requests and Radarr 4K support ([ba88848](https://github.com/Ombi-app/Ombi/commit/ba88848866b0a9dedb1e79b55c4d81a0fd453843)) - - - diff --git a/version.json b/version.json index dd731e41b7..336f028121 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.16.16" + "version": "4.16.17" } \ No newline at end of file From 3cc84778a46191fc0c8d87e2222bef8210cb9351 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Mon, 25 Apr 2022 15:10:57 +0200 Subject: [PATCH 019/270] Add information about cache refresh --- .../src/app/settings/themoviedb/themoviedb.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts index 7f4076e87b..02ce9dc1d1 100644 --- a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts @@ -173,7 +173,7 @@ export class TheMovieDbComponent implements OnInit { this.settingsService.saveTheMovieDbSettings(this.settings).subscribe(x => { if (x) { - this.notificationService.success("Successfully saved The Movie Database settings"); + this.notificationService.success("Successfully saved The Movie Database settings. Restart the server to refresh the cache."); } else { this.notificationService.success("There was an error when saving The Movie Database settings"); } From d792bf5902ad14dcb90b15478ffe3f8b24e99c23 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 25 Apr 2022 16:06:12 +0100 Subject: [PATCH 020/270] Update pr.yml [skip ci] --- .github/workflows/pr.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 97ff5f305c..d8a4cf87f3 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -28,6 +28,8 @@ jobs: unit-test: runs-on: ubuntu-latest + permissions: + checks: write steps: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 From cac0288b724e279de301ee50253569f964c817eb Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 25 Apr 2022 16:18:38 +0100 Subject: [PATCH 021/270] Update pr.yml [skip ci] --- .github/workflows/pr.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d8a4cf87f3..cd911bc0f3 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -47,16 +47,7 @@ jobs: - name: Run Unit Tests run: | cd src - dotnet test --logger "trx;LogFileName=test-results.trx" || true - - - name: Test Report - uses: dorny/test-reporter@v1 - if: always() - with: - name: DotNET Tests - path: "**/test-results.trx" - reporter: dotnet-trx - fail-on-error: true + dotnet test --configuration "Release" --logger "trx;LogFileName=test-results.trx" || true analysis: runs-on: ubuntu-latest From 8b7b11c70ffc562d8227f4599616628a80fbae5e Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 25 Apr 2022 16:18:53 +0100 Subject: [PATCH 022/270] Update pr.yml [skip ci] --- .github/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index cd911bc0f3..08955b8a59 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -47,7 +47,7 @@ jobs: - name: Run Unit Tests run: | cd src - dotnet test --configuration "Release" --logger "trx;LogFileName=test-results.trx" || true + dotnet test --configuration "Release" --logger "trx;LogFileName=test-results.trx" analysis: runs-on: ubuntu-latest From e0a23313c160d6a00f0f6f0c3fe29677527f5b80 Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Mon, 25 Apr 2022 15:23:05 +0000 Subject: [PATCH 023/270] chore(release): :rocket: v4.17.0 --- CHANGELOG.md | 18 +++++++++--------- version.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e14fa33f2..bae5e48519 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# [4.17.0](https://github.com/Ombi-app/Ombi/compare/v4.16.17...v4.17.0) (2022-04-25) + + +### Features + +* **discover:** Add original language filter ([ef7ec86](https://github.com/Ombi-app/Ombi/commit/ef7ec861d8aede2a4817752c990617f583805391)) + + + ## [4.16.17](https://github.com/Ombi-app/Ombi/compare/v4.16.16...v4.16.17) (2022-04-25) @@ -329,12 +338,3 @@ -## [4.12.1](https://github.com/Ombi-app/Ombi/compare/v4.12.0...v4.12.1) (2022-02-16) - - -### Bug Fixes - -* **requests:** :bug: Fixed the issue where Approving a 4K Request wouldn't send it to the correct 4K radarr instance ([87cb990](https://github.com/Ombi-app/Ombi/commit/87cb9903db30e1dead25ee8c5ea34305eb084a03)), closes [#4509](https://github.com/Ombi-app/Ombi/issues/4509) - - - diff --git a/version.json b/version.json index 336f028121..e4a3f1a5b8 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.16.17" + "version": "4.17.0" } \ No newline at end of file From 1a0823ca80559417c67323aaeaa1ef5243e98031 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Mon, 25 Apr 2022 18:53:44 +0200 Subject: [PATCH 024/270] feat(discover): Add new trending source experimental feature --- .../Engine/Interfaces/IMovieEngineV2.cs | 1 + .../Engine/V2/MovieSearchEngineV2.cs | 16 +++++++++++ src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs | 14 +++++++--- .../Settings/Models/FeatureSettings.cs | 1 + src/Ombi.TheMovieDbApi/IMovieDbApi.cs | 2 ++ src/Ombi.TheMovieDbApi/TheMovieDbApi.cs | 27 +++++++++++++++++++ .../carousel-list/carousel-list.component.ts | 4 +++ .../src/app/services/searchV2.service.ts | 4 +++ .../src/app/state/features/features.facade.ts | 4 ++- .../app/state/features/features.selectors.ts | 7 ++++- src/Ombi/Controllers/V2/SearchController.cs | 21 ++++++++++++--- 11 files changed, 93 insertions(+), 8 deletions(-) diff --git a/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs b/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs index 2d86443d18..f70c34c1e8 100644 --- a/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs +++ b/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs @@ -17,6 +17,7 @@ public interface IMovieEngineV2 Task> UpcomingMovies(); Task> NowPlayingMovies(); Task> NowPlayingMovies(int currentPosition, int amountToLoad); + Task> TrendingMovies(int currentPosition, int amountToLoad); Task GetCollection(int collectionId, CancellationToken cancellationToken, string langCode = null); Task GetTvDbId(int theMovieDbId); Task> PopularMovies(int currentlyLoaded, int toLoad, CancellationToken cancellationToken, string langCustomCode = null); diff --git a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs index 3acd7d1f0e..74a49930cd 100644 --- a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs @@ -208,6 +208,22 @@ public async Task> NowPlayingMovies(int curren } return await TransformMovieResultsToResponse(results); } + + public async Task> TrendingMovies(int currentPosition, int amountToLoad) + { + var langCode = await DefaultLanguageCode(null); + + var pages = PaginationHelper.GetNextPages(currentPosition, amountToLoad, _theMovieDbMaxPageItems); + + var results = new List(); + foreach (var pagesToLoad in pages) + { + var apiResult = await Cache.GetOrAddAsync(nameof(NowPlayingMovies) + pagesToLoad.Page + langCode, + () => MovieApi.TrendingMovies(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); + results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); + } + return await TransformMovieResultsToResponse(results); + } public async Task> SeasonalList(int currentPosition, int amountToLoad, CancellationToken cancellationToken) { diff --git a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs index 344ced8132..6de7479649 100644 --- a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs @@ -26,6 +26,7 @@ using Ombi.Core.Engine.Interfaces; using Ombi.Core.Models.UI; using Ombi.Core.Helpers; +using Ombi.Core.Services; namespace Ombi.Core.Engine.V2 { @@ -37,10 +38,12 @@ public class TvSearchEngineV2 : BaseMediaEngine, ITVSearchEngineV2 private readonly IMovieDbApi _movieApi; private readonly ISettingsService _customization; private readonly ITvRequestEngine _requestEngine; + private readonly IFeatureService _feature; public TvSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, ISettingsService s, - IRepository sub, IMovieDbApi movieApi, ISettingsService customization, ITvRequestEngine requestEngine) + IRepository sub, IMovieDbApi movieApi, ISettingsService customization, ITvRequestEngine requestEngine, + IFeatureService feature) : base(identity, service, r, um, memCache, s, sub) { _tvMaze = tvMaze; @@ -49,6 +52,7 @@ public TvSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, ITvM _movieApi = movieApi; _customization = customization; _requestEngine = requestEngine; + _feature = feature; } @@ -132,15 +136,19 @@ public async Task> Anticipated(int currentlyL } public async Task> Trending(int currentlyLoaded, int amountToLoad) - { + { var langCode = await DefaultLanguageCode(null); + var isNewTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.NewTrendingSource); var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit); var results = new List(); foreach (var pagesToLoad in pages) { + var search = ( async () => (isNewTrendingSourceEnabled) ? + await _movieApi.TrendingTv(langCode, pagesToLoad.Page) + : await _movieApi.TopRatedTv(langCode, pagesToLoad.Page)); var apiResult = await Cache.GetOrAddAsync(nameof(Trending) + langCode + pagesToLoad.Page, - async () => await _movieApi.TopRatedTv(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); + search, DateTimeOffset.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); } diff --git a/src/Ombi.Settings/Settings/Models/FeatureSettings.cs b/src/Ombi.Settings/Settings/Models/FeatureSettings.cs index 6a285d4220..b4301b3280 100644 --- a/src/Ombi.Settings/Settings/Models/FeatureSettings.cs +++ b/src/Ombi.Settings/Settings/Models/FeatureSettings.cs @@ -20,5 +20,6 @@ public class FeatureEnablement public static class FeatureNames { public const string Movie4KRequests = nameof(Movie4KRequests); + public const string NewTrendingSource = nameof(NewTrendingSource); } } diff --git a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs index 51da958b62..4f3885ef0a 100644 --- a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs @@ -15,6 +15,7 @@ public interface IMovieDbApi Task GetMovieInformation(int movieId); Task GetMovieInformationWithExtraInfo(int movieId, string langCode = "en"); Task> NowPlaying(string languageCode, int? page = null); + Task> TrendingMovies(string languageCode, int? page = null); Task> PopularMovies(string languageCode, int? page = null, CancellationToken cancellationToken = default(CancellationToken)); Task> PopularTv(string langCode, int? page = null, CancellationToken cancellationToken = default(CancellationToken)); Task> SearchMovie(string searchTerm, int? year, string languageCode); @@ -23,6 +24,7 @@ public interface IMovieDbApi Task> TopRated(string languageCode, int? page = null); Task> Upcoming(string languageCode, int? page = null); Task> TopRatedTv(string languageCode, int? page = null); + Task> TrendingTv(string languageCode, int? page = null); Task> UpcomingTv(string languageCode, int? page = null); Task> SimilarMovies(int movieId, string langCode); Task Find(string externalId, ExternalSource source); diff --git a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs index 02862fb7d8..ba61ccfcf7 100644 --- a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs @@ -281,6 +281,33 @@ private async Task> TopRated(string type, string langC var result = await Api.Request>(request); return Mapper.Map>(result.results); } + + public Task> TrendingMovies(string langCode, int? page = null) + { + return Trending("movie", langCode, page); + } + + public Task> TrendingTv(string langCode, int? page = null) + { + return Trending("tv", langCode, page); + } + private async Task> Trending(string type, string langCode, int? page = null) + { + // https://developers.themoviedb.org/3/trending/get-trending + var timeWindow = "week"; // another option can be 'day' + var request = new Request($"trending/{type}/{timeWindow}", BaseUri, HttpMethod.Get); + request.AddQueryString("api_key", ApiToken); + request.AddQueryString("language", langCode); + + if (page != null) + { + request.AddQueryString("page", page.ToString()); + } + + AddRetry(request); + var result = await Api.Request>(request); + return Mapper.Map>(result.results); + } public Task> Upcoming(string langCode, int? page = null) { diff --git a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts index 9617c993eb..92896a8776 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts @@ -224,7 +224,11 @@ export class CarouselListComponent implements OnInit { this.movies = await this.searchService.popularMoviesByPage(this.currentlyLoaded, this.amountToLoad); break; case DiscoverType.Trending: + if(this.featureFacade.isNewTrendingSourceEnabled) { + this.movies = await this.searchService.trendingMoviesByPage(this.currentlyLoaded, this.amountToLoad); + } else { this.movies = await this.searchService.nowPlayingMoviesByPage(this.currentlyLoaded, this.amountToLoad); + } break; case DiscoverType.Upcoming: this.movies = await this.searchService.upcomingMoviesByPage(this.currentlyLoaded, this.amountToLoad); diff --git a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts index 56b1057c60..fd43044f53 100644 --- a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts +++ b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts @@ -91,6 +91,10 @@ export class SearchV2Service extends ServiceHelpers { return this.http.get(`${this.url}/Movie/nowplaying/${currentlyLoaded}/${toLoad}`).toPromise(); } + public trendingMoviesByPage(currentlyLoaded: number, toLoad: number): Promise { + return this.http.get(`${this.url}/Movie/trending/${currentlyLoaded}/${toLoad}`).toPromise(); + } + public topRatedMovies(): Observable { return this.http.get(`${this.url}/Movie/toprated`); } diff --git a/src/Ombi/ClientApp/src/app/state/features/features.facade.ts b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts index 10e229ebad..4dd74d3f96 100644 --- a/src/Ombi/ClientApp/src/app/state/features/features.facade.ts +++ b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts @@ -23,4 +23,6 @@ export class FeaturesFacade { public is4kEnabled = (): boolean => this.store.selectSnapshot(FeaturesSelectors.is4kEnabled); -} \ No newline at end of file + public isNewTrendingSourceEnabled = (): boolean => this.store.selectSnapshot(FeaturesSelectors.isNewTrendingSourceEnabled); + +} diff --git a/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts b/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts index 143dfb8758..cda4921a73 100644 --- a/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts +++ b/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts @@ -15,4 +15,9 @@ export class FeaturesSelectors { return features.filter(x => x.name === "Movie4KRequests")[0].enabled; } -} \ No newline at end of file + @Selector([FeaturesSelectors.features]) + public static isNewTrendingSourceEnabled(features: IFeatureEnablement[]): boolean { + return features.filter(x => x.name === "NewTrendingSource")[0].enabled; + } + +} diff --git a/src/Ombi/Controllers/V2/SearchController.cs b/src/Ombi/Controllers/V2/SearchController.cs index 5227f06ec8..c487fc4c26 100644 --- a/src/Ombi/Controllers/V2/SearchController.cs +++ b/src/Ombi/Controllers/V2/SearchController.cs @@ -285,6 +285,21 @@ public Task> NowPlayingMovies(int currentPosit () => _movieEngineV2.NowPlayingMovies(currentPosition, amountToLoad), DateTimeOffset.Now.AddHours(12)); } + + /// + /// Returns trending movies by page + /// + /// We use TheMovieDb as the Provider + /// + [HttpGet("movie/trending/{currentPosition}/{amountToLoad}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesDefaultResponseType] + public Task> TrendingMovies(int currentPosition, int amountToLoad) + { + return _mediaCacheService.GetOrAddAsync(nameof(TrendingMovies) + currentPosition + amountToLoad, + () => _movieEngineV2.TrendingMovies(currentPosition, amountToLoad), + DateTimeOffset.Now.AddHours(12)); + } /// /// Returns top rated movies. @@ -392,14 +407,14 @@ public Task> MostWatched(int currentPosition, /// /// Returns trending shows by page /// - /// We use Trakt.tv as the Provider + /// We use TheMovieDb as the Provider /// [HttpGet("tv/trending/{currentPosition}/{amountToLoad}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesDefaultResponseType] - public Task> Trending(int currentPosition, int amountToLoad) + public Task> TrendingTv(int currentPosition, int amountToLoad) { - return _mediaCacheService.GetOrAddAsync(nameof(Trending) + currentPosition + amountToLoad, + return _mediaCacheService.GetOrAddAsync(nameof(TrendingTv) + currentPosition + amountToLoad, () => _tvEngineV2.Trending(currentPosition, amountToLoad), DateTimeOffset.Now.AddHours(12)); } From a373359ae8e6bad42b558a6e01a8ff2840d3bbaa Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Mon, 25 Apr 2022 18:54:29 +0200 Subject: [PATCH 025/270] fix(settings): Allow toggling features when there are more than one --- .../src/app/settings/features/features.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ombi/ClientApp/src/app/settings/features/features.component.html b/src/Ombi/ClientApp/src/app/settings/features/features.component.html index 4eb975cfee..37de15a4c1 100644 --- a/src/Ombi/ClientApp/src/app/settings/features/features.component.html +++ b/src/Ombi/ClientApp/src/app/settings/features/features.component.html @@ -8,7 +8,7 @@
- +

{{feature.name}}

@@ -17,4 +17,4 @@

{{feature.name}}

-
\ No newline at end of file +
From 6794b887f6544fb41528bdd9728b7824b65e47ee Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Mon, 25 Apr 2022 19:16:26 +0200 Subject: [PATCH 026/270] fix(discover): Fix new trending feature detection --- .../components/carousel-list/carousel-list.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts index 92896a8776..dee44fff92 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts @@ -38,6 +38,7 @@ export class CarouselListComponent implements OnInit { public loadingFlag: boolean; public DiscoverType = DiscoverType; public is4kEnabled = false; + public isNewTrendingSourceEnabled = false; get mediaTypeStorageKey() { return "DiscoverOptions" + this.discoverType.toString(); @@ -139,6 +140,7 @@ export class CarouselListComponent implements OnInit { public async ngOnInit() { this.is4kEnabled = this.featureFacade.is4kEnabled(); + this.isNewTrendingSourceEnabled = this.featureFacade.isNewTrendingSourceEnabled(); this.currentlyLoaded = 0; const localDiscoverOptions = +this.storageService.get(this.mediaTypeStorageKey); if (localDiscoverOptions) { @@ -224,7 +226,7 @@ export class CarouselListComponent implements OnInit { this.movies = await this.searchService.popularMoviesByPage(this.currentlyLoaded, this.amountToLoad); break; case DiscoverType.Trending: - if(this.featureFacade.isNewTrendingSourceEnabled) { + if(this.isNewTrendingSourceEnabled) { this.movies = await this.searchService.trendingMoviesByPage(this.currentlyLoaded, this.amountToLoad); } else { this.movies = await this.searchService.nowPlayingMoviesByPage(this.currentlyLoaded, this.amountToLoad); From 03d94220c7eaafb50c6c80a6ed1150794b873ac3 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Mon, 25 Apr 2022 19:16:47 +0200 Subject: [PATCH 027/270] fix(discover): Fix cache mix up --- src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs index 74a49930cd..1a353cb55f 100644 --- a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs @@ -218,7 +218,7 @@ public async Task> TrendingMovies(int currentP var results = new List(); foreach (var pagesToLoad in pages) { - var apiResult = await Cache.GetOrAddAsync(nameof(NowPlayingMovies) + pagesToLoad.Page + langCode, + var apiResult = await Cache.GetOrAddAsync(nameof(TrendingMovies) + pagesToLoad.Page + langCode, () => MovieApi.TrendingMovies(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); } From 70a6a8f953e5bc0d42b371df8cf43a7d18994253 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Tue, 26 Apr 2022 12:56:02 +0200 Subject: [PATCH 028/270] refactor(discover): Move movie trending feature toggle to backend --- .../Engine/Interfaces/IMovieEngineV2.cs | 1 - .../Engine/V2/MovieSearchEngineV2.cs | 29 +++++++------------ .../carousel-list/carousel-list.component.ts | 6 ---- .../src/app/services/searchV2.service.ts | 4 --- .../src/app/state/features/features.facade.ts | 4 +-- .../app/state/features/features.selectors.ts | 7 +---- src/Ombi/Controllers/V2/SearchController.cs | 15 ---------- 7 files changed, 13 insertions(+), 53 deletions(-) diff --git a/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs b/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs index f70c34c1e8..2d86443d18 100644 --- a/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs +++ b/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs @@ -17,7 +17,6 @@ public interface IMovieEngineV2 Task> UpcomingMovies(); Task> NowPlayingMovies(); Task> NowPlayingMovies(int currentPosition, int amountToLoad); - Task> TrendingMovies(int currentPosition, int amountToLoad); Task GetCollection(int collectionId, CancellationToken cancellationToken, string langCode = null); Task GetTvDbId(int theMovieDbId); Task> PopularMovies(int currentlyLoaded, int toLoad, CancellationToken cancellationToken, string langCustomCode = null); diff --git a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs index 1a353cb55f..d4aede4f62 100644 --- a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs @@ -11,6 +11,7 @@ using Ombi.Core.Models.Search.V2; using Ombi.Core.Models.UI; using Ombi.Core.Rule.Interfaces; +using Ombi.Core.Services; using Ombi.Core.Settings; using Ombi.Helpers; using Ombi.Settings.Settings.Models; @@ -31,7 +32,8 @@ public class MovieSearchEngineV2 : BaseMediaEngine, IMovieEngineV2 { public MovieSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, IRepository sub, - ISettingsService customizationSettings, IMovieRequestEngine movieRequestEngine, IHttpClientFactory httpClientFactory) + ISettingsService customizationSettings, IMovieRequestEngine movieRequestEngine, IHttpClientFactory httpClientFactory, + IFeatureService feature) : base(identity, service, r, um, mem, s, sub) { MovieApi = movApi; @@ -40,6 +42,7 @@ public MovieSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, I _customizationSettings = customizationSettings; _movieRequestEngine = movieRequestEngine; _client = httpClientFactory.CreateClient(); + _feature = feature; } private IMovieDbApi MovieApi { get; } @@ -48,6 +51,7 @@ public MovieSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, I private readonly ISettingsService _customizationSettings; private readonly IMovieRequestEngine _movieRequestEngine; private readonly HttpClient _client; + private readonly IFeatureService _feature; public async Task GetFullMovieInformation(int theMovieDbId, CancellationToken cancellationToken, string langCode = null) { @@ -196,30 +200,19 @@ public async Task> TopRatedMovies(int currentP public async Task> NowPlayingMovies(int currentPosition, int amountToLoad) { var langCode = await DefaultLanguageCode(null); + var isNewTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.NewTrendingSource); var pages = PaginationHelper.GetNextPages(currentPosition, amountToLoad, _theMovieDbMaxPageItems); var results = new List(); foreach (var pagesToLoad in pages) { + var search = () => (isNewTrendingSourceEnabled) ? + MovieApi.TrendingMovies(langCode, pagesToLoad.Page) + : MovieApi.NowPlaying(langCode, pagesToLoad.Page); + var apiResult = await Cache.GetOrAddAsync(nameof(NowPlayingMovies) + pagesToLoad.Page + langCode, - () => MovieApi.NowPlaying(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); - results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); - } - return await TransformMovieResultsToResponse(results); - } - - public async Task> TrendingMovies(int currentPosition, int amountToLoad) - { - var langCode = await DefaultLanguageCode(null); - - var pages = PaginationHelper.GetNextPages(currentPosition, amountToLoad, _theMovieDbMaxPageItems); - - var results = new List(); - foreach (var pagesToLoad in pages) - { - var apiResult = await Cache.GetOrAddAsync(nameof(TrendingMovies) + pagesToLoad.Page + langCode, - () => MovieApi.TrendingMovies(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); + search, DateTimeOffset.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); } return await TransformMovieResultsToResponse(results); diff --git a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts index dee44fff92..9617c993eb 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts @@ -38,7 +38,6 @@ export class CarouselListComponent implements OnInit { public loadingFlag: boolean; public DiscoverType = DiscoverType; public is4kEnabled = false; - public isNewTrendingSourceEnabled = false; get mediaTypeStorageKey() { return "DiscoverOptions" + this.discoverType.toString(); @@ -140,7 +139,6 @@ export class CarouselListComponent implements OnInit { public async ngOnInit() { this.is4kEnabled = this.featureFacade.is4kEnabled(); - this.isNewTrendingSourceEnabled = this.featureFacade.isNewTrendingSourceEnabled(); this.currentlyLoaded = 0; const localDiscoverOptions = +this.storageService.get(this.mediaTypeStorageKey); if (localDiscoverOptions) { @@ -226,11 +224,7 @@ export class CarouselListComponent implements OnInit { this.movies = await this.searchService.popularMoviesByPage(this.currentlyLoaded, this.amountToLoad); break; case DiscoverType.Trending: - if(this.isNewTrendingSourceEnabled) { - this.movies = await this.searchService.trendingMoviesByPage(this.currentlyLoaded, this.amountToLoad); - } else { this.movies = await this.searchService.nowPlayingMoviesByPage(this.currentlyLoaded, this.amountToLoad); - } break; case DiscoverType.Upcoming: this.movies = await this.searchService.upcomingMoviesByPage(this.currentlyLoaded, this.amountToLoad); diff --git a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts index fd43044f53..56b1057c60 100644 --- a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts +++ b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts @@ -91,10 +91,6 @@ export class SearchV2Service extends ServiceHelpers { return this.http.get(`${this.url}/Movie/nowplaying/${currentlyLoaded}/${toLoad}`).toPromise(); } - public trendingMoviesByPage(currentlyLoaded: number, toLoad: number): Promise { - return this.http.get(`${this.url}/Movie/trending/${currentlyLoaded}/${toLoad}`).toPromise(); - } - public topRatedMovies(): Observable { return this.http.get(`${this.url}/Movie/toprated`); } diff --git a/src/Ombi/ClientApp/src/app/state/features/features.facade.ts b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts index 4dd74d3f96..10e229ebad 100644 --- a/src/Ombi/ClientApp/src/app/state/features/features.facade.ts +++ b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts @@ -23,6 +23,4 @@ export class FeaturesFacade { public is4kEnabled = (): boolean => this.store.selectSnapshot(FeaturesSelectors.is4kEnabled); - public isNewTrendingSourceEnabled = (): boolean => this.store.selectSnapshot(FeaturesSelectors.isNewTrendingSourceEnabled); - -} +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts b/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts index cda4921a73..143dfb8758 100644 --- a/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts +++ b/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts @@ -15,9 +15,4 @@ export class FeaturesSelectors { return features.filter(x => x.name === "Movie4KRequests")[0].enabled; } - @Selector([FeaturesSelectors.features]) - public static isNewTrendingSourceEnabled(features: IFeatureEnablement[]): boolean { - return features.filter(x => x.name === "NewTrendingSource")[0].enabled; - } - -} +} \ No newline at end of file diff --git a/src/Ombi/Controllers/V2/SearchController.cs b/src/Ombi/Controllers/V2/SearchController.cs index c487fc4c26..429add7c82 100644 --- a/src/Ombi/Controllers/V2/SearchController.cs +++ b/src/Ombi/Controllers/V2/SearchController.cs @@ -285,21 +285,6 @@ public Task> NowPlayingMovies(int currentPosit () => _movieEngineV2.NowPlayingMovies(currentPosition, amountToLoad), DateTimeOffset.Now.AddHours(12)); } - - /// - /// Returns trending movies by page - /// - /// We use TheMovieDb as the Provider - /// - [HttpGet("movie/trending/{currentPosition}/{amountToLoad}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesDefaultResponseType] - public Task> TrendingMovies(int currentPosition, int amountToLoad) - { - return _mediaCacheService.GetOrAddAsync(nameof(TrendingMovies) + currentPosition + amountToLoad, - () => _movieEngineV2.TrendingMovies(currentPosition, amountToLoad), - DateTimeOffset.Now.AddHours(12)); - } /// /// Returns top rated movies. From 4f12939e22020a67a5ee75e2907923faea136e8d Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Tue, 26 Apr 2022 12:58:21 +0200 Subject: [PATCH 029/270] feat(discover): Default trending source to new logic --- src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs | 8 ++++---- src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs | 8 ++++---- src/Ombi.Settings/Settings/Models/FeatureSettings.cs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs index d4aede4f62..3423bc139c 100644 --- a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs @@ -200,16 +200,16 @@ public async Task> TopRatedMovies(int currentP public async Task> NowPlayingMovies(int currentPosition, int amountToLoad) { var langCode = await DefaultLanguageCode(null); - var isNewTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.NewTrendingSource); + var isOldTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.OldTrendingSource); var pages = PaginationHelper.GetNextPages(currentPosition, amountToLoad, _theMovieDbMaxPageItems); var results = new List(); foreach (var pagesToLoad in pages) { - var search = () => (isNewTrendingSourceEnabled) ? - MovieApi.TrendingMovies(langCode, pagesToLoad.Page) - : MovieApi.NowPlaying(langCode, pagesToLoad.Page); + var search = () => (isOldTrendingSourceEnabled) ? + MovieApi.NowPlaying(langCode, pagesToLoad.Page) + : MovieApi.TrendingMovies(langCode, pagesToLoad.Page); var apiResult = await Cache.GetOrAddAsync(nameof(NowPlayingMovies) + pagesToLoad.Page + langCode, search, DateTimeOffset.Now.AddHours(12)); diff --git a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs index 6de7479649..21035567a8 100644 --- a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs @@ -138,15 +138,15 @@ public async Task> Anticipated(int currentlyL public async Task> Trending(int currentlyLoaded, int amountToLoad) { var langCode = await DefaultLanguageCode(null); - var isNewTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.NewTrendingSource); + var isOldTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.OldTrendingSource); var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit); var results = new List(); foreach (var pagesToLoad in pages) { - var search = ( async () => (isNewTrendingSourceEnabled) ? - await _movieApi.TrendingTv(langCode, pagesToLoad.Page) - : await _movieApi.TopRatedTv(langCode, pagesToLoad.Page)); + var search = ( async () => (isOldTrendingSourceEnabled) ? + await _movieApi.TopRatedTv(langCode, pagesToLoad.Page) + : await _movieApi.TrendingTv(langCode, pagesToLoad.Page)); var apiResult = await Cache.GetOrAddAsync(nameof(Trending) + langCode + pagesToLoad.Page, search, DateTimeOffset.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); diff --git a/src/Ombi.Settings/Settings/Models/FeatureSettings.cs b/src/Ombi.Settings/Settings/Models/FeatureSettings.cs index b4301b3280..9d0149e5d4 100644 --- a/src/Ombi.Settings/Settings/Models/FeatureSettings.cs +++ b/src/Ombi.Settings/Settings/Models/FeatureSettings.cs @@ -20,6 +20,6 @@ public class FeatureEnablement public static class FeatureNames { public const string Movie4KRequests = nameof(Movie4KRequests); - public const string NewTrendingSource = nameof(NewTrendingSource); + public const string OldTrendingSource = nameof(OldTrendingSource); } } From 5973056393274759fb5b340088a09f7d929eaf79 Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Tue, 26 Apr 2022 14:45:31 +0000 Subject: [PATCH 030/270] chore(release): :rocket: v4.18.0 --- CHANGELOG.md | 26 +++++++++++++++++--------- version.json | 2 +- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bae5e48519..256e31749b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +# [4.18.0](https://github.com/Ombi-app/Ombi/compare/v4.17.0...v4.18.0) (2022-04-26) + + +### Bug Fixes + +* **discover:** Fix cache mix up ([03d9422](https://github.com/Ombi-app/Ombi/commit/03d94220c7eaafb50c6c80a6ed1150794b873ac3)) +* **discover:** Fix new trending feature detection ([6794b88](https://github.com/Ombi-app/Ombi/commit/6794b887f6544fb41528bdd9728b7824b65e47ee)) +* **settings:** Allow toggling features when there are more than one ([a373359](https://github.com/Ombi-app/Ombi/commit/a373359ae8e6bad42b558a6e01a8ff2840d3bbaa)) + + +### Features + +* **discover:** Add new trending source experimental feature ([1a0823c](https://github.com/Ombi-app/Ombi/commit/1a0823ca80559417c67323aaeaa1ef5243e98031)) +* **discover:** Default trending source to new logic ([4f12939](https://github.com/Ombi-app/Ombi/commit/4f12939e22020a67a5ee75e2907923faea136e8d)) + + + # [4.17.0](https://github.com/Ombi-app/Ombi/compare/v4.16.17...v4.17.0) (2022-04-25) @@ -329,12 +346,3 @@ -## [4.12.2](https://github.com/Ombi-app/Ombi/compare/v4.12.1...v4.12.2) (2022-02-16) - - -### Bug Fixes - -* **requests:** :bug: Fixed the approve 4k option on the requests list not working as expected ([c0189da](https://github.com/Ombi-app/Ombi/commit/c0189dad478ea375beda61ba3bee3f029a39b8e5)) - - - diff --git a/version.json b/version.json index e4a3f1a5b8..48c62b29c1 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.17.0" + "version": "4.18.0" } \ No newline at end of file From 5938077d82a5357f79c07b218b3986557a5816e8 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Tue, 26 Apr 2022 17:33:33 +0200 Subject: [PATCH 031/270] feat(sync): Detect reidentified movies in Emby and Jellyfin --- .../Jobs/Emby/EmbyContentSync.cs | 43 ++++++++++++------ .../Jobs/Jellyfin/JellyfinContentSync.cs | 44 +++++++++++++------ 2 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index b4d61f93d0..8d93c804c1 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -265,23 +265,22 @@ private async Task ProcessMovies(EmbyMovie movieInfo, ICollection c return; } _logger.LogDebug($"Adding new movie {movieInfo.Name}"); - - content.Add(new EmbyContent - { - ImdbId = movieInfo.ProviderIds.Imdb, - TheMovieDbId = movieInfo.ProviderIds?.Tmdb, - Title = movieInfo.Name, - Type = MediaType.Movie, - EmbyId = movieInfo.Id, - Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname), - AddedAt = DateTime.UtcNow, - Quality = has4K ? null : quality, - Has4K = has4K - }); + var newMovie = new EmbyContent(); + newMovie.AddedAt = DateTime.UtcNow; + MapEmbyContent(newMovie, movieInfo, server, has4K, quality); + content.Add(newMovie); } else { - if (!quality.Equals(existingMovie?.Quality, StringComparison.InvariantCultureIgnoreCase)) + var movieHasChanged = false; + if(existingMovie.ImdbId != movieInfo.ProviderIds.Imdb || existingMovie.TheMovieDbId != movieInfo.ProviderIds.Tmdb) + { + _logger.LogDebug($"Updating existing movie '{movieInfo.Name}'"); + MapEmbyContent(existingMovie, movieInfo, server, has4K, quality); + movieHasChanged = true; + + } + else if (!quality.Equals(existingMovie?.Quality, StringComparison.InvariantCultureIgnoreCase)) { _logger.LogDebug($"We have found another quality for Movie '{movieInfo.Name}', Quality: '{quality}'"); existingMovie.Quality = has4K ? null : quality; @@ -290,6 +289,11 @@ private async Task ProcessMovies(EmbyMovie movieInfo, ICollection c // Probably could refactor here // If a 4k movie comes in (we don't store the quality on 4k) // it will always get updated even know it's not changed + movieHasChanged = true; + } + + if(movieHasChanged) + { toUpdate.Add(existingMovie); } else @@ -300,6 +304,17 @@ private async Task ProcessMovies(EmbyMovie movieInfo, ICollection c } } + private void MapEmbyContent(EmbyContent content, EmbyMovie movieInfo, EmbyServers server, bool has4K, string quality){ + content.ImdbId = movieInfo.ProviderIds.Imdb; + content.TheMovieDbId = movieInfo.ProviderIds?.Tmdb; + content.Title = movieInfo.Name; + content.Type = MediaType.Movie; + content.EmbyId = movieInfo.Id; + content.Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname); + content.Quality = has4K ? null : quality; + content.Has4K = has4K; + } + private bool ValidateSettings(EmbyServers server) { if (server?.Ip == null || string.IsNullOrEmpty(server?.ApiKey)) diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs index 060c974e77..eb937ecf0e 100644 --- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs @@ -230,22 +230,22 @@ private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection Date: Tue, 26 Apr 2022 18:17:07 +0200 Subject: [PATCH 032/270] feat(sync): Detect reidentified series in Emby and Jellyfin --- src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs | 11 +++++++++++ .../Jobs/Jellyfin/JellyfinContentSync.cs | 11 +++++++++++ src/Ombi.Store/Repository/EmbyContentRepository.cs | 7 +++++++ .../Repository/IMediaServerContentRepository.cs | 1 + .../Repository/JellyfinContentRepository.cs | 7 +++++++ src/Ombi.Store/Repository/MediaServerRepository.cs | 1 + src/Ombi.Store/Repository/PlexContentRepository.cs | 7 +++++++ 7 files changed, 45 insertions(+) diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index 8d93c804c1..c0acba55c4 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -157,6 +157,17 @@ private async Task ProcessTv(EmbyServers server, bool recentlyAdded, string pare } var existingTv = await _repo.GetByEmbyId(tvShow.Id); + + if (existingTv != null && + ( existingTv.ImdbId != tvShow.ProviderIds?.Imdb + || existingTv.TheMovieDbId != tvShow.ProviderIds?.Tmdb + || existingTv.TvDbId != tvShow.ProviderIds?.Tvdb)) + { + _logger.LogCritical($"Series '{tvShow.Name}' has different IDs, probably a reidentification."); + await _repo.DeleteTv(existingTv); + existingTv = null; + } + if (existingTv == null) { _logger.LogDebug("Adding new TV Show {0}", tvShow.Name); diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs index eb937ecf0e..cdbb886611 100644 --- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs @@ -132,6 +132,17 @@ private async Task ProcessTv(JellyfinServers server, string parentId = default) } var existingTv = await _repo.GetByJellyfinId(tvShow.Id); + + if (existingTv != null && + ( existingTv.ImdbId != tvShow.ProviderIds?.Imdb + || existingTv.TheMovieDbId != tvShow.ProviderIds?.Tmdb + || existingTv.TvDbId != tvShow.ProviderIds?.Tvdb)) + { + _logger.LogDebug($"Series '{tvShow.Name}' has different IDs, probably a reidentification."); + await _repo.DeleteTv(existingTv); + existingTv = null; + } + if (existingTv == null) { _logger.LogDebug("Adding new TV Show {0}", tvShow.Name); diff --git a/src/Ombi.Store/Repository/EmbyContentRepository.cs b/src/Ombi.Store/Repository/EmbyContentRepository.cs index df88d82922..8f9904ebb4 100644 --- a/src/Ombi.Store/Repository/EmbyContentRepository.cs +++ b/src/Ombi.Store/Repository/EmbyContentRepository.cs @@ -102,6 +102,13 @@ public override Task UpdateRange(IEnumerable existingConten return InternalSaveChanges(); } + public override async Task DeleteTv(EmbyContent tv) + { + var episodesToDelete = GetAllEpisodes().Cast().Where(x => x.ParentId == tv.EmbyId).ToList(); + Db.EmbyEpisode.RemoveRange(episodesToDelete); + await Delete(tv); + } + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Emby; } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/IMediaServerContentRepository.cs b/src/Ombi.Store/Repository/IMediaServerContentRepository.cs index db4835a161..3f165b7e63 100644 --- a/src/Ombi.Store/Repository/IMediaServerContentRepository.cs +++ b/src/Ombi.Store/Repository/IMediaServerContentRepository.cs @@ -14,6 +14,7 @@ public interface IMediaServerContentRepository : IExternalRepository GetAllEpisodes(); Task Add(IMediaServerEpisode content); Task AddRange(IEnumerable content); + Task DeleteTv(Content tv); void UpdateWithoutSave(IMediaServerContent existingContent); } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/JellyfinContentRepository.cs b/src/Ombi.Store/Repository/JellyfinContentRepository.cs index c3451da620..8dc729a6b2 100644 --- a/src/Ombi.Store/Repository/JellyfinContentRepository.cs +++ b/src/Ombi.Store/Repository/JellyfinContentRepository.cs @@ -104,6 +104,13 @@ public override Task UpdateRange(IEnumerable existingConten return InternalSaveChanges(); } + public override async Task DeleteTv(JellyfinContent tv) + { + var episodesToDelete = GetAllEpisodes().Cast().Where(x => x.ParentId == tv.JellyfinId).ToList(); + Db.JellyfinEpisode.RemoveRange(episodesToDelete); + await Delete(tv); + } + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Jellyfin; } } diff --git a/src/Ombi.Store/Repository/MediaServerRepository.cs b/src/Ombi.Store/Repository/MediaServerRepository.cs index c1c7d4ec8c..251fe3ceac 100644 --- a/src/Ombi.Store/Repository/MediaServerRepository.cs +++ b/src/Ombi.Store/Repository/MediaServerRepository.cs @@ -22,5 +22,6 @@ public MediaServerContentRepository(ExternalContext db) : base(db) public abstract Task AddRange(IEnumerable content); public abstract void UpdateWithoutSave(IMediaServerContent existingContent); public abstract Task UpdateRange(IEnumerable existingContent); + public abstract Task DeleteTv(T tv); } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/PlexContentRepository.cs b/src/Ombi.Store/Repository/PlexContentRepository.cs index 96dfbe8e19..9f34af6a1c 100644 --- a/src/Ombi.Store/Repository/PlexContentRepository.cs +++ b/src/Ombi.Store/Repository/PlexContentRepository.cs @@ -169,5 +169,12 @@ public override Task UpdateRange(IEnumerable existingConten Db.PlexServerContent.UpdateRange((IEnumerable)existingContent); return InternalSaveChanges(); } + + public override Task DeleteTv(PlexServerContent tv) + { + // not used for now + // TODO: delete episodes, then delete series + throw new NotImplementedException(); + } } } \ No newline at end of file From ae25e41b1b01dcc949e1cdc4f7e9a69040e587d4 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Tue, 26 Apr 2022 18:51:06 +0200 Subject: [PATCH 033/270] Fix sync log criticity --- src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index c0acba55c4..46cd7cf76f 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -163,7 +163,7 @@ private async Task ProcessTv(EmbyServers server, bool recentlyAdded, string pare || existingTv.TheMovieDbId != tvShow.ProviderIds?.Tmdb || existingTv.TvDbId != tvShow.ProviderIds?.Tvdb)) { - _logger.LogCritical($"Series '{tvShow.Name}' has different IDs, probably a reidentification."); + _logger.LogDebug($"Series '{tvShow.Name}' has different IDs, probably a reidentification."); await _repo.DeleteTv(existingTv); existingTv = null; } From 4da0a597d7127c9cb8eeeaf8b49f0f9ed98ecbd5 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 26 Apr 2022 20:02:06 +0100 Subject: [PATCH 034/270] Update pr.yml [skip ci] --- .github/workflows/pr.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 08955b8a59..c45a555a72 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -5,6 +5,11 @@ on: types: [opened, synchronize, reopened] workflow_dispatch: +permissions: + pull-requests: write + issues: write + repository-projects: write + jobs: build-ui: runs-on: ubuntu-latest @@ -28,8 +33,7 @@ jobs: unit-test: runs-on: ubuntu-latest - permissions: - checks: write + steps: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 @@ -47,7 +51,16 @@ jobs: - name: Run Unit Tests run: | cd src - dotnet test --configuration "Release" --logger "trx;LogFileName=test-results.trx" + dotnet test --configuration "Release" --logger "trx;LogFileName=test-results.trx" || true + + - name: Test Report + uses: dorny/test-reporter@v1 + if: always() + with: + name: DotNET Tests + path: "**/test-results.trx" + reporter: dotnet-trx + fail-on-error: true analysis: runs-on: ubuntu-latest From 75d279b83a4ce7ef5ae328790d47191c870f40f3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 26 Apr 2022 20:02:43 +0100 Subject: [PATCH 035/270] Update label.yml [skip ci] --- .github/workflows/label.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 7c724a62ac..4e0c7b2ded 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -7,6 +7,10 @@ name: Labeler on: [pull_request] +permissions: + pull-requests: write + issues: write + repository-projects: write jobs: label: From a96d2a7818b50d8dd6ec999f672400070123ec7c Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Wed, 27 Apr 2022 08:15:25 +0200 Subject: [PATCH 036/270] Fix formatting --- src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs | 7 +++---- src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index 46cd7cf76f..27cdf0f3ae 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -170,7 +170,7 @@ private async Task ProcessTv(EmbyServers server, bool recentlyAdded, string pare if (existingTv == null) { - _logger.LogDebug("Adding new TV Show {0}", tvShow.Name); + _logger.LogDebug("Adding TV Show {0}", tvShow.Name); mediaToAdd.Add(new EmbyContent { TvDbId = tvShow.ProviderIds?.Tvdb, @@ -284,12 +284,11 @@ private async Task ProcessMovies(EmbyMovie movieInfo, ICollection c else { var movieHasChanged = false; - if(existingMovie.ImdbId != movieInfo.ProviderIds.Imdb || existingMovie.TheMovieDbId != movieInfo.ProviderIds.Tmdb) + if (existingMovie.ImdbId != movieInfo.ProviderIds.Imdb || existingMovie.TheMovieDbId != movieInfo.ProviderIds.Tmdb) { _logger.LogDebug($"Updating existing movie '{movieInfo.Name}'"); MapEmbyContent(existingMovie, movieInfo, server, has4K, quality); movieHasChanged = true; - } else if (!quality.Equals(existingMovie?.Quality, StringComparison.InvariantCultureIgnoreCase)) { @@ -303,7 +302,7 @@ private async Task ProcessMovies(EmbyMovie movieInfo, ICollection c movieHasChanged = true; } - if(movieHasChanged) + if (movieHasChanged) { toUpdate.Add(existingMovie); } diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs index cdbb886611..5519b34136 100644 --- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs @@ -145,7 +145,7 @@ private async Task ProcessTv(JellyfinServers server, string parentId = default) if (existingTv == null) { - _logger.LogDebug("Adding new TV Show {0}", tvShow.Name); + _logger.LogDebug("Adding TV Show {0}", tvShow.Name); mediaToAdd.Add(new JellyfinContent { TvDbId = tvShow.ProviderIds?.Tvdb, @@ -249,12 +249,11 @@ private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection Date: Wed, 27 Apr 2022 08:03:20 +0100 Subject: [PATCH 037/270] Update pr.yml [skip ci] --- .github/workflows/pr.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c45a555a72..7465635cc8 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -51,16 +51,7 @@ jobs: - name: Run Unit Tests run: | cd src - dotnet test --configuration "Release" --logger "trx;LogFileName=test-results.trx" || true - - - name: Test Report - uses: dorny/test-reporter@v1 - if: always() - with: - name: DotNET Tests - path: "**/test-results.trx" - reporter: dotnet-trx - fail-on-error: true + dotnet test --configuration "Release" --logger "trx;LogFileName=test-results.trx" analysis: runs-on: ubuntu-latest From 7017806bfb0da0730cb14261104519d1b8f40b3a Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 27 Apr 2022 08:04:26 +0100 Subject: [PATCH 038/270] Update label.yml [skip ci] --- .github/workflows/label.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 4e0c7b2ded..402c5ffd02 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -7,10 +7,8 @@ name: Labeler on: [pull_request] -permissions: - pull-requests: write - issues: write - repository-projects: write + +permissions: write-all jobs: label: From da6ed76bd66135a3003670ae9e7b1516f00e43fa Mon Sep 17 00:00:00 2001 From: contrib-readme-bot Date: Wed, 27 Apr 2022 07:05:31 +0000 Subject: [PATCH 039/270] chore: :busts_in_silhouette: Updated Contributors [skip ci] --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a8360d6c87..7f3b6bb55c 100644 --- a/README.md +++ b/README.md @@ -100,17 +100,17 @@ Here are some of the features Ombi has: - - anojht + + sephrat
- Anojh Thayaparan + Sephrat
- - sephrat + + anojht
- Sephrat + Anojh Thayaparan
From 1ac0e5768b9704f6ea7441b635df1702f0c31396 Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Wed, 27 Apr 2022 07:09:25 +0000 Subject: [PATCH 040/270] chore(release): :rocket: v4.19.0 --- CHANGELOG.md | 14 ++++++++++---- version.json | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 256e31749b..230f732fc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# [4.19.0](https://github.com/Ombi-app/Ombi/compare/v4.18.0...v4.19.0) (2022-04-27) + + +### Features + +* **sync:** Detect reidentified movies in Emby and Jellyfin ([5938077](https://github.com/Ombi-app/Ombi/commit/5938077d82a5357f79c07b218b3986557a5816e8)) +* **sync:** Detect reidentified series in Emby and Jellyfin ([9096e91](https://github.com/Ombi-app/Ombi/commit/9096e91d55d268819bce22831f8a8b27f2a1776b)) + + + # [4.18.0](https://github.com/Ombi-app/Ombi/compare/v4.17.0...v4.18.0) (2022-04-26) @@ -342,7 +352,3 @@ -## [4.12.3](https://github.com/Ombi-app/Ombi/compare/v4.12.2...v4.12.3) (2022-02-16) - - - diff --git a/version.json b/version.json index 48c62b29c1..0a0bca1d6b 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.18.0" + "version": "4.19.0" } \ No newline at end of file From 44840bcd87bf67ba0ccec0cf25ac9639090ea945 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Wed, 27 Apr 2022 09:14:29 +0200 Subject: [PATCH 041/270] refactor(newsletter): Clarify very rare cases where newsletter doesn't publish a series --- src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs | 38 +++----------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs index a11a9ff807..f0f30f869b 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs @@ -409,7 +409,9 @@ public async Task Execute(IJobExecutionContext job) private HashSet FilterEpisodes(IEnumerable source, IEnumerable recentlyAdded) { var itemsToReturn = new HashSet(); - foreach (var ep in source.Where(x => x.Series.HasTvDb)) + foreach (var ep in source.Where(x => x.Series.HasTvDb // needed for recentlyAddedLog + && x.Series.HasTheMovieDb // needed to fetch info to publish, this is just in case... + )) { var tvDbId = StringHelper.IntParseLinq(ep.Series.TvDbId); if (recentlyAdded.Any(x => x.ContentId == tvDbId && x.EpisodeNumber == ep.EpisodeNumber && x.SeasonNumber == ep.SeasonNumber)) @@ -665,48 +667,18 @@ private async Task ProcessTv(IEnumerable episodes, string l var orderedTv = series.OrderByDescending(x => x.AddedAt); foreach (var t in orderedTv) { - if (!t.HasTvDb) - { - // We may need to use themoviedb for the imdbid or their own id to get info - if (t.HasTheMovieDb) - { - int.TryParse(t.TheMovieDbId, out var movieId); - var externals = await _movieApi.GetTvExternals(movieId); - if (externals == null || externals.tvdb_id <= 0) - { - // needed later for recently added log - _log.LogWarning($"{t.Title} has no TVDB ID, it won't be published."); - continue; - } - t.TvDbId = externals.tvdb_id.ToString(); - } - // WE could check the below but we need to get the moviedb and then perform the above, let the metadata job figure this out. - //else if(t.HasImdb) - //{ - // // Check the imdbid - // var externals = await _movieApi.Find(t.ImdbId, ExternalSource.imdb_id); - // if (externals?.tv_results == null || externals.tv_results.Length <= 0) - // { - // continue; - // } - // t.TvDbId = externals.tv_results.FirstOrDefault()..ToString(); - //} - - } - try { var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode); if (tvInfo == null) { - _log.LogWarning($"TMDB does not know series {t.Title}, it won't be published."); + _log.LogError($"TMDB does not know series {t.Title}. This shouldn't happen because our media server knows it as ID '{t.TheMovieDbId}'."); continue; } if (tvInfo.backdrop_path.HasValue()) { - AddBackgroundInsideTable($"https://image.tmdb.org/t/p/w500{tvInfo.backdrop_path}"); } else @@ -732,7 +704,7 @@ private async Task ProcessTv(IEnumerable episodes, string l } catch (Exception e) { - _log.LogError(e, "Error when processing Plex TV {0}", t.Title); + _log.LogError(e, "Error when processing TV {0}", t.Title); } finally { From 77057432510b620bdc4901de42dbe7eadf87a8fb Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Wed, 27 Apr 2022 09:18:11 +0200 Subject: [PATCH 042/270] refactor(newsletter): Clarify very rare cases where newsletter doesn't publish movie --- src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs index f0f30f869b..0782a796a2 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs @@ -503,16 +503,11 @@ private async Task ProcessMovies(ICollection plexContentToS foreach (var content in ordered) { int.TryParse(content.TheMovieDbId, out var movieDbId); - if (movieDbId <= 0) - { - _log.LogWarning($"{content.Title} does not have a TMDB ID, it won't be published."); - continue; - } var info = await _movieApi.GetMovieInformationWithExtraInfo(movieDbId, defaultLanguageCode); var mediaurl = content.Url; if (info == null) { - _log.LogWarning($"TMDB does not know movie {content.Title}, it won't be published."); + _log.LogError($"TMDB does not know movie {content.Title}. This shouldn't happen because our media server knows it as ID '{movieDbId}'."); continue; } try From b54fba5c990a0cc440c78e5a8411b019d2c0e46d Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Wed, 27 Apr 2022 07:56:54 +0000 Subject: [PATCH 043/270] chore(release): :rocket: v4.19.1 --- CHANGELOG.md | 8 ++++---- version.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 230f732fc8..df382b310f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [4.19.1](https://github.com/Ombi-app/Ombi/compare/v4.19.0...v4.19.1) (2022-04-27) + + + # [4.19.0](https://github.com/Ombi-app/Ombi/compare/v4.18.0...v4.19.0) (2022-04-27) @@ -348,7 +352,3 @@ -## [4.12.4](https://github.com/Ombi-app/Ombi/compare/v4.12.3...v4.12.4) (2022-02-17) - - - diff --git a/version.json b/version.json index 0a0bca1d6b..d9208778de 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.19.0" + "version": "4.19.1" } \ No newline at end of file From 8357819b53b8c675c0b246d7006b5a778bdba33f Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Thu, 28 Apr 2022 09:55:34 +0200 Subject: [PATCH 044/270] feat(discover): Show more relevant shows in upcoming TV --- src/Ombi.Core/Engine/MovieSearchEngine.cs | 2 +- .../Engine/V2/MovieSearchEngineV2.cs | 4 +-- src/Ombi.TheMovieDbApi/IMovieDbApi.cs | 2 +- src/Ombi.TheMovieDbApi/TheMovieDbApi.cs | 36 ++++++++++++------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/Ombi.Core/Engine/MovieSearchEngine.cs b/src/Ombi.Core/Engine/MovieSearchEngine.cs index 682a999ebf..975e48d118 100644 --- a/src/Ombi.Core/Engine/MovieSearchEngine.cs +++ b/src/Ombi.Core/Engine/MovieSearchEngine.cs @@ -161,7 +161,7 @@ public async Task> UpcomingMovies() var result = await Cache.GetOrAddAsync(CacheKeys.UpcomingMovies, async () => { var langCode = await DefaultLanguageCode(null); - return await MovieApi.Upcoming(langCode); + return await MovieApi.UpcomingMovies(langCode); }, DateTimeOffset.Now.AddHours(12)); if (result != null) { diff --git a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs index 3423bc139c..27edbacbbf 100644 --- a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs @@ -287,7 +287,7 @@ public async Task> UpcomingMovies() var result = await Cache.GetOrAddAsync(CacheKeys.UpcomingMovies, async () => { var langCode = await DefaultLanguageCode(null); - return await MovieApi.Upcoming(langCode); + return await MovieApi.UpcomingMovies(langCode); }, DateTimeOffset.Now.AddHours(12)); if (result != null) { @@ -307,7 +307,7 @@ public async Task> UpcomingMovies(int currentP foreach (var pagesToLoad in pages) { var apiResult = await Cache.GetOrAddAsync(nameof(UpcomingMovies) + pagesToLoad.Page + langCode, - () => MovieApi.Upcoming(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); + () => MovieApi.UpcomingMovies(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); } return await TransformMovieResultsToResponse(results); diff --git a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs index 4f3885ef0a..12f5255b46 100644 --- a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs @@ -22,7 +22,7 @@ public interface IMovieDbApi Task> GetMoviesViaKeywords(string keywordId, string langCode, CancellationToken cancellationToken, int? page = null); Task> SearchTv(string searchTerm, string year = default); Task> TopRated(string languageCode, int? page = null); - Task> Upcoming(string languageCode, int? page = null); + Task> UpcomingMovies(string languageCode, int? page = null); Task> TopRatedTv(string languageCode, int? page = null); Task> TrendingTv(string languageCode, int? page = null); Task> UpcomingTv(string languageCode, int? page = null); diff --git a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs index ba61ccfcf7..5b0817388a 100644 --- a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs @@ -308,22 +308,12 @@ private async Task> Trending(string type, string langC var result = await Api.Request>(request); return Mapper.Map>(result.results); } - - public Task> Upcoming(string langCode, int? page = null) - { - return Upcoming("movie", langCode, page); - } - public Task> UpcomingTv(string langCode, int? page = null) - { - return Upcoming("tv", langCode, page); - } - /// /// Maintains filter parity with /movie/upcoming. /// - private async Task> Upcoming(string type, string langCode, int? page = null) + public async Task> UpcomingMovies(string langCode, int? page = null) { - var request = new Request($"discover/{type}", BaseUri, HttpMethod.Get); + var request = new Request($"discover/movie", BaseUri, HttpMethod.Get); request.AddQueryString("api_key", ApiToken); request.AddQueryString("language", langCode); @@ -340,7 +330,27 @@ private async Task> Upcoming(string type, string langC request.AddQueryString("page", page.ToString()); } await AddDiscoverSettings(request); - await AddGenreFilter(request, type); + await AddGenreFilter(request, "movie"); + AddRetry(request); + var result = await Api.Request>(request); + return Mapper.Map>(result.results); + } + public async Task> UpcomingTv(string langCode, int? page = null) + { + var request = new Request($"discover/tv", BaseUri, HttpMethod.Get); + request.AddQueryString("api_key", ApiToken); + request.AddQueryString("language", langCode); + + // Search for shows that will air in the next month + var startDate = DateTime.Today.AddDays(1); + request.AddQueryString($"first_air_date.gte", startDate.ToString("yyyy-MM-dd")); + request.AddQueryString($"first_air_date.lte", startDate.AddDays(30).ToString("yyyy-MM-dd")); + if (page != null) + { + request.AddQueryString("page", page.ToString()); + } + await AddDiscoverSettings(request); + await AddGenreFilter(request, "tv"); AddRetry(request); var result = await Api.Request>(request); return Mapper.Map>(result.results); From d03b29856dd0b7d8a1d3e7b41d283b34b6b6ed09 Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Thu, 28 Apr 2022 09:48:12 +0000 Subject: [PATCH 045/270] chore(release): :rocket: v4.20.0 --- CHANGELOG.md | 19 +++++++++---------- version.json | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df382b310f..55e1a648df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# [4.20.0](https://github.com/Ombi-app/Ombi/compare/v4.19.1...v4.20.0) (2022-04-28) + + +### Features + +* **discover:** Show more relevant shows in upcoming TV ([8357819](https://github.com/Ombi-app/Ombi/commit/8357819b53b8c675c0b246d7006b5a778bdba33f)) + + + ## [4.19.1](https://github.com/Ombi-app/Ombi/compare/v4.19.0...v4.19.1) (2022-04-27) @@ -342,13 +351,3 @@ -## [4.12.5](https://github.com/Ombi-app/Ombi/compare/v4.12.4...v4.12.5) (2022-02-21) - - -### Bug Fixes - -* **emby:** :bug: Fixed the emby content sync [#4513](https://github.com/Ombi-app/Ombi/issues/4513) ([2927504](https://github.com/Ombi-app/Ombi/commit/2927504f0e0b4e7251e69b44e0e30c7ec9519980)) -* **emby:** :bug: Fixed the emby content sync [#4513](https://github.com/Ombi-app/Ombi/issues/4513) ([bd441cb](https://github.com/Ombi-app/Ombi/commit/bd441cb54fd77d6befb03fae321dc36c29f0de2e)) - - - diff --git a/version.json b/version.json index d9208778de..bcef7521a9 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.19.1" + "version": "4.20.0" } \ No newline at end of file From bd8fd890554c9d85d6da4d2cee813e82ce698e52 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Thu, 5 May 2022 10:58:33 +0200 Subject: [PATCH 046/270] fix(sync): Emby+Jellyfin - sync multi-episode files of 3+ episodes * perf(sync): Emby+Jellyfin - use a more reliable filter to missing items * fix(sync): Emby+Jellyfin - sync multi-episode files of 3+ episodes [skip ci] --- src/Ombi.Api.Emby/EmbyApi.cs | 8 ++--- src/Ombi.Api.Jellyfin/JellyfinApi.cs | 6 ++-- .../Jobs/Emby/EmbyEpisodeSync.cs | 36 ++++++++++--------- .../Jobs/Jellyfin/JellyfinEpisodeSync.cs | 35 +++++++++--------- 4 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/Ombi.Api.Emby/EmbyApi.cs b/src/Ombi.Api.Emby/EmbyApi.cs index a1791494d7..e9e5f0fca7 100644 --- a/src/Ombi.Api.Emby/EmbyApi.cs +++ b/src/Ombi.Api.Emby/EmbyApi.cs @@ -106,7 +106,7 @@ public async Task> GetCollection(string mediaId, st request.AddQueryString("Fields", "ProviderIds,Overview"); - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("IsMissing", "False"); return await Api.Request>(request); } @@ -180,7 +180,7 @@ private async Task> RecentlyAdded(string type, string ap request.AddQueryString("ParentId", parentIdFilder); } - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("IsMissing", "False"); AddHeaders(request, apiKey); @@ -207,7 +207,7 @@ private async Task> GetAll(string type, string apiKey, s request.AddQueryString("IncludeItemTypes", type); request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds"); - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("IsMissing", "False"); AddHeaders(request, apiKey); @@ -229,7 +229,7 @@ private async Task> GetAll(string type, string apiKey, s request.AddQueryString("ParentId", parentIdFilder); } - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("isMissing", "False"); AddHeaders(request, apiKey); diff --git a/src/Ombi.Api.Jellyfin/JellyfinApi.cs b/src/Ombi.Api.Jellyfin/JellyfinApi.cs index f6afb7912e..0604cb9848 100644 --- a/src/Ombi.Api.Jellyfin/JellyfinApi.cs +++ b/src/Ombi.Api.Jellyfin/JellyfinApi.cs @@ -82,7 +82,7 @@ public async Task> GetCollection(string med request.AddQueryString("Fields", "ProviderIds,Overview"); - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("isMissing", "False"); return await Api.Request>(request); } @@ -143,7 +143,7 @@ private async Task> GetAll(string type, string apiKe request.AddQueryString("IncludeItemTypes", type); request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds"); - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("isMissing", "False"); AddHeaders(request, apiKey); @@ -165,7 +165,7 @@ private async Task> GetAll(string type, string apiKe request.AddQueryString("ParentId", parentIdFilder); } - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("isMissing", "False"); AddHeaders(request, apiKey); diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs index b3c1ffbab8..5293d30b4a 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs @@ -130,12 +130,6 @@ private async Task CacheEpisodes(EmbyServers server, bool recentlyAdded, string { processed++; - if (ep.LocationType?.Equals("Virtual", StringComparison.InvariantCultureIgnoreCase) ?? false) - { - // For some reason Emby is not respecting the `IsVirtualItem` field. - continue; - } - // Let's make sure we have the parent request, stop those pesky forign key errors, // Damn me having data integrity var parent = await _repo.GetByEmbyId(ep.SeriesId); @@ -176,18 +170,26 @@ private async Task CacheEpisodes(EmbyServers server, bool recentlyAdded, string if (ep.IndexNumberEnd.HasValue && ep.IndexNumberEnd.Value != ep.IndexNumber) { - epToAdd.Add(new EmbyEpisode + int episodeNumber = ep.IndexNumber; + do { - EmbyId = ep.Id, - EpisodeNumber = ep.IndexNumberEnd.Value, - SeasonNumber = ep.ParentIndexNumber, - ParentId = ep.SeriesId, - TvDbId = ep.ProviderIds.Tvdb, - TheMovieDbId = ep.ProviderIds.Tmdb, - ImdbId = ep.ProviderIds.Imdb, - Title = ep.Name, - AddedAt = DateTime.UtcNow - }); + _logger.LogDebug($"Multiple-episode file detected. Adding episode ${episodeNumber}"); + episodeNumber++; + epToAdd.Add(new EmbyEpisode + { + EmbyId = ep.Id, + EpisodeNumber = episodeNumber, + SeasonNumber = ep.ParentIndexNumber, + ParentId = ep.SeriesId, + TvDbId = ep.ProviderIds.Tvdb, + TheMovieDbId = ep.ProviderIds.Tmdb, + ImdbId = ep.ProviderIds.Imdb, + Title = ep.Name, + AddedAt = DateTime.UtcNow + }); + + } while (episodeNumber < ep.IndexNumberEnd.Value); + } } } diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs index 6e2daa7b35..31b8801143 100644 --- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs @@ -106,12 +106,6 @@ private async Task CacheEpisodes(JellyfinServers server, string parentIdFilter) { processed++; - if (ep.LocationType?.Equals("Virtual", StringComparison.InvariantCultureIgnoreCase) ?? false) - { - // For some reason Jellyfin is not respecting the `IsVirtualItem` field. - continue; - } - // Let's make sure we have the parent request, stop those pesky forign key errors, // Damn me having data integrity var parent = await _repo.GetByJellyfinId(ep.SeriesId); @@ -152,18 +146,25 @@ private async Task CacheEpisodes(JellyfinServers server, string parentIdFilter) if (ep.IndexNumberEnd.HasValue && ep.IndexNumberEnd.Value != ep.IndexNumber) { - epToAdd.Add(new JellyfinEpisode + int episodeNumber = ep.IndexNumber; + do { - JellyfinId = ep.Id, - EpisodeNumber = ep.IndexNumberEnd.Value, - SeasonNumber = ep.ParentIndexNumber, - ParentId = ep.SeriesId, - TvDbId = ep.ProviderIds.Tvdb, - TheMovieDbId = ep.ProviderIds.Tmdb, - ImdbId = ep.ProviderIds.Imdb, - Title = ep.Name, - AddedAt = DateTime.UtcNow - }); + _logger.LogDebug($"Multiple-episode file detected. Adding episode ${episodeNumber}"); + episodeNumber++; + epToAdd.Add(new JellyfinEpisode + { + JellyfinId = ep.Id, + EpisodeNumber = episodeNumber, + SeasonNumber = ep.ParentIndexNumber, + ParentId = ep.SeriesId, + TvDbId = ep.ProviderIds.Tvdb, + TheMovieDbId = ep.ProviderIds.Tmdb, + ImdbId = ep.ProviderIds.Imdb, + Title = ep.Name, + AddedAt = DateTime.UtcNow + }); + + } while (episodeNumber < ep.IndexNumberEnd.Value); } } } From fe501d34a0c36ac9f000b107eca49dbc6694d006 Mon Sep 17 00:00:00 2001 From: dr3amer <91037083+dr3am37@users.noreply.github.com> Date: Mon, 9 May 2022 00:24:38 -0700 Subject: [PATCH 047/270] fix: added media type tag to media type text (#4638) [skip ci] --- .../app/discover/components/card/discover-card.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html index 9ca607082b..40f0d27098 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html @@ -2,7 +2,7 @@
-
+
{{ 'Common.' + RequestType[result.type] | translate }}
@@ -48,4 +48,4 @@
-
\ No newline at end of file +
From 6d16442d4d714920367df065a3ced42b729f4233 Mon Sep 17 00:00:00 2001 From: echel0n Date: Tue, 10 May 2022 13:54:50 -0700 Subject: [PATCH 048/270] fix(sickrage): Fixed issue with incorrect handling of SiCKRAGE episode results returned during episode status changes, now expects array of objects from data path if present (#4648) [skip ci] --- src/Ombi.Api.SickRage/Models/SickRageEpisodeStatus.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Api.SickRage/Models/SickRageEpisodeStatus.cs b/src/Ombi.Api.SickRage/Models/SickRageEpisodeStatus.cs index 4f131d5e36..9142e2b42e 100644 --- a/src/Ombi.Api.SickRage/Models/SickRageEpisodeStatus.cs +++ b/src/Ombi.Api.SickRage/Models/SickRageEpisodeStatus.cs @@ -9,7 +9,7 @@ public class SickRageEpisodeStatus public class SickRageEpisodeSetStatus { - public Data data { get; set; } + public Data[] data { get; set; } public string message { get; set; } public string result { get; set; } } From 4070f0d093b1c92487a1c80cabad8283a9650f51 Mon Sep 17 00:00:00 2001 From: dr3amer <91037083+dr3am37@users.noreply.github.com> Date: Tue, 10 May 2022 13:55:38 -0700 Subject: [PATCH 049/270] fix: Missing Poster broken link fix (#4637) [skip ci] --- .../components/movie/movie-details.component.html | 6 +++--- .../components/movie/movie-details.component.ts | 11 ++++++++++- .../components/tv/tv-details.component.html | 4 ++-- .../components/tv/tv-details.component.ts | 10 +++++++++- 4 files changed, 24 insertions(+), 7 deletions(-) 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 2207ea3232..282683fedc 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,7 +24,7 @@
- +
@@ -107,7 +107,7 @@ - +
\ No newline at end of file +
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 c040fe4e09..079af8db5c 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 @@ -68,6 +68,7 @@ export class MovieDetailsComponent implements OnInit{ if (this.imdbId) { this.searchService.getMovieByImdbId(this.imdbId).subscribe(async x => { this.movie = x; + this.checkPoster(); if (this.movie.requestId > 0) { // Load up this request this.hasRequest = true; @@ -78,6 +79,7 @@ export class MovieDetailsComponent implements OnInit{ } else { this.searchService.getFullMovieDetails(this.theMovidDbId).subscribe(async x => { this.movie = x; + this.checkPoster(); if (this.movie.requestId > 0) { // Load up this request this.hasRequest = true; @@ -272,7 +274,14 @@ export class MovieDetailsComponent implements OnInit{ } }); } - + private checkPoster() { + if (this.movie.posterPath == null) { + this.movie.posterPath = "../../../images/default_movie_poster.png"; + } + else { + this.movie.posterPath = "https://image.tmdb.org/t/p/w300/" + this.movie.posterPath + }; + } private loadAdvancedInfo() { const profile = this.radarrService.getQualityProfilesFromSettings(); const folders = this.radarrService.getRootFoldersFromSettings(); diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/tv-details.component.html b/src/Ombi/ClientApp/src/app/media-details/components/tv/tv-details.component.html index cb1ec6ffb9..0ae1ae499a 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/tv/tv-details.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/tv-details.component.html @@ -42,7 +42,7 @@

{{ 'MediaDetails.NotEnoughInfo' | translate }}

- +
@@ -82,7 +82,7 @@

{{ 'MediaDetails.NotEnoughInfo' | translate }}

class="btn-spacing" color="accent" [disabled]> {{'Common.PartiallyAvailable' | translate }} - + diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/tv-details.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/tv/tv-details.component.ts index 2d02dc63b3..473417d53d 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/tv/tv-details.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/tv-details.component.ts @@ -48,6 +48,7 @@ export class TvDetailsComponent implements OnInit { public async ngOnInit() { await this.load(); + this.checkPoster(); } public async load() { @@ -128,7 +129,14 @@ export class TvDetailsComponent implements OnInit { public allEpisodesRequested(): boolean { return this.tv.seasonRequests.every(e => e.episodes.every(x => x.approved || x.requested)); } - + private checkPoster() { + if (this.tv.images.original == null) { + this.tv.images.original = "../../../images/default_movie_poster.png"; + } + else { + 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(); From 25c7c6ab404dde6072d680dff2f3ce1c8c1df0e4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 10 May 2022 21:57:33 +0100 Subject: [PATCH 050/270] =?UTF-8?q?=F0=9F=8C=90=20Translations=20Update=20?= =?UTF-8?q?(#4622)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- src/Ombi.I18n/Resources/Texts.pl.resx | 14 +++++++------- src/Ombi/wwwroot/translations/bg.json | 3 ++- src/Ombi/wwwroot/translations/cs.json | 3 ++- src/Ombi/wwwroot/translations/da.json | 3 ++- src/Ombi/wwwroot/translations/de.json | 3 ++- src/Ombi/wwwroot/translations/es.json | 3 ++- src/Ombi/wwwroot/translations/fr.json | 3 ++- src/Ombi/wwwroot/translations/hu.json | 3 ++- src/Ombi/wwwroot/translations/it.json | 3 ++- src/Ombi/wwwroot/translations/nl.json | 3 ++- src/Ombi/wwwroot/translations/no.json | 3 ++- src/Ombi/wwwroot/translations/pl.json | 3 ++- src/Ombi/wwwroot/translations/pt-BR.json | 3 ++- src/Ombi/wwwroot/translations/pt.json | 3 ++- src/Ombi/wwwroot/translations/ru.json | 3 ++- src/Ombi/wwwroot/translations/sk.json | 3 ++- src/Ombi/wwwroot/translations/sv.json | 3 ++- src/Ombi/wwwroot/translations/zh-TW.json | 3 ++- src/Ombi/wwwroot/translations/zh.json | 3 ++- 19 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/Ombi.I18n/Resources/Texts.pl.resx b/src/Ombi.I18n/Resources/Texts.pl.resx index c8e5e5ee16..f7833ced67 100644 --- a/src/Ombi.I18n/Resources/Texts.pl.resx +++ b/src/Ombi.I18n/Resources/Texts.pl.resx @@ -118,13 +118,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Nowy Album + Nowe Albumy - Nowy film + Nowe filmy - Nowy telewizor + Nowe seriale Gatunki: @@ -136,21 +136,21 @@ Sezon: - OdcinkΓ³w: + Odcinki: Wspierane przez - WypisaΔ‡ siΔ™ + Wypisz siΔ™ Album - Movie + Film - TV Show + Serial \ No newline at end of file diff --git a/src/Ombi/wwwroot/translations/bg.json b/src/Ombi/wwwroot/translations/bg.json index fd207e4bb8..16ae7dc061 100644 --- a/src/Ombi/wwwroot/translations/bg.json +++ b/src/Ombi/wwwroot/translations/bg.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "ΠŸΡ€ΠΎΠ²Π΅Ρ€Π΅Ρ‚Π΅ Ρ‚Π°Π·ΠΈ страница Π·Π° послСдни Π½ΠΎΠ²ΠΈΠ½ΠΈ Π½Π° сайта." }, "ErrorPages": { - "NotFound": "Page not found" + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "ΠžΡ‚ΠΊΡ€ΠΈΠΉΡ‚Π΅", diff --git a/src/Ombi/wwwroot/translations/cs.json b/src/Ombi/wwwroot/translations/cs.json index c1dec8f372..31376e92ff 100644 --- a/src/Ombi/wwwroot/translations/cs.json +++ b/src/Ombi/wwwroot/translations/cs.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Check this page for continuous site updates." }, "ErrorPages": { - "NotFound": "StrΓ‘nka nenalezena" + "NotFound": "StrΓ‘nka nenalezena", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Objevit novΓ©", diff --git a/src/Ombi/wwwroot/translations/da.json b/src/Ombi/wwwroot/translations/da.json index 1486bcfae2..932f40ae8e 100644 --- a/src/Ombi/wwwroot/translations/da.json +++ b/src/Ombi/wwwroot/translations/da.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Tjek denne side for lΓΈbende opdateringer." }, "ErrorPages": { - "NotFound": "Siden blev ikke fundet" + "NotFound": "Siden blev ikke fundet", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Opdag", diff --git a/src/Ombi/wwwroot/translations/de.json b/src/Ombi/wwwroot/translations/de.json index d397f0c551..99d147a9c8 100644 --- a/src/Ombi/wwwroot/translations/de.json +++ b/src/Ombi/wwwroot/translations/de.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "ÜberprΓΌfe diese Seite fΓΌr kontinuierliche Website-Updates." }, "ErrorPages": { - "NotFound": "Seite nicht gefunden" + "NotFound": "Seite nicht gefunden", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Entdecken", diff --git a/src/Ombi/wwwroot/translations/es.json b/src/Ombi/wwwroot/translations/es.json index bb8cb4a9a6..adc0479163 100644 --- a/src/Ombi/wwwroot/translations/es.json +++ b/src/Ombi/wwwroot/translations/es.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Consulta esta pΓ‘gina para ver las ΓΊltimas novedades." }, "ErrorPages": { - "NotFound": "PΓ‘gina no encontrada" + "NotFound": "PΓ‘gina no encontrada", + "SomethingWentWrong": "Β‘Algo saliΓ³ mal!" }, "NavigationBar": { "Discover": "Descubre", diff --git a/src/Ombi/wwwroot/translations/fr.json b/src/Ombi/wwwroot/translations/fr.json index ec7e1c27d5..f8f52ea97f 100644 --- a/src/Ombi/wwwroot/translations/fr.json +++ b/src/Ombi/wwwroot/translations/fr.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Consultez cette page pour voir les mises Γ  jour du site." }, "ErrorPages": { - "NotFound": "Page non trouvΓ©e" + "NotFound": "Page non trouvΓ©e", + "SomethingWentWrong": "Une erreur s'est produite !" }, "NavigationBar": { "Discover": "DΓ©couvrir", diff --git a/src/Ombi/wwwroot/translations/hu.json b/src/Ombi/wwwroot/translations/hu.json index 9a9013317e..f26d4bc066 100644 --- a/src/Ombi/wwwroot/translations/hu.json +++ b/src/Ombi/wwwroot/translations/hu.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "LΓ‘togasd meg ezt az oldalt a frissΓ­tΓ©sekhez." }, "ErrorPages": { - "NotFound": "Az oldal nem talΓ‘lhatΓ³" + "NotFound": "Az oldal nem talΓ‘lhatΓ³", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "FelfedezΓ©s", diff --git a/src/Ombi/wwwroot/translations/it.json b/src/Ombi/wwwroot/translations/it.json index 71b7c121f3..7c1cda82e1 100644 --- a/src/Ombi/wwwroot/translations/it.json +++ b/src/Ombi/wwwroot/translations/it.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Controlla questa pagina per aggiornamenti continui del sito." }, "ErrorPages": { - "NotFound": "Pagina non trovata" + "NotFound": "Pagina non trovata", + "SomethingWentWrong": "Qualcosa Γ¨ andato storto!" }, "NavigationBar": { "Discover": "Scopri", diff --git a/src/Ombi/wwwroot/translations/nl.json b/src/Ombi/wwwroot/translations/nl.json index 932bbff9c5..5c949461a3 100644 --- a/src/Ombi/wwwroot/translations/nl.json +++ b/src/Ombi/wwwroot/translations/nl.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Controleer deze pagina voor updates." }, "ErrorPages": { - "NotFound": "Page not found" + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Ontdekken", diff --git a/src/Ombi/wwwroot/translations/no.json b/src/Ombi/wwwroot/translations/no.json index fcb16d35bc..01cc7a4d99 100644 --- a/src/Ombi/wwwroot/translations/no.json +++ b/src/Ombi/wwwroot/translations/no.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Sjekk denne siden for kontinuerlige oppdateringer." }, "ErrorPages": { - "NotFound": "Page not found" + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Discover", diff --git a/src/Ombi/wwwroot/translations/pl.json b/src/Ombi/wwwroot/translations/pl.json index 869feaac14..6cb9589da6 100644 --- a/src/Ombi/wwwroot/translations/pl.json +++ b/src/Ombi/wwwroot/translations/pl.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Tutaj znajdziesz aktualizacje dotyczΔ…ce tej strony." }, "ErrorPages": { - "NotFound": "Nie znaleziono strony" + "NotFound": "Nie znaleziono strony", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Odkryj", diff --git a/src/Ombi/wwwroot/translations/pt-BR.json b/src/Ombi/wwwroot/translations/pt-BR.json index 88623edd56..cfc718950d 100644 --- a/src/Ombi/wwwroot/translations/pt-BR.json +++ b/src/Ombi/wwwroot/translations/pt-BR.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Verifique esta pΓ‘gina para acompanhar as atualizaçáes do site." }, "ErrorPages": { - "NotFound": "Pagina nΓ£o encontrada" + "NotFound": "Pagina nΓ£o encontrada", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Explorar", diff --git a/src/Ombi/wwwroot/translations/pt.json b/src/Ombi/wwwroot/translations/pt.json index ed1aa54346..b6f05d2a24 100644 --- a/src/Ombi/wwwroot/translations/pt.json +++ b/src/Ombi/wwwroot/translations/pt.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Check this page for continuous site updates." }, "ErrorPages": { - "NotFound": "Page not found" + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Discover", diff --git a/src/Ombi/wwwroot/translations/ru.json b/src/Ombi/wwwroot/translations/ru.json index b60adcaaa8..a3b793fdb3 100644 --- a/src/Ombi/wwwroot/translations/ru.json +++ b/src/Ombi/wwwroot/translations/ru.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ эту страницу для получСния послСдних новостСй сайта." }, "ErrorPages": { - "NotFound": "Page not found" + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Discover", diff --git a/src/Ombi/wwwroot/translations/sk.json b/src/Ombi/wwwroot/translations/sk.json index b13ddd8ff0..ced89f1709 100644 --- a/src/Ombi/wwwroot/translations/sk.json +++ b/src/Ombi/wwwroot/translations/sk.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "Prezrite tΓΊto strΓ‘nku pre aktualizΓ‘cie." }, "ErrorPages": { - "NotFound": "StrΓ‘nka sa nenaΕ‘la" + "NotFound": "StrΓ‘nka sa nenaΕ‘la", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "ObjaviΕ₯", diff --git a/src/Ombi/wwwroot/translations/sv.json b/src/Ombi/wwwroot/translations/sv.json index 7b4ba04392..a06953dd2b 100644 --- a/src/Ombi/wwwroot/translations/sv.json +++ b/src/Ombi/wwwroot/translations/sv.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "HΓ₯ll utkik hΓ€r fΓΆr uppdateringar pΓ₯ denna sida." }, "ErrorPages": { - "NotFound": "Page not found" + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "UpptΓ€ck", diff --git a/src/Ombi/wwwroot/translations/zh-TW.json b/src/Ombi/wwwroot/translations/zh-TW.json index 16d8d9adf4..c9300bafa7 100644 --- a/src/Ombi/wwwroot/translations/zh-TW.json +++ b/src/Ombi/wwwroot/translations/zh-TW.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "ζ£€ζŸ₯歀鑡青δ»₯θŽ·ε–η«™η‚ΉθΏžη»­ζ›΄ζ–°γ€‚" }, "ErrorPages": { - "NotFound": "ζ‰ΎδΈεˆ°ι‘΅ι’" + "NotFound": "ζ‰ΎδΈεˆ°ι‘΅ι’", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "ε‘ηŽ°", diff --git a/src/Ombi/wwwroot/translations/zh.json b/src/Ombi/wwwroot/translations/zh.json index edbdf6e944..5adca37ecc 100644 --- a/src/Ombi/wwwroot/translations/zh.json +++ b/src/Ombi/wwwroot/translations/zh.json @@ -60,7 +60,8 @@ "CheckPageForUpdates": "ζ£€ζŸ₯歀鑡青δ»₯θŽ·ε–η«™η‚ΉθΏžη»­ζ›΄ζ–°γ€‚" }, "ErrorPages": { - "NotFound": "ζ‰ΎδΈεˆ°ι‘΅ι’" + "NotFound": "ζ‰ΎδΈεˆ°ι‘΅ι’", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "ε‘ηŽ°", From ae430e700c7cf5b8d2767a962ec90055d6c3517d Mon Sep 17 00:00:00 2001 From: Marley <55280588+marleypowell@users.noreply.github.com> Date: Fri, 13 May 2022 07:03:14 +0100 Subject: [PATCH 051/270] Update launch.json (#4650) [skip ci] --- src/Ombi/.vscode/launch.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ombi/.vscode/launch.json b/src/Ombi/.vscode/launch.json index 642e584c56..9b68386308 100644 --- a/src/Ombi/.vscode/launch.json +++ b/src/Ombi/.vscode/launch.json @@ -6,7 +6,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/bin/Debug/net5.0/ombi.dll", + "program": "${workspaceFolder}/bin/Debug/net6.0/ombi.dll", "args": ["--host", "http://localhost:3577"], "cwd": "${workspaceFolder}", "stopAtEntry": false, @@ -47,4 +47,4 @@ } }, ] - } \ No newline at end of file + } From 181892bcfe88e6d76febf49ef57745d04552d08e Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Fri, 27 May 2022 10:59:10 +0200 Subject: [PATCH 052/270] fix: Improve Swagger documentation (#4652) * Upgrade Swashbuckle dependency * Document /token response * Add support for Newtonsoft annotations in Swagger * Remove unecessary ActionResult [skip ci] --- src/Ombi.Api.Plex/Models/Metadata.cs | 4 ++++ src/Ombi/Controllers/V1/TokenController.cs | 18 +++++++++++++++--- src/Ombi/Extensions/StartupExtensions.cs | 2 ++ src/Ombi/Ombi.csproj | 3 ++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Ombi.Api.Plex/Models/Metadata.cs b/src/Ombi.Api.Plex/Models/Metadata.cs index 3481e9b579..495a06c508 100644 --- a/src/Ombi.Api.Plex/Models/Metadata.cs +++ b/src/Ombi.Api.Plex/Models/Metadata.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Newtonsoft.Json; namespace Ombi.Api.Plex.Models { @@ -38,6 +39,9 @@ public class Metadata public string grandparentTheme { get; set; } public string chapterSource { get; set; } public Medium[] Media { get; set; } + + + [JsonProperty("guids")] public List Guid { get; set; } = new List(); } diff --git a/src/Ombi/Controllers/V1/TokenController.cs b/src/Ombi/Controllers/V1/TokenController.cs index 1dd08fcbed..657c95f91d 100644 --- a/src/Ombi/Controllers/V1/TokenController.cs +++ b/src/Ombi/Controllers/V1/TokenController.cs @@ -16,9 +16,20 @@ using Ombi.Store.Repository; using Ombi.Core.Settings; using Ombi.Settings.Settings.Models; +using System.Text.Json.Serialization; +using Newtonsoft.Json; namespace Ombi.Controllers.V1 { + + + public class Token + { + [JsonProperty("access_token")] + public string AccessToken { get; set; } + public DateTime Expiration { get; set; } + } + [ApiV1] [Produces("application/json")] [ApiController] @@ -47,6 +58,7 @@ public TokenController(OmbiUserManager um, ITokenRepository token, /// [HttpPost] [ProducesResponseType(401)] + [ProducesResponseType(typeof(Token), 200)] public async Task GetToken([FromBody] UserAuthModel model) { if (!model.UsePlexOAuth) @@ -161,10 +173,10 @@ private async Task CreateToken(bool rememberMe, OmbiUser user) await _userManager.UpdateAsync(user); - return new JsonResult(new + return Ok(new Token { - access_token = accessToken, - expiration = token.ValidTo + AccessToken = accessToken, + Expiration = token.ValidTo }); } diff --git a/src/Ombi/Extensions/StartupExtensions.cs b/src/Ombi/Extensions/StartupExtensions.cs index 296339dd01..227085e077 100644 --- a/src/Ombi/Extensions/StartupExtensions.cs +++ b/src/Ombi/Extensions/StartupExtensions.cs @@ -79,6 +79,8 @@ public static void AddSwagger(this IServiceCollection services) c.DescribeAllParametersInCamelCase(); }); + + services.AddSwaggerGenNewtonsoftSupport(); } public static void AddAppSettingsValues(this IServiceCollection services, IConfigurationRoot configuration) diff --git a/src/Ombi/Ombi.csproj b/src/Ombi/Ombi.csproj index 69ee6b233a..f0091002a7 100644 --- a/src/Ombi/Ombi.csproj +++ b/src/Ombi/Ombi.csproj @@ -79,7 +79,8 @@ - + + From a70bf8f46c76d74c9dfdf908c53bd9955ca0a35d Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Fri, 27 May 2022 10:59:24 +0200 Subject: [PATCH 053/270] fix(API): Fix pagination in some edge cases (#4649) [skip ci] --- src/Ombi.Helpers.Tests/PagnationHelperTests.cs | 2 ++ src/Ombi.Helpers/PaginationHelper.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Ombi.Helpers.Tests/PagnationHelperTests.cs b/src/Ombi.Helpers.Tests/PagnationHelperTests.cs index 4b058c403c..44bbfdd8ea 100644 --- a/src/Ombi.Helpers.Tests/PagnationHelperTests.cs +++ b/src/Ombi.Helpers.Tests/PagnationHelperTests.cs @@ -83,6 +83,8 @@ public static IEnumerable CurrentPositionMultiplePagesTestData .SetName("PaginationPosition_Load_SecondHalf_FirstPage_FirstHalf_SecondPage"); yield return new TestCaseData(0, 40, 20, new List { new MultiplePagesTestData(1, 20, 0), new MultiplePagesTestData(2, 20, 0) }) .SetName("PaginationPosition_Load_Full_First_And_SecondPage"); + yield return new TestCaseData(40, 40, 20, new List { new MultiplePagesTestData(3, 20, 0), new MultiplePagesTestData(4, 20, 0) }) + .SetName("PaginationPosition_Load_Full_Third_And_ForthPage"); yield return new TestCaseData(35, 15, 20, new List { new MultiplePagesTestData(2, 5, 15), new MultiplePagesTestData(3, 10, 0) }) .SetName("PaginationPosition_Load_EndSecondPage_Beginning_ThirdPage"); yield return new TestCaseData(18, 22, 20, new List { new MultiplePagesTestData(1, 2, 18), new MultiplePagesTestData(2, 20, 0) }) diff --git a/src/Ombi.Helpers/PaginationHelper.cs b/src/Ombi.Helpers/PaginationHelper.cs index 520f56b19e..2caafe1869 100644 --- a/src/Ombi.Helpers/PaginationHelper.cs +++ b/src/Ombi.Helpers/PaginationHelper.cs @@ -17,7 +17,7 @@ public static List GetNextPages(int currentlyLoaded, int toTake, in var lastPage = lastItemIndex / maxItemsPerPage + 1; var stopPos = lastItemIndex % maxItemsPerPage + 1; - while (currentlyLoaded > maxItemsPerPage) + while (currentlyLoaded >= maxItemsPerPage) { currentlyLoaded -= maxItemsPerPage; } From acc0b4a326c114215ac5c0c3ea7db5eae3dda83b Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 27 May 2022 10:17:29 +0100 Subject: [PATCH 054/270] =?UTF-8?q?=F0=9F=8C=90=20Translations=20Update=20?= =?UTF-8?q?(#4655)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(translations): 🌐 New translations from Crowdin [skip ci] * fix(translations): 🌐 New translations from Crowdin [skip ci] --- src/Ombi/wwwroot/translations/zh.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Ombi/wwwroot/translations/zh.json b/src/Ombi/wwwroot/translations/zh.json index 5adca37ecc..2117d65c00 100644 --- a/src/Ombi/wwwroot/translations/zh.json +++ b/src/Ombi/wwwroot/translations/zh.json @@ -61,7 +61,7 @@ }, "ErrorPages": { "NotFound": "ζ‰ΎδΈεˆ°ι‘΅ι’", - "SomethingWentWrong": "Something went wrong!" + "SomethingWentWrong": "ε‡ΊδΊ†δΊ›ι—ι’˜" }, "NavigationBar": { "Discover": "ε‘ηŽ°", @@ -208,13 +208,13 @@ "RequestPanel": { "Delete": "εˆ ι™€θ―·ζ±‚", "Approve": "批准请求", - "Deny": "Deny Request", + "Deny": "拒绝请求", "Approve4K": "批准4K请求", - "Deny4K": "Deny 4K Request", + "Deny4K": "拒绝 4K 请求", "ChangeAvailability": "ζ ‡θ°δΈΊε―用", "Deleted": "所选鑹η›ε·²εˆ ι™€", "Approved": "所选鑹η›ε·²ζ‰Ήε‡†", - "Denied": "Successfully denied selected items" + "Denied": "所选鑹η›ε·²ζ‹’绝" }, "SuccessfullyApproved": "ζ‰Ήε‡†ζˆεŠŸ", "SuccessfullyDeleted": "εˆ ι™€θ―·ζ±‚ζˆεŠŸ", @@ -384,7 +384,7 @@ "StartDate": "开始ζ—₯期:", "EndDate": "η»“ζŸζ—₯期:" }, - "RequestSource": "Source:" + "RequestSource": "ζ₯源:" }, "Discovery": { "PopularTab": "ηƒ­ι—¨", From d5ef1d53e5f77d19dba8b8059c80b538a3e14f2a Mon Sep 17 00:00:00 2001 From: dr3amer <91037083+dr3am37@users.noreply.github.com> Date: Fri, 27 May 2022 02:17:57 -0700 Subject: [PATCH 055/270] fix(discover): Carousel touch not working when scrolling page and recommendations and similar movie navigation (#4633) * fixed touch not working on carousels * fixed touch not working * Movie details component fixes Fixed recommendations and similar not changing the data on the component by calling the init function again on param change Moved the ngif results > 0 to the mat-expansion panel to avoid rendering the entire element if it doesn't have any results instead of having an empty panel. * removed unused line, added scroll to top on init * updated recommendation refresh implementation Changed the implementation to use the router instead in order to reload the component instead of just reloading the data. This implementation makes sure the component gets destroyed on navigation eliminating any memory leaks, reloading CSS in case of having animations on page load and generally a continuation of the experience you get when you browse into a movie from the discover page. --- .../carousel-list/carousel-list.component.ts | 1 + .../movie/movie-details.component.html | 8 ++-- .../movie/movie-details.component.ts | 40 +++++++++++++------ 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts index 9617c993eb..43cde5036e 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts @@ -48,6 +48,7 @@ export class CarouselListComponent implements OnInit { constructor(private searchService: SearchV2Service, private storageService: StorageService, private featureFacade: FeaturesFacade) { + Carousel.prototype.onTouchMove = () => { }, this.responsiveOptions = [ { breakpoint: '4000px', 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 282683fedc..90cf455f0e 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 @@ -239,14 +239,14 @@
- + {{'MediaDetails.RecommendationsTitle' | translate}} -
+
- + {{'MediaDetails.SimilarTitle' | translate}} -
+
- {{result.title}} + {{result.title}}
diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts index 559a962b50..d5557c0b50 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts @@ -169,6 +169,19 @@ export class DiscoverCardComponent implements OnInit { } } + public onImageError(event: any) { + const originalSrc = event.target.src; + + // set to a placeholder + event.target.src = "../../../images/default_movie_poster.png"; + + // Retry the original image + const timeout = setTimeout(() => { + event.target.src = originalSrc; + clearTimeout(timeout); + }, Math.floor(Math.random() * (7000 - 1000 + 1)) + 1000); + } + private getExtraMovieInfo() { if (!this.result.imdbid) { this.searchService.getFullMovieDetails(+this.result.id) From c8090b4e93eef8d718891371e930bb87bafe5e7e Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Mon, 11 Jul 2022 19:27:48 +0000 Subject: [PATCH 070/270] chore(release): :rocket: v4.21.1 [skip ci] --- CHANGELOG.md | 13 +++++++++---- version.json | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20b51d9d41..068cc25b2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [4.21.1](https://github.com/Ombi-app/Ombi/compare/v4.21.0...v4.21.1) (2022-07-11) + + +### Bug Fixes + +* **images:** Retry images with a backoff when we get a Too Many requests from TheMovieDb [#4685](https://github.com/Ombi-app/Ombi/issues/4685) ([3f1f35d](https://github.com/Ombi-app/Ombi/commit/3f1f35df3164db6739691cdda8f925c296239791)) + + + # [4.21.0](https://github.com/Ombi-app/Ombi/compare/v4.20.4...v4.21.0) (2022-06-22) @@ -349,7 +358,3 @@ -# [4.14.0](https://github.com/Ombi-app/Ombi/compare/v4.13.2...v4.14.0) (2022-03-02) - - - diff --git a/version.json b/version.json index cda1d2e0b6..b4b91706e1 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.21.0" + "version": "4.21.1" } \ No newline at end of file From c08156ca329333cc0aee7e86cb2a988b5067e81d Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 22 Jul 2022 13:31:06 +0100 Subject: [PATCH 071/270] =?UTF-8?q?=F0=9F=8C=90=20Translations=20Update=20?= =?UTF-8?q?(#4683)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(translations): 🌐 New translations from Crowdin [skip ci] * fix(translations): 🌐 New translations from Crowdin [skip ci] * fix(translations): 🌐 New translations from Crowdin [skip ci] --- src/Ombi.I18n/Resources/Texts.de.resx | 6 +++--- src/Ombi/wwwroot/translations/de.json | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Ombi.I18n/Resources/Texts.de.resx b/src/Ombi.I18n/Resources/Texts.de.resx index a222d02b0e..91a4aced41 100644 --- a/src/Ombi.I18n/Resources/Texts.de.resx +++ b/src/Ombi.I18n/Resources/Texts.de.resx @@ -139,7 +139,7 @@ Episoden: - Powered by + Betrieben durch Abbestellen @@ -148,9 +148,9 @@ Album - Movie + Film - TV Show + TV-Serie \ No newline at end of file diff --git a/src/Ombi/wwwroot/translations/de.json b/src/Ombi/wwwroot/translations/de.json index 99d147a9c8..b3c854a1fb 100644 --- a/src/Ombi/wwwroot/translations/de.json +++ b/src/Ombi/wwwroot/translations/de.json @@ -61,7 +61,7 @@ }, "ErrorPages": { "NotFound": "Seite nicht gefunden", - "SomethingWentWrong": "Something went wrong!" + "SomethingWentWrong": "Etwas ist schiefgelaufen!" }, "NavigationBar": { "Discover": "Entdecken", @@ -208,13 +208,13 @@ "RequestPanel": { "Delete": "Anfrage lâschen", "Approve": "Anfrage genehmigen", - "Deny": "Deny Request", + "Deny": "Anfrage ablehnen", "Approve4K": "4K Anfrage genehmigen", - "Deny4K": "Deny 4K Request", + "Deny4K": "4K Anfrage ablehnen", "ChangeAvailability": "Als verfügbar markieren", "Deleted": "AusgewÀhlte Elemente erfolgreich gelâscht", "Approved": "AusgewÀhlte Elemente erfolgreich freigegeben", - "Denied": "Successfully denied selected items" + "Denied": "AusgewÀhlte Elemente erfolgreich abgelehnt" }, "SuccessfullyApproved": "Erfolgreich genehmigt", "SuccessfullyDeleted": "Anfrage erfolgreich gelâscht", @@ -328,12 +328,12 @@ "LanguageProfileSelect": "WÀhlen Sie ein Sprachprofil", "Status": "Status:", "StatusValues": { - "Rumored": "Rumored", + "Rumored": "Gerüchten zufolge", "Planned": "Geplant", "In Production": "In Produktion", "Post Production": "Postproduktion", "Released": "Verâffentlicht", - "Running": "Running", + "Running": "Aktiv", "Returning Series": "Wiederkehrende Serie", "Ended": "Beendet", "Canceled": "Abgesagt" @@ -433,10 +433,10 @@ "Unsubscribed": "Abbestellt!" }, "UserTypeLabel": { - "1": "Local User", - "2": "Plex User", - "3": "Emby User", - "4": "Emby Connect User", + "1": "Lokaler Benutzer", + "2": "Plex Benutzer", + "3": "Embe Benutzer", + "4": "Emby Connect Benutzer", "5": "Jellyfin Server" }, "Paginator": { From 6d423b5447c52c5e59d8d2bd92a23b47468eb736 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 22 Jul 2022 15:25:39 +0100 Subject: [PATCH 072/270] fix: Landing and Login page improvements (#4690) --- src/Ombi/ClientApp/src/app/app.module.ts | 4 +- .../image-background.component.html | 6 + .../image-background.component.scss | 26 +++++ .../image-background.component.ts | 43 ++++++++ .../ClientApp/src/app/components/index.ts | 1 + .../ClientApp/src/app/components/modules.ts | 3 + .../ClientApp/src/app/interfaces/IImages.ts | 4 + .../landingpage/landingpage.component.html | 4 +- .../landingpage/landingpage.component.scss | 9 -- .../app/landingpage/landingpage.component.ts | 36 +----- .../src/app/login/login.component.html | 5 +- .../src/app/login/login.component.scss | 17 --- .../src/app/login/login.component.ts | 29 ----- .../app/login/resetpassword.component.html | 5 +- .../src/app/login/resetpassword.component.ts | 13 +-- .../login/tokenresetpassword.component.html | 20 ++-- .../app/login/tokenresetpassword.component.ts | 12 +- .../src/app/services/image.service.ts | 13 ++- src/Ombi/Controllers/V1/ImagesController.cs | 104 ++++++++++++++---- 19 files changed, 199 insertions(+), 155 deletions(-) create mode 100644 src/Ombi/ClientApp/src/app/components/image-background/image-background.component.html create mode 100644 src/Ombi/ClientApp/src/app/components/image-background/image-background.component.scss create mode 100644 src/Ombi/ClientApp/src/app/components/image-background/image-background.component.ts create mode 100644 src/Ombi/ClientApp/src/app/components/index.ts create mode 100644 src/Ombi/ClientApp/src/app/components/modules.ts diff --git a/src/Ombi/ClientApp/src/app/app.module.ts b/src/Ombi/ClientApp/src/app/app.module.ts index d0fa556154..30f4b2ea6f 100644 --- a/src/Ombi/ClientApp/src/app/app.module.ts +++ b/src/Ombi/ClientApp/src/app/app.module.ts @@ -68,6 +68,7 @@ import { TooltipModule } from "primeng/tooltip"; import { TranslateHttpLoader } from "@ngx-translate/http-loader"; import { TranslateService } from "@ngx-translate/core"; import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor"; +import { ImageBackgroundComponent } from "./components/"; import { environment } from "../environments/environment"; const routes: Routes = [ @@ -166,7 +167,8 @@ export function JwtTokenGetter() { ...environment.production ? [] : [ NgxsReduxDevtoolsPluginModule.forRoot(), - ] + ], + ImageBackgroundComponent ], declarations: [ AppComponent, diff --git a/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.html b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.html new file mode 100644 index 0000000000..97fff36710 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.html @@ -0,0 +1,6 @@ +
+ + +
{{name}}
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.scss b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.scss new file mode 100644 index 0000000000..177a22d015 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.scss @@ -0,0 +1,26 @@ +.login-gradient-bar{ + background: linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.6) 20.0%, rgba(0,0,0,0.6) 80.0%, transparent 60%),transparent; + height:100%; + width:100%; + position: absolute; +} + +.bg { + background-position: center center; + background-repeat: no-repeat; + background-attachment: fixed; + background-size: cover; + height: 100vh; + width: 100vw; + position: fixed; +} + +.poster-desc { + padding-left: 1%; + color: white; + height: 100vh; + width: 100vw; + display: flex; + justify-content: end; + flex-direction: column; +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.ts b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.ts new file mode 100644 index 0000000000..ebd228d856 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.ts @@ -0,0 +1,43 @@ +import { OmbiCommonModules } from "../modules"; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { DomSanitizer } from "@angular/platform-browser"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { ImageService } from "../../services"; +import { fadeInOutAnimation } from "app/animations/fadeinout"; + +@Component({ + standalone: true, + selector: 'ombi-image-background', + templateUrl: './image-background.component.html', + styleUrls: ['./image-background.component.scss'], + imports: [...OmbiCommonModules, BrowserAnimationsModule], + providers: [ ImageService ], + animations: [ fadeInOutAnimation ], + }) + export class ImageBackgroundComponent implements OnInit, OnDestroy { + + public background: any; + public name: string; + private timer: NodeJS.Timer; + + constructor(private images: ImageService, private sanitizer: DomSanitizer) { } + + public ngOnDestroy(): void { + clearTimeout(this.timer); + } + + public ngOnInit(): void { + this.cycleBackground(); + + this.timer = setInterval(() => { + this.cycleBackground(); + }, 30000); + } + + private cycleBackground() { + this.images.getRandomBackgroundWithInfo().subscribe((x) => { + this.background = this.sanitizer.bypassSecurityTrustStyle("url(" + x.url + ")"); + this.name = x.name; + }); + } + } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/index.ts b/src/Ombi/ClientApp/src/app/components/index.ts new file mode 100644 index 0000000000..75334a9e48 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/index.ts @@ -0,0 +1 @@ +export * from "./image-background/image-background.component"; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/modules.ts b/src/Ombi/ClientApp/src/app/components/modules.ts new file mode 100644 index 0000000000..1bf5697e6c --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/modules.ts @@ -0,0 +1,3 @@ +import { CommonModule } from "@angular/common"; + +export const OmbiCommonModules = [ CommonModule ]; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/interfaces/IImages.ts b/src/Ombi/ClientApp/src/app/interfaces/IImages.ts index 0c73df4908..baa1a98293 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IImages.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IImages.ts @@ -1,3 +1,7 @@ ο»Ώexport interface IImages { url: string; } +export interface IImagesInfo { + url: string; + name: string; +} diff --git a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.html b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.html index abad6473fc..3b8a46db75 100644 --- a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.html +++ b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.html @@ -1,5 +1,5 @@ -ο»Ώ
-
+ο»Ώ
+
diff --git a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.scss b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.scss index 7eb4a4b3c9..4c6e7ea9a4 100644 --- a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.scss +++ b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.scss @@ -26,15 +26,6 @@ div.centered { transform: translate(-50%, -50%); } -div.bg { - background-position: center center; - background-repeat: no-repeat; - background-attachment: fixed; - background-size: cover; - height: 100vh; - width: 100vw; - position: fixed; -} .online{ color:lightgreen; diff --git a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.ts b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.ts index 33f8873f81..e2758b146d 100644 --- a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.ts +++ b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.ts @@ -1,48 +1,34 @@ -ο»Ώimport { PlatformLocation, APP_BASE_HREF } from "@angular/common"; -import { Component, OnDestroy, OnInit, Inject } from "@angular/core"; +ο»Ώimport { APP_BASE_HREF } from "@angular/common"; +import { Component, OnInit, Inject } from "@angular/core"; import { IMediaServerStatus } from "../interfaces"; import { ICustomizationSettings, ILandingPageSettings } from "../interfaces"; import { LandingPageService } from "../services"; import { SettingsService } from "../services"; -import { DomSanitizer } from "@angular/platform-browser"; -import { ImageService } from "../services"; - -import { fadeInOutAnimation } from "../animations/fadeinout"; import { CustomizationFacade } from "../state/customization"; -import { ThousandShortPipe } from "../pipes/ThousandShortPipe"; @Component({ templateUrl: "./landingpage.component.html", - animations: [fadeInOutAnimation], styleUrls: ["./landingpage.component.scss"], }) -export class LandingPageComponent implements OnDestroy, OnInit { +export class LandingPageComponent implements OnInit { public customizationSettings: ICustomizationSettings; public landingPageSettings: ILandingPageSettings; - public background: any; public mediaServerStatus: IMediaServerStatus; public baseUrl: string; - private timer: any; private href: string; constructor(private settingsService: SettingsService, - private images: ImageService, private sanitizer: DomSanitizer, private landingPageService: LandingPageService, + private landingPageService: LandingPageService, private customizationFacade: CustomizationFacade, @Inject(APP_BASE_HREF) href :string) { this.href = href } public ngOnInit() { this.customizationFacade.settings$().subscribe(x => this.customizationSettings = x); this.settingsService.getLandingPage().subscribe(x => this.landingPageSettings = x); - this.images.getRandomBackground().subscribe(x => { - this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 19%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 79%, transparent 80%), url(" + x.url + ")"); - }); - this.timer = setInterval(() => { - this.cycleBackground(); - }, 30000); const base = this.href; if (base.length > 1) { @@ -53,18 +39,4 @@ export class LandingPageComponent implements OnDestroy, OnInit { this.mediaServerStatus = x; }); } - - public ngOnDestroy() { - clearInterval(this.timer); - } - - public cycleBackground() { - this.images.getRandomBackground().subscribe(x => { - this.background = ""; - }); - this.images.getRandomBackground().subscribe(x => { - this.background = this.sanitizer - .bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%), url(" + x.url + ")"); - }); - } } diff --git a/src/Ombi/ClientApp/src/app/login/login.component.html b/src/Ombi/ClientApp/src/app/login/login.component.html index c0932999be..71caa80b49 100644 --- a/src/Ombi/ClientApp/src/app/login/login.component.html +++ b/src/Ombi/ClientApp/src/app/login/login.component.html @@ -1,7 +1,4 @@ -ο»Ώ
- -
+ο»Ώ
diff --git a/src/Ombi/ClientApp/src/app/login/login.component.scss b/src/Ombi/ClientApp/src/app/login/login.component.scss index 4ad645dd84..df368ee0c9 100644 --- a/src/Ombi/ClientApp/src/app/login/login.component.scss +++ b/src/Ombi/ClientApp/src/app/login/login.component.scss @@ -11,23 +11,6 @@ img.center { max-width: 100%; } -.login-gradient-bar{ - background: linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.6) 20.0%, rgba(0,0,0,0.6) 80.0%, transparent 60%),transparent; - height:100%; - width:100%; - position: absolute; -} - -div.bg { - background-position: center center; - background-repeat: no-repeat; - background-attachment: fixed; - background-size: cover; - height: 100vh; - width: 100vw; - position: fixed; -} - .card-container.card { max-width: 500px; padding: 45px 45px; diff --git a/src/Ombi/ClientApp/src/app/login/login.component.ts b/src/Ombi/ClientApp/src/app/login/login.component.ts index 7808081724..6e8efc00bc 100644 --- a/src/Ombi/ClientApp/src/app/login/login.component.ts +++ b/src/Ombi/ClientApp/src/app/login/login.component.ts @@ -10,17 +10,12 @@ import { PlexTvService } from "../services"; import { SettingsService } from "../services"; import { StatusService } from "../services"; -import { DomSanitizer } from "@angular/platform-browser"; -import { ImageService } from "../services"; - -import { fadeInOutAnimation } from "../animations/fadeinout"; import { StorageService } from "../shared/storage/storage-service"; import { MatSnackBar } from "@angular/material/snack-bar"; import { CustomizationFacade } from "../state/customization"; @Component({ templateUrl: "./login.component.html", - animations: [fadeInOutAnimation], styleUrls: ["./login.component.scss"], }) export class LoginComponent implements OnDestroy, OnInit { @@ -28,7 +23,6 @@ export class LoginComponent implements OnDestroy, OnInit { public customizationSettings: ICustomizationSettings; public authenticationSettings: IAuthenticationSettings; public plexEnabled: boolean; - public background: any; public landingFlag: boolean; public baseUrl: string; public loginWithOmbi: boolean; @@ -46,7 +40,6 @@ export class LoginComponent implements OnDestroy, OnInit { public get appNameTranslate(): object { return { appName: this.appName }; } - private timer: any; private clientId: string; private errorBody: string; @@ -62,8 +55,6 @@ export class LoginComponent implements OnDestroy, OnInit { private fb: UntypedFormBuilder, private settingsService: SettingsService, private customziationFacade: CustomizationFacade, - private images: ImageService, - private sanitizer: DomSanitizer, private route: ActivatedRoute, @Inject(APP_BASE_HREF) href: string, private translate: TranslateService, @@ -111,14 +102,6 @@ export class LoginComponent implements OnDestroy, OnInit { this.headerAuth(); }); this.settingsService.getClientId().subscribe((x) => (this.clientId = x)); - this.images.getRandomBackground().subscribe((x) => { - this.background = this.sanitizer.bypassSecurityTrustStyle( - "url(" + x.url + ")" - ); - }); - this.timer = setInterval(() => { - this.cycleBackground(); - }, 30000); const base = this.href; if (base.length > 1) { @@ -284,18 +267,6 @@ export class LoginComponent implements OnDestroy, OnInit { } public ngOnDestroy() { - clearInterval(this.timer); clearInterval(this.pinTimer); } - - private cycleBackground() { - this.images.getRandomBackground().subscribe((x) => { - this.background = ""; - }); - this.images.getRandomBackground().subscribe((x) => { - this.background = this.sanitizer.bypassSecurityTrustStyle( - "url(" + x.url + ")" - ); - }); - } } diff --git a/src/Ombi/ClientApp/src/app/login/resetpassword.component.html b/src/Ombi/ClientApp/src/app/login/resetpassword.component.html index 9fbeb7eda0..2012238001 100644 --- a/src/Ombi/ClientApp/src/app/login/resetpassword.component.html +++ b/src/Ombi/ClientApp/src/app/login/resetpassword.component.html @@ -1,8 +1,5 @@ ο»Ώ -
- -
+
diff --git a/src/Ombi/ClientApp/src/app/login/resetpassword.component.ts b/src/Ombi/ClientApp/src/app/login/resetpassword.component.ts index 97d8e88f98..bd0376cb1b 100644 --- a/src/Ombi/ClientApp/src/app/login/resetpassword.component.ts +++ b/src/Ombi/ClientApp/src/app/login/resetpassword.component.ts @@ -1,16 +1,14 @@ -ο»Ώimport { PlatformLocation, APP_BASE_HREF } from "@angular/common"; +ο»Ώimport { APP_BASE_HREF } from "@angular/common"; import { Component, OnInit, Inject } from "@angular/core"; import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; -import { DomSanitizer } from "@angular/platform-browser"; import { fadeInOutAnimation } from "../animations/fadeinout"; import { ICustomizationSettings } from "../interfaces"; -import { IdentityService, ImageService, NotificationService, SettingsService } from "../services"; +import { IdentityService, NotificationService, SettingsService } from "../services"; import { CustomizationFacade } from "../state/customization"; @Component({ templateUrl: "./resetpassword.component.html", - animations: [fadeInOutAnimation], styleUrls: ["./login.component.scss"], }) export class ResetPasswordComponent implements OnInit { @@ -19,12 +17,11 @@ export class ResetPasswordComponent implements OnInit { public customizationSettings: ICustomizationSettings; public emailSettingsEnabled: boolean; public baseUrl: string; - public background: any; private href: string; constructor(private identityService: IdentityService, private notify: NotificationService, private fb: UntypedFormBuilder, private settingsService: SettingsService, @Inject(APP_BASE_HREF) href:string, - private images: ImageService, private sanitizer: DomSanitizer, private customizationFacade: CustomizationFacade) { + private customizationFacade: CustomizationFacade) { this.href = href; this.form = this.fb.group({ email: ["", [Validators.required]], @@ -32,9 +29,7 @@ export class ResetPasswordComponent implements OnInit { } public ngOnInit() { - this.images.getRandomBackground().subscribe(x => { - this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%),url(" + x.url + ")"); - }); + const base = this.href; if (base.length > 1) { this.baseUrl = base; diff --git a/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.html b/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.html index 6a1c2567f3..bd8bc3e386 100644 --- a/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.html +++ b/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.html @@ -1,11 +1,7 @@ -ο»Ώ -
- -
+ο»Ώ
- +
diff --git a/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.ts b/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.ts index 590c233f98..b7ef08281d 100644 --- a/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.ts +++ b/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.ts @@ -1,10 +1,9 @@ ο»Ώimport { ActivatedRoute, Params } from "@angular/router"; import { Component, OnInit } from "@angular/core"; import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; -import { IdentityService, ImageService } from "../services"; +import { IdentityService } from "../services"; import { CustomizationFacade } from "../state/customization"; -import { DomSanitizer } from "@angular/platform-browser"; import { ICustomizationSettings } from "../interfaces"; import { IResetPasswordToken } from "../interfaces"; import { NotificationService } from "../services"; @@ -19,13 +18,10 @@ export class TokenResetPasswordComponent implements OnInit { public form: UntypedFormGroup; public customizationSettings: ICustomizationSettings; - public background: any; public baseUrl: string; constructor(private identityService: IdentityService, private router: Router, private route: ActivatedRoute, private notify: NotificationService, - private fb: UntypedFormBuilder, private location: PlatformLocation, private images: ImageService, - private sanitizer: DomSanitizer, private customizationFacade: CustomizationFacade, - ) { + private fb: UntypedFormBuilder, private location: PlatformLocation, private customizationFacade: CustomizationFacade) { this.route.queryParams .subscribe((params: Params) => { @@ -39,9 +35,6 @@ export class TokenResetPasswordComponent implements OnInit { } public ngOnInit() { - this.images.getRandomBackground().subscribe(x => { - this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%),url(" + x.url + ")"); - }); const base = this.location.getBaseHrefFromDOM(); if (base.length > 1) { this.baseUrl = base; @@ -65,6 +58,5 @@ export class TokenResetPasswordComponent implements OnInit { }); } }); - } } diff --git a/src/Ombi/ClientApp/src/app/services/image.service.ts b/src/Ombi/ClientApp/src/app/services/image.service.ts index 521a207e36..c46876d733 100644 --- a/src/Ombi/ClientApp/src/app/services/image.service.ts +++ b/src/Ombi/ClientApp/src/app/services/image.service.ts @@ -1,10 +1,10 @@ -import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; +import { APP_BASE_HREF } from "@angular/common"; import { Injectable, Inject } from "@angular/core"; import { Observable } from "rxjs"; import { HttpClient } from "@angular/common/http"; -import { IImages } from "../interfaces"; +import { IImages, IImagesInfo } from "../interfaces"; import { ServiceHelpers } from "./service.helpers"; @Injectable() @@ -17,6 +17,10 @@ export class ImageService extends ServiceHelpers { return this.http.get(`${this.url}background/`, {headers: this.headers}); } + public getRandomBackgroundWithInfo(): Observable { + return this.http.get(`${this.url}background/info`, {headers: this.headers}); + } + public getTvBanner(tvdbid: number): Observable { return this.http.get(`${this.url}tv/${tvdbid}`, {headers: this.headers}); } @@ -31,8 +35,9 @@ export class ImageService extends ServiceHelpers { public getMovieBackground(movieDbId: string): Observable { return this.http.get(`${this.url}background/movie/${movieDbId}`, { headers: this.headers }); - } - public getMovieBanner(movieDbId: string): Observable { + } + + public getMovieBanner(movieDbId: string): Observable { return this.http.get(`${this.url}banner/movie/${movieDbId}`, { headers: this.headers }); } diff --git a/src/Ombi/Controllers/V1/ImagesController.cs b/src/Ombi/Controllers/V1/ImagesController.cs index 9683c54b0d..0b8a6ce4c2 100644 --- a/src/Ombi/Controllers/V1/ImagesController.cs +++ b/src/Ombi/Controllers/V1/ImagesController.cs @@ -45,9 +45,9 @@ public async Task GetTvBanner(int tvdbid) { return string.Empty; } - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvdbid}", () => FanartTvApi.GetTvImages(tvdbid, key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvdbid}", () => FanartTvApi.GetTvImages(tvdbid, key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { return string.Empty; @@ -70,16 +70,16 @@ public async Task GetTvBanner(int tvdbid) [HttpGet("poster")] public async Task GetRandomPoster() { - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); var rand = new Random(); var val = rand.Next(1, 3); if (val == 1) { - var movies = (await _movieEngineV2.PopularMovies(0, 10, HttpContext.RequestAborted ,"en")).ToArray(); + var movies = (await _movieEngineV2.PopularMovies(0, 10, HttpContext.RequestAborted, "en")).ToArray(); var selectedMovieIndex = rand.Next(movies.Count()); var movie = movies[selectedMovieIndex]; - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movie.Id}", () => FanartTvApi.GetMovieImages(movie.Id.ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movie.Id}", () => FanartTvApi.GetMovieImages(movie.Id.ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { return string.Empty; @@ -99,7 +99,7 @@ public async Task GetRandomPoster() { return images.moviethumb.OrderBy(x => x.likes).Select(x => x.url).FirstOrDefault(); } - } + } else { var tv = (await _tvSearchEngineV2.Popular(0, 10, "en")).ToArray(); @@ -114,9 +114,9 @@ public async Task GetRandomPoster() [HttpGet("poster/movie/{movieDbId}")] public async Task GetMoviePoster(string movieDbId) { - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { @@ -148,9 +148,9 @@ public async Task GetTvPoster(int tvdbid) { return string.Empty; } - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvdbid}", () => FanartTvApi.GetTvImages(tvdbid, key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvdbid}", () => FanartTvApi.GetTvImages(tvdbid, key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { @@ -178,10 +178,10 @@ public async Task GetTvPoster(int tvdbid) [HttpGet("background/movie/{movieDbId}")] public async Task GetMovieBackground(string movieDbId) { - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); - if (images == null) { return string.Empty; @@ -203,9 +203,9 @@ public async Task GetMovieBackground(string movieDbId) [HttpGet("banner/movie/{movieDbId}")] public async Task GetMovieBanner(string movieDbId) { - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { @@ -246,34 +246,34 @@ public async Task GetBackgroundImage() var movieUrl = string.Empty; var tvUrl = string.Empty; - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); if (moviesArray.Length > 0) { var item = rand.Next(moviesArray.Length); - var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); while (!result.moviebackground?.Any() ?? true) { item = rand.Next(moviesArray.Length); - result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); } var otherRand = new Random(); var res = otherRand.Next(result.moviebackground.Length); - + movieUrl = result.moviebackground[res].url; } if (tvArray.Length > 0) { var item = rand.Next(tvArray.Length); - var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); + var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); while (!result.showbackground?.Any() ?? true) { item = rand.Next(tvArray.Length); - result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); + result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); } var otherRand = new Random(); var res = otherRand.Next(result.showbackground.Length); @@ -294,5 +294,67 @@ public async Task GetBackgroundImage() } return new { url = tvUrl }; } + + [HttpGet("background/info")] + public async Task GetBackgroundImageWithInfo() + { + var moviesArray = Options.Movies ?? Array.Empty(); + var tvArray = Options.TvShows ?? Array.Empty(); + + var rand = new Random(); + var movieUrl = string.Empty; + var movieName = string.Empty; + var tvName = string.Empty; + var tvUrl = string.Empty; + + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + + if (moviesArray.Length > 0) + { + var item = rand.Next(moviesArray.Length); + var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + + while (!result.moviebackground?.Any() ?? true) + { + item = rand.Next(moviesArray.Length); + result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + } + + var otherRand = new Random(); + var res = otherRand.Next(result.moviebackground.Length); + + movieUrl = result.moviebackground[res].url; + movieName = result.name; + } + if (tvArray.Length > 0) + { + var item = rand.Next(tvArray.Length); + var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); + + while (!result.showbackground?.Any() ?? true) + { + item = rand.Next(tvArray.Length); + result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); + } + var otherRand = new Random(); + var res = otherRand.Next(result.showbackground.Length); + + tvUrl = result.showbackground[res].url; + tvName = result.name; + } + + if (!string.IsNullOrEmpty(movieUrl) && !string.IsNullOrEmpty(tvUrl)) + { + var result = rand.Next(2); + if (result == 0) return new { url = movieUrl, name = movieName }; + if (result == 1) return new { url = tvUrl, name = tvName }; + } + + if (!string.IsNullOrEmpty(movieUrl)) + { + return new { url = movieUrl, name = movieName }; + } + return new { url = tvUrl, name = tvName }; + } } } From e00e39a1be58aabf5f8dcb250b51f19191e4076a Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Fri, 22 Jul 2022 14:30:31 +0000 Subject: [PATCH 073/270] chore(release): :rocket: v4.21.2 [skip ci] --- CHANGELOG.md | 13 +++++++++---- version.json | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 068cc25b2c..031506331f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [4.21.2](https://github.com/Ombi-app/Ombi/compare/v4.21.1...v4.21.2) (2022-07-22) + + +### Bug Fixes + +* Landing and Login page improvements ([#4690](https://github.com/Ombi-app/Ombi/issues/4690)) ([6d423b5](https://github.com/Ombi-app/Ombi/commit/6d423b5447c52c5e59d8d2bd92a23b47468eb736)) + + + ## [4.21.1](https://github.com/Ombi-app/Ombi/compare/v4.21.0...v4.21.1) (2022-07-11) @@ -354,7 +363,3 @@ -## [4.14.1](https://github.com/Ombi-app/Ombi/compare/v4.14.0...v4.14.1) (2022-03-03) - - - diff --git a/version.json b/version.json index b4b91706e1..bc378e7baa 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.21.1" + "version": "4.21.2" } \ No newline at end of file From 898bc89fa78245c1f3de9481f6c724f087a16e39 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 22 Jul 2022 22:04:18 +0100 Subject: [PATCH 074/270] =?UTF-8?q?feat(discover):=20=E2=9C=A8=20Added=20i?= =?UTF-8?q?nfinite=20scroll=20on=20advanced=20search=20results?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(discover): :sparkles: Added infinite scroll on advanced search results --- .../Engine/V2/MovieSearchEngineV2.cs | 14 +++++----- src/Ombi.TheMovieDbApi/IMovieDbApi.cs | 2 +- src/Ombi.TheMovieDbApi/TheMovieDbApi.cs | 20 +++++++------ src/Ombi/ClientApp/package.json | 2 +- .../search-results.component.html | 8 +++++- .../search-results.component.ts | 28 ++++++++++++++++++- .../src/app/search/tvsearch.component.ts | 2 +- .../advanced-search-dialog-data.service.ts | 22 +++++++++++++++ .../advanced-search-dialog.component.html | 1 - .../advanced-search-dialog.component.ts | 4 ++- src/Ombi/ClientApp/yarn.lock | 21 ++++---------- .../fixtures/api/v1/tv-search-extra-info.json | 4 +-- 12 files changed, 88 insertions(+), 40 deletions(-) diff --git a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs index ab78231a85..044d799693 100644 --- a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs @@ -152,15 +152,15 @@ public async Task> AdvancedSearch(DiscoverMode { var langCode = await DefaultLanguageCode(null); - //var pages = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, _theMovieDbMaxPageItems); + var pages = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, _theMovieDbMaxPageItems); var results = new List(); - //foreach (var pagesToLoad in pages) - //{ - var apiResult = await MovieApi.AdvancedSearch(model, cancellationToken); - //results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); - //} - return await TransformMovieResultsToResponse(apiResult); + foreach (var pagesToLoad in pages) + { + var apiResult = await MovieApi.AdvancedSearch(model, pagesToLoad.Page, cancellationToken); + results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); + } + return await TransformMovieResultsToResponse(results); } /// diff --git a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs index 12f5255b46..9b277c0917 100644 --- a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs @@ -45,6 +45,6 @@ public interface IMovieDbApi Task> GetGenres(string media, CancellationToken cancellationToken, string languageCode); Task> GetLanguages(CancellationToken cancellationToken); Task> SearchWatchProviders(string media, string searchTerm, CancellationToken cancellationToken); - Task> AdvancedSearch(DiscoverModel model, CancellationToken cancellationToken); + Task> AdvancedSearch(DiscoverModel model, int page, CancellationToken cancellationToken); } } diff --git a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs index 5b0817388a..055265701d 100644 --- a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs @@ -70,11 +70,11 @@ public async Task> DiscoverMovies(string lan - public async Task> AdvancedSearch(DiscoverModel model, CancellationToken cancellationToken) + public async Task> AdvancedSearch(DiscoverModel model, int page, CancellationToken cancellationToken) { var request = new Request($"discover/{model.Type}", BaseUri, HttpMethod.Get); request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); - if(model.ReleaseYear.HasValue && model.ReleaseYear.Value > 1900) + if (model.ReleaseYear.HasValue && model.ReleaseYear.Value > 1900) { request.FullUri = request.FullUri.AddQueryParameter("year", model.ReleaseYear.Value.ToString()); } @@ -92,6 +92,9 @@ public async Task> AdvancedSearch(DiscoverModel model, } //request.FullUri = request.FullUri.AddQueryParameter("sort_by", "popularity.desc"); + request.AddQueryString("page", page.ToString()); + + var result = await Api.Request>(request, cancellationToken); return Mapper.Map>(result.results); } @@ -139,7 +142,7 @@ public async Task GetActorMovieCredits(int actorId, string langCod var result = await Api.Request(request); return result; } - + public async Task GetActorTvCredits(int actorId, string langCode) { var request = new Request($"person/{actorId}/tv_credits", BaseUri, HttpMethod.Get); @@ -281,7 +284,7 @@ private async Task> TopRated(string type, string langC var result = await Api.Request>(request); return Mapper.Map>(result.results); } - + public Task> TrendingMovies(string langCode, int? page = null) { return Trending("movie", langCode, page); @@ -295,7 +298,7 @@ private async Task> Trending(string type, string langC { // https://developers.themoviedb.org/3/trending/get-trending var timeWindow = "week"; // another option can be 'day' - var request = new Request($"trending/{type}/{timeWindow}", BaseUri, HttpMethod.Get); + var request = new Request($"trending/{type}/{timeWindow}", BaseUri, HttpMethod.Get); request.AddQueryString("api_key", ApiToken); request.AddQueryString("language", langCode); @@ -413,8 +416,8 @@ public async Task> GetMoviesViaKeywords(string keyword request.AddQueryString("language", langCode); request.AddQueryString("sort_by", "vote_average.desc"); - request.AddQueryString("with_keywords", keywordId); - + request.AddQueryString("with_keywords", keywordId); + // `vote_count` consideration isn't explicitly documented, but using only the `sort_by` filter // does not provide the same results as `/movie/top_rated`. This appears to be adequate enough // to filter out extremely high-rated movies due to very little votes @@ -530,7 +533,8 @@ private async Task AddGenreFilter(Request request, string media_type) var settings = await Settings; List excludedGenres; - switch (media_type) { + switch (media_type) + { case "tv": excludedGenres = settings.ExcludedTvGenreIds; break; diff --git a/src/Ombi/ClientApp/package.json b/src/Ombi/ClientApp/package.json index a07dc81c49..a995527fd2 100644 --- a/src/Ombi/ClientApp/package.json +++ b/src/Ombi/ClientApp/package.json @@ -47,7 +47,7 @@ "moment": "^2.29.1", "ng2-cookies": "^1.0.12", "ngx-clipboard": "^12.1.0", - "ngx-infinite-scroll": "^9.0.0", + "ngx-infinite-scroll": "^14.0.0", "ngx-moment": "^3.0.1", "ngx-order-pipe": "^2.2.0", "popper.js": "^1.14.3", diff --git a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html index b1911ceee1..97ff038a0d 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html @@ -2,7 +2,13 @@
-
+ +
diff --git a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts index a8544365db..2959029271 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts @@ -29,6 +29,7 @@ export class DiscoverSearchResultsComponent implements OnInit { public filter: SearchFilter; private isAdvancedSearch: boolean; + private loadPosition: number = 30; constructor(private searchService: SearchV2Service, private route: ActivatedRoute, @@ -65,7 +66,7 @@ export class DiscoverSearchResultsComponent implements OnInit { } }); - if (this.advancedDataService) { + if (this.isAdvancedSearch) { return; } this.loadingFlag = true; @@ -179,6 +180,31 @@ export class DiscoverSearchResultsComponent implements OnInit { }); } + public onScroll() { + console.log("scrolled"); + if (this.advancedDataService) { + this.loadMoreAdvancedSearch(); + return; + } + } + + private loadMoreAdvancedSearch() { + const advancedOptions = this.advancedDataService.getOptions(); + + this.searchService.advancedSearch({ + type: advancedOptions.type == RequestType.movie ? "movie" : "tv", + companies: advancedOptions.companies, + genreIds: advancedOptions.genres, + keywordIds : advancedOptions.keywords, + releaseYear: advancedOptions.releaseYear, + watchProviders: advancedOptions.watchProviders, + }, this.loadPosition, 30).then(x => { + + this.loadPosition += 30; + this.mapAdvancedData(x); + }); + } + private async search() { this.clear(); this.results = await this.searchService diff --git a/src/Ombi/ClientApp/src/app/search/tvsearch.component.ts b/src/Ombi/ClientApp/src/app/search/tvsearch.component.ts index 5f65f3192c..dc87f08008 100644 --- a/src/Ombi/ClientApp/src/app/search/tvsearch.component.ts +++ b/src/Ombi/ClientApp/src/app/search/tvsearch.component.ts @@ -37,7 +37,7 @@ export class TvSearchComponent implements OnInit { private notificationService: NotificationService, private authService: AuthService, private imageService: ImageService, private sanitizer: DomSanitizer, @Inject(APP_BASE_HREF) href:string) { -this.href = href; + this.href = href; 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 diff --git a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog-data.service.ts b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog-data.service.ts index c6312915a4..480751e783 100644 --- a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog-data.service.ts +++ b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog-data.service.ts @@ -8,7 +8,9 @@ import { RequestType } from "../../interfaces"; export class AdvancedSearchDialogDataService { @Output() public onDataChange = new EventEmitter(); + @Output() public onOptionsChange = new EventEmitter(); private _data: any; + private _options: any; private _type: RequestType; setData(data: any, type: RequestType) { @@ -17,10 +19,30 @@ export class AdvancedSearchDialogDataService { this.onDataChange.emit(this._data); } + setOptions(watchProviders: number[], genres: number[], keywords: number[], releaseYear: number, type: RequestType, position: number) { + this._options = { + watchProviders, + genres, + keywords, + releaseYear, + type, + position + }; + this.onOptionsChange.emit(this._options); + } + getData(): any { return this._data; } + getOptions(): any { + return this._options; + } + + getLoaded(): number { + return this._options.loaded; + } + getType(): RequestType { return this._type; } diff --git a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html index b0ff4a81ed..d5bf4defc4 100644 --- a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html +++ b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html @@ -33,7 +33,6 @@

- {{ "Search.YearOfRelease" | translate }}
diff --git a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts index 3aa0042611..7e58b3790c 100644 --- a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts +++ b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts @@ -49,7 +49,9 @@ export class AdvancedSearchDialogComponent implements OnInit { type: formData.type, }, 0, 30); - this.advancedSearchDialogService.setData(data, formData.type === 'movie' ? RequestType.movie : RequestType.tvShow); + const type = formData.type === 'movie' ? RequestType.movie : RequestType.tvShow; + this.advancedSearchDialogService.setData(data, type); + this.advancedSearchDialogService.setOptions(watchProviderIds, genres, keywords, formData.releaseYear, type, 30); this.dialogRef.close(true); } diff --git a/src/Ombi/ClientApp/yarn.lock b/src/Ombi/ClientApp/yarn.lock index 7c65cc425a..cc330dd361 100644 --- a/src/Ombi/ClientApp/yarn.lock +++ b/src/Ombi/ClientApp/yarn.lock @@ -1902,11 +1902,6 @@ node-gyp "^8.4.1" read-package-json-fast "^2.0.3" -"@scarf/scarf@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.1.1.tgz#d8b9f20037b3a37dbf8dcdc4b3b72f9285bfce35" - integrity sha512-VGbKDbk1RFIaSmdVb0cNjjWJoRWRI/Weo23AjRCC2nryO0iAS8pzsToJfPVPtVs74WHw4L1UTADNdIYRLkirZQ== - "@schematics/angular@14.0.0": version "14.0.0" resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-14.0.0.tgz#de6cb4c86586ed5b06adfd7a759cc9908e627787" @@ -5619,13 +5614,12 @@ ngx-clipboard@^12.1.0: ngx-window-token "^2.0.0" tslib "^1.9.0" -ngx-infinite-scroll@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/ngx-infinite-scroll/-/ngx-infinite-scroll-9.1.0.tgz#6716a47613ff59f236b85c3ce291b2fd57106824" - integrity sha512-ZulbahgFsoPmP8cz7qPGDeFX9nKiSm74aav8vXNSI1ZoPiGYY5FQd8AK+yXqygY7tyCJRyt8Wp3DIg7zgP5dPA== +ngx-infinite-scroll@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/ngx-infinite-scroll/-/ngx-infinite-scroll-14.0.0.tgz#395b15be5f451c3e3d2ad7ce2aeb66f8c66aba5d" + integrity sha512-YZB5PBPXSERNtCGQRZTVflbgkh5asp01NPfC8KPItemmQik1Ip8ZCCbcyHA77TDTdilmaiu8TbguA3geg/LMWw== dependencies: - "@scarf/scarf" "^1.1.0" - opencollective-postinstall "^2.0.2" + tslib "^2.3.0" ngx-moment@^3.0.1: version "3.5.0" @@ -5901,11 +5895,6 @@ open@8.4.0, open@^8.0.9: is-docker "^2.1.1" is-wsl "^2.2.0" -opencollective-postinstall@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" - integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== - ora@5.4.1, ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" diff --git a/tests/cypress/fixtures/api/v1/tv-search-extra-info.json b/tests/cypress/fixtures/api/v1/tv-search-extra-info.json index 03b894eb2b..3421514a2c 100644 --- a/tests/cypress/fixtures/api/v1/tv-search-extra-info.json +++ b/tests/cypress/fixtures/api/v1/tv-search-extra-info.json @@ -25,14 +25,14 @@ { "episodeNumber": 1, "title": "Our Cup Runneth Over", - "airDate": "2015-01-14T01:00:00+00:00", + "airDate": "2015-01-13T00:00:00", "url": "https://www.tvmaze.com/episodes/153107/schitts-creek-1x01-our-cup-runneth-over", "available": false, "approved": false, "requested": false, "seasonId": 0, "season": null, - "airDateDisplay": "01/14/2015 01:00:00", + "airDateDisplay": "01/13/2015 00:00:00", "requestStatus": "", "id": 0 }, From 2849e026849d30abd174d5a4410f9abf53df5d36 Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Fri, 22 Jul 2022 21:08:19 +0000 Subject: [PATCH 075/270] chore(release): :rocket: v4.22.0 [skip ci] --- CHANGELOG.md | 18 +++++++++--------- version.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 031506331f..1b163362fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# [4.22.0](https://github.com/Ombi-app/Ombi/compare/v4.21.2...v4.22.0) (2022-07-22) + + +### Features + +* **discover:** ✨ Added infinite scroll on advanced search results ([898bc89](https://github.com/Ombi-app/Ombi/commit/898bc89fa78245c1f3de9481f6c724f087a16e39)) + + + ## [4.21.2](https://github.com/Ombi-app/Ombi/compare/v4.21.1...v4.21.2) (2022-07-22) @@ -354,12 +363,3 @@ -## [4.14.2](https://github.com/Ombi-app/Ombi/compare/v4.14.1...v4.14.2) (2022-03-05) - - -### Bug Fixes - -* **Sonarr:** :bug: Fixed an issue where some seasons were not being monitored correctly in sonarr ([60cfd41](https://github.com/Ombi-app/Ombi/commit/60cfd41f68e9006555c1a419dcff1aaa24b3e09f)), closes [#4506](https://github.com/Ombi-app/Ombi/issues/4506) - - - diff --git a/version.json b/version.json index bc378e7baa..a117f57ed6 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.21.2" + "version": "4.22.0" } \ No newline at end of file From 1fe7e9dda24b7c3059dc06db4a82874c7883f6d5 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 25 Jul 2022 21:11:12 +0100 Subject: [PATCH 076/270] =?UTF-8?q?=F0=9F=8C=90=20Translations=20Update=20?= =?UTF-8?q?(#4694)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(translations): 🌐 New translations from Crowdin [skip ci] * fix(translations): 🌐 New translations from Crowdin [skip ci] --- src/Ombi/wwwroot/translations/pt-BR.json | 34 ++++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Ombi/wwwroot/translations/pt-BR.json b/src/Ombi/wwwroot/translations/pt-BR.json index cfc718950d..19859cf814 100644 --- a/src/Ombi/wwwroot/translations/pt-BR.json +++ b/src/Ombi/wwwroot/translations/pt-BR.json @@ -61,7 +61,7 @@ }, "ErrorPages": { "NotFound": "Pagina nΓ£o encontrada", - "SomethingWentWrong": "Something went wrong!" + "SomethingWentWrong": "Algo deu errado!" }, "NavigationBar": { "Discover": "Explorar", @@ -212,26 +212,26 @@ "Approve4K": "Aprovar pedido 4K", "Deny4K": "Recusar pedido de 4K", "ChangeAvailability": "Marcar Como DisponΓ­vel", - "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items", + "Deleted": "Itens selecionados excluΓ­dos com sucesso", + "Approved": "Itens selecionados aprovados com sucesso", "Denied": "Itens selecionados negados com sucesso" }, - "SuccessfullyApproved": "Successfully Approved", - "SuccessfullyDeleted": "Request successfully deleted", - "NowAvailable": "Request is now available", - "NowUnavailable": "Request is now unavailable", - "SuccessfullyReprocessed": "Successfully Re-processed the request", - "DeniedRequest": "Denied Request", - "RequestCollection": "Request Collection", - "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", - "NeedToSelectEpisodes": "You need to select some episodes!", + "SuccessfullyApproved": "Aprovado com Sucesso", + "SuccessfullyDeleted": "Solicitação excluΓ­da com sucesso", + "NowAvailable": "O pedido agora estΓ‘ disponΓ­vel", + "NowUnavailable": "A solicitação estΓ‘ indisponΓ­vel", + "SuccessfullyReprocessed": "A solicitação foi reprocessada com sucesso", + "DeniedRequest": "Pedido negado", + "RequestCollection": "Solicitar Coleção", + "CollectionSuccesfullyAdded": "A coleção {{name}} foi adicionada com sucesso!", + "NeedToSelectEpisodes": "VocΓͺ precisa selecionar alguns episΓ³dios!", "RequestAddedSuccessfully": "Solicitação de {{title}} foi adicionada com sucesso", "ErrorCodes": { - "AlreadyRequested": "This has already been requested", - "EpisodesAlreadyRequested": "We already have episodes requested from this series", - "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", - "NoPermissions": "You do not have the correct permissions!", - "RequestDoesNotExist": "Request does not exist", + "AlreadyRequested": "Isso jΓ‘ foi solicitado", + "EpisodesAlreadyRequested": "JΓ‘ temos episΓ³dios solicitados desta sΓ©rie", + "NoPermissionsOnBehalf": "VocΓͺ nΓ£o tem as permissΓ΅es corretas para pedir em nome dos usuΓ‘rios!", + "NoPermissions": "VocΓͺ nΓ£o tem as permissΓ΅es corretas!", + "RequestDoesNotExist": "A solicitação nΓ£o existe", "ChildRequestDoesNotExist": "Child Request does not exist", "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", From f22d3da765799365455b919027f7563e52b347c3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 25 Jul 2022 21:46:11 +0100 Subject: [PATCH 077/270] fix(discover): :bug: Created new Image component to handle 429's from TMDB (#4698) and fixed #4635 (#4699) --- src/Ombi/ClientApp/src/app/app.module.ts | 5 +- .../app/components/image/image.component.html | 1 + .../app/components/image/image.component.ts | 57 +++++++++++++++++++ .../ClientApp/src/app/components/index.ts | 3 +- .../card/discover-card.component.html | 2 +- .../card/discover-card.component.scss | 2 +- .../src/app/discover/discover.module.ts | 2 + .../movie/movie-details.component.html | 8 +-- .../cast-carousel.component.html | 4 +- .../cast-carousel.component.scss | 4 +- .../media-poster/media-poster.component.html | 4 +- .../top-banner/top-banner.component.html | 1 - .../tv-information-panel.component.html | 2 +- .../app/media-details/media-details.module.ts | 2 + 14 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 src/Ombi/ClientApp/src/app/components/image/image.component.html create mode 100644 src/Ombi/ClientApp/src/app/components/image/image.component.ts diff --git a/src/Ombi/ClientApp/src/app/app.module.ts b/src/Ombi/ClientApp/src/app/app.module.ts index 30f4b2ea6f..24644d1dfb 100644 --- a/src/Ombi/ClientApp/src/app/app.module.ts +++ b/src/Ombi/ClientApp/src/app/app.module.ts @@ -68,7 +68,7 @@ import { TooltipModule } from "primeng/tooltip"; import { TranslateHttpLoader } from "@ngx-translate/http-loader"; import { TranslateService } from "@ngx-translate/core"; import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor"; -import { ImageBackgroundComponent } from "./components/"; +import { ImageBackgroundComponent, ImageComponent } from "./components/"; import { environment } from "../environments/environment"; const routes: Routes = [ @@ -168,7 +168,8 @@ export function JwtTokenGetter() { [ NgxsReduxDevtoolsPluginModule.forRoot(), ], - ImageBackgroundComponent + ImageBackgroundComponent, + ImageComponent, ], declarations: [ AppComponent, diff --git a/src/Ombi/ClientApp/src/app/components/image/image.component.html b/src/Ombi/ClientApp/src/app/components/image/image.component.html new file mode 100644 index 0000000000..3d55533139 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image/image.component.html @@ -0,0 +1 @@ + diff --git a/src/Ombi/ClientApp/src/app/components/image/image.component.ts b/src/Ombi/ClientApp/src/app/components/image/image.component.ts new file mode 100644 index 0000000000..57099016af --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image/image.component.ts @@ -0,0 +1,57 @@ +import { OmbiCommonModules } from "../modules"; +import { ChangeDetectionStrategy, Component, ElementRef, Inject, Input, ViewEncapsulation } from "@angular/core"; +import { RequestType } from "../../interfaces"; +import { APP_BASE_HREF } from "@angular/common"; + +@Component({ + standalone: true, + selector: 'ombi-image', + imports: [...OmbiCommonModules], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './image.component.html', + }) + export class ImageComponent { + + @Input() public src: string; + @Input() public type: RequestType; + + // Attributes from the parent + @Input() public class: string; + @Input() public id: string; + @Input() public alt: string; + @Input() public style: string; + + public baseUrl: string = ""; + + public defaultTv = "/images/default_tv_poster.png"; + private defaultMovie = "/images/default_movie_poster.png"; + private defaultMusic = "i/mages/default-music-placeholder.png"; + + constructor (@Inject(APP_BASE_HREF) public href: string) { + if (this.href.length > 1) { + this.baseUrl = this.href; + } + } + + public onError(event: any) { + // set to a placeholder + switch(this.type) { + case RequestType.movie: + event.target.src = this.baseUrl + this.defaultMovie; + break; + case RequestType.tvShow: + event.target.src = this.baseUrl + this.defaultTv; + break; + case RequestType.album: + event.target.src = this.baseUrl + this.defaultMusic; + break; + } + + // Retry the original image + const timeout = setTimeout(() => { + event.target.src = this.src; + clearTimeout(timeout); + }, Math.floor(Math.random() * (7000 - 1000 + 1)) + 1000); + } + } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/index.ts b/src/Ombi/ClientApp/src/app/components/index.ts index 75334a9e48..092f6504b8 100644 --- a/src/Ombi/ClientApp/src/app/components/index.ts +++ b/src/Ombi/ClientApp/src/app/components/index.ts @@ -1 +1,2 @@ -export * from "./image-background/image-background.component"; \ No newline at end of file +export * from "./image-background/image-background.component"; +export * from "./image/image.component"; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html index d7ffbb6c1a..a479b5072a 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html @@ -9,7 +9,7 @@ {{getAvailabilityStatus()}}

- {{result.title}} +
diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss index 5fe422fd78..6a79112576 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss @@ -83,7 +83,7 @@ small { } -.image { +::ng-deep .image { border-radius: 10px; opacity: 1; display: block; diff --git a/src/Ombi/ClientApp/src/app/discover/discover.module.ts b/src/Ombi/ClientApp/src/app/discover/discover.module.ts index 414c881e6b..eade4e4518 100644 --- a/src/Ombi/ClientApp/src/app/discover/discover.module.ts +++ b/src/Ombi/ClientApp/src/app/discover/discover.module.ts @@ -8,6 +8,7 @@ import { PipeModule } from "../pipes/pipe.module"; import { RouterModule } from "@angular/router"; import { SharedModule } from "../shared/shared.module"; import { SkeletonModule } from 'primeng/skeleton'; +import { ImageComponent } from 'app/components'; @NgModule({ imports: [ @@ -18,6 +19,7 @@ import { SkeletonModule } from 'primeng/skeleton'; MatButtonToggleModule, InfiniteScrollModule, SkeletonModule, + ImageComponent ], declarations: [ ...fromComponents.components 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 90cf455f0e..6659e1ccb0 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 @@ -252,9 +252,9 @@ @@ -274,9 +274,9 @@ diff --git a/src/Ombi/ClientApp/src/app/media-details/components/shared/cast-carousel/cast-carousel.component.html b/src/Ombi/ClientApp/src/app/media-details/components/shared/cast-carousel/cast-carousel.component.html index 49875514d4..e14323a0ec 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/shared/cast-carousel/cast-carousel.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/shared/cast-carousel/cast-carousel.component.html @@ -6,10 +6,10 @@