commit
2026a682ed
|
@ -349,7 +349,7 @@ namespace MediaBrowser.Api
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var timerDuration = 1000;
|
var timerDuration = 10000;
|
||||||
|
|
||||||
if (job.Type != TranscodingJobType.Progressive)
|
if (job.Type != TranscodingJobType.Progressive)
|
||||||
{
|
{
|
||||||
|
@ -559,13 +559,13 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
//Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, path);
|
//Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, path);
|
||||||
|
|
||||||
DeletePartialStreamFiles(path, jobType, retryCount + 1, 500);
|
DeletePartialStreamFiles(path, jobType, retryCount + 1, 500);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
//Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, path);
|
//Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using MediaBrowser.Controller.Providers;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using CommonIO;
|
using CommonIO;
|
||||||
|
using MediaBrowser.Model.Logging;
|
||||||
|
|
||||||
namespace MediaBrowser.Api
|
namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
|
@ -39,12 +40,14 @@ namespace MediaBrowser.Api
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IProviderManager _providerManager;
|
private readonly IProviderManager _providerManager;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public ItemRefreshService(ILibraryManager libraryManager, IProviderManager providerManager, IFileSystem fileSystem)
|
public ItemRefreshService(ILibraryManager libraryManager, IProviderManager providerManager, IFileSystem fileSystem, ILogger logger)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_providerManager = providerManager;
|
_providerManager = providerManager;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -69,7 +72,7 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
private MetadataRefreshOptions GetRefreshOptions(BaseRefreshRequest request)
|
private MetadataRefreshOptions GetRefreshOptions(BaseRefreshRequest request)
|
||||||
{
|
{
|
||||||
return new MetadataRefreshOptions(new DirectoryService(_fileSystem))
|
return new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem))
|
||||||
{
|
{
|
||||||
MetadataRefreshMode = request.MetadataRefreshMode,
|
MetadataRefreshMode = request.MetadataRefreshMode,
|
||||||
ImageRefreshMode = request.ImageRefreshMode,
|
ImageRefreshMode = request.ImageRefreshMode,
|
||||||
|
|
|
@ -286,28 +286,41 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
protected string GetH264Encoder(StreamState state)
|
protected string GetH264Encoder(StreamState state)
|
||||||
{
|
{
|
||||||
|
var defaultEncoder = "libx264";
|
||||||
|
|
||||||
// Only use alternative encoders for video files.
|
// Only use alternative encoders for video files.
|
||||||
// When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully
|
// When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully
|
||||||
// Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this.
|
// Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this.
|
||||||
if (state.VideoType == VideoType.VideoFile)
|
if (state.VideoType == VideoType.VideoFile)
|
||||||
{
|
{
|
||||||
if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) ||
|
var hwType = ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType;
|
||||||
string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
|
||||||
|
if (string.Equals(hwType, "qsv", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(hwType, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return "h264_qsv";
|
return GetAvailableEncoder("h264_qsv", defaultEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(hwType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return "h264_nvenc";
|
return GetAvailableEncoder("h264_nvenc", defaultEncoder);
|
||||||
}
|
}
|
||||||
if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(hwType, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return "h264_omx";
|
return GetAvailableEncoder("h264_omx", defaultEncoder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "libx264";
|
return defaultEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetAvailableEncoder(string preferredEncoder, string defaultEncoder)
|
||||||
|
{
|
||||||
|
if (MediaEncoder.SupportsEncoder(preferredEncoder))
|
||||||
|
{
|
||||||
|
return preferredEncoder;
|
||||||
|
}
|
||||||
|
return defaultEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1080,7 +1093,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
//process.BeginOutputReadLine();
|
//process.BeginOutputReadLine();
|
||||||
|
|
||||||
// Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
|
// Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
|
||||||
Task.Run(() => StartStreamingLog(transcodingJob, state, process.StandardError.BaseStream, state.LogFileStream));
|
var task = Task.Run(() => StartStreamingLog(transcodingJob, state, process.StandardError.BaseStream, state.LogFileStream));
|
||||||
|
|
||||||
// Wait for the file to exist before proceeeding
|
// Wait for the file to exist before proceeeding
|
||||||
while (!FileSystem.FileExists(state.WaitForPath ?? outputPath) && !transcodingJob.HasExited)
|
while (!FileSystem.FileExists(state.WaitForPath ?? outputPath) && !transcodingJob.HasExited)
|
||||||
|
|
|
@ -142,7 +142,8 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
var outputPath = state.OutputFilePath;
|
var outputPath = state.OutputFilePath;
|
||||||
var outputPathExists = FileSystem.FileExists(outputPath);
|
var outputPathExists = FileSystem.FileExists(outputPath);
|
||||||
|
|
||||||
var isTranscodeCached = outputPathExists && !ApiEntryPoint.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive);
|
var transcodingJob = ApiEntryPoint.Instance.GetTranscodingJob(outputPath, TranscodingJobType.Progressive);
|
||||||
|
var isTranscodeCached = outputPathExists && transcodingJob != null;
|
||||||
|
|
||||||
AddDlnaHeaders(state, responseHeaders, request.Static || isTranscodeCached);
|
AddDlnaHeaders(state, responseHeaders, request.Static || isTranscodeCached);
|
||||||
|
|
||||||
|
@ -159,6 +160,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
ContentType = contentType,
|
ContentType = contentType,
|
||||||
IsHeadRequest = isHeadRequest,
|
IsHeadRequest = isHeadRequest,
|
||||||
Path = state.MediaPath
|
Path = state.MediaPath
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,13 +172,25 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (transcodingJob != null)
|
||||||
|
{
|
||||||
|
ApiEntryPoint.Instance.OnTranscodeBeginRequest(transcodingJob);
|
||||||
|
}
|
||||||
|
|
||||||
return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
|
return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
|
||||||
{
|
{
|
||||||
ResponseHeaders = responseHeaders,
|
ResponseHeaders = responseHeaders,
|
||||||
ContentType = contentType,
|
ContentType = contentType,
|
||||||
IsHeadRequest = isHeadRequest,
|
IsHeadRequest = isHeadRequest,
|
||||||
Path = outputPath,
|
Path = outputPath,
|
||||||
FileShare = FileShare.ReadWrite
|
FileShare = FileShare.ReadWrite,
|
||||||
|
OnComplete = () =>
|
||||||
|
{
|
||||||
|
if (transcodingJob != null)
|
||||||
|
{
|
||||||
|
ApiEntryPoint.Instance.OnTranscodeEndRequest(transcodingJob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
@ -348,7 +362,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
outputHeaders[item.Key] = item.Value;
|
outputHeaders[item.Key] = item.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Func<Stream,Task> streamWriter = stream => new ProgressiveFileCopier(FileSystem, job, Logger).StreamFile(outputPath, stream, CancellationToken.None);
|
Func<Stream, Task> streamWriter = stream => new ProgressiveFileCopier(FileSystem, job, Logger).StreamFile(outputPath, stream, CancellationToken.None);
|
||||||
|
|
||||||
return ResultFactory.GetAsyncStreamWriter(streamWriter, outputHeaders);
|
return ResultFactory.GetAsyncStreamWriter(streamWriter, outputHeaders);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StreamFile(string path, Stream outputStream, CancellationToken cancellationToken)
|
public async Task StreamFile(string path, Stream outputStream, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var eofCount = 0;
|
var eofCount = 0;
|
||||||
|
|
||||||
|
@ -53,6 +55,14 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (_job != null)
|
||||||
|
{
|
||||||
|
ApiEntryPoint.Instance.OnTranscodeEndRequest(_job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<int> CopyToAsyncInternal(Stream source, Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
|
private async Task<int> CopyToAsyncInternal(Stream source, Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
|
@ -153,7 +153,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
|
var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
|
||||||
5.ToString(UsCulture));
|
5.ToString(UsCulture));
|
||||||
|
|
||||||
args += keyFrameArg;
|
args += keyFrameArg;
|
||||||
|
|
|
@ -80,7 +80,10 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
if (userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) != -1)
|
if (userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||||
|
userAgent.IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||||
|
userAgent.IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||||
|
userAgent.IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1)
|
||||||
{
|
{
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ namespace MediaBrowser.Api
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
//Logger.ErrorException("Error getting plugin list", ex);
|
//Logger.ErrorException("Error getting plugin list", ex);
|
||||||
// Play it safe here
|
// Play it safe here
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace MediaBrowser.Api
|
||||||
config.EnableStandaloneMusicKeys = true;
|
config.EnableStandaloneMusicKeys = true;
|
||||||
config.EnableCaseSensitiveItemIds = true;
|
config.EnableCaseSensitiveItemIds = true;
|
||||||
//config.EnableFolderView = true;
|
//config.EnableFolderView = true;
|
||||||
config.SchemaVersion = 108;
|
config.SchemaVersion = 109;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Post(UpdateStartupConfiguration request)
|
public void Post(UpdateStartupConfiguration request)
|
||||||
|
|
|
@ -11,6 +11,7 @@ using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommonIO;
|
using CommonIO;
|
||||||
|
using MediaBrowser.Model.Dto;
|
||||||
|
|
||||||
namespace MediaBrowser.Api
|
namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
|
@ -81,11 +82,18 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
var dtoOptions = GetDtoOptions(request);
|
var dtoOptions = GetDtoOptions(request);
|
||||||
|
|
||||||
var video = (Video)item;
|
var video = item as Video;
|
||||||
|
BaseItemDto[] items;
|
||||||
var items = video.GetAdditionalParts()
|
if (video != null)
|
||||||
|
{
|
||||||
|
items = video.GetAdditionalParts()
|
||||||
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, video))
|
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, video))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
items = new BaseItemDto[] { };
|
||||||
|
}
|
||||||
|
|
||||||
var result = new ItemsResult
|
var result = new ItemsResult
|
||||||
{
|
{
|
||||||
|
|
|
@ -211,7 +211,7 @@ namespace MediaBrowser.Common.Plugins
|
||||||
{
|
{
|
||||||
return (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType));
|
return (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
return (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType));
|
return (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType));
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
var locations = PhysicalLocations.ToList();
|
var locations = PhysicalLocations.ToList();
|
||||||
|
|
||||||
var newLocations = CreateResolveArgs(new DirectoryService(BaseItem.FileSystem), false).PhysicalLocations.ToList();
|
var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations.ToList();
|
||||||
|
|
||||||
if (!locations.SequenceEqual(newLocations))
|
if (!locations.SequenceEqual(newLocations))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1003,7 +1003,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
public Task RefreshMetadata(CancellationToken cancellationToken)
|
public Task RefreshMetadata(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken);
|
return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem)), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -82,7 +82,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
var locations = PhysicalLocations.ToList();
|
var locations = PhysicalLocations.ToList();
|
||||||
|
|
||||||
var newLocations = CreateResolveArgs(new DirectoryService(BaseItem.FileSystem), false).PhysicalLocations.ToList();
|
var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations.ToList();
|
||||||
|
|
||||||
if (!locations.SequenceEqual(newLocations))
|
if (!locations.SequenceEqual(newLocations))
|
||||||
{
|
{
|
||||||
|
|
|
@ -278,7 +278,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
public Task ValidateChildren(IProgress<double> progress, CancellationToken cancellationToken)
|
public Task ValidateChildren(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(FileSystem)));
|
return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -213,7 +213,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
Name = newName;
|
Name = newName;
|
||||||
|
|
||||||
return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem))
|
return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem))
|
||||||
{
|
{
|
||||||
ReplaceAllMetadata = true,
|
ReplaceAllMetadata = true,
|
||||||
ImageRefreshMode = ImageRefreshMode.FullRefresh,
|
ImageRefreshMode = ImageRefreshMode.FullRefresh,
|
||||||
|
|
|
@ -562,5 +562,6 @@ namespace MediaBrowser.Controller.Library
|
||||||
QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query);
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query);
|
||||||
QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query);
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query);
|
||||||
QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query);
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query);
|
||||||
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -133,5 +133,6 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
Task Init();
|
Task Init();
|
||||||
|
|
||||||
Task UpdateEncoderPath(string path, string pathType);
|
Task UpdateEncoderPath(string path, string pathType);
|
||||||
|
bool SupportsEncoder(string encoder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ namespace MediaBrowser.Controller.Persistence
|
||||||
QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query);
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query);
|
||||||
QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query);
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query);
|
||||||
QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query);
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query);
|
||||||
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,9 @@ namespace MediaBrowser.Controller.Providers
|
||||||
private readonly ConcurrentDictionary<string, Dictionary<string, FileSystemMetadata>> _cache =
|
private readonly ConcurrentDictionary<string, Dictionary<string, FileSystemMetadata>> _cache =
|
||||||
new ConcurrentDictionary<string, Dictionary<string, FileSystemMetadata>>(StringComparer.OrdinalIgnoreCase);
|
new ConcurrentDictionary<string, Dictionary<string, FileSystemMetadata>>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<string, FileSystemMetadata> _fileCache =
|
||||||
|
new ConcurrentDictionary<string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public DirectoryService(ILogger logger, IFileSystem fileSystem)
|
public DirectoryService(ILogger logger, IFileSystem fileSystem)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -100,20 +103,19 @@ namespace MediaBrowser.Controller.Providers
|
||||||
|
|
||||||
public FileSystemMetadata GetFile(string path)
|
public FileSystemMetadata GetFile(string path)
|
||||||
{
|
{
|
||||||
var directory = Path.GetDirectoryName(path);
|
FileSystemMetadata file;
|
||||||
|
if (!_fileCache.TryGetValue(path, out file))
|
||||||
if (string.IsNullOrWhiteSpace(directory))
|
|
||||||
{
|
{
|
||||||
_logger.Debug("Parent path is null for {0}", path);
|
file = _fileSystem.GetFileInfo(path);
|
||||||
return null;
|
|
||||||
|
if (file != null)
|
||||||
|
{
|
||||||
|
_fileCache.TryAdd(path, file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var dict = GetFileSystemDictionary(directory, false);
|
return file;
|
||||||
|
//return _fileSystem.GetFileInfo(path);
|
||||||
FileSystemMetadata entry;
|
|
||||||
dict.TryGetValue(path, out entry);
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<FileSystemMetadata> GetDirectories(string path)
|
public IEnumerable<FileSystemMetadata> GetDirectories(string path)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using CommonIO;
|
using CommonIO;
|
||||||
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.Providers;
|
using MediaBrowser.Model.Providers;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Providers
|
namespace MediaBrowser.Controller.Providers
|
||||||
|
@ -19,7 +20,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
public bool ForceSave { get; set; }
|
public bool ForceSave { get; set; }
|
||||||
|
|
||||||
public MetadataRefreshOptions(IFileSystem fileSystem)
|
public MetadataRefreshOptions(IFileSystem fileSystem)
|
||||||
: this(new DirectoryService(fileSystem))
|
: this(new DirectoryService(new NullLogger(), fileSystem))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -248,8 +248,7 @@ namespace MediaBrowser.Dlna
|
||||||
//_logger.Debug("IsMatch-Substring value: {0} testValue: {1} isMatch: {2}", value, header.Value, isMatch);
|
//_logger.Debug("IsMatch-Substring value: {0} testValue: {1} isMatch: {2}", value, header.Value, isMatch);
|
||||||
return isMatch;
|
return isMatch;
|
||||||
case HeaderMatchType.Regex:
|
case HeaderMatchType.Regex:
|
||||||
// Reports of IgnoreCase not working on linux so try it a couple different ways.
|
return Regex.IsMatch(value, header.Value, RegexOptions.IgnoreCase);
|
||||||
return Regex.IsMatch(value, header.Value, RegexOptions.IgnoreCase) || Regex.IsMatch(value.ToUpper(), header.Value.ToUpper(), RegexOptions.IgnoreCase);
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Unrecognized HeaderMatchType");
|
throw new ArgumentException("Unrecognized HeaderMatchType");
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ namespace MediaBrowser.Dlna.Profiles
|
||||||
new HttpHeaderInfo
|
new HttpHeaderInfo
|
||||||
{
|
{
|
||||||
Name = "User-Agent",
|
Name = "User-Agent",
|
||||||
Value = @".*(SEC_HHP_\[TV\] [A-Z]{2}\d{2}J[A-Z]?\d{3,4})*.",
|
Value = @"SEC_",
|
||||||
Match = HeaderMatchType.Regex
|
Match = HeaderMatchType.Substring
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<Identification>
|
<Identification>
|
||||||
<ModelUrl>samsung.com</ModelUrl>
|
<ModelUrl>samsung.com</ModelUrl>
|
||||||
<Headers>
|
<Headers>
|
||||||
<HttpHeaderInfo name="User-Agent" value=".*(SEC_HHP_\[TV\] [A-Z]{2}\d{2}J[A-Z]?\d{3,4})*." match="Regex" />
|
<HttpHeaderInfo name="User-Agent" value="SEC_" match="Substring" />
|
||||||
</Headers>
|
</Headers>
|
||||||
</Identification>
|
</Identification>
|
||||||
<Manufacturer>Emby</Manufacturer>
|
<Manufacturer>Emby</Manufacturer>
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace MediaBrowser.LocalMetadata
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order
|
public virtual int Order
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace MediaBrowser.LocalMetadata.Providers
|
||||||
return directoryService.GetFile(Path.Combine(info.Path, "series.xml"));
|
return directoryService.GetFile(Path.Combine(info.Path, "series.xml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order
|
public override int Order
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,6 +86,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
"srt",
|
"srt",
|
||||||
"h264_nvenc",
|
"h264_nvenc",
|
||||||
"h264_qsv",
|
"h264_qsv",
|
||||||
|
"h264_omx",
|
||||||
|
"h264_vaapi",
|
||||||
"ac3"
|
"ac3"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -522,10 +522,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the output video codec
|
/// Gets the name of the output video codec
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="state">The state.</param>
|
|
||||||
/// <param name="options">The options.</param>
|
|
||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
internal static string GetVideoEncoder(EncodingJob state, EncodingOptions options)
|
internal static string GetVideoEncoder(IMediaEncoder mediaEncoder, EncodingJob state, EncodingOptions options)
|
||||||
{
|
{
|
||||||
var codec = state.OutputVideoCodec;
|
var codec = state.OutputVideoCodec;
|
||||||
|
|
||||||
|
@ -533,7 +531,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
{
|
{
|
||||||
if (string.Equals(codec, "h264", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(codec, "h264", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return GetH264Encoder(state, options);
|
return GetH264Encoder(mediaEncoder, state, options);
|
||||||
}
|
}
|
||||||
if (string.Equals(codec, "vpx", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(codec, "vpx", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -554,24 +552,43 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return "copy";
|
return "copy";
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string GetH264Encoder(EncodingJob state, EncodingOptions options)
|
private static string GetAvailableEncoder(IMediaEncoder mediaEncoder, string preferredEncoder, string defaultEncoder)
|
||||||
{
|
{
|
||||||
if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) ||
|
if (mediaEncoder.SupportsEncoder(preferredEncoder))
|
||||||
string.Equals(options.HardwareAccelerationType, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
return "h264_qsv";
|
return preferredEncoder;
|
||||||
|
}
|
||||||
|
return defaultEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
internal static string GetH264Encoder(IMediaEncoder mediaEncoder, EncodingJob state, EncodingOptions options)
|
||||||
{
|
{
|
||||||
return "h264_nvenc";
|
var defaultEncoder = "libx264";
|
||||||
}
|
|
||||||
if (string.Equals(options.HardwareAccelerationType, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
// Only use alternative encoders for video files.
|
||||||
|
// When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully
|
||||||
|
// Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this.
|
||||||
|
if (state.VideoType == VideoType.VideoFile)
|
||||||
{
|
{
|
||||||
return "h264_omx";
|
var hwType = options.HardwareAccelerationType;
|
||||||
|
|
||||||
|
if (string.Equals(hwType, "qsv", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(hwType, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return GetAvailableEncoder(mediaEncoder, "h264_qsv", defaultEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "libx264";
|
if (string.Equals(hwType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return GetAvailableEncoder(mediaEncoder, "h264_nvenc", defaultEncoder);
|
||||||
|
}
|
||||||
|
if (string.Equals(hwType, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return GetAvailableEncoder(mediaEncoder, "h264_omx", defaultEncoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool CanStreamCopyVideo(EncodingJobOptions request, MediaStream videoStream)
|
internal static bool CanStreamCopyVideo(EncodingJobOptions request, MediaStream videoStream)
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Kick this off, but no need to wait on it
|
// Kick this off, but no need to wait on it
|
||||||
Task.Run(async () =>
|
var task = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await DownloadFontFile(fontsDirectory, fontFilename, new Progress<double>()).ConfigureAwait(false);
|
await DownloadFontFile(fontsDirectory, fontFilename, new Progress<double>()).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
|
@ -392,9 +392,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
//_logger.Info("Supported decoders: {0}", string.Join(",", list.ToArray()));
|
//_logger.Info("Supported decoders: {0}", string.Join(",", list.ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SupportsEncoder(string decoder)
|
public bool SupportsEncoder(string encoder)
|
||||||
{
|
{
|
||||||
return _encoders.Contains(decoder, StringComparer.OrdinalIgnoreCase);
|
return _encoders.Contains(encoder, StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SupportsDecoder(string decoder)
|
public bool SupportsDecoder(string decoder)
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
protected override async Task<string> GetCommandLineArguments(EncodingJob state)
|
protected override async Task<string> GetCommandLineArguments(EncodingJob state)
|
||||||
{
|
{
|
||||||
// Get the output codec name
|
// Get the output codec name
|
||||||
var videoCodec = EncodingJobFactory.GetVideoEncoder(state, GetEncodingOptions());
|
var videoCodec = EncodingJobFactory.GetVideoEncoder(MediaEncoder, state, GetEncodingOptions());
|
||||||
|
|
||||||
var format = string.Empty;
|
var format = string.Empty;
|
||||||
var keyFrame = string.Empty;
|
var keyFrame = string.Empty;
|
||||||
|
@ -84,7 +84,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
|
var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
|
||||||
5.ToString(UsCulture));
|
5.ToString(UsCulture));
|
||||||
|
|
||||||
args += keyFrameArg;
|
args += keyFrameArg;
|
||||||
|
|
|
@ -398,7 +398,8 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
// These are mp4 chapters
|
// These are mp4 chapters
|
||||||
if (string.Equals(streamInfo.codec_name, "mov_text", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(streamInfo.codec_name, "mov_text", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return null;
|
// Edit: but these are also sometimes subtitles?
|
||||||
|
//return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stream = new MediaStream
|
var stream = new MediaStream
|
||||||
|
|
|
@ -349,9 +349,6 @@ namespace MediaBrowser.Providers.Manager
|
||||||
|
|
||||||
if (!runAllProviders)
|
if (!runAllProviders)
|
||||||
{
|
{
|
||||||
// Avoid implicitly captured closure
|
|
||||||
var currentItem = item;
|
|
||||||
|
|
||||||
var providersWithChanges = providers
|
var providersWithChanges = providers
|
||||||
.Where(i =>
|
.Where(i =>
|
||||||
{
|
{
|
||||||
|
@ -361,12 +358,6 @@ namespace MediaBrowser.Providers.Manager
|
||||||
return HasChanged(item, hasFileChangeMonitor, options.DirectoryService);
|
return HasChanged(item, hasFileChangeMonitor, options.DirectoryService);
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasChangeMonitor = i as IHasChangeMonitor;
|
|
||||||
if (hasChangeMonitor != null)
|
|
||||||
{
|
|
||||||
return HasChanged(item, hasChangeMonitor, currentItem.DateLastSaved, options.DirectoryService);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
@ -726,27 +717,6 @@ namespace MediaBrowser.Providers.Manager
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HasChanged(IHasMetadata item, IHasChangeMonitor changeMonitor, DateTime date, IDirectoryService directoryService)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var hasChanged = changeMonitor.HasChanged(item, directoryService, date);
|
|
||||||
|
|
||||||
//if (hasChanged)
|
|
||||||
//{
|
|
||||||
// Logger.Debug("{0} reports change to {1} since {2}", changeMonitor.GetType().Name,
|
|
||||||
// item.Path ?? item.Name, date);
|
|
||||||
//}
|
|
||||||
|
|
||||||
return hasChanged;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.ErrorException("Error in {0}.HasChanged", ex, changeMonitor.GetType().Name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RefreshResult
|
public class RefreshResult
|
||||||
|
|
|
@ -298,7 +298,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
{
|
{
|
||||||
var options = GetMetadataOptions(item);
|
var options = GetMetadataOptions(item);
|
||||||
|
|
||||||
return GetImageProviders(item, options, new ImageRefreshOptions(new DirectoryService(_fileSystem)), includeDisabled).OfType<IRemoteImageProvider>();
|
return GetImageProviders(item, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), includeDisabled).OfType<IRemoteImageProvider>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, MetadataOptions options, bool includeDisabled, bool checkIsOwnedItem)
|
private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, MetadataOptions options, bool includeDisabled, bool checkIsOwnedItem)
|
||||||
|
@ -488,7 +488,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
ItemType = typeof(T).Name
|
ItemType = typeof(T).Name
|
||||||
};
|
};
|
||||||
|
|
||||||
var imageProviders = GetImageProviders(dummy, options, new ImageRefreshOptions(new DirectoryService(_fileSystem)), true).ToList();
|
var imageProviders = GetImageProviders(dummy, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), true).ToList();
|
||||||
|
|
||||||
AddMetadataPlugins(summary.Plugins, dummy, options);
|
AddMetadataPlugins(summary.Plugins, dummy, options);
|
||||||
AddImagePlugins(summary.Plugins, dummy, imageProviders);
|
AddImagePlugins(summary.Plugins, dummy, imageProviders);
|
||||||
|
|
|
@ -61,14 +61,14 @@ namespace MediaBrowser.Providers.Music
|
||||||
{
|
{
|
||||||
result.Item = new MusicAlbum();
|
result.Item = new MusicAlbum();
|
||||||
result.HasMetadata = true;
|
result.HasMetadata = true;
|
||||||
ProcessResult(result.Item, obj.album[0]);
|
ProcessResult(result.Item, obj.album[0], info.MetadataLanguage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessResult(MusicAlbum item, Album result)
|
private void ProcessResult(MusicAlbum item, Album result, string preferredLanguage)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(result.strArtist))
|
if (!string.IsNullOrWhiteSpace(result.strArtist))
|
||||||
{
|
{
|
||||||
|
@ -91,7 +91,39 @@ namespace MediaBrowser.Providers.Music
|
||||||
item.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, result.strMusicBrainzArtistID);
|
item.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, result.strMusicBrainzArtistID);
|
||||||
item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, result.strMusicBrainzID);
|
item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, result.strMusicBrainzID);
|
||||||
|
|
||||||
item.Overview = (result.strDescriptionEN ?? string.Empty).StripHtml();
|
string overview = null;
|
||||||
|
|
||||||
|
if (string.Equals(preferredLanguage, "de", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strDescriptionDE;
|
||||||
|
}
|
||||||
|
else if (string.Equals(preferredLanguage, "fr", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strDescriptionFR;
|
||||||
|
}
|
||||||
|
else if (string.Equals(preferredLanguage, "nl", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strDescriptionNL;
|
||||||
|
}
|
||||||
|
else if (string.Equals(preferredLanguage, "ru", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strDescriptionRU;
|
||||||
|
}
|
||||||
|
else if (string.Equals(preferredLanguage, "it", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strDescriptionIT;
|
||||||
|
}
|
||||||
|
else if ((preferredLanguage ?? string.Empty).StartsWith("pt", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strDescriptionPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(overview))
|
||||||
|
{
|
||||||
|
overview = result.strDescriptionEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.Overview = (overview ?? string.Empty).StripHtml();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
|
@ -186,20 +218,20 @@ namespace MediaBrowser.Providers.Music
|
||||||
public string strAlbumThumb { get; set; }
|
public string strAlbumThumb { get; set; }
|
||||||
public string strAlbumCDart { get; set; }
|
public string strAlbumCDart { get; set; }
|
||||||
public string strDescriptionEN { get; set; }
|
public string strDescriptionEN { get; set; }
|
||||||
public object strDescriptionDE { get; set; }
|
public string strDescriptionDE { get; set; }
|
||||||
public object strDescriptionFR { get; set; }
|
public string strDescriptionFR { get; set; }
|
||||||
public object strDescriptionCN { get; set; }
|
public string strDescriptionCN { get; set; }
|
||||||
public object strDescriptionIT { get; set; }
|
public string strDescriptionIT { get; set; }
|
||||||
public object strDescriptionJP { get; set; }
|
public string strDescriptionJP { get; set; }
|
||||||
public object strDescriptionRU { get; set; }
|
public string strDescriptionRU { get; set; }
|
||||||
public object strDescriptionES { get; set; }
|
public string strDescriptionES { get; set; }
|
||||||
public object strDescriptionPT { get; set; }
|
public string strDescriptionPT { get; set; }
|
||||||
public object strDescriptionSE { get; set; }
|
public string strDescriptionSE { get; set; }
|
||||||
public object strDescriptionNL { get; set; }
|
public string strDescriptionNL { get; set; }
|
||||||
public object strDescriptionHU { get; set; }
|
public string strDescriptionHU { get; set; }
|
||||||
public object strDescriptionNO { get; set; }
|
public string strDescriptionNO { get; set; }
|
||||||
public object strDescriptionIL { get; set; }
|
public string strDescriptionIL { get; set; }
|
||||||
public object strDescriptionPL { get; set; }
|
public string strDescriptionPL { get; set; }
|
||||||
public object intLoved { get; set; }
|
public object intLoved { get; set; }
|
||||||
public object intScore { get; set; }
|
public object intScore { get; set; }
|
||||||
public string strReview { get; set; }
|
public string strReview { get; set; }
|
||||||
|
|
|
@ -61,17 +61,16 @@ namespace MediaBrowser.Providers.Music
|
||||||
{
|
{
|
||||||
result.Item = new MusicArtist();
|
result.Item = new MusicArtist();
|
||||||
result.HasMetadata = true;
|
result.HasMetadata = true;
|
||||||
ProcessResult(result.Item, obj.artists[0]);
|
ProcessResult(result.Item, obj.artists[0], info.MetadataLanguage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessResult(MusicArtist item, Artist result)
|
private void ProcessResult(MusicArtist item, Artist result, string preferredLanguage)
|
||||||
{
|
{
|
||||||
item.HomePageUrl = result.strWebsite;
|
item.HomePageUrl = result.strWebsite;
|
||||||
item.Overview = (result.strBiographyEN ?? string.Empty).StripHtml();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(result.strGenre))
|
if (!string.IsNullOrEmpty(result.strGenre))
|
||||||
{
|
{
|
||||||
|
@ -80,6 +79,40 @@ namespace MediaBrowser.Providers.Music
|
||||||
|
|
||||||
item.SetProviderId(MetadataProviders.AudioDbArtist, result.idArtist);
|
item.SetProviderId(MetadataProviders.AudioDbArtist, result.idArtist);
|
||||||
item.SetProviderId(MetadataProviders.MusicBrainzArtist, result.strMusicBrainzID);
|
item.SetProviderId(MetadataProviders.MusicBrainzArtist, result.strMusicBrainzID);
|
||||||
|
|
||||||
|
string overview = null;
|
||||||
|
|
||||||
|
if (string.Equals(preferredLanguage, "de", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strBiographyDE;
|
||||||
|
}
|
||||||
|
else if (string.Equals(preferredLanguage, "fr", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strBiographyFR;
|
||||||
|
}
|
||||||
|
else if (string.Equals(preferredLanguage, "nl", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strBiographyNL;
|
||||||
|
}
|
||||||
|
else if (string.Equals(preferredLanguage, "ru", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strBiographyRU;
|
||||||
|
}
|
||||||
|
else if (string.Equals(preferredLanguage, "it", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strBiographyIT;
|
||||||
|
}
|
||||||
|
else if ((preferredLanguage ?? string.Empty).StartsWith("pt", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = result.strBiographyPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(overview))
|
||||||
|
{
|
||||||
|
overview = result.strBiographyEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.Overview = (overview ?? string.Empty).StripHtml();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
|
@ -180,18 +213,18 @@ namespace MediaBrowser.Providers.Music
|
||||||
public string strBiographyEN { get; set; }
|
public string strBiographyEN { get; set; }
|
||||||
public string strBiographyDE { get; set; }
|
public string strBiographyDE { get; set; }
|
||||||
public string strBiographyFR { get; set; }
|
public string strBiographyFR { get; set; }
|
||||||
public object strBiographyCN { get; set; }
|
public string strBiographyCN { get; set; }
|
||||||
public string strBiographyIT { get; set; }
|
public string strBiographyIT { get; set; }
|
||||||
public object strBiographyJP { get; set; }
|
public string strBiographyJP { get; set; }
|
||||||
public object strBiographyRU { get; set; }
|
public string strBiographyRU { get; set; }
|
||||||
public object strBiographyES { get; set; }
|
public string strBiographyES { get; set; }
|
||||||
public object strBiographyPT { get; set; }
|
public string strBiographyPT { get; set; }
|
||||||
public object strBiographySE { get; set; }
|
public string strBiographySE { get; set; }
|
||||||
public object strBiographyNL { get; set; }
|
public string strBiographyNL { get; set; }
|
||||||
public object strBiographyHU { get; set; }
|
public string strBiographyHU { get; set; }
|
||||||
public object strBiographyNO { get; set; }
|
public string strBiographyNO { get; set; }
|
||||||
public object strBiographyIL { get; set; }
|
public string strBiographyIL { get; set; }
|
||||||
public object strBiographyPL { get; set; }
|
public string strBiographyPL { get; set; }
|
||||||
public string strGender { get; set; }
|
public string strGender { get; set; }
|
||||||
public string intMembers { get; set; }
|
public string intMembers { get; set; }
|
||||||
public string strCountry { get; set; }
|
public string strCountry { get; set; }
|
||||||
|
|
|
@ -254,7 +254,7 @@ namespace MediaBrowser.Providers.Subtitles
|
||||||
_monitor.ReportFileSystemChangeComplete(path, false);
|
_monitor.ReportFileSystemChangeComplete(path, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _libraryManager.GetItemById(itemId).RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem))
|
return _libraryManager.GetItemById(itemId).RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem))
|
||||||
{
|
{
|
||||||
ImageRefreshMode = ImageRefreshMode.ValidationOnly,
|
ImageRefreshMode = ImageRefreshMode.ValidationOnly,
|
||||||
MetadataRefreshMode = MetadataRefreshMode.ValidationOnly
|
MetadataRefreshMode = MetadataRefreshMode.ValidationOnly
|
||||||
|
|
|
@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
foreach (var series in group)
|
foreach (var series in group)
|
||||||
{
|
{
|
||||||
var directoryService = new DirectoryService(_fileSystem);
|
var directoryService = new DirectoryService(_logger, _fileSystem);
|
||||||
|
|
||||||
await series.RefreshMetadata(new MetadataRefreshOptions(directoryService), cancellationToken).ConfigureAwait(false);
|
await series.RefreshMetadata(new MetadataRefreshOptions(directoryService), cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
|
@ -65,12 +65,11 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(address))
|
if (!string.IsNullOrWhiteSpace(address))
|
||||||
{
|
{
|
||||||
try
|
Uri newUri;
|
||||||
{
|
|
||||||
address = new Uri(address).Host;
|
if (Uri.TryCreate(address, UriKind.Absolute, out newUri))
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
{
|
||||||
|
address = newUri.Host;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +150,7 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||||
{
|
{
|
||||||
DiscoveredWanIpAddress = address;
|
DiscoveredWanIpAddress = address;
|
||||||
|
|
||||||
UpdateConnectInfo();
|
var task = UpdateConnectInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateConnectInfo()
|
private async Task UpdateConnectInfo()
|
||||||
|
|
|
@ -1620,7 +1620,7 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||||
{
|
{
|
||||||
size = _imageProcessor.GetImageSize(imageInfo);
|
size = _imageProcessor.GetImageSize(imageInfo);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
//_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path);
|
//_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
private readonly IInstallationManager _installationManager;
|
private readonly IInstallationManager _installationManager;
|
||||||
|
|
||||||
//private readonly ILogManager _logManager;
|
//private readonly ILogManager _logManager;
|
||||||
private readonly ILogger _logger;
|
//private readonly ILogger _logger;
|
||||||
private readonly ISessionManager _sessionManager;
|
private readonly ISessionManager _sessionManager;
|
||||||
private readonly ITaskManager _taskManager;
|
private readonly ITaskManager _taskManager;
|
||||||
private readonly IActivityManager _activityManager;
|
private readonly IActivityManager _activityManager;
|
||||||
|
|
|
@ -165,7 +165,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
|
|
||||||
CreateRules(device);
|
CreateRules(device);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
// I think it could be a good idea to log the exception because
|
// I think it could be a good idea to log the exception because
|
||||||
// you are using permanent portmapping here (never expire) and that means that next time
|
// you are using permanent portmapping here (never expire) and that means that next time
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
var changes = _changedItems.ToList();
|
var changes = _changedItems.ToList();
|
||||||
_changedItems.Clear();
|
_changedItems.Clear();
|
||||||
|
|
||||||
SendNotifications(changes, CancellationToken.None);
|
var task = SendNotifications(changes, CancellationToken.None);
|
||||||
|
|
||||||
if (UpdateTimer != null)
|
if (UpdateTimer != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -251,7 +251,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
|
|
||||||
httpRes.Close();
|
httpRes.Close();
|
||||||
}
|
}
|
||||||
catch (Exception errorEx)
|
catch
|
||||||
{
|
{
|
||||||
//_logger.ErrorException("Error this.ProcessRequest(context)(Exception while writing error to the response)", errorEx);
|
//_logger.ErrorException("Error this.ProcessRequest(context)(Exception while writing error to the response)", errorEx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
|
@ -923,14 +923,14 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
|
|
||||||
if (type == typeof(Person))
|
if (type == typeof(Person))
|
||||||
{
|
{
|
||||||
var subFolderIndex = 0;
|
foreach (char c in validFilename)
|
||||||
|
|
||||||
while (!char.IsLetterOrDigit(validFilename[subFolderIndex]))
|
|
||||||
{
|
{
|
||||||
subFolderIndex++;
|
if (char.IsLetterOrDigit(c))
|
||||||
|
{
|
||||||
|
subFolderPrefix = c.ToString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subFolderPrefix = validFilename.Substring(subFolderIndex, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullPath = string.IsNullOrEmpty(subFolderPrefix) ?
|
var fullPath = string.IsNullOrEmpty(subFolderPrefix) ?
|
||||||
|
@ -1385,6 +1385,17 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
return ItemRepository.GetMusicGenres(query);
|
return ItemRepository.GetMusicGenres(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query)
|
||||||
|
{
|
||||||
|
if (query.User != null)
|
||||||
|
{
|
||||||
|
AddUserToQuery(query, query.User);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTopParentOrAncestorIds(query);
|
||||||
|
return ItemRepository.GetAllArtists(query);
|
||||||
|
}
|
||||||
|
|
||||||
public QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query)
|
public QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query.User != null)
|
if (query.User != null)
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Library.Validators
|
namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
|
@ -43,36 +44,39 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var allSongs = _libraryManager.RootFolder
|
var items = _libraryManager.GetAllArtists(new InternalItemsQuery())
|
||||||
.GetRecursiveChildren(i => !i.IsFolder && i is IHasArtist)
|
.Items
|
||||||
.Cast<IHasArtist>()
|
.Select(i => i.Item1)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var allArtists = _libraryManager.GetArtists(allSongs).ToList();
|
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var numArtists = allArtists.Count;
|
var count = items.Count;
|
||||||
|
|
||||||
foreach (var artistItem in allArtists)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await artistItem.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error validating Artist {0}", ex, artistItem.Name);
|
// Don't clutter the log
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Error refreshing {0}", ex, item.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update progress
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
double percent = numComplete;
|
double percent = numComplete;
|
||||||
percent /= numArtists;
|
percent /= count;
|
||||||
|
percent *= 100;
|
||||||
|
|
||||||
progress.Report(100 * percent);
|
progress.Report(percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress.Report(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,21 +34,22 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var items = _libraryManager.RootFolder.GetRecursiveChildren(i => i is Game)
|
var items = _libraryManager.GetGameGenres(new InternalItemsQuery
|
||||||
.SelectMany(i => i.Genres)
|
{
|
||||||
.DistinctNames()
|
IncludeItemTypes = new[] { typeof(Game).Name }
|
||||||
|
})
|
||||||
|
.Items
|
||||||
|
.Select(i => i.Item1)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var count = items.Count;
|
var count = items.Count;
|
||||||
|
|
||||||
foreach (var name in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var itemByName = _libraryManager.GetGameGenre(name);
|
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error refreshing {0}", ex, name);
|
_logger.ErrorException("Error refreshing {0}", ex, item.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
|
|
|
@ -35,21 +35,22 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var items = _libraryManager.RootFolder.GetRecursiveChildren(i => !(i is IHasMusicGenres) && !(i is Game))
|
var items = _libraryManager.GetGenres(new InternalItemsQuery
|
||||||
.SelectMany(i => i.Genres)
|
{
|
||||||
.DistinctNames()
|
ExcludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Game).Name }
|
||||||
|
})
|
||||||
|
.Items
|
||||||
|
.Select(i => i.Item1)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var count = items.Count;
|
var count = items.Count;
|
||||||
|
|
||||||
foreach (var name in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var itemByName = _libraryManager.GetGenre(name);
|
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error refreshing {0}", ex, name);
|
_logger.ErrorException("Error refreshing {0}", ex, item.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Library.Validators
|
namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
|
@ -34,21 +35,22 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var items = _libraryManager.RootFolder.GetRecursiveChildren(i => i is IHasMusicGenres)
|
var items = _libraryManager.GetMusicGenres(new InternalItemsQuery
|
||||||
.SelectMany(i => i.Genres)
|
{
|
||||||
.DistinctNames()
|
IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(MusicVideo).Name }
|
||||||
|
})
|
||||||
|
.Items
|
||||||
|
.Select(i => i.Item1)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var count = items.Count;
|
var count = items.Count;
|
||||||
|
|
||||||
foreach (var name in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var itemByName = _libraryManager.GetMusicGenre(name);
|
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error refreshing {0}", ex, name);
|
_logger.ErrorException("Error refreshing {0}", ex, item.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
|
|
|
@ -125,7 +125,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
|
|
||||||
var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview);
|
var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview);
|
||||||
var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 90;
|
var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 90;
|
||||||
performFullRefresh = false;
|
|
||||||
|
|
||||||
var defaultMetadataRefreshMode = performFullRefresh
|
var defaultMetadataRefreshMode = performFullRefresh
|
||||||
? MetadataRefreshMode.FullRefresh
|
? MetadataRefreshMode.FullRefresh
|
||||||
|
@ -138,7 +137,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
var options = new MetadataRefreshOptions(_fileSystem)
|
var options = new MetadataRefreshOptions(_fileSystem)
|
||||||
{
|
{
|
||||||
MetadataRefreshMode = person.Value ? defaultMetadataRefreshMode : MetadataRefreshMode.ValidationOnly,
|
MetadataRefreshMode = person.Value ? defaultMetadataRefreshMode : MetadataRefreshMode.ValidationOnly,
|
||||||
ImageRefreshMode = person.Value ? imageRefreshMode : ImageRefreshMode.ValidationOnly
|
ImageRefreshMode = person.Value ? imageRefreshMode : ImageRefreshMode.ValidationOnly,
|
||||||
|
ForceSave = performFullRefresh
|
||||||
};
|
};
|
||||||
|
|
||||||
await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false);
|
await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Library.Validators
|
namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
|
@ -34,21 +34,19 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var items = _libraryManager.RootFolder.GetRecursiveChildren(i => true)
|
var items = _libraryManager.GetStudios(new InternalItemsQuery())
|
||||||
.SelectMany(i => i.Studios)
|
.Items
|
||||||
.DistinctNames()
|
.Select(i => i.Item1)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var count = items.Count;
|
var count = items.Count;
|
||||||
|
|
||||||
foreach (var name in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var itemByName = _libraryManager.GetStudio(name);
|
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error refreshing {0}", ex, name);
|
_logger.ErrorException("Error refreshing {0}", ex, item.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
|
|
|
@ -55,8 +55,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
public static EmbyTV Current;
|
public static EmbyTV Current;
|
||||||
|
|
||||||
public event EventHandler DataSourceChanged;
|
public event EventHandler DataSourceChanged { add { } remove { } }
|
||||||
public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged;
|
public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged { add { } remove { } }
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings =
|
private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings =
|
||||||
new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase);
|
new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
|
@ -191,7 +191,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
var maxBitrate = 25000000;
|
var maxBitrate = 25000000;
|
||||||
videoArgs = string.Format(
|
videoArgs = string.Format(
|
||||||
"-codec:v:0 libx264 -force_key_frames expr:gte(t,n_forced*5) {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41",
|
"-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41",
|
||||||
GetOutputSizeParam(),
|
GetOutputSizeParam(),
|
||||||
maxBitrate.ToString(CultureInfo.InvariantCulture));
|
maxBitrate.ToString(CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
catch (DirectoryNotFoundException ex)
|
catch (DirectoryNotFoundException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
|
|
|
@ -132,9 +132,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
}
|
}
|
||||||
|
|
||||||
void service_DataSourceChanged(object sender, EventArgs e)
|
void service_DataSourceChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isDisposed)
|
||||||
{
|
{
|
||||||
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
|
public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
@ -1238,7 +1241,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
var programs = new List<Guid>();
|
var programs = new List<Guid>();
|
||||||
var channels = new List<Guid>();
|
var channels = new List<Guid>();
|
||||||
|
|
||||||
var guideDays = GetGuideDays(list.Count);
|
var guideDays = GetGuideDays();
|
||||||
|
|
||||||
_logger.Info("Refreshing guide with {0} days of guide data", guideDays);
|
_logger.Info("Refreshing guide with {0} days of guide data", guideDays);
|
||||||
|
|
||||||
|
@ -1326,7 +1329,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int MaxGuideDays = 14;
|
private const int MaxGuideDays = 14;
|
||||||
private double GetGuideDays(int channelCount)
|
private double GetGuideDays()
|
||||||
{
|
{
|
||||||
var config = GetConfiguration();
|
var config = GetConfiguration();
|
||||||
|
|
||||||
|
@ -1335,13 +1338,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
return Math.Max(1, Math.Min(config.GuideDays.Value, MaxGuideDays));
|
return Math.Max(1, Math.Min(config.GuideDays.Value, MaxGuideDays));
|
||||||
}
|
}
|
||||||
|
|
||||||
var programsPerDay = channelCount * 48;
|
return 7;
|
||||||
|
|
||||||
const int maxPrograms = 24000;
|
|
||||||
|
|
||||||
var days = Math.Round((double)maxPrograms / programsPerDay);
|
|
||||||
|
|
||||||
return Math.Max(3, Math.Min(days, MaxGuideDays));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<Tuple<string, ChannelInfo>>> GetChannels(ILiveTvService service, CancellationToken cancellationToken)
|
private async Task<IEnumerable<Tuple<string, ChannelInfo>>> GetChannels(ILiveTvService service, CancellationToken cancellationToken)
|
||||||
|
@ -2309,6 +2306,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly object _disposeLock = new object();
|
private readonly object _disposeLock = new object();
|
||||||
|
private bool _isDisposed = false;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases unmanaged and - optionally - managed resources.
|
/// Releases unmanaged and - optionally - managed resources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2317,6 +2315,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
{
|
{
|
||||||
if (dispose)
|
if (dispose)
|
||||||
{
|
{
|
||||||
|
_isDisposed = true;
|
||||||
|
|
||||||
lock (_disposeLock)
|
lock (_disposeLock)
|
||||||
{
|
{
|
||||||
foreach (var stream in _openStreams.Values.ToList())
|
foreach (var stream in _openStreams.Values.ToList())
|
||||||
|
|
|
@ -431,7 +431,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
list.Add(await GetMediaSource(info, hdhrId, "mobile").ConfigureAwait(false));
|
list.Add(await GetMediaSource(info, hdhrId, "mobile").ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -649,7 +649,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp
|
||||||
|
|
||||||
#region Public Events
|
#region Public Events
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
////public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,8 @@
|
||||||
<HintPath>..\packages\SimpleInjector.3.2.0\lib\net45\SimpleInjector.dll</HintPath>
|
<HintPath>..\packages\SimpleInjector.3.2.0\lib\net45\SimpleInjector.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="SocketHttpListener, Version=1.0.6057.1168, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="SocketHttpListener, Version=1.0.6063.4624, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\SocketHttpListener.1.0.0.36\lib\net45\SocketHttpListener.dll</HintPath>
|
<HintPath>..\packages\SocketHttpListener.1.0.0.39\lib\net45\SocketHttpListener.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace MediaBrowser.Server.Implementations.Notifications
|
||||||
|
|
||||||
public event EventHandler<NotificationUpdateEventArgs> NotificationAdded;
|
public event EventHandler<NotificationUpdateEventArgs> NotificationAdded;
|
||||||
public event EventHandler<NotificationReadEventArgs> NotificationsMarkedRead;
|
public event EventHandler<NotificationReadEventArgs> NotificationsMarkedRead;
|
||||||
public event EventHandler<NotificationUpdateEventArgs> NotificationUpdated;
|
////public event EventHandler<NotificationUpdateEventArgs> NotificationUpdated;
|
||||||
|
|
||||||
public async Task Initialize()
|
public async Task Initialize()
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
private IDbCommand _updateInheritedRatingCommand;
|
private IDbCommand _updateInheritedRatingCommand;
|
||||||
private IDbCommand _updateInheritedTagsCommand;
|
private IDbCommand _updateInheritedTagsCommand;
|
||||||
|
|
||||||
public const int LatestSchemaVersion = 108;
|
public const int LatestSchemaVersion = 109;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
||||||
|
@ -915,7 +915,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.Name.RemoveDiacritics();
|
_saveItemCommand.GetParameter(index++).Value = GetCleanValue(item.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.PresentationUniqueKey;
|
_saveItemCommand.GetParameter(index++).Value = item.PresentationUniqueKey;
|
||||||
|
@ -2763,13 +2763,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
if (!string.IsNullOrWhiteSpace(query.Name))
|
if (!string.IsNullOrWhiteSpace(query.Name))
|
||||||
{
|
{
|
||||||
whereClauses.Add("CleanName=@Name");
|
whereClauses.Add("CleanName=@Name");
|
||||||
cmd.Parameters.Add(cmd, "@Name", DbType.String).Value = query.Name.RemoveDiacritics();
|
cmd.Parameters.Add(cmd, "@Name", DbType.String).Value = GetCleanValue(query.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(query.NameContains))
|
if (!string.IsNullOrWhiteSpace(query.NameContains))
|
||||||
{
|
{
|
||||||
whereClauses.Add("CleanName like @NameContains");
|
whereClauses.Add("CleanName like @NameContains");
|
||||||
cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains.RemoveDiacritics() + "%";
|
cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + GetCleanValue(query.NameContains) + "%";
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrWhiteSpace(query.NameStartsWith))
|
if (!string.IsNullOrWhiteSpace(query.NameStartsWith))
|
||||||
{
|
{
|
||||||
|
@ -2877,7 +2877,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
foreach (var artist in query.ArtistNames)
|
foreach (var artist in query.ArtistNames)
|
||||||
{
|
{
|
||||||
clauses.Add("@ArtistName" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type <= 1)");
|
clauses.Add("@ArtistName" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type <= 1)");
|
||||||
cmd.Parameters.Add(cmd, "@ArtistName" + index, DbType.String).Value = artist.RemoveDiacritics();
|
cmd.Parameters.Add(cmd, "@ArtistName" + index, DbType.String).Value = GetCleanValue(artist);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
||||||
|
@ -2894,7 +2894,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
if (artistItem != null)
|
if (artistItem != null)
|
||||||
{
|
{
|
||||||
clauses.Add("@ExcludeArtistName" + index + " not in (select CleanValue from itemvalues where ItemId=Guid and Type <= 1)");
|
clauses.Add("@ExcludeArtistName" + index + " not in (select CleanValue from itemvalues where ItemId=Guid and Type <= 1)");
|
||||||
cmd.Parameters.Add(cmd, "@ExcludeArtistName" + index, DbType.String).Value = artistItem.Name.RemoveDiacritics();
|
cmd.Parameters.Add(cmd, "@ExcludeArtistName" + index, DbType.String).Value = GetCleanValue(artistItem.Name);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2915,7 +2915,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
foreach (var item in query.Genres)
|
foreach (var item in query.Genres)
|
||||||
{
|
{
|
||||||
clauses.Add("@Genre" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=2)");
|
clauses.Add("@Genre" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=2)");
|
||||||
cmd.Parameters.Add(cmd, "@Genre" + index, DbType.String).Value = item.RemoveDiacritics();
|
cmd.Parameters.Add(cmd, "@Genre" + index, DbType.String).Value = GetCleanValue(item);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
||||||
|
@ -2929,7 +2929,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
foreach (var item in query.Tags)
|
foreach (var item in query.Tags)
|
||||||
{
|
{
|
||||||
clauses.Add("@Tag" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=4)");
|
clauses.Add("@Tag" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=4)");
|
||||||
cmd.Parameters.Add(cmd, "@Tag" + index, DbType.String).Value = item.RemoveDiacritics();
|
cmd.Parameters.Add(cmd, "@Tag" + index, DbType.String).Value = GetCleanValue(item);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
||||||
|
@ -2949,7 +2949,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
foreach (var item in query.Studios)
|
foreach (var item in query.Studios)
|
||||||
{
|
{
|
||||||
clauses.Add("@Studio" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=3)");
|
clauses.Add("@Studio" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=3)");
|
||||||
cmd.Parameters.Add(cmd, "@Studio" + index, DbType.String).Value = item.RemoveDiacritics();
|
cmd.Parameters.Add(cmd, "@Studio" + index, DbType.String).Value = GetCleanValue(item);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
||||||
|
@ -2963,7 +2963,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
foreach (var item in query.Keywords)
|
foreach (var item in query.Keywords)
|
||||||
{
|
{
|
||||||
clauses.Add("@Keyword" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=5)");
|
clauses.Add("@Keyword" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=5)");
|
||||||
cmd.Parameters.Add(cmd, "@Keyword" + index, DbType.String).Value = item.RemoveDiacritics();
|
cmd.Parameters.Add(cmd, "@Keyword" + index, DbType.String).Value = GetCleanValue(item);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
||||||
|
@ -3298,6 +3298,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
return whereClauses;
|
return whereClauses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetCleanValue(string value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.RemoveDiacritics().ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
private bool EnableGroupByPresentationUniqueKey(InternalItemsQuery query)
|
private bool EnableGroupByPresentationUniqueKey(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (!query.GroupByPresentationUniqueKey)
|
if (!query.GroupByPresentationUniqueKey)
|
||||||
|
@ -3817,37 +3827,42 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query)
|
||||||
|
{
|
||||||
|
return GetItemValues(query, new[] { 0, 1 }, typeof(MusicArtist).FullName);
|
||||||
|
}
|
||||||
|
|
||||||
public QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query)
|
public QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
return GetItemValues(query, 0, typeof(MusicArtist).FullName);
|
return GetItemValues(query, new[] { 0 }, typeof(MusicArtist).FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query)
|
public QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
return GetItemValues(query, 1, typeof(MusicArtist).FullName);
|
return GetItemValues(query, new[] { 1 }, typeof(MusicArtist).FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query)
|
public QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
return GetItemValues(query, 3, typeof(Studio).FullName);
|
return GetItemValues(query, new[] { 3 }, typeof(Studio).FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query)
|
public QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
return GetItemValues(query, 2, typeof(Genre).FullName);
|
return GetItemValues(query, new[] { 2 }, typeof(Genre).FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryResult<Tuple<BaseItem, ItemCounts>> GetGameGenres(InternalItemsQuery query)
|
public QueryResult<Tuple<BaseItem, ItemCounts>> GetGameGenres(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
return GetItemValues(query, 2, typeof(GameGenre).FullName);
|
return GetItemValues(query, new[] { 2 }, typeof(GameGenre).FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query)
|
public QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
return GetItemValues(query, 2, typeof(MusicGenre).FullName);
|
return GetItemValues(query, new[] { 2 }, typeof(MusicGenre).FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryResult<Tuple<BaseItem, ItemCounts>> GetItemValues(InternalItemsQuery query, int itemValueType, string returnType)
|
private QueryResult<Tuple<BaseItem, ItemCounts>> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType)
|
||||||
{
|
{
|
||||||
if (query == null)
|
if (query == null)
|
||||||
{
|
{
|
||||||
|
@ -3863,6 +3878,10 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
|
var typeClause = itemValueTypes.Length == 1 ?
|
||||||
|
("Type=" + itemValueTypes[0].ToString(CultureInfo.InvariantCulture)) :
|
||||||
|
("Type in (" + string.Join(",", itemValueTypes.Select(i => i.ToString(CultureInfo.InvariantCulture)).ToArray()) + ")");
|
||||||
|
|
||||||
using (var cmd = _connection.CreateCommand())
|
using (var cmd = _connection.CreateCommand())
|
||||||
{
|
{
|
||||||
var itemCountColumns = new List<Tuple<string, string>>();
|
var itemCountColumns = new List<Tuple<string, string>>();
|
||||||
|
@ -3887,7 +3906,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
};
|
};
|
||||||
var whereClauses = GetWhereClauses(typeSubQuery, cmd, "itemTypes");
|
var whereClauses = GetWhereClauses(typeSubQuery, cmd, "itemTypes");
|
||||||
|
|
||||||
whereClauses.Add("guid in (select ItemId from ItemValues where ItemValues.CleanValue=A.CleanName AND Type=@ItemValueType)");
|
whereClauses.Add("guid in (select ItemId from ItemValues where ItemValues.CleanValue=A.CleanName AND " + typeClause + ")");
|
||||||
|
|
||||||
var typeWhereText = whereClauses.Count == 0 ?
|
var typeWhereText = whereClauses.Count == 0 ?
|
||||||
string.Empty :
|
string.Empty :
|
||||||
|
@ -3929,12 +3948,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
|
|
||||||
if (typesToCount.Count == 0)
|
if (typesToCount.Count == 0)
|
||||||
{
|
{
|
||||||
whereText += " And CleanName In (Select CleanValue from ItemValues where Type=@ItemValueType AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))";
|
whereText += " And CleanName In (Select CleanValue from ItemValues where " + typeClause + " AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//whereText += " And itemTypes not null";
|
//whereText += " And itemTypes not null";
|
||||||
whereText += " And CleanName In (Select CleanValue from ItemValues where Type=@ItemValueType AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))";
|
whereText += " And CleanName In (Select CleanValue from ItemValues where " + typeClause + " AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))";
|
||||||
}
|
}
|
||||||
|
|
||||||
var outerQuery = new InternalItemsQuery(query.User)
|
var outerQuery = new InternalItemsQuery(query.User)
|
||||||
|
@ -3964,7 +3983,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
cmd.CommandText += " group by PresentationUniqueKey";
|
cmd.CommandText += " group by PresentationUniqueKey";
|
||||||
|
|
||||||
cmd.Parameters.Add(cmd, "@SelectType", DbType.String).Value = returnType;
|
cmd.Parameters.Add(cmd, "@SelectType", DbType.String).Value = returnType;
|
||||||
cmd.Parameters.Add(cmd, "@ItemValueType", DbType.Int32).Value = itemValueType;
|
|
||||||
|
|
||||||
if (EnableJoinUserData(query))
|
if (EnableJoinUserData(query))
|
||||||
{
|
{
|
||||||
|
@ -4016,7 +4034,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
? (CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)
|
? (CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)
|
||||||
: CommandBehavior.SequentialAccess;
|
: CommandBehavior.SequentialAccess;
|
||||||
|
|
||||||
//Logger.Debug("GetItemValues: " + cmd.CommandText);
|
Logger.Debug("GetItemValues: " + cmd.CommandText);
|
||||||
|
|
||||||
using (var reader = cmd.ExecuteReader(commandBehavior))
|
using (var reader = cmd.ExecuteReader(commandBehavior))
|
||||||
{
|
{
|
||||||
|
@ -4260,7 +4278,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_saveItemValuesCommand.GetParameter(3).Value = pair.Item2.RemoveDiacritics();
|
_saveItemValuesCommand.GetParameter(3).Value = GetCleanValue(pair.Item2);
|
||||||
}
|
}
|
||||||
_saveItemValuesCommand.Transaction = transaction;
|
_saveItemValuesCommand.Transaction = transaction;
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,5 @@
|
||||||
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||||
<package id="SimpleInjector" version="3.2.0" targetFramework="net45" />
|
<package id="SimpleInjector" version="3.2.0" targetFramework="net45" />
|
||||||
<package id="SocketHttpListener" version="1.0.0.36" targetFramework="net45" />
|
<package id="SocketHttpListener" version="1.0.0.39" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -606,7 +606,7 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
{
|
{
|
||||||
return new ImageMagickEncoder(LogManager.GetLogger("ImageMagick"), ApplicationPaths, HttpClient, FileSystemManager, ServerConfigurationManager);
|
return new ImageMagickEncoder(LogManager.GetLogger("ImageMagick"), ApplicationPaths, HttpClient, FileSystemManager, ServerConfigurationManager);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
Logger.Error("Error loading ImageMagick. Will revert to GDI.");
|
Logger.Error("Error loading ImageMagick. Will revert to GDI.");
|
||||||
}
|
}
|
||||||
|
@ -616,7 +616,7 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
{
|
{
|
||||||
return new GDIImageEncoder(FileSystemManager, LogManager.GetLogger("GDI"));
|
return new GDIImageEncoder(FileSystemManager, LogManager.GetLogger("GDI"));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
Logger.Error("Error loading GDI. Will revert to NullImageEncoder.");
|
Logger.Error("Error loading GDI. Will revert to NullImageEncoder.");
|
||||||
}
|
}
|
||||||
|
@ -1412,7 +1412,7 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
{
|
{
|
||||||
return new Uri(externalDns).Host;
|
return new Uri(externalDns).Host;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch
|
||||||
{
|
{
|
||||||
return externalDns;
|
return externalDns;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace MediaBrowser.Tests.ConsistencyTests
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of file extension to search.
|
/// List of file extension to search.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string[] TargetExtensions = new[] { "js", "html" };
|
public static string[] TargetExtensions = new[] { ".js", ".html" };
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of paths to exclude from search.
|
/// List of paths to exclude from search.
|
||||||
|
@ -96,11 +96,11 @@ namespace MediaBrowser.Tests.ConsistencyTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
//[TestMethod]
|
||||||
public void ReportStringUsage()
|
//public void ReportStringUsage()
|
||||||
{
|
//{
|
||||||
this.CheckDashboardStrings(false);
|
// this.CheckDashboardStrings(false);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void ReportUnusedStrings()
|
public void ReportUnusedStrings()
|
||||||
|
@ -135,7 +135,7 @@ namespace MediaBrowser.Tests.ConsistencyTests
|
||||||
|
|
||||||
var allFiles = rootFolderInfo.GetFiles("*", SearchOption.AllDirectories);
|
var allFiles = rootFolderInfo.GetFiles("*", SearchOption.AllDirectories);
|
||||||
|
|
||||||
var filteredFiles1 = allFiles.Where(f => TargetExtensions.Any(e => f.Name.EndsWith(e)));
|
var filteredFiles1 = allFiles.Where(f => TargetExtensions.Any(e => string.Equals(e, f.Extension, StringComparison.OrdinalIgnoreCase)));
|
||||||
var filteredFiles2 = filteredFiles1.Where(f => !ExcludePaths.Any(p => f.FullName.Contains(p)));
|
var filteredFiles2 = filteredFiles1.Where(f => !ExcludePaths.Any(p => f.FullName.Contains(p)));
|
||||||
|
|
||||||
var selectedFiles = filteredFiles2.OrderBy(f => f.FullName).ToList();
|
var selectedFiles = filteredFiles2.OrderBy(f => f.FullName).ToList();
|
||||||
|
|
|
@ -13,6 +13,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||||
Performance3.psess = Performance3.psess
|
Performance3.psess = Performance3.psess
|
||||||
Performance4.psess = Performance4.psess
|
Performance4.psess = Performance4.psess
|
||||||
Performance5.psess = Performance5.psess
|
Performance5.psess = Performance5.psess
|
||||||
|
Performance6.psess = Performance6.psess
|
||||||
|
Performance7.psess = Performance7.psess
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget (2)", ".nuget (2)", "{E60FB157-87E2-4A41-8B04-27EA49B63B4D}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget (2)", ".nuget (2)", "{E60FB157-87E2-4A41-8B04-27EA49B63B4D}"
|
||||||
|
@ -63,6 +65,9 @@ EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
|
GlobalSection(Performance) = preSolution
|
||||||
|
HasPerformanceSessions = true
|
||||||
|
EndGlobalSection
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
//[assembly: AssemblyVersion("3.1.*")]
|
//[assembly: AssemblyVersion("3.1.*")]
|
||||||
[assembly: AssemblyVersion("3.0.6030")]
|
[assembly: AssemblyVersion("3.1.95")]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user