mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-19 21:03:17 -07:00
Added Tv watchlist import
This commit is contained in:
parent
268e31c019
commit
0329c2b9d9
7 changed files with 185 additions and 20 deletions
|
@ -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)
|
||||
{
|
||||
if (response.ErrorCode == ErrorCode.AlreadyRequested)
|
||||
{
|
||||
// We need a MovieDbId to support this;
|
||||
return;
|
||||
}
|
||||
_movieRequestEngine.SetUser(user);
|
||||
var response = await _movieRequestEngine.RequestMovie(new() { TheMovieDbId = int.Parse(providerIds.TheMovieDb), Source = RequestSource.PlexWatchlist});
|
||||
_logger.LogInformation($"Error adding title from PlexWatchlist for user '{user.UserName}'. Message: '{response.ErrorMessage}'");
|
||||
}
|
||||
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…
Add table
Add a link
Reference in a new issue