mirror of
https://github.com/Radarr/Radarr.git
synced 2024-10-05 15:47:20 +02:00
New: Support Plex API Path Scan (Similar to autoscan)
Closes #4640 Closes #5527
This commit is contained in:
parent
2fc7cbff89
commit
24206ad0a3
@ -16,6 +16,7 @@ public interface IPlexServerProxy
|
|||||||
List<PlexSection> GetMovieSections(PlexServerSettings settings);
|
List<PlexSection> GetMovieSections(PlexServerSettings settings);
|
||||||
void Update(int sectionId, PlexServerSettings settings);
|
void Update(int sectionId, PlexServerSettings settings);
|
||||||
void UpdateMovie(string metadataId, PlexServerSettings settings);
|
void UpdateMovie(string metadataId, PlexServerSettings settings);
|
||||||
|
void UpdatePath(string path, int sectionId, PlexServerSettings settings);
|
||||||
string Version(PlexServerSettings settings);
|
string Version(PlexServerSettings settings);
|
||||||
List<PlexPreference> Preferences(PlexServerSettings settings);
|
List<PlexPreference> Preferences(PlexServerSettings settings);
|
||||||
string GetMetadataId(int sectionId, string imdbId, string language, PlexServerSettings settings);
|
string GetMetadataId(int sectionId, string imdbId, string language, PlexServerSettings settings);
|
||||||
@ -81,6 +82,16 @@ public void UpdateMovie(string metadataId, PlexServerSettings settings)
|
|||||||
CheckForError(response);
|
CheckForError(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdatePath(string path, int sectionId, PlexServerSettings settings)
|
||||||
|
{
|
||||||
|
var resource = $"library/sections/{sectionId}/refresh";
|
||||||
|
var request = BuildRequest(resource, HttpMethod.Get, settings);
|
||||||
|
request.AddQueryParam("path", path);
|
||||||
|
var response = ProcessRequest(request);
|
||||||
|
|
||||||
|
CheckForError(response);
|
||||||
|
}
|
||||||
|
|
||||||
public string Version(PlexServerSettings settings)
|
public string Version(PlexServerSettings settings)
|
||||||
{
|
{
|
||||||
var request = BuildRequest("identity", HttpMethod.Get, settings);
|
var request = BuildRequest("identity", HttpMethod.Get, settings);
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Movies;
|
using NzbDrone.Core.Movies;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
@ -23,6 +25,7 @@ public class PlexServerService : IPlexServerService
|
|||||||
{
|
{
|
||||||
private readonly ICached<Version> _versionCache;
|
private readonly ICached<Version> _versionCache;
|
||||||
private readonly ICached<bool> _partialUpdateCache;
|
private readonly ICached<bool> _partialUpdateCache;
|
||||||
|
private readonly ICached<bool> _pathScanCache;
|
||||||
private readonly IPlexServerProxy _plexServerProxy;
|
private readonly IPlexServerProxy _plexServerProxy;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
@ -30,6 +33,7 @@ public PlexServerService(ICacheManager cacheManager, IPlexServerProxy plexServer
|
|||||||
{
|
{
|
||||||
_versionCache = cacheManager.GetCache<Version>(GetType(), "versionCache");
|
_versionCache = cacheManager.GetCache<Version>(GetType(), "versionCache");
|
||||||
_partialUpdateCache = cacheManager.GetCache<bool>(GetType(), "partialUpdateCache");
|
_partialUpdateCache = cacheManager.GetCache<bool>(GetType(), "partialUpdateCache");
|
||||||
|
_pathScanCache = cacheManager.GetCache<bool>(GetType(), "pathScanCache");
|
||||||
_plexServerProxy = plexServerProxy;
|
_plexServerProxy = plexServerProxy;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
@ -51,7 +55,26 @@ public void UpdateLibrary(IEnumerable<Movie> multipleMovies, PlexServerSettings
|
|||||||
|
|
||||||
var sections = GetSections(settings);
|
var sections = GetSections(settings);
|
||||||
var partialUpdates = _partialUpdateCache.Get(settings.Host, () => PartialUpdatesAllowed(settings, version), TimeSpan.FromHours(2));
|
var partialUpdates = _partialUpdateCache.Get(settings.Host, () => PartialUpdatesAllowed(settings, version), TimeSpan.FromHours(2));
|
||||||
|
var pathScanCache = _pathScanCache.Get(settings.Host, () => PathUpdatesAllowed(settings, version), TimeSpan.FromHours(2));
|
||||||
|
|
||||||
|
var pathUpdated = true;
|
||||||
|
|
||||||
|
if (pathScanCache)
|
||||||
|
{
|
||||||
|
foreach (var movie in multipleMovies)
|
||||||
|
{
|
||||||
|
pathUpdated &= UpdatePath(movie, sections, settings);
|
||||||
|
|
||||||
|
if (!pathUpdated)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we couldn't path update then try partial and full update
|
||||||
|
if (!pathUpdated)
|
||||||
|
{
|
||||||
if (partialUpdates)
|
if (partialUpdates)
|
||||||
{
|
{
|
||||||
var partiallyUpdated = true;
|
var partiallyUpdated = true;
|
||||||
@ -77,6 +100,7 @@ public void UpdateLibrary(IEnumerable<Movie> multipleMovies, PlexServerSettings
|
|||||||
{
|
{
|
||||||
sections.ForEach(s => UpdateSection(s.Id, settings));
|
sections.ForEach(s => UpdateSection(s.Id, settings));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_logger.Debug("Finished sending Update Request to Plex Server (took {0} ms)", watch.ElapsedMilliseconds);
|
_logger.Debug("Finished sending Update Request to Plex Server (took {0} ms)", watch.ElapsedMilliseconds);
|
||||||
}
|
}
|
||||||
@ -119,6 +143,31 @@ private bool PartialUpdatesAllowed(PlexServerSettings settings, Version version)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool PathUpdatesAllowed(PlexServerSettings settings, Version version)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (version >= new Version(1, 20, 0, 3125))
|
||||||
|
{
|
||||||
|
var preferences = GetPreferences(settings);
|
||||||
|
var partialScanPreference = preferences.SingleOrDefault(p => p.Id.Equals("FSEventLibraryPartialScanEnabled"));
|
||||||
|
|
||||||
|
if (partialScanPreference == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ToBoolean(partialScanPreference.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Unable to check if path updates are allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void ValidateVersion(Version version)
|
private void ValidateVersion(Version version)
|
||||||
{
|
{
|
||||||
if (version >= new Version(1, 3, 0) && version < new Version(1, 3, 1))
|
if (version >= new Version(1, 3, 0) && version < new Version(1, 3, 1))
|
||||||
@ -171,6 +220,34 @@ private bool UpdatePartialSection(Movie movie, List<PlexSection> sections, PlexS
|
|||||||
return partiallyUpdated;
|
return partiallyUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UpdatePath(Movie movie, List<PlexSection> sections, PlexServerSettings settings)
|
||||||
|
{
|
||||||
|
var pathUpdated = false;
|
||||||
|
|
||||||
|
var movieLocation = new OsPath(movie.Path);
|
||||||
|
var mappedPath = movieLocation;
|
||||||
|
|
||||||
|
if (settings.MapTo.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
mappedPath = new OsPath(settings.MapTo) + (movieLocation - new OsPath(settings.MapFrom));
|
||||||
|
|
||||||
|
_logger.Trace("Mapping Path from {0} to {1} for partial scan", movieLocation, mappedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchingSection = sections.FirstOrDefault(section => section.Locations.Any(location => location.Path.IsParentPath(mappedPath.FullPath)));
|
||||||
|
|
||||||
|
if (matchingSection != null)
|
||||||
|
{
|
||||||
|
_logger.Debug("Updating Path on Plex host: {0}, Section: {1}, Path: {2}", settings.Host, matchingSection.Id, mappedPath);
|
||||||
|
|
||||||
|
_plexServerProxy.UpdatePath(mappedPath.FullPath, matchingSection.Id, settings);
|
||||||
|
|
||||||
|
pathUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pathUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
private string GetMetadataId(int sectionId, Movie movie, string language, PlexServerSettings settings)
|
private string GetMetadataId(int sectionId, Movie movie, string language, PlexServerSettings settings)
|
||||||
{
|
{
|
||||||
_logger.Debug("Getting metadata from Plex host: {0} for movie: {1}", settings.Host, movie);
|
_logger.Debug("Getting metadata from Plex host: {0} for movie: {1}", settings.Host, movie);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
@ -11,6 +12,8 @@ public PlexServerSettingsValidator()
|
|||||||
{
|
{
|
||||||
RuleFor(c => c.Host).ValidHost();
|
RuleFor(c => c.Host).ValidHost();
|
||||||
RuleFor(c => c.Port).InclusiveBetween(1, 65535);
|
RuleFor(c => c.Port).InclusiveBetween(1, 65535);
|
||||||
|
RuleFor(c => c.MapFrom).NotEmpty().Unless(c => c.MapTo.IsNullOrWhiteSpace());
|
||||||
|
RuleFor(c => c.MapTo).NotEmpty().Unless(c => c.MapFrom.IsNullOrWhiteSpace());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +46,12 @@ public PlexServerSettings()
|
|||||||
[FieldDefinition(5, Label = "Update Library", Type = FieldType.Checkbox)]
|
[FieldDefinition(5, Label = "Update Library", Type = FieldType.Checkbox)]
|
||||||
public bool UpdateLibrary { get; set; }
|
public bool UpdateLibrary { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(6, Label = "Map Paths From", Type = FieldType.Textbox, Advanced = true, HelpText = "Radarr Path, Used to modify movie paths when Plex sees library path location differently from Radarr")]
|
||||||
|
public string MapFrom { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(7, Label = "Map Paths To", Type = FieldType.Textbox, Advanced = true, HelpText = "Plex Path, Used to modify movie paths when Plex sees library path location differently from Radarr")]
|
||||||
|
public string MapTo { get; set; }
|
||||||
|
|
||||||
public bool IsValid => !string.IsNullOrWhiteSpace(Host);
|
public bool IsValid => !string.IsNullOrWhiteSpace(Host);
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
Loading…
Reference in New Issue
Block a user