Added Tv watchlist import

pull/4576/head
tidusjar 2 years ago
parent 268e31c019
commit 0329c2b9d9

@ -188,7 +188,7 @@ namespace Ombi.Core.Engine
(await tvBuilder
.GetShowInfo(tv.TheMovieDbId, tv.languageCode))
.CreateTvList(tv)
.CreateChild(tv, canRequestOnBehalf ? tv.RequestOnBehalf : user.Id);
.CreateChild(tv, canRequestOnBehalf ? tv.RequestOnBehalf : user.Id, tv.Source);
await tvBuilder.BuildEpisodes(tv);

@ -53,7 +53,7 @@ namespace Ombi.Core.Helpers
return this;
}
public TvShowRequestBuilderV2 CreateChild(TvRequestViewModelV2 model, string userId)
public TvShowRequestBuilderV2 CreateChild(TvRequestViewModelV2 model, string userId, RequestSource source)
{
var animationGenre = TheMovieDbRecord.genres?.Any(s => s.name.Equals("Animation", StringComparison.InvariantCultureIgnoreCase)) ?? false;
var animeKeyword = TheMovieDbRecord.Keywords?.KeywordsValue?.Any(s => s.Name.Equals("Anime", StringComparison.InvariantCultureIgnoreCase)) ?? false;
@ -68,7 +68,8 @@ namespace Ombi.Core.Helpers
Title = TheMovieDbRecord.name,
ReleaseYear = FirstAir,
RequestedByAlias = model.RequestedByAlias,
SeriesType = animationGenre && animeKeyword ? SeriesType.Anime : SeriesType.Standard
SeriesType = animationGenre && animeKeyword ? SeriesType.Anime : SeriesType.Standard,
Source = source
};
return this;

@ -1,5 +1,6 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Ombi.Store.Entities.Requests;
namespace Ombi.Core.Models.Requests
{
@ -7,5 +8,6 @@ namespace Ombi.Core.Models.Requests
{
public int TheMovieDbId { get; set; }
public string languageCode { get; set; } = "en";
public RequestSource Source { get; set; } = RequestSource.Ombi;
}
}

