Merge pull request #4311 from Ombi-app/feature/PlexGuids

Feature/plex guids
pull/4317/head v4.0.1487
Jamie 3 years ago committed by GitHub
commit cb368e959a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,3 +1,5 @@
using System.Collections.Generic;
namespace Ombi.Api.Plex.Models namespace Ombi.Api.Plex.Models
{ {
public class Metadata public class Metadata
@ -44,7 +46,7 @@ namespace Ombi.Api.Plex.Models
public string grandparentTheme { get; set; } public string grandparentTheme { get; set; }
public string chapterSource { get; set; } public string chapterSource { get; set; }
public Medium[] Media { get; set; } public Medium[] Media { get; set; }
public PlexGuids[] Guid { get; set; } public List<PlexGuids> Guid { get; set; } = new List<PlexGuids>();
// public Director[] Director { get; set; } // public Director[] Director { get; set; }
// public Writer[] Writer { get; set; } // public Writer[] Writer { get; set; }
} }

@ -123,6 +123,7 @@ namespace Ombi.Api.Plex
public async Task<PlexContainer> GetLibrary(string authToken, string plexFullHost, string libraryId) public async Task<PlexContainer> GetLibrary(string authToken, string plexFullHost, string libraryId)
{ {
var request = new Request($"library/sections/{libraryId}/all", plexFullHost, HttpMethod.Get); var request = new Request($"library/sections/{libraryId}/all", plexFullHost, HttpMethod.Get);
request.AddQueryString("includeGuids","1");
await AddHeaders(request, authToken); await AddHeaders(request, authToken);
return await Api.Request<PlexContainer>(request); return await Api.Request<PlexContainer>(request);
} }

@ -7,12 +7,13 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="MockQueryable.Moq" Version="5.0.0-preview.7" /> <PackageReference Include="MockQueryable.Moq" Version="5.0.0-preview.7" />
<PackageReference Include="Moq" Version="4.10.0" /> <PackageReference Include="Moq" Version="4.15.1" />
<PackageReference Include="Moq.AutoMock" Version="0.4.0" />
<PackageReference Include="Nunit" Version="3.11.0" /> <PackageReference Include="Nunit" Version="3.11.0" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" /> <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" />
<PackageReference Include="NUnit.ConsoleRunner" Version="3.9.0" /> <PackageReference Include="NUnit.ConsoleRunner" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<packagereference Include="Microsoft.NET.Test.Sdk" Version="16.8.0"></packagereference> <packagereference Include="Microsoft.NET.Test.Sdk" Version="16.11.0"></packagereference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

