mirror of
https://github.com/Radarr/Radarr.git
synced 2024-10-27 06:02:33 +01:00
Fixed: Speed up initial movie load when opening the UI
This commit is contained in:
parent
f917d0e9bc
commit
0a8dd85856
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
@ -40,15 +41,16 @@ public void should_convert_cover_urls_to_local()
|
|||||||
new MediaCover.MediaCover { CoverType = MediaCoverTypes.Banner }
|
new MediaCover.MediaCover { CoverType = MediaCoverTypes.Banner }
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.FileGetLastWrite(It.IsAny<string>()))
|
var path = Path.Combine(TestContext.CurrentContext.TestDirectory, "Files", "Media", "H264_sample.mp4");
|
||||||
.Returns(new DateTime(1234));
|
var fileInfo = new FileInfo(path);
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.FileExists(It.IsAny<string>()))
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Returns(true);
|
.Setup(c => c.GetFileInfo(It.IsAny<string>()))
|
||||||
|
.Returns(fileInfo);
|
||||||
|
|
||||||
Subject.ConvertToLocalUrls(12, covers);
|
Subject.ConvertToLocalUrls(12, covers);
|
||||||
|
|
||||||
covers.Single().Url.Should().Be("/MediaCover/12/banner.jpg?lastWrite=1234");
|
covers.Single().Url.Should().Be($"/MediaCover/12/banner.jpg?lastWrite={fileInfo.LastWriteTimeUtc.Ticks}");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -59,6 +61,13 @@ public void should_convert_media_urls_to_local_without_time_if_file_doesnt_exist
|
|||||||
new MediaCover.MediaCover { CoverType = MediaCoverTypes.Banner }
|
new MediaCover.MediaCover { CoverType = MediaCoverTypes.Banner }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var path = Path.Combine(TestContext.CurrentContext.TestDirectory, "Files", "Media", "NonExistant.mp4");
|
||||||
|
var fileInfo = new FileInfo(path);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(c => c.GetFileInfo(It.IsAny<string>()))
|
||||||
|
.Returns(fileInfo);
|
||||||
|
|
||||||
Subject.ConvertToLocalUrls(12, covers);
|
Subject.ConvertToLocalUrls(12, covers);
|
||||||
|
|
||||||
covers.Single().Url.Should().Be("/MediaCover/12/banner.jpg");
|
covers.Single().Url.Should().Be("/MediaCover/12/banner.jpg");
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
@ -17,7 +19,8 @@ namespace NzbDrone.Core.MediaCover
|
|||||||
{
|
{
|
||||||
public interface IMapCoversToLocal
|
public interface IMapCoversToLocal
|
||||||
{
|
{
|
||||||
void ConvertToLocalUrls(int movieId, IEnumerable<MediaCover> covers);
|
Dictionary<string, FileInfo> GetCoverFileInfos();
|
||||||
|
void ConvertToLocalUrls(int movieId, IEnumerable<MediaCover> covers, Dictionary<string, FileInfo> fileInfos = null);
|
||||||
string GetCoverPath(int movieId, MediaCoverTypes mediaCoverTypes, int? height = null);
|
string GetCoverPath(int movieId, MediaCoverTypes mediaCoverTypes, int? height = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +73,19 @@ public string GetCoverPath(int movieId, MediaCoverTypes coverTypes, int? height
|
|||||||
return Path.Combine(GetMovieCoverPath(movieId), coverTypes.ToString().ToLower() + heightSuffix + ".jpg");
|
return Path.Combine(GetMovieCoverPath(movieId), coverTypes.ToString().ToLower() + heightSuffix + ".jpg");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConvertToLocalUrls(int movieId, IEnumerable<MediaCover> covers)
|
public Dictionary<string, FileInfo> GetCoverFileInfos()
|
||||||
|
{
|
||||||
|
if (!_diskProvider.FolderExists(_coverRootFolder))
|
||||||
|
{
|
||||||
|
return new Dictionary<string, FileInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _diskProvider
|
||||||
|
.GetFileInfos(_coverRootFolder, SearchOption.AllDirectories)
|
||||||
|
.ToDictionary(x => x.FullName, PathEqualityComparer.Instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConvertToLocalUrls(int movieId, IEnumerable<MediaCover> covers, Dictionary<string, FileInfo> fileInfos = null)
|
||||||
{
|
{
|
||||||
if (movieId == 0)
|
if (movieId == 0)
|
||||||
{
|
{
|
||||||
@ -90,9 +105,21 @@ public void ConvertToLocalUrls(int movieId, IEnumerable<MediaCover> covers)
|
|||||||
mediaCover.RemoteUrl = mediaCover.Url;
|
mediaCover.RemoteUrl = mediaCover.Url;
|
||||||
mediaCover.Url = _configFileProvider.UrlBase + @"/MediaCover/" + movieId + "/" + mediaCover.CoverType.ToString().ToLower() + ".jpg";
|
mediaCover.Url = _configFileProvider.UrlBase + @"/MediaCover/" + movieId + "/" + mediaCover.CoverType.ToString().ToLower() + ".jpg";
|
||||||
|
|
||||||
if (_diskProvider.FileExists(filePath))
|
FileInfo file;
|
||||||
|
var fileExists = false;
|
||||||
|
if (fileInfos != null)
|
||||||
{
|
{
|
||||||
var lastWrite = _diskProvider.FileGetLastWrite(filePath);
|
fileExists = fileInfos.TryGetValue(filePath, out file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file = _diskProvider.GetFileInfo(filePath);
|
||||||
|
fileExists = file.Exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileExists)
|
||||||
|
{
|
||||||
|
var lastWrite = file.LastWriteTimeUtc;
|
||||||
mediaCover.Url += "?lastWrite=" + lastWrite.Ticks;
|
mediaCover.Url += "?lastWrite=" + lastWrite.Ticks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
@ -42,21 +44,21 @@ public class MovieModule : RadarrRestModuleWithSignalR<MovieResource, Movie>,
|
|||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
|
|
||||||
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
|
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
IMovieService moviesService,
|
IMovieService moviesService,
|
||||||
IMovieTranslationService movieTranslationService,
|
IMovieTranslationService movieTranslationService,
|
||||||
IAddMovieService addMovieService,
|
IAddMovieService addMovieService,
|
||||||
IMapCoversToLocal coverMapper,
|
IMapCoversToLocal coverMapper,
|
||||||
IManageCommandQueue commandQueueManager,
|
IManageCommandQueue commandQueueManager,
|
||||||
IUpgradableSpecification qualityUpgradableSpecification,
|
IUpgradableSpecification qualityUpgradableSpecification,
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
RootFolderValidator rootFolderValidator,
|
RootFolderValidator rootFolderValidator,
|
||||||
MappedNetworkDriveValidator mappedNetworkDriveValidator,
|
MappedNetworkDriveValidator mappedNetworkDriveValidator,
|
||||||
MoviePathValidator moviesPathValidator,
|
MoviePathValidator moviesPathValidator,
|
||||||
MovieExistsValidator moviesExistsValidator,
|
MovieExistsValidator moviesExistsValidator,
|
||||||
MovieAncestorValidator moviesAncestorValidator,
|
MovieAncestorValidator moviesAncestorValidator,
|
||||||
SystemFolderValidator systemFolderValidator,
|
SystemFolderValidator systemFolderValidator,
|
||||||
ProfileExistsValidator profileExistsValidator,
|
ProfileExistsValidator profileExistsValidator,
|
||||||
MovieFolderAsRootFolderValidator movieFolderAsRootFolderValidator)
|
MovieFolderAsRootFolderValidator movieFolderAsRootFolderValidator)
|
||||||
: base(signalRBroadcaster)
|
: base(signalRBroadcaster)
|
||||||
{
|
{
|
||||||
_moviesService = moviesService;
|
_moviesService = moviesService;
|
||||||
@ -104,6 +106,8 @@ private List<MovieResource> AllMovie()
|
|||||||
var moviesResources = new List<MovieResource>();
|
var moviesResources = new List<MovieResource>();
|
||||||
var configLanguage = (Language)_configService.MovieInfoLanguage;
|
var configLanguage = (Language)_configService.MovieInfoLanguage;
|
||||||
|
|
||||||
|
Dictionary<string, FileInfo> coverFileInfos = null;
|
||||||
|
|
||||||
if (tmdbId > 0)
|
if (tmdbId > 0)
|
||||||
{
|
{
|
||||||
var movie = _moviesService.FindByTmdbId(tmdbId);
|
var movie = _moviesService.FindByTmdbId(tmdbId);
|
||||||
@ -117,18 +121,27 @@ private List<MovieResource> AllMovie()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var translations = _movieTranslationService.GetAllTranslationsForLanguage(configLanguage);
|
var movieTask = Task.Run(() => _moviesService.GetAllMovies());
|
||||||
var movies = _moviesService.GetAllMovies();
|
|
||||||
|
var translations = _movieTranslationService
|
||||||
|
.GetAllTranslationsForLanguage(configLanguage)
|
||||||
|
.ToDictionary(x => x.MovieId);
|
||||||
|
|
||||||
|
coverFileInfos = _coverMapper.GetCoverFileInfos();
|
||||||
|
|
||||||
|
var movies = movieTask.GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
moviesResources = new List<MovieResource>(movies.Count);
|
||||||
|
|
||||||
foreach (var movie in movies)
|
foreach (var movie in movies)
|
||||||
{
|
{
|
||||||
var translation = GetMovieTranslation(translations, movie, configLanguage);
|
var translation = GetTranslationFromDict(translations, movie, configLanguage);
|
||||||
moviesResources.Add(movie.ToResource(_qualityUpgradableSpecification, translation));
|
var resource = movie.ToResource(_qualityUpgradableSpecification, translation);
|
||||||
|
_coverMapper.ConvertToLocalUrls(resource.Id, resource.Images, coverFileInfos);
|
||||||
|
moviesResources.Add(resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MapCoversToLocal(moviesResources.ToArray());
|
|
||||||
|
|
||||||
return moviesResources;
|
return moviesResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +181,21 @@ private MovieTranslation GetMovieTranslation(List<MovieTranslation> translations
|
|||||||
return translations.FirstOrDefault(t => t.Language == configLanguage && t.MovieId == movie.Id);
|
return translations.FirstOrDefault(t => t.Language == configLanguage && t.MovieId == movie.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MovieTranslation GetTranslationFromDict(Dictionary<int, MovieTranslation> translations, Movie movie, Language configLanguage)
|
||||||
|
{
|
||||||
|
if (configLanguage == Language.Original)
|
||||||
|
{
|
||||||
|
return new MovieTranslation
|
||||||
|
{
|
||||||
|
Title = movie.OriginalTitle,
|
||||||
|
Overview = movie.Overview
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
translations.TryGetValue(movie.Id, out var translation);
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
|
||||||
private int AddMovie(MovieResource moviesResource)
|
private int AddMovie(MovieResource moviesResource)
|
||||||
{
|
{
|
||||||
var movie = _addMovieService.AddMovie(moviesResource.ToModel());
|
var movie = _addMovieService.AddMovie(moviesResource.ToModel());
|
||||||
@ -211,12 +239,9 @@ private void DeleteMovie(int id)
|
|||||||
_moviesService.DeleteMovie(id, deleteFiles, addExclusion);
|
_moviesService.DeleteMovie(id, deleteFiles, addExclusion);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MapCoversToLocal(params MovieResource[] movies)
|
private void MapCoversToLocal(MovieResource movie)
|
||||||
{
|
{
|
||||||
foreach (var moviesResource in movies)
|
_coverMapper.ConvertToLocalUrls(movie.Id, movie.Images);
|
||||||
{
|
|
||||||
_coverMapper.ConvertToLocalUrls(moviesResource.Id, moviesResource.Images);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(MovieImportedEvent message)
|
public void Handle(MovieImportedEvent message)
|
||||||
|
Loading…
Reference in New Issue
Block a user