From 07f3f4162a86cc4f282473fae3caabeb5a7e98b3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 26 Oct 2018 21:07:43 +0100 Subject: [PATCH 01/20] Added the ability to get the ombi user via a Plex Token #2591 --- .../Authentication/OmbiUserManager.cs | 17 +++++++++++++++ src/Ombi/Controllers/TokenController.cs | 21 ++++++++++++++++--- .../External/PlexTokenAuthentication.cs | 7 +++++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 src/Ombi/Models/External/PlexTokenAuthentication.cs diff --git a/src/Ombi.Core/Authentication/OmbiUserManager.cs b/src/Ombi.Core/Authentication/OmbiUserManager.cs index 185677215..4e3d9ef43 100644 --- a/src/Ombi.Core/Authentication/OmbiUserManager.cs +++ b/src/Ombi.Core/Authentication/OmbiUserManager.cs @@ -29,6 +29,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Ombi.Api.Emby; @@ -101,6 +102,22 @@ public async Task RequiresPassword(OmbiUser user) return true; } + public async Task GetOmbiUserFromPlexToken(string plexToken) + { + var plexAccount = await _plexApi.GetAccount(plexToken); + + // Check for a ombi user + if (plexAccount?.user != null) + { + var potentialOmbiUser = await Users.FirstOrDefaultAsync(x => + x.ProviderUserId.Equals(plexAccount.user.id, StringComparison.InvariantCultureIgnoreCase)); + return potentialOmbiUser; + } + + return null; + } + + /// /// Sign the user into plex and make sure we can get the authentication token. /// We do not check if the user is in the owners "friends" since they must have a local user account to get this far diff --git a/src/Ombi/Controllers/TokenController.cs b/src/Ombi/Controllers/TokenController.cs index 87136fd00..0c05c81fe 100644 --- a/src/Ombi/Controllers/TokenController.cs +++ b/src/Ombi/Controllers/TokenController.cs @@ -10,14 +10,13 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; -using Ombi.Api; using Ombi.Core.Authentication; using Ombi.Helpers; using Ombi.Models; +using Ombi.Models.External; using Ombi.Models.Identity; using Ombi.Store.Entities; using Ombi.Store.Repository; -using StackExchange.Profiling.Helpers; namespace Ombi.Controllers { @@ -80,7 +79,7 @@ await _audit.Record(AuditType.None, AuditArea.Authentication, { // Plex OAuth // Redirect them to Plex - + var websiteAddress = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}"; //https://app.plex.tv/auth#?forwardUrl=http://google.com/&clientID=Ombi-Test&context%5Bdevice%5D%5Bproduct%5D=Ombi%20SSO&pinID=798798&code=4lgfd var url = await _plexOAuthManager.GetOAuthUrl(model.PlexTvPin.code, websiteAddress); @@ -97,6 +96,22 @@ await _audit.Record(AuditType.None, AuditArea.Authentication, return new UnauthorizedResult(); } + [HttpPost("plextoken")] + public async Task GetTokenWithPlexToken([FromBody] PlexTokenAuthentication model) + { + if (!model.PlexToken.HasValue()) + { + return BadRequest("Token was not provided"); + } + var user = await _userManager.GetOmbiUserFromPlexToken(model.PlexToken); + if (user == null) + { + return Unauthorized(); + } + return await CreateToken(true, user); + } + + private async Task CreateToken(bool rememberMe, OmbiUser user) { var roles = await _userManager.GetRolesAsync(user); diff --git a/src/Ombi/Models/External/PlexTokenAuthentication.cs b/src/Ombi/Models/External/PlexTokenAuthentication.cs new file mode 100644 index 000000000..38184ecdb --- /dev/null +++ b/src/Ombi/Models/External/PlexTokenAuthentication.cs @@ -0,0 +1,7 @@ +namespace Ombi.Models.External +{ + public class PlexTokenAuthentication + { + public string PlexToken { get; set; } + } +} \ No newline at end of file From d3c33fa804d77afe120fda6610401574123185e0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 26 Oct 2018 22:29:29 +0100 Subject: [PATCH 02/20] Show the TV show as available when we have all the episodes but future episodes have not aired. #2585 --- .../Rule/Rules/Search/PlexAvailabilityRule.cs | 18 +++++++++++++++++- src/Ombi/Controllers/TokenController.cs | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs index 016a2817c..e1ddcecd0 100644 --- a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Core.Models.Search; @@ -104,6 +105,21 @@ public async Task Execute(SearchViewModel obj) { search.FullyAvailable = true; } + else + { + var airedButNotAvailable = search.SeasonRequests.Any(x => + x.Episodes.Any(c => !c.Available && c.AirDate <= DateTime.Now.Date)); + if (!airedButNotAvailable) + { + var unairedEpisodes = search.SeasonRequests.Any(x => + x.Episodes.Any(c => !c.Available && c.AirDate > DateTime.Now.Date)); + if (unairedEpisodes) + { + search.FullyAvailable = true; + } + } + + } } } } diff --git a/src/Ombi/Controllers/TokenController.cs b/src/Ombi/Controllers/TokenController.cs index 0c05c81fe..75e40639f 100644 --- a/src/Ombi/Controllers/TokenController.cs +++ b/src/Ombi/Controllers/TokenController.cs @@ -96,6 +96,9 @@ await _audit.Record(AuditType.None, AuditArea.Authentication, return new UnauthorizedResult(); } + /// + /// Returns the Token for the Ombi User if we can match the Plex user with a valid Ombi User + /// [HttpPost("plextoken")] public async Task GetTokenWithPlexToken([FromBody] PlexTokenAuthentication model) { From 4f5c879fd77d92291d5c0fbf30b65b9cd721e54e Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 26 Oct 2018 23:25:30 +0100 Subject: [PATCH 03/20] Fixed error !wip #2591 --- src/Ombi.Core/Authentication/OmbiUserManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Core/Authentication/OmbiUserManager.cs b/src/Ombi.Core/Authentication/OmbiUserManager.cs index 4e3d9ef43..2c78f39bf 100644 --- a/src/Ombi.Core/Authentication/OmbiUserManager.cs +++ b/src/Ombi.Core/Authentication/OmbiUserManager.cs @@ -110,7 +110,7 @@ public async Task GetOmbiUserFromPlexToken(string plexToken) if (plexAccount?.user != null) { var potentialOmbiUser = await Users.FirstOrDefaultAsync(x => - x.ProviderUserId.Equals(plexAccount.user.id, StringComparison.InvariantCultureIgnoreCase)); + x.ProviderUserId == plexAccount.user.id); return potentialOmbiUser; } From 6152503aa183b68b4acf1b55eb913a286e95e505 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Nov 2018 08:30:53 +0000 Subject: [PATCH 04/20] !wip --- appveyor.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 99ec1e669..b1d83cee3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,11 @@ configuration: Release os: Visual Studio 2017 environment: nodejs_version: "9.8.0" - typescript_version: "3.0.1" + typescript_version: "3.0.1" + github_auth_token: + secure: H/7uCrjmWHGJxgN3l9fbhhdVjvvWI8VVF4ZzQqeXuJwAf+PgSNBdxv4SS+rMQ+RH + sonarrcloud_token: + secure: WGkIog4wuMSx1q5vmSOgIBXMtI/leMpLbZhi9MJnJdBBuDfcv12zwXg3LQwY0WbE install: # Get the latest stable version of Node.js or io.js @@ -12,7 +16,11 @@ install: - cmd: set path=%programfiles(x86)%\\Microsoft SDKs\TypeScript\3.0;%path% - cmd: tsc -v build_script: + - dotnet tool install --global dotnet-sonarscanner + - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=%sonarrcloud_token%" /d:"sonar.analysis.mode=preview" /d:"sonar.github.pullRequest=$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:"sonar.github.repository=https://github.com/tidusjar/ombi" /d:"sonar.github.oauth=%github_auth_token%" } + - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=%sonarrcloud_token%" } - ps: ./build.ps1 --settings_skipverification=true + - dotnet sonarscanner end /d:"sonar.login=YourSonarQubeToken" test: off From a480f9295b7e732cb5b0f3d356169ea78da4522b Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Nov 2018 08:31:27 +0000 Subject: [PATCH 05/20] !wip --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index b1d83cee3..34d5ce4e7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,7 +20,7 @@ build_script: - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=%sonarrcloud_token%" /d:"sonar.analysis.mode=preview" /d:"sonar.github.pullRequest=$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:"sonar.github.repository=https://github.com/tidusjar/ombi" /d:"sonar.github.oauth=%github_auth_token%" } - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=%sonarrcloud_token%" } - ps: ./build.ps1 --settings_skipverification=true - - dotnet sonarscanner end /d:"sonar.login=YourSonarQubeToken" + - dotnet sonarscanner end /d:"sonar.login=%sonarrcloud_token%" test: off From 9deaeb15df50fc5931932366c30abc11d75f4602 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Nov 2018 08:35:20 +0000 Subject: [PATCH 06/20] !wip --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 34d5ce4e7..ef01cf231 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,8 +17,8 @@ install: - cmd: tsc -v build_script: - dotnet tool install --global dotnet-sonarscanner - - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=%sonarrcloud_token%" /d:"sonar.analysis.mode=preview" /d:"sonar.github.pullRequest=$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:"sonar.github.repository=https://github.com/tidusjar/ombi" /d:"sonar.github.oauth=%github_auth_token%" } - - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=%sonarrcloud_token%" } + - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=$env.sonarrcloud_token" /d:"sonar.analysis.mode=preview" /d:"sonar.github.pullRequest=$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:"sonar.github.repository=https://github.com/tidusjar/ombi" /d:"sonar.github.oauth=$env.github_auth_token" } + - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=$env.sonarrcloud_token" } - ps: ./build.ps1 --settings_skipverification=true - dotnet sonarscanner end /d:"sonar.login=%sonarrcloud_token%" From 5684ba25033779af5f447d866ea4c6a3961207a6 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Nov 2018 08:38:25 +0000 Subject: [PATCH 07/20] !wip --- appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index ef01cf231..0618f57f4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,13 +17,13 @@ install: - cmd: tsc -v build_script: - dotnet tool install --global dotnet-sonarscanner - - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=$env.sonarrcloud_token" /d:"sonar.analysis.mode=preview" /d:"sonar.github.pullRequest=$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:"sonar.github.repository=https://github.com/tidusjar/ombi" /d:"sonar.github.oauth=$env.github_auth_token" } - - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:"sonar.host.url=https://sonarcloud.io" /d:"sonar.login=$env.sonarrcloud_token" } + - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.sonarrcloud_token" /d:sonar.analysis.mode="preview" /d:sonar.github.pullRequest="$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:sonar.github.repository="https://github.com/tidusjar/ombi" /d:sonar.github.oauth="$env.github_auth_token" } + - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.sonarrcloud_token" } - ps: ./build.ps1 --settings_skipverification=true - dotnet sonarscanner end /d:"sonar.login=%sonarrcloud_token%" test: off - + after_build: - cmd: >- From d9adf22b0c27946365ce62d142416f4ed348cb30 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Nov 2018 08:43:20 +0000 Subject: [PATCH 08/20] !wip --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0618f57f4..d68214c63 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: typescript_version: "3.0.1" github_auth_token: secure: H/7uCrjmWHGJxgN3l9fbhhdVjvvWI8VVF4ZzQqeXuJwAf+PgSNBdxv4SS+rMQ+RH - sonarrcloud_token: + sonarrcloudtoken: secure: WGkIog4wuMSx1q5vmSOgIBXMtI/leMpLbZhi9MJnJdBBuDfcv12zwXg3LQwY0WbE install: @@ -17,10 +17,10 @@ install: - cmd: tsc -v build_script: - dotnet tool install --global dotnet-sonarscanner - - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.sonarrcloud_token" /d:sonar.analysis.mode="preview" /d:sonar.github.pullRequest="$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:sonar.github.repository="https://github.com/tidusjar/ombi" /d:sonar.github.oauth="$env.github_auth_token" } - - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.sonarrcloud_token" } + #- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.sonarrcloud_token" /d:sonar.analysis.mode="preview" /d:sonar.github.pullRequest="$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:sonar.github.repository="https://github.com/tidusjar/ombi" /d:sonar.github.oauth="$env.github_auth_token" } + - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.SONARRCLOUDTOKEN" } - ps: ./build.ps1 --settings_skipverification=true - - dotnet sonarscanner end /d:"sonar.login=%sonarrcloud_token%" + - dotnet sonarscanner end /d:sonar.login="%sonarrcloudtoken%" test: off From 5f765dbf562be7e294935598a44473ea5d9a716d Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Nov 2018 08:51:50 +0000 Subject: [PATCH 09/20] !wip --- appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d68214c63..448e1b9c8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,11 +16,11 @@ install: - cmd: set path=%programfiles(x86)%\\Microsoft SDKs\TypeScript\3.0;%path% - cmd: tsc -v build_script: - - dotnet tool install --global dotnet-sonarscanner + # - dotnet tool install --global dotnet-sonarscanner #- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.sonarrcloud_token" /d:sonar.analysis.mode="preview" /d:sonar.github.pullRequest="$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:sonar.github.repository="https://github.com/tidusjar/ombi" /d:sonar.github.oauth="$env.github_auth_token" } - - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.SONARRCLOUDTOKEN" } + # - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.SONARRCLOUDTOKEN" } - ps: ./build.ps1 --settings_skipverification=true - - dotnet sonarscanner end /d:sonar.login="%sonarrcloudtoken%" + # - dotnet sonarscanner end /d:sonar.login="%sonarrcloudtoken%" test: off From 2c66793986853e90db60f5bd05a705f44e550508 Mon Sep 17 00:00:00 2001 From: TidusJar Date: Mon, 5 Nov 2018 08:25:06 +0000 Subject: [PATCH 10/20] Fixed #2633 --- .../Rules/Request/ExistingTVRequestRule.cs | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs diff --git a/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs new file mode 100644 index 000000000..9942ece63 --- /dev/null +++ b/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs @@ -0,0 +1,57 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Ombi.Core.Rule.Interfaces; +using Ombi.Store.Entities; +using Ombi.Store.Entities.Requests; +using Ombi.Store.Repository.Requests; + +namespace Ombi.Core.Rule.Rules.Request +{ + public class ExistingTvRequestRule : BaseRequestRule, IRules + { + public ExistingTvRequestRule(ITvRequestRepository rv) + { + Tv = rv; + } + + private ITvRequestRepository Tv { get; } + + /// + /// We check if the request exists, if it does then we don't want to re-request it. + /// + /// The object. + /// + public async Task Execute(BaseRequest obj) + { + if (obj.RequestType == RequestType.TvShow) + { + var tv = (ChildRequests) obj; + var tvRequests = Tv.GetChild(); + var currentRequest = await tvRequests.FirstOrDefaultAsync(x => x.ParentRequest.TvDbId == tv.Id); // the Id on the child is the tvdbid at this point + if (currentRequest == null) + { + return Success(); + } + foreach (var season in tv.SeasonRequests) + { + var currentSeasonRequest = + currentRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == season.SeasonNumber); + if (currentSeasonRequest == null) + { + continue; + } + foreach (var e in season.Episodes) + { + var hasEpisode = currentSeasonRequest.Episodes.Any(x => x.EpisodeNumber == e.EpisodeNumber); + if (hasEpisode) + { + return Fail($"We already have episodes requested from series {tv.Title}"); + } + } + } + } + return Success(); + } + } +} \ No newline at end of file From 46e3b878a132365be333fee08a741233c877a80f Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 7 Nov 2018 19:43:35 +0000 Subject: [PATCH 11/20] Fixed #2623 --- src/Ombi.Api.Emby/EmbyApi.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Ombi.Api.Emby/EmbyApi.cs b/src/Ombi.Api.Emby/EmbyApi.cs index fcb989094..fa8414ac9 100644 --- a/src/Ombi.Api.Emby/EmbyApi.cs +++ b/src/Ombi.Api.Emby/EmbyApi.cs @@ -98,7 +98,7 @@ public async Task> GetCollection(string mediaId, st request.AddQueryString("Fields", "ProviderIds,Overview"); - request.AddQueryString("VirtualItem", "False"); + request.AddQueryString("IsVirtualItem", "False"); return await Api.Request>(request); } @@ -149,7 +149,7 @@ private async Task> GetAll(string type, string apiKey, s request.AddQueryString("IncludeItemTypes", type); request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds"); - request.AddQueryString("VirtualItem", "False"); + request.AddQueryString("IsVirtualItem", "False"); AddHeaders(request, apiKey); @@ -167,7 +167,7 @@ private async Task> GetAll(string type, string apiKey, s request.AddQueryString("startIndex", startIndex.ToString()); request.AddQueryString("limit", count.ToString()); - request.AddQueryString("VirtualItem", "False"); + request.AddQueryString("IsVirtualItem", "False"); AddHeaders(request, apiKey); From 39700c4bf755ef6f490147e865da6644ec7db318 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Nov 2018 14:42:27 +0000 Subject: [PATCH 12/20] Fixed #2639 --- .../ClientApp/app/requests/remainingrequests.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts b/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts index c88e63009..bf43b7330 100644 --- a/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts +++ b/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts @@ -39,7 +39,9 @@ export class RemainingRequestsComponent implements OnInit { public update(): void { const callback = (remaining => { this.remaining = remaining; - this.calculateTime(); + if(this.remaining) { + this.calculateTime(); + } }); if (this.movie) { From 3de88be16c9debff726ae8d7a4668224e958a223 Mon Sep 17 00:00:00 2001 From: TidusJar Date: Wed, 14 Nov 2018 20:48:23 +0000 Subject: [PATCH 13/20] Fixed the issue where we were marking the whole season as wanted in Sonarr rather than the individual episode #2629 --- src/Ombi.Core/Senders/TvSender.cs | 2 +- src/Ombi.Schedule/Processor/ChangeLogProcessor.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ombi.Core/Senders/TvSender.cs b/src/Ombi.Core/Senders/TvSender.cs index e48e54c1a..1b3ed9461 100644 --- a/src/Ombi.Core/Senders/TvSender.cs +++ b/src/Ombi.Core/Senders/TvSender.cs @@ -355,7 +355,7 @@ private static List GetSeasonsToCreate(ChildRequests model) var sea = new Season { seasonNumber = i, - monitored = model.SeasonRequests.Any(x => x.SeasonNumber == index && x.SeasonNumber != 0) + monitored = false }; seasonsToUpdate.Add(sea); } diff --git a/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs b/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs index e645097ef..a34bd89e1 100644 --- a/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs +++ b/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs @@ -174,7 +174,7 @@ private async Task GetGitubRelease(Release release, string releaseTag) var client = new GitHubClient(Octokit.ProductHeaderValue.Parse("OmbiV3")); var releases = await client.Repository.Release.GetAll("tidusjar", "ombi"); - var latest = releases.FirstOrDefault(x => x.TagName == releaseTag); + var latest = releases.FirstOrDefault(x => x.TagName.Equals(releaseTag, StringComparison.InvariantCultureIgnoreCase)); if (latest.Name.Contains("V2", CompareOptions.IgnoreCase)) { latest = null; From 527bc00c09ec0b9f91abbef4a3c392aab1052908 Mon Sep 17 00:00:00 2001 From: TidusJar Date: Wed, 14 Nov 2018 21:40:20 +0000 Subject: [PATCH 14/20] Fixed the issue where we were marking episodes as available with the Emby connection when they have not yet aired #2417 #2623 --- src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs index f66ff89ab..23ad24268 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs @@ -82,6 +82,13 @@ private async Task CacheEpisodes(EmbyServers server) foreach (var ep in allEpisodes.Items) { processed++; + + if (ep.LocationType.Equals("Virtual", StringComparison.InvariantCultureIgnoreCase)) + { + // 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); From 417e4085c55a16999a47823459c39cf3c0c8ed93 Mon Sep 17 00:00:00 2001 From: Jamie Date: Sun, 18 Nov 2018 20:14:47 +0000 Subject: [PATCH 15/20] Fixed the issue where we could sometimes allow the request of a whole series when the user shouldn't be able to --- src/Ombi.Core/Engine/TvRequestEngine.cs | 1 + src/Ombi.Core/Helpers/TvShowRequestBuilder.cs | 7 +- .../Rules/Request/ExistingPlexRequestRule.cs | 82 +++++++++++++++++++ .../Entities/Requests/ChildRequests.cs | 5 +- 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index f1a5b9880..290bedd6b 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -116,6 +116,7 @@ public async Task RequestTvShow(TvRequestViewModel tv) } // Remove the ID since this is a new child + // This was a TVDBID for the request rules to run tvBuilder.ChildRequest.Id = 0; if (!tvBuilder.ChildRequest.SeasonRequests.Any()) { diff --git a/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs b/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs index e5277e236..334284484 100644 --- a/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs +++ b/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs @@ -41,7 +41,7 @@ public async Task GetShowInfo(int id) ShowInfo = await TvApi.ShowLookupByTheTvDbId(id); Results = await MovieDbApi.SearchTv(ShowInfo.name); foreach (TvSearchResult result in Results) { - if (result.Name == ShowInfo.name) + if (result.Name.Equals(ShowInfo.name, StringComparison.InvariantCultureIgnoreCase)) { var showIds = await MovieDbApi.GetTvExternals(result.Id); ShowInfo.externals.imdb = showIds.imdb_id; @@ -64,14 +64,15 @@ public TvShowRequestBuilder CreateChild(TvRequestViewModel model, string userId) { ChildRequest = new ChildRequests { - Id = model.TvDbId, + Id = model.TvDbId, // This is set to 0 after the request rules have run, the request rules needs it to identify the request RequestType = RequestType.TvShow, RequestedDate = DateTime.UtcNow, Approved = false, RequestedUserId = userId, SeasonRequests = new List(), Title = ShowInfo.name, - SeriesType = ShowInfo.genres.Any( s => s.Equals("Anime", StringComparison.OrdinalIgnoreCase)) ? SeriesType.Anime : SeriesType.Standard + ReleaseYear = FirstAir, + SeriesType = ShowInfo.genres.Any( s => s.Equals("Anime", StringComparison.InvariantCultureIgnoreCase)) ? SeriesType.Anime : SeriesType.Standard }; return this; diff --git a/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs new file mode 100644 index 000000000..5d7658c83 --- /dev/null +++ b/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Ombi.Core.Rule.Interfaces; +using Ombi.Store.Entities; +using Ombi.Store.Entities.Requests; +using Ombi.Store.Repository; + +namespace Ombi.Core.Rule.Rules.Request +{ + public class ExistingPlexRequestRule : BaseRequestRule, IRules + { + public ExistingPlexRequestRule(IPlexContentRepository rv) + { + _plexContent = rv; + } + + private readonly IPlexContentRepository _plexContent; + + /// + /// We check if the request exists, if it does then we don't want to re-request it. + /// + /// The object. + /// + public async Task Execute(BaseRequest obj) + { + if (obj.RequestType == RequestType.TvShow) + { + var tvRequest = (ChildRequests) obj; + + var tvContent = _plexContent.GetAll().Where(x => x.Type == PlexMediaTypeEntity.Show); + // We need to do a check on the TVDBId + var anyTvDbMatches = await tvContent.Include(x => x.Episodes).FirstOrDefaultAsync(x => x.HasTvDb && x.TvDbId.Equals(tvRequest.Id.ToString())); // the Id on the child is the tvdbid at this point + if (anyTvDbMatches == null) + { + // So we do not have a TVDB Id, that really sucks. + // Let's try and match on the title and year of the show + var titleAndYearMatch = await tvContent.Include(x=> x.Episodes).FirstOrDefaultAsync(x => + x.Title.Equals(tvRequest.Title, StringComparison.InvariantCultureIgnoreCase) + && x.ReleaseYear == tvRequest.ReleaseYear.Year.ToString()); + if (titleAndYearMatch != null) + { + // We have a match! Suprise Motherfucker + return CheckExistingContent(tvRequest, titleAndYearMatch); + } + + // We do not have this + return Success(); + } + // looks like we have a match on the TVDbID + return CheckExistingContent(tvRequest, anyTvDbMatches); + } + return Success(); + } + + + private RuleResult CheckExistingContent(ChildRequests child, PlexServerContent content) + { + foreach (var season in child.SeasonRequests) + { + var currentSeasonRequest = + content.Episodes.Where(x => x.SeasonNumber == season.SeasonNumber).ToList(); + if (!currentSeasonRequest.Any()) + { + continue; + } + foreach (var e in season.Episodes) + { + var hasEpisode = currentSeasonRequest.Any(x => x.EpisodeNumber == e.EpisodeNumber); + if (hasEpisode) + { + return Fail($"We already have episodes requested from series {child.Title}"); + } + } + } + + return Success(); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Entities/Requests/ChildRequests.cs b/src/Ombi.Store/Entities/Requests/ChildRequests.cs index 3b5156ce5..f212aa3e7 100644 --- a/src/Ombi.Store/Entities/Requests/ChildRequests.cs +++ b/src/Ombi.Store/Entities/Requests/ChildRequests.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using Ombi.Store.Repository.Requests; @@ -22,6 +23,8 @@ public class ChildRequests : BaseRequest [NotMapped] public bool ShowSubscribe { get; set; } + [NotMapped] + public DateTime ReleaseYear { get; set; } // Used in the ExistingPlexRequestRule.cs [ForeignKey(nameof(IssueId))] public List Issues { get; set; } From aa487e6ccf3a0f1a6553472ab2ebd0807dc8eba2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 19 Nov 2018 21:27:25 +0000 Subject: [PATCH 16/20] Fixed the issue with the user overrides #2646 --- src/Ombi.Core/Senders/MovieSender.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Ombi.Core/Senders/MovieSender.cs b/src/Ombi.Core/Senders/MovieSender.cs index 8b89ef7bb..66978f758 100644 --- a/src/Ombi.Core/Senders/MovieSender.cs +++ b/src/Ombi.Core/Senders/MovieSender.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; @@ -101,13 +102,17 @@ private async Task SendToRadarr(MovieRequests model, RadarrSetting var profiles = await _userProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == model.RequestedUserId); if (profiles != null) { - if (profiles.SonarrRootPathAnime > 0) - { - rootFolderPath = await RadarrRootPath(profiles.SonarrRootPathAnime, settings); + if (profiles.RadarrRootPath > 0) + { + var tempPath = await RadarrRootPath(profiles.RadarrRootPath, settings); + if (tempPath.HasValue()) + { + rootFolderPath = tempPath; + } } - if (profiles.SonarrQualityProfileAnime > 0) + if (profiles.RadarrQualityProfile > 0) { - qualityToUse = profiles.SonarrQualityProfileAnime; + qualityToUse = profiles.RadarrQualityProfile; } } @@ -163,7 +168,7 @@ private async Task RadarrRootPath(int overrideId, RadarrSettings setting { var paths = await RadarrApi.GetRootFolders(settings.ApiKey, settings.FullUri); var selectedPath = paths.FirstOrDefault(x => x.id == overrideId); - return selectedPath.path; + return selectedPath?.path ?? String.Empty; } } } \ No newline at end of file From cd43bed26be05ee9f3c74206bcb4df7de2f00c06 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 19 Nov 2018 21:31:38 +0000 Subject: [PATCH 17/20] Fixed #2603 --- src/Ombi/ClientApp/app/requests/request.component.html | 2 +- src/Ombi/ClientApp/app/requests/request.component.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Ombi/ClientApp/app/requests/request.component.html b/src/Ombi/ClientApp/app/requests/request.component.html index d2df3c97a..db72b9d17 100644 --- a/src/Ombi/ClientApp/app/requests/request.component.html +++ b/src/Ombi/ClientApp/app/requests/request.component.html @@ -9,7 +9,7 @@

