Merge pull request #621 from Bond-009/perf

Minor improvements to library scan code
This commit is contained in:
Andrew Rabert 2019-01-20 18:13:49 -05:00 committed by GitHub
commit 803bf563d7
9 changed files with 55 additions and 117 deletions

View File

@ -22,17 +22,17 @@ namespace Emby.Naming.TV
throw new ArgumentNullException(nameof(path));
}
var isStub = false;
bool isStub = false;
string container = null;
string stubType = null;
if (!IsDirectory)
{
var extension = Path.GetExtension(path) ?? string.Empty;
var extension = Path.GetExtension(path);
// Check supported extensions
if (!_options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
{
var stubResult = new StubResolver(_options).ResolveFile(path);
var stubResult = StubResolver.ResolveFile(path, _options);
isStub = stubResult.IsStub;

View File

@ -5,21 +5,14 @@ using Emby.Naming.Common;
namespace Emby.Naming.Video
{
public class StubResolver
public static class StubResolver
{
private readonly NamingOptions _options;
public StubResolver(NamingOptions options)
{
_options = options;
}
public StubResult ResolveFile(string path)
public static StubResult ResolveFile(string path, NamingOptions options)
{
var result = new StubResult();
var extension = Path.GetExtension(path) ?? string.Empty;
if (_options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
if (options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
{
result.IsStub = true;
@ -27,12 +20,11 @@ namespace Emby.Naming.Video
var token = (Path.GetExtension(path) ?? string.Empty).TrimStart('.');
foreach (var rule in _options.StubTypes)
foreach (var rule in options.StubTypes)
{
if (string.Equals(rule.Token, token, StringComparison.OrdinalIgnoreCase))
{
result.StubType = rule.StubType;
result.Tokens.Add(token);
break;
}
}

View File

@ -1,8 +1,6 @@
using System.Collections.Generic;
namespace Emby.Naming.Video
{
public class StubResult
public struct StubResult
{
/// <summary>
/// Gets or sets a value indicating whether this instance is stub.
@ -14,15 +12,5 @@ namespace Emby.Naming.Video
/// </summary>
/// <value>The type of the stub.</value>
public string StubType { get; set; }
/// <summary>
/// Gets or sets the tokens.
/// </summary>
/// <value>The tokens.</value>
public List<string> Tokens { get; set; }
public StubResult()
{
Tokens = new List<string>();
}
}
}

View File

@ -48,17 +48,17 @@ namespace Emby.Naming.Video
throw new ArgumentNullException(nameof(path));
}
var isStub = false;
bool isStub = false;
string container = null;
string stubType = null;
if (!IsDirectory)
{
var extension = Path.GetExtension(path) ?? string.Empty;
var extension = Path.GetExtension(path);
// Check supported extensions
if (!_options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
{
var stubResult = new StubResolver(_options).ResolveFile(path);
var stubResult = StubResolver.ResolveFile(path, _options);
isStub = stubResult.IsStub;
@ -79,9 +79,9 @@ namespace Emby.Naming.Video
var extraResult = new ExtraResolver(_options).GetExtraInfo(path);
var name = !IsDirectory
? Path.GetFileNameWithoutExtension(path)
: Path.GetFileName(path);
var name = IsDirectory
? Path.GetFileName(path)
: Path.GetFileNameWithoutExtension(path);
int? year = null;
@ -91,8 +91,7 @@ namespace Emby.Naming.Video
if (string.IsNullOrEmpty(extraResult.ExtraType))
{
name = cleanDateTimeResult.Name;
name = CleanString(name).Name;
name = CleanString(cleanDateTimeResult.Name).Name;
}
year = cleanDateTimeResult.Year;

View File

@ -268,7 +268,7 @@ namespace Emby.Server.Implementations.HttpClientManager
var responseCachePath = Path.Combine(_appPaths.CachePath, "httpclient", urlHash);
var response = await GetCachedResponse(responseCachePath, options.CacheLength, url).ConfigureAwait(false);
var response = GetCachedResponse(responseCachePath, options.CacheLength, url);
if (response != null)
{
return response;
@ -284,30 +284,24 @@ namespace Emby.Server.Implementations.HttpClientManager
return response;
}
private async Task<HttpResponseInfo> GetCachedResponse(string responseCachePath, TimeSpan cacheLength, string url)
private HttpResponseInfo GetCachedResponse(string responseCachePath, TimeSpan cacheLength, string url)
{
try
{
if (_fileSystem.GetLastWriteTimeUtc(responseCachePath).Add(cacheLength) > DateTime.UtcNow)
{
using (var stream = _fileSystem.GetFileStream(responseCachePath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read, true))
var stream = _fileSystem.GetFileStream(responseCachePath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read, true);
return new HttpResponseInfo
{
var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
memoryStream.Position = 0;
return new HttpResponseInfo
{
ResponseUrl = url,
Content = memoryStream,
StatusCode = HttpStatusCode.OK,
ContentLength = memoryStream.Length
};
}
ResponseUrl = url,
Content = stream,
StatusCode = HttpStatusCode.OK,
ContentLength = stream.Length
};
}
}
catch (FileNotFoundException)
catch (FileNotFoundException) // REVIEW: @bond Is this really faster?
{
}
@ -323,19 +317,11 @@ namespace Emby.Server.Implementations.HttpClientManager
{
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(responseCachePath));
using (var responseStream = response.Content)
using (var fileStream = _fileSystem.GetFileStream(responseCachePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None, true))
{
var memoryStream = new MemoryStream();
await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
memoryStream.Position = 0;
await response.Content.CopyToAsync(fileStream).ConfigureAwait(false);
using (var fileStream = _fileSystem.GetFileStream(responseCachePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None, true))
{
await memoryStream.CopyToAsync(fileStream).ConfigureAwait(false);
memoryStream.Position = 0;
response.Content = memoryStream;
}
response.Content.Position = 0;
}
}

View File

@ -450,10 +450,7 @@ namespace Emby.Server.Implementations.IO
}
public Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, FileOpenOptions fileOpenOptions)
{
var defaultBufferSize = 4096;
return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), defaultBufferSize, GetFileOptions(fileOpenOptions));
}
=> new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), 4096, GetFileOptions(fileOpenOptions));
private static FileOptions GetFileOptions(FileOpenOptions mode)
{
@ -764,18 +761,13 @@ namespace Emby.Server.Implementations.IO
// Only include drives in the ready state or this method could end up being very slow, waiting for drives to timeout
return DriveInfo.GetDrives().Where(d => d.IsReady).Select(d => new FileSystemMetadata
{
Name = GetName(d),
Name = d.Name,
FullName = d.RootDirectory.FullName,
IsDirectory = true
}).ToList();
}
private static string GetName(DriveInfo drive)
{
return drive.Name;
}
public IEnumerable<FileSystemMetadata> GetDirectories(string path, bool recursive = false)
{
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
@ -851,17 +843,6 @@ namespace Emby.Server.Implementations.IO
return File.OpenRead(path);
}
private void CopyFileUsingStreams(string source, string target, bool overwrite)
{
using (var sourceStream = OpenRead(source))
{
using (var targetStream = GetFileStream(target, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
{
sourceStream.CopyTo(targetStream);
}
}
}
public void CopyFile(string source, string target, bool overwrite)
{
File.Copy(source, target, overwrite);

View File

@ -107,7 +107,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
return null;
}
public static bool IsSeriesFolder(string path,
public static bool IsSeriesFolder(
string path,
IEnumerable<FileSystemMetadata> fileSystemChildren,
IDirectoryService directoryService,
IFileSystem fileSystem,
@ -135,7 +136,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
{
if (IsSeasonFolder(child.FullName, isTvContentType, libraryManager))
{
//logger.LogDebug("{0} is a series because of season folder {1}.", path, child.FullName);
logger.LogDebug("{Path} is a series because of season folder {Dir}.", path, child.FullName);
return true;
}
}
@ -161,7 +162,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
isOptimistic = false;
}
var episodeInfo = episodeResolver.Resolve(fullName, false, isNamed, isOptimistic, null, false);
var episodeInfo = episodeResolver.Resolve(fullName, false, isNamed, isOptimistic, fillExtendedInfo: false);
if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue)
{
return true;
@ -170,7 +171,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
}
}
//logger.LogDebug("{0} is not a series folder.", path);
logger.LogDebug("{Path} is not a series folder.", path);
return false;
}

View File

@ -1403,9 +1403,9 @@ namespace MediaBrowser.Controller.Entities
private async Task<bool> RefreshLocalTrailers(IHasTrailers item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newItems = LibraryManager.FindTrailers(this, fileSystemChildren, options.DirectoryService).ToList();
var newItems = LibraryManager.FindTrailers(this, fileSystemChildren, options.DirectoryService);
var newItemIds = newItems.Select(i => i.Id).ToArray();
var newItemIds = newItems.Select(i => i.Id);
var itemsChanged = !item.LocalTrailerIds.SequenceEqual(newItemIds);
var ownerId = item.Id;
@ -1414,8 +1414,7 @@ namespace MediaBrowser.Controller.Entities
{
var subOptions = new MetadataRefreshOptions(options);
if (!i.ExtraType.HasValue ||
i.ExtraType.Value != Model.Entities.ExtraType.Trailer ||
if (i.ExtraType != Model.Entities.ExtraType.Trailer ||
i.OwnerId != ownerId ||
!i.ParentId.Equals(Guid.Empty))
{
@ -1430,7 +1429,7 @@ namespace MediaBrowser.Controller.Entities
await Task.WhenAll(tasks).ConfigureAwait(false);
item.LocalTrailerIds = newItemIds;
item.LocalTrailerIds = newItemIds.ToArray();
return itemsChanged;
}

View File

@ -177,13 +177,7 @@ namespace MediaBrowser.Providers.TV
private async Task<MetadataResult<Series>> FetchMovieData(string tmdbId, string language, string preferredCountryCode, CancellationToken cancellationToken)
{
string dataFilePath = null;
RootObject seriesInfo = null;
if (!string.IsNullOrEmpty(tmdbId))
{
seriesInfo = await FetchMainResult(tmdbId, language, cancellationToken).ConfigureAwait(false);
}
RootObject seriesInfo = await FetchMainResult(tmdbId, language, cancellationToken).ConfigureAwait(false);
if (seriesInfo == null)
{
@ -192,7 +186,7 @@ namespace MediaBrowser.Providers.TV
tmdbId = seriesInfo.id.ToString(_usCulture);
dataFilePath = GetDataFilePath(tmdbId, language);
string dataFilePath = GetDataFilePath(tmdbId, language);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(dataFilePath));
_jsonSerializer.SerializeToFile(seriesInfo, dataFilePath);
@ -220,7 +214,7 @@ namespace MediaBrowser.Providers.TV
string voteAvg = seriesInfo.vote_average.ToString(CultureInfo.InvariantCulture);
if (float.TryParse(voteAvg, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var rating))
if (float.TryParse(voteAvg, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out float rating))
{
series.CommunityRating = rating;
}
@ -293,14 +287,11 @@ namespace MediaBrowser.Providers.TV
{
foreach (var video in seriesInfo.videos.results)
{
if (video.type.Equals("trailer", System.StringComparison.OrdinalIgnoreCase)
|| video.type.Equals("clip", System.StringComparison.OrdinalIgnoreCase))
if ((video.type.Equals("trailer", StringComparison.OrdinalIgnoreCase)
|| video.type.Equals("clip", StringComparison.OrdinalIgnoreCase))
&& video.site.Equals("youtube", StringComparison.OrdinalIgnoreCase))
{
if (video.site.Equals("youtube", System.StringComparison.OrdinalIgnoreCase))
{
var videoUrl = string.Format("http://www.youtube.com/watch?v={0}", video.key);
series.AddTrailerUrl(videoUrl);
}
series.AddTrailerUrl($"http://www.youtube.com/watch?v={video.key}");
}
}
}
@ -351,9 +342,12 @@ namespace MediaBrowser.Providers.TV
internal async Task DownloadSeriesInfo(string id, string preferredMetadataLanguage, CancellationToken cancellationToken)
{
var mainResult = await FetchMainResult(id, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false);
RootObject mainResult = await FetchMainResult(id, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false);
if (mainResult == null) return;
if (mainResult == null)
{
return;
}
var dataFilePath = GetDataFilePath(id, preferredMetadataLanguage);
@ -368,10 +362,8 @@ namespace MediaBrowser.Providers.TV
if (!string.IsNullOrEmpty(language))
{
url += string.Format("&language={0}", MovieDbProvider.NormalizeLanguage(language));
// Get images in english and with no language
url += "&include_image_language=" + MovieDbProvider.GetImageLanguagesParam(language);
url += "&language=" + MovieDbProvider.NormalizeLanguage(language)
+ "&include_image_language=" + MovieDbProvider.GetImageLanguagesParam(language); // Get images in english and with no language
}
cancellationToken.ThrowIfCancellationRequested();
@ -405,7 +397,7 @@ namespace MediaBrowser.Providers.TV
!string.IsNullOrEmpty(language) &&
!string.Equals(language, "en", StringComparison.OrdinalIgnoreCase))
{
_logger.LogInformation("MovieDbSeriesProvider couldn't find meta for language " + language + ". Trying English...");
_logger.LogInformation("MovieDbSeriesProvider couldn't find meta for language {Language}. Trying English...", language);
url = string.Format(GetTvInfo3, id, MovieDbProvider.ApiKey) + "&language=en";