feat: almost got it all working now

This commit is contained in:
tidusjar 2022-02-12 22:40:24 +00:00
commit 5169ffd6ce
15 changed files with 227 additions and 28 deletions

View file

@ -44,7 +44,10 @@ namespace Ombi.Api.Radarr.Models
public int id { get; set; } public int id { get; set; }
} }
public class MovieQuality
{
public V3.Quality quality { get; set; }
}
public class Moviefile public class Moviefile
{ {
public int movieId { get; set; } public int movieId { get; set; }
@ -54,7 +57,7 @@ namespace Ombi.Api.Radarr.Models
public DateTime dateAdded { get; set; } public DateTime dateAdded { get; set; }
public string sceneName { get; set; } public string sceneName { get; set; }
public int indexerFlags { get; set; } public int indexerFlags { get; set; }
public V3.Quality quality { get; set; } public MovieQuality quality { get; set; }
public Mediainfo mediaInfo { get; set; } public Mediainfo mediaInfo { get; set; }
public string originalFilePath { get; set; } public string originalFilePath { get; set; }
public bool qualityCutoffNotMet { get; set; } public bool qualityCutoffNotMet { get; set; }

View file

@ -35,7 +35,8 @@ namespace Ombi.Core.Tests.Rule.Search
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings()); SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings());
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
{ {
TheMovieDbId = "123" TheMovieDbId = "123",
Quality = "1"
}); });
var search = new SearchMovieViewModel() var search = new SearchMovieViewModel()
{ {
@ -47,6 +48,47 @@ namespace Ombi.Core.Tests.Rule.Search
Assert.True(search.Available); Assert.True(search.Available);
} }
[Test]
public async Task Movie_ShouldBe_Available_WhenFoundInEmby_4K()
{
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings());
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
{
TheMovieDbId = "123",
Has4K = true
});
var search = new SearchMovieViewModel()
{
TheMovieDbId = "123",
};
var result = await Rule.Execute(search);
Assert.True(result.Success);
Assert.True(search.Available4K);
Assert.False(search.Available);
}
[Test]
public async Task Movie_ShouldBe_Available_WhenFoundInEmby_Both()
{
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings());
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
{
TheMovieDbId = "123",
Has4K = true,
Quality = "1"
});
var search = new SearchMovieViewModel()
{
TheMovieDbId = "123",
};
var result = await Rule.Execute(search);
Assert.True(result.Success);
Assert.True(search.Available4K);
Assert.True(search.Available);
}
[Test] [Test]
public async Task Movie_ShouldBe_NotAvailable_WhenNotFoundInEmby() public async Task Movie_ShouldBe_NotAvailable_WhenNotFoundInEmby()
{ {

View file

@ -35,7 +35,8 @@ namespace Ombi.Core.Tests.Rule.Search
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings()); SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings());
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
{ {
ProviderId = "123" TheMovieDbId = "123",
Quality = "1080"
}); });
var search = new SearchMovieViewModel() var search = new SearchMovieViewModel()
{ {
@ -47,6 +48,47 @@ namespace Ombi.Core.Tests.Rule.Search
Assert.True(search.Available); Assert.True(search.Available);
} }
[Test]
public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_4K()
{
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings());
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
{
TheMovieDbId = "123",
Has4K = true
});
var search = new SearchMovieViewModel()
{
TheMovieDbId = "123",
};
var result = await Rule.Execute(search);
Assert.True(result.Success);
Assert.False(search.Available);
Assert.True(search.Available4K);
}
[Test]
public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_Both()
{
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings());
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
{
TheMovieDbId = "123",
Has4K = true,
Quality = "1"
});
var search = new SearchMovieViewModel()
{
TheMovieDbId = "123",
};
var result = await Rule.Execute(search);
Assert.True(result.Success);
Assert.True(search.Available);
Assert.True(search.Available4K);
}
[Test] [Test]
public async Task Movie_Uses_Default_Url_When() public async Task Movie_Uses_Default_Url_When()
{ {
@ -66,7 +108,7 @@ namespace Ombi.Core.Tests.Rule.Search
}); });
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
{ {
ProviderId = "123", TheMovieDbId = "123",
JellyfinId = 1.ToString() JellyfinId = 1.ToString()
}); });
var search = new SearchMovieViewModel() var search = new SearchMovieViewModel()

