Fixed: Speed up initial movie load when opening the UI

pull/5211/head
ta264 4 years ago committed by Qstick
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 @@ namespace NzbDrone.Core.Test.MediaCoverTests
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 @@ namespace NzbDrone.Core.Test.MediaCoverTests
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 @@ namespace NzbDrone.Core.MediaCover
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 @@ namespace NzbDrone.Core.MediaCover
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)
{
fileExists = fileInfos.TryGetValue(filePath, out file);
}
else
{
file = _diskProvider.GetFileInfo(filePath);
fileExists = file.Exists;
}
if (fileExists)
{ {
var lastWrite = _diskProvider.FileGetLastWrite(filePath); 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;
@ -104,6 +106,8 @@ namespace Radarr.Api.V3.Movies
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 @@ namespace Radarr.Api.V3.Movies
} }
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 @@ namespace Radarr.Api.V3.Movies
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 @@ namespace Radarr.Api.V3.Movies
_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…
Cancel
Save