{{ 'Requests.TvTab' | translate }} -
  • +
  • {{ 'Requests.MusicTab' | translate }}
  • diff --git a/src/Ombi/ClientApp/app/requests/request.component.ts b/src/Ombi/ClientApp/app/requests/request.component.ts index d0fa9d0b1..b318d619b 100644 --- a/src/Ombi/ClientApp/app/requests/request.component.ts +++ b/src/Ombi/ClientApp/app/requests/request.component.ts @@ -15,6 +15,7 @@ export class RequestComponent implements OnInit { public issueCategories: IIssueCategory[]; public issuesEnabled = false; + public musicEnabled: boolean; constructor(private issuesService: IssuesService, private settingsService: SettingsService) { @@ -23,6 +24,7 @@ export class RequestComponent implements OnInit { public ngOnInit(): void { this.issuesService.getCategories().subscribe(x => this.issueCategories = x); + this.settingsService.lidarrEnabled().subscribe(x => this.musicEnabled = x); this.settingsService.getIssueSettings().subscribe(x => this.issuesEnabled = x.enabled); } From fa19ab322cf4ba907b8cecfb6028b869f5b48108 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 19 Nov 2018 21:43:12 +0000 Subject: [PATCH 18/20] Updated the emby api since we no longer need the extra parameters to send to emby to log in a local user #2546 --- src/Ombi.Api.Emby/EmbyApi.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Ombi.Api.Emby/EmbyApi.cs b/src/Ombi.Api.Emby/EmbyApi.cs index fa8414ac9..43a2badb6 100644 --- a/src/Ombi.Api.Emby/EmbyApi.cs +++ b/src/Ombi.Api.Emby/EmbyApi.cs @@ -53,8 +53,6 @@ public async Task LogIn(string username, string password, string apiKe { username, pw = password, - password = password.GetSha1Hash().ToLower(), - passwordMd5 = password.CalcuateMd5Hash() }; request.AddJsonBody(body); From d545dc5823cfccc87a04989e9c2c7342957d8673 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 19 Nov 2018 22:01:48 +0000 Subject: [PATCH 19/20] Made the subscribe/unsubscribe button more obvious on the UI #2309 --- .../app/search/moviesearch.component.html | 128 ++++++++++-------- .../app/search/moviesearch.component.ts | 2 +- 2 files changed, 76 insertions(+), 54 deletions(-) diff --git a/src/Ombi/ClientApp/app/search/moviesearch.component.html b/src/Ombi/ClientApp/app/search/moviesearch.component.html index 05dbf15ad..daf77a079 100644 --- a/src/Ombi/ClientApp/app/search/moviesearch.component.html +++ b/src/Ombi/ClientApp/app/search/moviesearch.component.html @@ -2,7 +2,8 @@
    - +

    {{result.title}} ({{result.releaseDate | amLocal | amDateFormat: 'YYYY'}})

    - - {{ 'Search.TheatricalRelease' | translate: {date: result.releaseDate | amLocal | amDateFormat: 'LL'} }} - {{ 'Search.DigitalDate' | translate: {date: result.digitalReleaseDate | amLocal | amDateFormat: 'LL'} }} - - - - - {{result.quality}}p - - - - - - - - - -
    + + {{ + 'Search.TheatricalRelease' | translate: {date: result.releaseDate | amLocal | + amDateFormat: 'LL'} }} + {{ 'Search.DigitalDate' | translate: {date: result.digitalReleaseDate | + amLocal | amDateFormat: 'LL'} }} + + + + + {{result.quality}}p + + + + + + + + + +

    {{result.overview}}

    -
    -
    - - - -
    -
    - +
    -
    - - - - - - -
    - - -
    +
    + + + + + + +
    + + + +
    -
    -
    +
    +
    @@ -117,4 +139,4 @@

    {{result.title}} ({{result.releaseDate | amLocal | amDateFormat: 'YYYY'}}) + [issueCategory]="issueCategorySelected" [id]="issueRequestId" [providerId]="issueProviderId"> \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/search/moviesearch.component.ts b/src/Ombi/ClientApp/app/search/moviesearch.component.ts index f4d19565a..600fc19eb 100644 --- a/src/Ombi/ClientApp/app/search/moviesearch.component.ts +++ b/src/Ombi/ClientApp/app/search/moviesearch.component.ts @@ -172,7 +172,7 @@ export class MovieSearchComponent implements OnInit { r.subscribed = true; this.requestService.subscribeToMovie(r.requestId) .subscribe(x => { - this.notificationService.success("Subscribed To Movie!"); + this.notificationService.success(`Subscribed To Movie ${r.title}!`); }); } From 05a8846104a821375f1b402e75b491c92b2b06dd Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 23 Nov 2018 19:53:39 +0000 Subject: [PATCH 20/20] !changelog --- CHANGELOG.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9fdea5a0..5e60b7be3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,43 @@ ## (unreleased) +### **New Features** + +- Updated the emby api since we no longer need the extra parameters to send to emby to log in a local user #2546. [Jamie] + +- Added the ability to get the ombi user via a Plex Token #2591. [Jamie] + +### **Fixes** + +- Made the subscribe/unsubscribe button more obvious on the UI #2309. [Jamie] + +- Fixed #2603. [Jamie] + +- Fixed the issue with the user overrides #2646. [Jamie] + +- Fixed the issue where we could sometimes allow the request of a whole series when the user shouldn't be able to. [Jamie] + +- Fixed the issue where we were marking episodes as available with the Emby connection when they have not yet aired #2417 #2623. [TidusJar] + +- Fixed the issue where we were marking the whole season as wanted in Sonarr rather than the individual episode #2629. [TidusJar] + +- Fixed #2623. [Jamie] + +- Fixed #2633. [TidusJar] + +- Fixed #2639. [Jamie] + +- Show the TV show as available when we have all the episodes but future episodes have not aired. #2585. [Jamie] + + +## v3.0.3945 (2018-10-25) + +### **New Features** + +- Update Readme for Lidarr. [Qstick] + +- Update CHANGELOG.md. [Jamie] + ### **Fixes** - New translations en.json (French) [Jamie]