@ -136,6 +136,54 @@ namespace Ombi.Schedule.Tests
_mocker.Verify<IMovieRequestEngine>(x => x.SetUser(It.Is<OmbiUser>(x => x.Id == "abc")), Times.Once);
}
[Test]
public async Task TvRequestFromWatchList_NoGuid()
{
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true });
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(new PlexWatchlistContainer
{
MediaContainer = new PlexWatchlist
{
Metadata = new List<Metadata>
{
new Metadata
{
type = "show",
ratingKey = "abc"
}
}
}
});
_mocker.Setup<IPlexApi, Task<PlexWatchlistMetadataContainer>>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new PlexWatchlistMetadataContainer
{
MediaContainer = new PlexWatchlistMetadata
{
Metadata = new WatchlistMetadata[]
{
new WatchlistMetadata
{
Guid = new List<PlexGuids>
{
new PlexGuids
{
Id = "tmdb://123"
}
}
}
}
}
});
_mocker.Setup<ITvRequestEngine, Task<RequestEngineResult>>(x => x.RequestTvShow(It.IsAny<TvRequestViewModelV2>()))
.ReturnsAsync(new RequestEngineResult { RequestId = 1 });
await _subject.Execute(_context.Object);
_mocker.Verify<ITvRequestEngine>(x => x.RequestTvShow(It.Is<TvRequestViewModelV2>(x => x.TheMovieDbId == 123)), Times.Once);
_mocker.Verify<IPlexApi>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Once);
_mocker.Verify<ITvRequestEngine>(x => x.SetUser(It.Is<OmbiUser>(x => x.Id == "abc")), Times.Once);
}
[Test]
public async Task MovieRequestFromWatchList_AlreadyRequested()
{
@ -183,6 +231,53 @@ namespace Ombi.Schedule.Tests
_mocker.Verify<IMovieRequestEngine>(x => x.SetUser(It.Is<OmbiUser>(x => x.Id == "abc")), Times.Once);
}
[Test]
public async Task TvRequestFromWatchList_AlreadyRequested()
{
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true });
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(new PlexWatchlistContainer
{
MediaContainer = new PlexWatchlist
{
Metadata = new List<Metadata>
{
new Metadata
{
type = "show",
ratingKey = "abc"
}
}
}
});
_mocker.Setup<IPlexApi, Task<PlexWatchlistMetadataContainer>>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new PlexWatchlistMetadataContainer
{
MediaContainer = new PlexWatchlistMetadata
{
Metadata = new WatchlistMetadata[]
{
new WatchlistMetadata
{
Guid = new List<PlexGuids>
{
new PlexGuids
{
Id = "tmdb://123"
}
}
}
}
}
});
_mocker.Setup<ITvRequestEngine, Task<RequestEngineResult>>(x => x.RequestTvShow(It.IsAny<TvRequestViewModelV2>()))
.ReturnsAsync(new RequestEngineResult { ErrorCode = ErrorCode.AlreadyRequested, ErrorMessage = "Requested" });
await _subject.Execute(_context.Object);
_mocker.Verify<ITvRequestEngine>(x => x.RequestTvShow(It.Is<TvRequestViewModelV2>(x => x.TheMovieDbId == 123)), Times.Once);
_mocker.Verify<IPlexApi>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Once);
_mocker.Verify<ITvRequestEngine>(x => x.SetUser(It.Is<OmbiUser>(x => x.Id == "abc")), Times.Once);
}
[Test]
public async Task MovieRequestFromWatchList_NoTmdbGuid()
{
@ -229,5 +324,52 @@ namespace Ombi.Schedule.Tests
_mocker.Verify<IPlexApi>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Once);
_mocker.Verify<IMovieRequestEngine>(x => x.SetUser(It.Is<OmbiUser>(x => x.Id == "abc")), Times.Never);
}
[Test]
public async Task TvRequestFromWatchList_NoTmdbGuid()
{
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true });
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(new PlexWatchlistContainer
{
MediaContainer = new PlexWatchlist
{
Metadata = new List<Metadata>
{
new Metadata
{
type = "movie",
ratingKey = "abc"
}
}
}
});
_mocker.Setup<IPlexApi, Task<PlexWatchlistMetadataContainer>>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new PlexWatchlistMetadataContainer
{
MediaContainer = new PlexWatchlistMetadata
{
Metadata = new WatchlistMetadata[]
{
new WatchlistMetadata
{
Guid = new List<PlexGuids>
{
new PlexGuids
{
Id = "imdb://123"
}
}
}
}
}
});
_mocker.Setup<ITvRequestEngine, Task<RequestEngineResult>>(x => x.RequestTvShow(It.IsAny<TvRequestViewModelV2>()))
.ReturnsAsync(new RequestEngineResult { RequestId = 1 });
await _subject.Execute(_context.Object);
_mocker.Verify<ITvRequestEngine>(x => x.RequestTvShow(It.IsAny<TvRequestViewModelV2>()), Times.Never);
_mocker.Verify<IPlexApi>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Once);
_mocker.Verify<ITvRequestEngine>(x => x.SetUser(It.Is<OmbiUser>(x => x.Id == "abc")), Times.Never);
}
}
}