View file

@ -28,25 +28,67 @@ namespace Ombi.Core.Tests.Rule.Search
{ {
var list = new List<RadarrCache>(){new RadarrCache var list = new List<RadarrCache>(){new RadarrCache
{ {
TheMovieDbId = 123 TheMovieDbId = 123,
HasRegular = true
}}.AsQueryable(); }}.AsQueryable();
ContextMock.Setup(x => x.GetAll()).Returns(list); ContextMock.Setup(x => x.GetAll()).Returns(list);
var request = new SearchMovieViewModel { Id = 123 }; var request = new SearchMovieViewModel { Id = 123 };
var result =await Rule.Execute(request); var result = await Rule.Execute(request);
Assert.True(result.Success); Assert.True(result.Success);
Assert.True(request.Approved); Assert.True(request.Approved);
} }
[Test]
public async Task Should_ReturnAvailabl_WhenMovieIsInRadarr_4K()
{
var list = new List<RadarrCache>(){new RadarrCache
{
TheMovieDbId = 123,
Has4K = true,
HasFile = true
}}.AsQueryable();
ContextMock.Setup(x => x.GetAll()).Returns(list);
var request = new SearchMovieViewModel { Id = 123 };
var result = await Rule.Execute(request);
Assert.True(result.Success);
Assert.False(request.Available);
Assert.True(request.Available4K);
}
[Test]
public async Task Should_ReturnAvailable_WhenMovieIsInRadarr_Both()
{
var list = new List<RadarrCache>(){new RadarrCache
{
TheMovieDbId = 123,
Has4K = true,
HasRegular = true,
HasFile = true
}}.AsQueryable();
ContextMock.Setup(x => x.GetAll()).Returns(list);
var request = new SearchMovieViewModel { Id = 123 };
var result = await Rule.Execute(request);
Assert.True(result.Success);
Assert.True(request.Available);
Assert.True(request.Available4K);
}
[Test] [Test]
public async Task Should_ReturnNotApproved_WhenMovieIsNotInRadarr() public async Task Should_ReturnNotApproved_WhenMovieIsNotInRadarr()
{ {
var list = DbHelper.GetQueryableMockDbSet(new RadarrCache var list = DbHelper.GetQueryableMockDbSet(new RadarrCache
{ {
TheMovieDbId = 000012 TheMovieDbId = 000012,
}); });
ContextMock.Setup(x => x.GetAll()).Returns(list); ContextMock.Setup(x => x.GetAll()).Returns(list);

View file

@ -63,11 +63,29 @@ namespace Ombi.Core.Rule.Rules.Search
} }
} }
} }
if (item != null) if (item != null)
{ {
obj.Available = true; if (obj is SearchMovieViewModel movie)
obj.EmbyUrl = item.Url; {
if (item.Has4K)
{
movie.Available4K = true;
obj.EmbyUrl = item.Url;
}
if (item.Quality.HasValue())
{
obj.Available = true;
obj.EmbyUrl = item.Url;
obj.Quality = item.Quality;
}
}
else
{
obj.Available = true;
obj.EmbyUrl = item.Url;
}
if (obj.Type == RequestType.TvShow) if (obj.Type == RequestType.TvShow)
{ {

View file

@ -26,9 +26,8 @@ namespace Ombi.Core.Rule.Rules.Search
public async Task<RuleResult> Execute(SearchViewModel obj) public async Task<RuleResult> Execute(SearchViewModel obj)
{ {
if (obj.Type == RequestType.Movie) if (obj is SearchMovieViewModel movie)
{ {
var movie = (SearchMovieViewModel)obj;
var movieRequests = await Movie.GetRequestAsync(obj.Id); var movieRequests = await Movie.GetRequestAsync(obj.Id);
if (movieRequests != null) // Do we already have a request for this? if (movieRequests != null) // Do we already have a request for this?
{ {

View file

@ -80,8 +80,26 @@ namespace Ombi.Core.Rule.Rules.Search
obj.TheMovieDbId = obj.Id.ToString(); obj.TheMovieDbId = obj.Id.ToString();
useTheMovieDb = true; useTheMovieDb = true;
} }
obj.Available = true; if (obj is SearchMovieViewModel movie)
obj.JellyfinUrl = item.Url; {
if (item.Has4K)
{
movie.Available4K = true;
obj.JellyfinUrl = item.Url;
}
if (item.Quality.HasValue())
{
obj.Available = true;
obj.EmbyUrl = item.Url;
obj.Quality = item.Quality;
}
}
else
{
obj.Available = true;
obj.JellyfinUrl = item.Url;
}
if (obj.Type == RequestType.TvShow) if (obj.Type == RequestType.TvShow)
{ {

View file

@ -89,7 +89,25 @@ namespace Ombi.Core.Rule.Rules.Search
obj.TheMovieDbId = obj.Id.ToString(); obj.TheMovieDbId = obj.Id.ToString();
useTheMovieDb = true; useTheMovieDb = true;
} }
obj.Available = true;
if (obj is SearchMovieViewModel movie)
{
if (item.Has4K)
{
movie.Available4K = true;
}
if (item.Quality.HasValue())
{
obj.Available = true;
obj.Quality = item.Quality;
}
}
else
{
obj.Available = true;
}
if (item.Url.StartsWith("http")) if (item.Url.StartsWith("http"))
{ {
obj.PlexUrl = item.Url; obj.PlexUrl = item.Url;
@ -99,11 +117,9 @@ namespace Ombi.Core.Rule.Rules.Search
// legacy content // legacy content
obj.PlexUrl = PlexHelper.BuildPlexMediaUrl(item.Url, host); obj.PlexUrl = PlexHelper.BuildPlexMediaUrl(item.Url, host);
} }
obj.Quality = item.Quality;
if (obj.Type == RequestType.TvShow) if (obj is SearchTvShowViewModel search)
{ {
var search = (SearchTvShowViewModel)obj;
// Let's go through the episodes now // Let's go through the episodes now
if (search.SeasonRequests.Any()) if (search.SeasonRequests.Any())
{ {

View file

@ -18,16 +18,23 @@ namespace Ombi.Core.Rule.Rules.Search
public Task<RuleResult> Execute(SearchViewModel obj) public Task<RuleResult> Execute(SearchViewModel obj)
{ {
if (obj.Type == RequestType.Movie) if (obj is SearchMovieViewModel movie)
{ {
// Check if it's in Radarr // Check if it's in Radarr
var result = _db.GetAll().FirstOrDefault(x => x.TheMovieDbId == obj.Id); var result = _db.GetAll().FirstOrDefault(x => x.TheMovieDbId == obj.Id);
if (result != null) if (result != null)
{ {
obj.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something? movie.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something?
if (result.HasFile) if (result.HasFile)
{ {
obj.Available = true; if (result.Has4K)
{
movie.Available4K = true;
}
if (result.HasRegular)
{
movie.Available = true;
}
} }
} }
} }

View file

@ -209,6 +209,7 @@ namespace Ombi.Schedule.Jobs.Plex
if (has4kRequest && item.Has4K) if (has4kRequest && item.Has4K)
{ {
movie.Available4K = true; movie.Available4K = true;
movie.Approved4K = true;
movie.MarkedAsAvailable4K = DateTime.Now; movie.MarkedAsAvailable4K = DateTime.Now;
} }
@ -216,6 +217,7 @@ namespace Ombi.Schedule.Jobs.Plex
if (item.Quality.HasValue()) if (item.Quality.HasValue())
{ {
movie.Available = true; movie.Available = true;
movie.Approved = true;
movie.MarkedAsAvailable = DateTime.Now; movie.MarkedAsAvailable = DateTime.Now;
} }

View file

@ -77,7 +77,7 @@ namespace Ombi.Schedule.Jobs.Radarr
{ {
if (m.tmdbId > 0) if (m.tmdbId > 0)
{ {
var is4k = m.movieFile?.quality?.resolution >= 2160; var is4k = m.movieFile?.quality?.quality?.resolution >= 2160;
// Do we have a cached movie for this already? // Do we have a cached movie for this already?
var existing = await existingMovies.FirstOrDefaultAsync(x => x.TheMovieDbId == m.tmdbId); var existing = await existingMovies.FirstOrDefaultAsync(x => x.TheMovieDbId == m.tmdbId);

View file

@ -79,12 +79,14 @@
<!-- 4k Status --> <!-- 4k Status -->
<span *permission="roleName4k"> <span *permission="roleName4k">
<button mat-raised-button class="btn-green btn-spacing" id="availableBtn" *ngIf="movie.available4K && !movie.plexUrl && !movie.embyUrl && !movie.jellyfinUrl"> {{ <button mat-raised-button class="btn-green btn-spacing" id="availableBtn4k" *ngIf="movie.available4K"> {{
'Common.Available4K' | translate }}</button> 'Common.Available4K' | translate }}
</button>
<span *ngIf="!movie.available4K"> <span *ngIf="!movie.available4K">
<span *ngIf="movie.has4KRequest || movie.approved4K; then requestedBtn4K else notRequestedBtn4K"></span> <span *ngIf="movie.has4KRequest || movie.approved4K; then requestedBtn4K else notRequestedBtn4K"></span>
<ng-template #requestedBtn4K> <ng-template #requestedBtn4K>
<button id="requestedBtn4K" mat-raised-button *ngIf="!hasRequest || hasRequest && movieRequest && !movieRequest.denied4K" class="btn-spacing" color="warn" [disabled]> <button id="requestedBtn4K" mat-raised-button *ngIf="movieRequest && !movieRequest.denied4K" class="btn-spacing" color="warn" [disabled]>
<i class="fas fa-check"></i> <i class="fas fa-check"></i>
{{ 'Common.Requested4K' | translate }} {{ 'Common.Requested4K' | translate }}
</button> </button>

View file

@ -64,6 +64,11 @@
<div>{{movie.quality | quality}}</div> <div>{{movie.quality | quality}}</div>
</div> </div>
<div *ngIf="movie.available4K">
<span class="label">{{'MediaDetails.Quality' | translate }}&nbsp;</span>
<span >{{"4K" | quality}}</span>
</div>
<div *ngIf="advancedOptions && request && request.rootPathOverrideTitle"> <div *ngIf="advancedOptions && request && request.rootPathOverrideTitle">
<span class="label">{{'MediaDetails.RootFolderOverride' | translate }}</span> <span class="label">{{'MediaDetails.RootFolderOverride' | translate }}</span>
<div>{{request.rootPathOverrideTitle}}</div> <div>{{request.rootPathOverrideTitle}}</div>

View file

@ -6,6 +6,9 @@ export class QualityPipe implements PipeTransform {
if (value.toUpperCase() === "4K" || value.toUpperCase() === "8K") { if (value.toUpperCase() === "4K" || value.toUpperCase() === "8K") {
return value; return value;
} }
if (value[value.length - 1].toUpperCase() === "P") {
return value;
}
return value + "p"; return value + "p";
} }
} }

View file

@ -23,7 +23,7 @@ export class RoleDirective implements OnInit {
} }
private updateView(): void { private updateView(): void {
if (this.auth.hasRole(this.roleName)) { if (this.auth.hasRole(this.roleName) || this.auth.hasRole("admin")) {
if (this.isHidden) { if (this.isHidden) {
this.viewContainer.createEmbeddedView(this.templateRef); this.viewContainer.createEmbeddedView(this.templateRef);
this.isHidden = false; this.isHidden = false;