@ -0,0 +1,144 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Moq;
using Moq.AutoMock;
using NUnit.Framework;
using Ombi.Api.Plex;
using Ombi.Api.Plex.Models;
using Ombi.Core.Settings.Models.External;
using Ombi.Schedule.Jobs.Plex;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Schedule.Tests
{
[TestFixture]
public class PlexContentSyncTests
{
private AutoMocker _mocker;
private PlexContentSync _subject;
[SetUp]
public void Setup()
{
_mocker = new AutoMocker();
_subject = _mocker.CreateInstance<PlexContentSync>();
}
[Test]
public async Task DoesNotSyncExistingMovie()
{
var content = new Mediacontainer
{
Metadata = new[]
{
new Metadata
{
title = "test1",
year = 2021,
type = "movie"
},
}
};
var contentToAdd = new HashSet<PlexServerContent>();
var contentProcessed = new Dictionary<int, int>();
_mocker.Setup<IPlexContentRepository>(x =>
x.GetFirstContentByCustom(It.IsAny<Expression<Func<PlexServerContent, bool>>>()))
.Returns(Task.FromResult(new PlexServerContent()));
await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed);
Assert.That(contentToAdd, Is.Empty);
}
[Test]
public async Task SyncsMovieWithGuidFromInitalMetadata()
{
var content = new Mediacontainer
{
Metadata = new[]
{
new Metadata
{
title = "test1",
year = 2021,
type = "movie",
Guid = new List<PlexGuids>
{
new PlexGuids
{
Id = "imdb://tt0322259"
}
},
ratingKey = 1
},
}
};
var contentToAdd = new HashSet<PlexServerContent>();
var contentProcessed = new Dictionary<int, int>();
await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed);
var first = contentToAdd.First();
Assert.That(first.ImdbId, Is.EqualTo("tt0322259"));
_mocker.Verify<IPlexApi>(x => x.GetMetadata(It.IsAny<string>(), It.IsAny<string>(),It.IsAny<int>()), Times.Never);
}
[Test]
public async Task SyncsMovieWithGuidFromCallToApi()
{
var content = new Mediacontainer
{
Metadata = new[]
{
new Metadata
{
ratingKey = 11,
title = "test1",
year = 2021,
type = "movie",
},
}
};
var contentToAdd = new HashSet<PlexServerContent>();
var contentProcessed = new Dictionary<int, int>();
_mocker.Setup<IPlexApi>(x => x.GetMetadata(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()))
.Returns(Task.FromResult(new PlexMetadata
{
MediaContainer = new Mediacontainer
{
Metadata = new[]
{
new Metadata
{
ratingKey = 11,
title = "test1",
year = 2021,
type = "movie",
Guid = new List<PlexGuids>
{
new PlexGuids
{
Id = "imdb://tt0322259"
}
},
}
}
}
}));
await _subject.MovieLoop(new PlexServers { Ip = "http://test.com/", Port = 80}, content, contentToAdd, contentProcessed);
var first = contentToAdd.First();
Assert.That(first.ImdbId, Is.EqualTo("tt0322259"));
_mocker.Verify<IPlexApi>(x => x.GetMetadata(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.Once);
}
}
}