@ -4,6 +4,7 @@ using Ombi.Api.Plex.Models;
using Ombi.Core.Authentication;
using Ombi.Core.Engine;
using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Models.Requests;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
@ -23,16 +24,18 @@ namespace Ombi.Schedule.Jobs.Plex
private readonly ISettingsService<PlexSettings> _settings;
private readonly OmbiUserManager _ombiUserManager;
private readonly IMovieRequestEngine _movieRequestEngine;
private readonly ITvRequestEngine _tvRequestEngine;
private readonly ILogger _logger;
public PlexWatchlistImport(IPlexApi plexApi, ISettingsService<PlexSettings> settings, OmbiUserManager ombiUserManager,
IMovieRequestEngine movieRequestEngine,
IMovieRequestEngine movieRequestEngine, ITvRequestEngine tvRequestEngine,
ILogger<PlexWatchlistImport> logger)
{
_plexApi = plexApi;
_settings = settings;
_ombiUserManager = ombiUserManager;
_movieRequestEngine = movieRequestEngine;
_tvRequestEngine = tvRequestEngine;
_logger = logger;
}
@ -56,29 +59,48 @@ namespace Ombi.Schedule.Jobs.Plex
var items = watchlist.MediaContainer.Metadata;
foreach (var item in items)
{
var providerIds = await GetProviderIds(user.MediaServerToken, item, context?.CancellationToken ?? CancellationToken.None);
if (!providerIds.TheMovieDb.HasValue())
{
// We need a MovieDbId to support this;
return;
}
switch (item.type)
{
case "show":
await ProcessShow(item);
await ProcessShow(int.Parse(providerIds.TheMovieDb), user, context?.CancellationToken ?? CancellationToken.None);
break;
case "movie":
await ProcessMovie(user.MediaServerToken, item, user, context?.CancellationToken ?? CancellationToken.None);
await ProcessMovie(int.Parse(providerIds.TheMovieDb), user, context?.CancellationToken ?? CancellationToken.None);
break;
}
}
}
}
private async Task ProcessMovie(string authToken, Metadata movie, OmbiUser user, CancellationToken cancellationToken)
private async Task ProcessMovie(int theMovieDbId, OmbiUser user, CancellationToken cancellationToken)
{
var providerIds = await GetProviderIds(authToken, movie, cancellationToken);
if (!providerIds.TheMovieDb.HasValue())
_movieRequestEngine.SetUser(user);
var response = await _movieRequestEngine.RequestMovie(new() { TheMovieDbId = theMovieDbId, Source = RequestSource.PlexWatchlist});
if (response.IsError)
{
// We need a MovieDbId to support this;
return;
if (response.ErrorCode == ErrorCode.AlreadyRequested)
{
return;
}
_logger.LogInformation($"Error adding title from PlexWatchlist for user '{user.UserName}'. Message: '{response.ErrorMessage}'");
}
_movieRequestEngine.SetUser(user);
var response = await _movieRequestEngine.RequestMovie(new() { TheMovieDbId = int.Parse(providerIds.TheMovieDb), Source = RequestSource.PlexWatchlist});
else
{
_logger.LogInformation($"Added title from PlexWatchlist for user '{user.UserName}'. {response.Message}");
}
}
private async Task ProcessShow(int theMovieDbId, OmbiUser user, CancellationToken cancellationToken)
{
_tvRequestEngine.SetUser(user);
var response = await _tvRequestEngine.RequestTvShow(new TvRequestViewModelV2 { RequestAll = true, TheMovieDbId = theMovieDbId, Source = RequestSource.PlexWatchlist });
if (response.IsError)
{
if (response.ErrorCode == ErrorCode.AlreadyRequested)
@ -122,11 +144,6 @@ namespace Ombi.Schedule.Jobs.Plex
return providerIds;
}
private async Task ProcessShow(Metadata metadata)
{
}
public void Dispose() { }
}
}

@ -9,6 +9,7 @@
user: request.requestedUser.userAlias,
date: request.requestedDate | amLocal | amUserLocale | amDateFormat: 'LL' } }}
<span *ngIf="request.denied"> - {{request.deniedReason}}</span>
<span *ngIf="request.source !== RequestSource.Ombi">{{'MediaDetails.RequestSource' | translate }} {{RequestSource[request.source]}}</span>
</mat-panel-description>
</mat-expansion-panel-header>

@ -1,5 +1,5 @@
import { Component, Input } from "@angular/core";
import { IChildRequests, RequestType } from "../../../../../interfaces";
import { IChildRequests, RequestSource, RequestType } from "../../../../../interfaces";
import { DenyDialogComponent } from "../../../shared/deny-dialog/deny-dialog.component";
import { MatDialog } from "@angular/material/dialog";
@ -17,6 +17,8 @@ export class TvRequestsPanelComponent {
@Input() public isAdmin: boolean;
@Input() public manageOwnRequests: boolean;
public RequestSource = RequestSource;
public displayedColumns: string[] = ['number', 'title', 'airDate', 'status'];
constructor(private requestService: RequestService,

Loading…
Cancel
Save