@ -262,91 +262,122 @@ namespace Ombi.Schedule.Jobs.Plex
} }
if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.InvariantCultureIgnoreCase)) if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.InvariantCultureIgnoreCase))
{ {
Logger.LogDebug("Processing Movies"); await MovieLoop(servers, content, contentToAdd, contentProcessed);
foreach (var movie in content?.Metadata ?? new Metadata[] { }) }
if (contentToAdd.Count > 500)
{
await Repo.AddRange(contentToAdd);
foreach (var c in contentToAdd)
{ {
// Let's check if we have this movie contentProcessed.Add(c.Id, c.Key);
}
contentToAdd.Clear();
}
}
try if (contentToAdd.Any())
{ {
var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title await Repo.AddRange(contentToAdd);
&& x.ReleaseYear == movie.year.ToString() foreach (var c in contentToAdd)
&& x.Type == PlexMediaTypeEntity.Movie); {
// The rating key keeps changing contentProcessed.Add(c.Id, c.Key);
//var existing = await Repo.GetByKey(movie.ratingKey); }
if (existing != null) }
{
Logger.LogDebug("We already have movie {0}", movie.title);
continue;
}
var hasSameKey = await Repo.GetByKey(movie.ratingKey); retVal.Content = contentProcessed.Values;
if (hasSameKey != null) retVal.Episodes = episodesProcessed;
{ return retVal;
await Repo.Delete(hasSameKey); }
}
Logger.LogDebug("Adding movie {0}", movie.title); public async Task MovieLoop(PlexServers servers, Mediacontainer content, HashSet<PlexServerContent> contentToAdd,
var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, Dictionary<int, int> contentProcessed)
movie.ratingKey); {
Logger.LogDebug("Processing Movies");
foreach (var movie in content?.Metadata ?? new Metadata[] { })
{
// Let's check if we have this movie
var meta = metaData.MediaContainer.Metadata.FirstOrDefault(); try
var guids = new List<string> {
{ var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title
meta.guid && x.ReleaseYear == movie.year.ToString()
}; && x.Type == PlexMediaTypeEntity.Movie);
if (meta.Guid != null) // The rating key keeps changing
{ //var existing = await Repo.GetByKey(movie.ratingKey);
foreach (var g in meta.Guid) if (existing != null)
{ {
guids.Add(g.Id); Logger.LogDebug("We already have movie {0}", movie.title);
} continue;
} }
var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray()); var hasSameKey = await Repo.GetByKey(movie.ratingKey);
if (hasSameKey != null)
{
await Repo.Delete(hasSameKey);
}
var item = new PlexServerContent Logger.LogDebug("Adding movie {0}", movie.title);
{ var guids = new List<string>();
AddedAt = DateTime.Now, if (!movie.Guid.Any())
Key = movie.ratingKey, {
ReleaseYear = movie.year.ToString(), var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri,
Type = PlexMediaTypeEntity.Movie, movie.ratingKey);
Title = movie.title,
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), var meta = metaData.MediaContainer.Metadata.FirstOrDefault();
Seasons = new List<PlexSeasonsContent>(), guids.Add(meta.guid);
Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty if (meta.Guid != null)
}; {
if (providerIds.ImdbId.HasValue()) foreach (var g in meta.Guid)
{
item.ImdbId = providerIds.ImdbId;
}
if (providerIds.TheMovieDb.HasValue())
{
item.TheMovieDbId = providerIds.TheMovieDb;
}
if (providerIds.TheTvDb.HasValue())
{ {
item.TvDbId = providerIds.TheTvDb; guids.Add(g.Id);
} }
contentToAdd.Add(item);
} }
catch (Exception e) }
else
{
// Currently a Plex Pass feature only
foreach (var g in movie.Guid)
{ {
Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new Movie {0}", guids.Add(g.Id);
movie.title);
} }
}
if (contentToAdd.Count > 500) var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray());
{
await Repo.AddRange(contentToAdd); var item = new PlexServerContent
foreach (var c in contentToAdd) {
{ AddedAt = DateTime.Now,
contentProcessed.Add(c.Id, c.Key); Key = movie.ratingKey,
} ReleaseYear = movie.year.ToString(),
contentToAdd.Clear(); Type = PlexMediaTypeEntity.Movie,
} Title = movie.title,
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey),
Seasons = new List<PlexSeasonsContent>(),
Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty
};
if (providerIds.ImdbId.HasValue())
{
item.ImdbId = providerIds.ImdbId;
} }
if (providerIds.TheMovieDb.HasValue())
{
item.TheMovieDbId = providerIds.TheMovieDb;
}
if (providerIds.TheTvDb.HasValue())
{
item.TvDbId = providerIds.TheTvDb;
}
contentToAdd.Add(item);
} }
catch (Exception e)
{
Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new Movie {0}",
movie.title);
}
if (contentToAdd.Count > 500) if (contentToAdd.Count > 500)
{ {
await Repo.AddRange(contentToAdd); await Repo.AddRange(contentToAdd);
@ -354,22 +385,10 @@ namespace Ombi.Schedule.Jobs.Plex
{ {
contentProcessed.Add(c.Id, c.Key); contentProcessed.Add(c.Id, c.Key);
} }
contentToAdd.Clear();
}
}
if (contentToAdd.Any()) contentToAdd.Clear();
{
await Repo.AddRange(contentToAdd);
foreach (var c in contentToAdd)
{
contentProcessed.Add(c.Id, c.Key);
} }
} }
retVal.Content = contentProcessed.Values;
retVal.Episodes = episodesProcessed;
return retVal;
} }
private async Task ProcessTvShow(PlexServers servers, Metadata show, HashSet<PlexServerContent> contentToAdd, Dictionary<int, int> contentProcessed) private async Task ProcessTvShow(PlexServers servers, Metadata show, HashSet<PlexServerContent> contentToAdd, Dictionary<int, int> contentProcessed)

Loading…
Cancel
Save