commit
026e58eb16
|
@ -10,11 +10,17 @@ namespace Emby.Common.Implementations.EnvironmentInfo
|
||||||
public class EnvironmentInfo : IEnvironmentInfo
|
public class EnvironmentInfo : IEnvironmentInfo
|
||||||
{
|
{
|
||||||
public MediaBrowser.Model.System.Architecture? CustomArchitecture { get; set; }
|
public MediaBrowser.Model.System.Architecture? CustomArchitecture { get; set; }
|
||||||
|
public MediaBrowser.Model.System.OperatingSystem? CustomOperatingSystem { get; set; }
|
||||||
|
|
||||||
public MediaBrowser.Model.System.OperatingSystem OperatingSystem
|
public MediaBrowser.Model.System.OperatingSystem OperatingSystem
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
if (CustomOperatingSystem.HasValue)
|
||||||
|
{
|
||||||
|
return CustomOperatingSystem.Value;
|
||||||
|
}
|
||||||
|
|
||||||
#if NET46
|
#if NET46
|
||||||
switch (Environment.OSVersion.Platform)
|
switch (Environment.OSVersion.Platform)
|
||||||
{
|
{
|
||||||
|
|
|
@ -282,9 +282,12 @@ namespace Emby.Common.Implementations.ScheduledTasks
|
||||||
throw new ArgumentNullException("value");
|
throw new ArgumentNullException("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveTriggers(value);
|
// This null check is not great, but is needed to handle bad user input, or user mucking with the config file incorrectly
|
||||||
|
var triggerList = value.Where(i => i != null).ToArray();
|
||||||
|
|
||||||
InternalTriggers = value.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
|
SaveTriggers(triggerList);
|
||||||
|
|
||||||
|
InternalTriggers = triggerList.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +538,8 @@ namespace Emby.Common.Implementations.ScheduledTasks
|
||||||
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
|
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
|
||||||
private Tuple<TaskTriggerInfo, ITaskTrigger>[] LoadTriggers()
|
private Tuple<TaskTriggerInfo, ITaskTrigger>[] LoadTriggers()
|
||||||
{
|
{
|
||||||
var settings = LoadTriggerSettings();
|
// This null check is not great, but is needed to handle bad user input, or user mucking with the config file incorrectly
|
||||||
|
var settings = LoadTriggerSettings().Where(i => i != null).ToArray();
|
||||||
|
|
||||||
return settings.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
|
return settings.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
|
||||||
}
|
}
|
||||||
|
@ -544,8 +548,12 @@ namespace Emby.Common.Implementations.ScheduledTasks
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath())
|
var list = JsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath());
|
||||||
.ToArray();
|
|
||||||
|
if (list != null)
|
||||||
|
{
|
||||||
|
return list.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -555,8 +563,8 @@ namespace Emby.Common.Implementations.ScheduledTasks
|
||||||
catch (DirectoryNotFoundException)
|
catch (DirectoryNotFoundException)
|
||||||
{
|
{
|
||||||
// File doesn't exist. No biggie. Return defaults.
|
// File doesn't exist. No biggie. Return defaults.
|
||||||
return ScheduledTask.GetDefaultTriggers().ToArray();
|
|
||||||
}
|
}
|
||||||
|
return ScheduledTask.GetDefaultTriggers().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1583,7 +1583,8 @@ namespace Emby.Server.Core
|
||||||
|
|
||||||
public void LaunchUrl(string url)
|
public void LaunchUrl(string url)
|
||||||
{
|
{
|
||||||
if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows)
|
if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows &&
|
||||||
|
EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -1591,7 +1592,7 @@ namespace Emby.Server.Core
|
||||||
var process = ProcessFactory.Create(new ProcessOptions
|
var process = ProcessFactory.Create(new ProcessOptions
|
||||||
{
|
{
|
||||||
FileName = url,
|
FileName = url,
|
||||||
EnableRaisingEvents = true,
|
//EnableRaisingEvents = true,
|
||||||
UseShellExecute = true,
|
UseShellExecute = true,
|
||||||
ErrorDialog = false
|
ErrorDialog = false
|
||||||
});
|
});
|
||||||
|
|
|
@ -203,20 +203,12 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
// Do not use the memoryStreamFactory here, they don't place nice with compression
|
// Do not use the memoryStreamFactory here, they don't place nice with compression
|
||||||
using (var ms = new MemoryStream())
|
using (var ms = new MemoryStream())
|
||||||
{
|
{
|
||||||
using (var compressionStream = GetCompressionStream(ms, compressionType))
|
ContentTypes.Instance.SerializeToStream(request, dto, ms);
|
||||||
{
|
ms.Position = 0;
|
||||||
ContentTypes.Instance.SerializeToStream(request, dto, compressionStream);
|
|
||||||
compressionStream.Dispose();
|
|
||||||
|
|
||||||
var compressedBytes = ms.ToArray();
|
var responseHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
var httpResult = new StreamWriter(compressedBytes, request.ResponseContentType, _logger);
|
return GetCompressedResult(ms, compressionType, responseHeaders, false, request.ResponseContentType).Result;
|
||||||
|
|
||||||
//httpResult.Headers["Content-Length"] = compressedBytes.Length.ToString(UsCulture);
|
|
||||||
httpResult.Headers["Content-Encoding"] = compressionType;
|
|
||||||
|
|
||||||
return httpResult;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,45 +583,53 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
string content;
|
|
||||||
|
|
||||||
using (var stream = await factoryFn().ConfigureAwait(false))
|
using (var stream = await factoryFn().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
using (var reader = new StreamReader(stream))
|
return await GetCompressedResult(stream, requestedCompressionType, responseHeaders, isHeadRequest, contentType).ConfigureAwait(false);
|
||||||
{
|
|
||||||
content = await reader.ReadToEndAsync().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var contents = Compress(content, requestedCompressionType);
|
|
||||||
|
|
||||||
responseHeaders["Content-Length"] = contents.Length.ToString(UsCulture);
|
|
||||||
responseHeaders["Content-Encoding"] = requestedCompressionType;
|
|
||||||
|
|
||||||
if (isHeadRequest)
|
|
||||||
{
|
|
||||||
return GetHttpResult(new byte[] { }, contentType, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetHttpResult(contents, contentType, true, responseHeaders);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] Compress(string text, string compressionType)
|
private async Task<IHasHeaders> GetCompressedResult(Stream stream,
|
||||||
|
string requestedCompressionType,
|
||||||
|
IDictionary<string,string> responseHeaders,
|
||||||
|
bool isHeadRequest,
|
||||||
|
string contentType)
|
||||||
|
{
|
||||||
|
using (var reader = new MemoryStream())
|
||||||
|
{
|
||||||
|
await stream.CopyToAsync(reader).ConfigureAwait(false);
|
||||||
|
|
||||||
|
reader.Position = 0;
|
||||||
|
var content = reader.ToArray();
|
||||||
|
|
||||||
|
if (content.Length >= 1024)
|
||||||
|
{
|
||||||
|
content = Compress(content, requestedCompressionType);
|
||||||
|
responseHeaders["Content-Encoding"] = requestedCompressionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
responseHeaders["Content-Length"] = content.Length.ToString(UsCulture);
|
||||||
|
|
||||||
|
if (isHeadRequest)
|
||||||
|
{
|
||||||
|
return GetHttpResult(new byte[] { }, contentType, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetHttpResult(content, contentType, true, responseHeaders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] Compress(byte[] bytes, string compressionType)
|
||||||
{
|
{
|
||||||
if (compressionType == "deflate")
|
if (compressionType == "deflate")
|
||||||
return Deflate(text);
|
return Deflate(bytes);
|
||||||
|
|
||||||
if (compressionType == "gzip")
|
if (compressionType == "gzip")
|
||||||
return GZip(text);
|
return GZip(bytes);
|
||||||
|
|
||||||
throw new NotSupportedException(compressionType);
|
throw new NotSupportedException(compressionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] Deflate(string text)
|
|
||||||
{
|
|
||||||
return Deflate(Encoding.UTF8.GetBytes(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] Deflate(byte[] bytes)
|
private byte[] Deflate(byte[] bytes)
|
||||||
{
|
{
|
||||||
// In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream
|
// In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream
|
||||||
|
@ -644,11 +644,6 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] GZip(string text)
|
|
||||||
{
|
|
||||||
return GZip(Encoding.UTF8.GetBytes(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] GZip(byte[] buffer)
|
private byte[] GZip(byte[] buffer)
|
||||||
{
|
{
|
||||||
using (var ms = new MemoryStream())
|
using (var ms = new MemoryStream())
|
||||||
|
|
|
@ -74,21 +74,21 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
|
|
||||||
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return ResolveVideos<MusicVideo>(parent, files, directoryService, false);
|
return ResolveVideos<MusicVideo>(parent, files, directoryService, false, collectionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) ||
|
if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) ||
|
||||||
string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
|
string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return ResolveVideos<Video>(parent, files, directoryService, false);
|
return ResolveVideos<Video>(parent, files, directoryService, false, collectionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(collectionType))
|
if (string.IsNullOrWhiteSpace(collectionType))
|
||||||
{
|
{
|
||||||
// Owned items should just use the plain video type
|
// Owned items should just use the plain video type
|
||||||
if (parent == null)
|
if (parent == null)
|
||||||
{
|
{
|
||||||
return ResolveVideos<Video>(parent, files, directoryService, false);
|
return ResolveVideos<Video>(parent, files, directoryService, false, collectionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent is Series || parent.GetParents().OfType<Series>().Any())
|
if (parent is Series || parent.GetParents().OfType<Series>().Any())
|
||||||
|
@ -96,18 +96,18 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResolveVideos<Movie>(parent, files, directoryService, false);
|
return ResolveVideos<Movie>(parent, files, directoryService, false, collectionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return ResolveVideos<Movie>(parent, files, directoryService, true);
|
return ResolveVideos<Movie>(parent, files, directoryService, true, collectionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MultiItemResolverResult ResolveVideos<T>(Folder parent, IEnumerable<FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, bool suppportMultiEditions)
|
private MultiItemResolverResult ResolveVideos<T>(Folder parent, IEnumerable<FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, bool suppportMultiEditions, string collectionType)
|
||||||
where T : Video, new()
|
where T : Video, new()
|
||||||
{
|
{
|
||||||
var files = new List<FileSystemMetadata>();
|
var files = new List<FileSystemMetadata>();
|
||||||
|
@ -117,6 +117,16 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
// Loop through each child file/folder and see if we find a video
|
// Loop through each child file/folder and see if we find a video
|
||||||
foreach (var child in fileSystemEntries)
|
foreach (var child in fileSystemEntries)
|
||||||
{
|
{
|
||||||
|
// This is a hack but currently no better way to resolve a sometimes ambiguous situation
|
||||||
|
if (string.IsNullOrWhiteSpace(collectionType))
|
||||||
|
{
|
||||||
|
if (string.Equals(child.Name, "tvshow.nfo", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(child.Name, "season.nfo", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (child.IsDirectory)
|
if (child.IsDirectory)
|
||||||
{
|
{
|
||||||
leftOver.Add(child);
|
leftOver.Add(child);
|
||||||
|
@ -408,7 +418,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
!string.Equals(collectionType, CollectionType.Photos) &&
|
!string.Equals(collectionType, CollectionType.Photos) &&
|
||||||
!string.Equals(collectionType, CollectionType.MusicVideos);
|
!string.Equals(collectionType, CollectionType.MusicVideos);
|
||||||
|
|
||||||
var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, supportsMultiVersion);
|
var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, supportsMultiVersion, collectionType) ??
|
||||||
|
new MultiItemResolverResult();
|
||||||
|
|
||||||
if (result.Items.Count == 1)
|
if (result.Items.Count == 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -422,7 +422,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
}
|
}
|
||||||
|
|
||||||
var showType = details.showType ?? string.Empty;
|
var showType = details.showType ?? string.Empty;
|
||||||
|
|
||||||
var info = new ProgramInfo
|
var info = new ProgramInfo
|
||||||
{
|
{
|
||||||
ChannelId = channel,
|
ChannelId = channel,
|
||||||
|
@ -440,10 +440,23 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
IsKids = string.Equals(details.audience, "children", StringComparison.OrdinalIgnoreCase),
|
IsKids = string.Equals(details.audience, "children", StringComparison.OrdinalIgnoreCase),
|
||||||
IsSports = showType.IndexOf("sports", StringComparison.OrdinalIgnoreCase) != -1,
|
IsSports = showType.IndexOf("sports", StringComparison.OrdinalIgnoreCase) != -1,
|
||||||
IsMovie = showType.IndexOf("movie", StringComparison.OrdinalIgnoreCase) != -1 || showType.IndexOf("film", StringComparison.OrdinalIgnoreCase) != -1,
|
IsMovie = showType.IndexOf("movie", StringComparison.OrdinalIgnoreCase) != -1 || showType.IndexOf("film", StringComparison.OrdinalIgnoreCase) != -1,
|
||||||
ShowId = programInfo.programID,
|
|
||||||
Etag = programInfo.md5
|
Etag = programInfo.md5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var showId = programInfo.programID ?? string.Empty;
|
||||||
|
|
||||||
|
// According to SchedulesDirect, these are generic, unidentified episodes
|
||||||
|
// SH005316560000
|
||||||
|
var hasUniqueShowId = !showId.StartsWith("SH", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
!showId.EndsWith("0000", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
if (!hasUniqueShowId)
|
||||||
|
{
|
||||||
|
showId = newID;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.ShowId = showId;
|
||||||
|
|
||||||
if (programInfo.videoProperties != null)
|
if (programInfo.videoProperties != null)
|
||||||
{
|
{
|
||||||
info.IsHD = programInfo.videoProperties.Contains("hdtv", StringComparer.OrdinalIgnoreCase);
|
info.IsHD = programInfo.videoProperties.Contains("hdtv", StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
|
@ -2647,7 +2647,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
public GuideInfo GetGuideInfo()
|
public GuideInfo GetGuideInfo()
|
||||||
{
|
{
|
||||||
var startDate = DateTime.UtcNow;
|
var startDate = DateTime.UtcNow;
|
||||||
var endDate = startDate.AddDays(14);
|
var endDate = startDate.AddDays(GetGuideDays());
|
||||||
|
|
||||||
return new GuideInfo
|
return new GuideInfo
|
||||||
{
|
{
|
||||||
|
|
|
@ -1042,10 +1042,7 @@ namespace Emby.Server.Implementations.Sync
|
||||||
throw new ArgumentException("Operation is not valid for this job item");
|
throw new ArgumentException("Operation is not valid for this job item");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jobItem.Status != SyncJobItemStatus.Synced)
|
jobItem.Status = SyncJobItemStatus.Cancelled;
|
||||||
{
|
|
||||||
jobItem.Status = SyncJobItemStatus.Cancelled;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobItem.Progress = 0;
|
jobItem.Progress = 0;
|
||||||
jobItem.IsMarkedForRemoval = true;
|
jobItem.IsMarkedForRemoval = true;
|
||||||
|
@ -1071,18 +1068,18 @@ namespace Emby.Server.Implementations.Sync
|
||||||
_logger.ErrorException("Error deleting directory {0}", ex, path);
|
_logger.ErrorException("Error deleting directory {0}", ex, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
//var jobItemsResult = GetJobItems(new SyncJobItemQuery
|
var jobItemsResult = GetJobItems(new SyncJobItemQuery
|
||||||
//{
|
{
|
||||||
// AddMetadata = false,
|
AddMetadata = false,
|
||||||
// JobId = jobItem.JobId,
|
JobId = jobItem.JobId,
|
||||||
// Limit = 0,
|
Limit = 0,
|
||||||
// Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Failed, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring }
|
Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring }
|
||||||
//});
|
});
|
||||||
|
|
||||||
//if (jobItemsResult.TotalRecordCount == 0)
|
if (jobItemsResult.TotalRecordCount == 0)
|
||||||
//{
|
{
|
||||||
// await CancelJob(jobItem.JobId).ConfigureAwait(false);
|
await CancelJob(jobItem.JobId).ConfigureAwait(false);
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task MarkJobItemForRemoval(string id)
|
public Task MarkJobItemForRemoval(string id)
|
||||||
|
|
|
@ -38,6 +38,18 @@ namespace Emby.Server.Implementations.Sync
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.Status == SyncJobItemStatus.Cancelled)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _sessionManager.SendMessageToUserDeviceSessions(item.TargetId, "SyncJobItemCancelled", item, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
@ -153,7 +153,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
|
|
||||||
if (!state.RunTimeTicks.HasValue)
|
if (!state.RunTimeTicks.HasValue)
|
||||||
{
|
{
|
||||||
args += " -fflags +genpts -flags +global_header";
|
args += " -flags -global_header -fflags +genpts";
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
|
|
|
@ -95,6 +95,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
int defaultImageExtractionTimeoutMs,
|
int defaultImageExtractionTimeoutMs,
|
||||||
bool enableEncoderFontFile, IEnvironmentInfo environmentInfo)
|
bool enableEncoderFontFile, IEnvironmentInfo environmentInfo)
|
||||||
{
|
{
|
||||||
|
if (jsonSerializer == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("jsonSerializer");
|
||||||
|
}
|
||||||
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_jsonSerializer = jsonSerializer;
|
_jsonSerializer = jsonSerializer;
|
||||||
ConfigurationManager = configurationManager;
|
ConfigurationManager = configurationManager;
|
||||||
|
@ -632,7 +637,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
|
var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
|
||||||
|
|
||||||
if (result.streams == null && result.format == null)
|
if (result == null || (result.streams == null && result.format == null))
|
||||||
{
|
{
|
||||||
throw new Exception("ffprobe failed - streams and format are both null.");
|
throw new Exception("ffprobe failed - streams and format are both null.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,7 +238,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
var targetSeries = DetermineAppropriateSeries(series, tuple.Item1);
|
var targetSeries = DetermineAppropriateSeries(series, tuple.Item1);
|
||||||
var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(targetSeries.ProviderIds) ?? ((targetSeries.AnimeSeriesIndex ?? 1) - 1);
|
var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(targetSeries.ProviderIds) ?? ((targetSeries.AnimeSeriesIndex ?? 1) - 1);
|
||||||
|
|
||||||
var unairedThresholdDays = 1;
|
var unairedThresholdDays = 2;
|
||||||
now = now.AddDays(0 - unairedThresholdDays);
|
now = now.AddDays(0 - unairedThresholdDays);
|
||||||
|
|
||||||
if (airDate.Value < now)
|
if (airDate.Value < now)
|
||||||
|
|
|
@ -142,7 +142,10 @@ namespace MediaBrowser.Server.Mac
|
||||||
|
|
||||||
private static EnvironmentInfo GetEnvironmentInfo()
|
private static EnvironmentInfo GetEnvironmentInfo()
|
||||||
{
|
{
|
||||||
var info = new EnvironmentInfo();
|
var info = new EnvironmentInfo()
|
||||||
|
{
|
||||||
|
CustomOperatingSystem = MediaBrowser.Model.System.OperatingSystem.OSX
|
||||||
|
};
|
||||||
|
|
||||||
var uname = GetUnixName();
|
var uname = GetUnixName();
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,11 @@ namespace MediaBrowser.Server.Mono
|
||||||
}
|
}
|
||||||
else if (environment.OperatingSystem == Model.System.OperatingSystem.Linux)
|
else if (environment.OperatingSystem == Model.System.OperatingSystem.Linux)
|
||||||
{
|
{
|
||||||
|
info.FFMpegFilename = "ffmpeg";
|
||||||
|
info.FFProbeFilename = "ffprobe";
|
||||||
info.ArchiveType = "7z";
|
info.ArchiveType = "7z";
|
||||||
info.Version = "20160215";
|
info.Version = "20160215";
|
||||||
|
info.DownloadUrls = GetDownloadUrls();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No version available - user requirement
|
// No version available - user requirement
|
||||||
|
@ -61,6 +64,25 @@ namespace MediaBrowser.Server.Mono
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string[] GetDownloadUrls()
|
||||||
|
{
|
||||||
|
switch (EnvironmentInfo.SystemArchitecture)
|
||||||
|
{
|
||||||
|
case Architecture.X64:
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
"https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-git-20160215-64bit-static.7z"
|
||||||
|
};
|
||||||
|
case Architecture.X86:
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
"https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-git-20160215-32bit-static.7z"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return new string[] { };
|
||||||
|
}
|
||||||
|
|
||||||
protected override void RestartInternal()
|
protected override void RestartInternal()
|
||||||
{
|
{
|
||||||
MainClass.Restart(StartupOptions);
|
MainClass.Restart(StartupOptions);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
@ -52,7 +53,7 @@ namespace MediaBrowser.ServerApplication.Native
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The STG m_ READ
|
/// The STG m_ READ
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint STGM_READ = 0;
|
public const int STGM_READ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -319,72 +320,6 @@ namespace MediaBrowser.ServerApplication.Native
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Interface IPersist
|
|
||||||
/// </summary>
|
|
||||||
[ComImport, Guid("0000010c-0000-0000-c000-000000000046"),
|
|
||||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
||||||
public interface IPersist
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the class ID.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pClassID">The p class ID.</param>
|
|
||||||
[PreserveSig]
|
|
||||||
void GetClassID(out Guid pClassID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Interface IPersistFile
|
|
||||||
/// </summary>
|
|
||||||
[ComImport, Guid("0000010b-0000-0000-C000-000000000046"),
|
|
||||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
||||||
public interface IPersistFile : IPersist
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the class ID.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pClassID">The p class ID.</param>
|
|
||||||
new void GetClassID(out Guid pClassID);
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether this instance is dirty.
|
|
||||||
/// </summary>
|
|
||||||
[PreserveSig]
|
|
||||||
int IsDirty();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Loads the specified PSZ file name.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pszFileName">Name of the PSZ file.</param>
|
|
||||||
/// <param name="dwMode">The dw mode.</param>
|
|
||||||
[PreserveSig]
|
|
||||||
void Load([In, MarshalAs(UnmanagedType.LPWStr)]
|
|
||||||
string pszFileName, uint dwMode);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the specified PSZ file name.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pszFileName">Name of the PSZ file.</param>
|
|
||||||
/// <param name="remember">if set to <c>true</c> [remember].</param>
|
|
||||||
[PreserveSig]
|
|
||||||
void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
|
|
||||||
[In, MarshalAs(UnmanagedType.Bool)] bool remember);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the completed.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pszFileName">Name of the PSZ file.</param>
|
|
||||||
[PreserveSig]
|
|
||||||
void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the cur file.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ppszFileName">Name of the PPSZ file.</param>
|
|
||||||
[PreserveSig]
|
|
||||||
void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// CLSID_ShellLink from ShlGuid.h
|
// CLSID_ShellLink from ShlGuid.h
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class ShellLink
|
/// Class ShellLink
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
using Emby.Server.Core;
|
using Emby.Server.Core;
|
||||||
using Emby.Server.Implementations;
|
using Emby.Server.Implementations;
|
||||||
using Emby.Server.Implementations.EntryPoints;
|
using Emby.Server.Implementations.EntryPoints;
|
||||||
|
@ -93,21 +94,30 @@ namespace MediaBrowser.ServerApplication
|
||||||
|
|
||||||
protected override void ConfigureAutoRunInternal(bool autorun)
|
protected override void ConfigureAutoRunInternal(bool autorun)
|
||||||
{
|
{
|
||||||
var shortcutPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.StartMenu), "Emby", "Emby Server.lnk");
|
|
||||||
|
|
||||||
var startupPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Startup);
|
var startupPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Startup);
|
||||||
|
|
||||||
if (autorun)
|
if (autorun && !MainStartup.IsRunningAsService)
|
||||||
{
|
{
|
||||||
//Copy our shortut into the startup folder for this user
|
//Copy our shortut into the startup folder for this user
|
||||||
var targetPath = Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk");
|
var targetPath = Path.Combine(startupPath, "Emby Server.lnk");
|
||||||
FileSystemManager.CreateDirectory(Path.GetDirectoryName(targetPath));
|
|
||||||
File.Copy(shortcutPath, targetPath, true);
|
IShellLinkW link = (IShellLinkW)new ShellLink();
|
||||||
|
|
||||||
|
var appPath = Process.GetCurrentProcess().MainModule.FileName;
|
||||||
|
|
||||||
|
// setup shortcut information
|
||||||
|
link.SetDescription(Name);
|
||||||
|
link.SetPath(appPath);
|
||||||
|
link.SetWorkingDirectory(Path.GetDirectoryName(appPath));
|
||||||
|
|
||||||
|
// save it
|
||||||
|
IPersistFile file = (IPersistFile)link;
|
||||||
|
file.Save(targetPath, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Remove our shortcut from the startup folder for this user
|
//Remove our shortcut from the startup folder for this user
|
||||||
FileSystemManager.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk"));
|
FileSystemManager.DeleteFile(Path.Combine(startupPath, "Emby Server.lnk"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ namespace SocketHttpListener.Net
|
||||||
// TODO: can we get this stream before reading the input?
|
// TODO: can we get this stream before reading the input?
|
||||||
if (o_stream == null)
|
if (o_stream == null)
|
||||||
{
|
{
|
||||||
context.Response.DetermineIfChunked();
|
//context.Response.DetermineIfChunked();
|
||||||
|
|
||||||
if (context.Response.SendChunked || isExpect100Continue || context.Request.IsWebSocketRequest || true)
|
if (context.Response.SendChunked || isExpect100Continue || context.Request.IsWebSocketRequest || true)
|
||||||
{
|
{
|
||||||
|
@ -508,7 +508,7 @@ namespace SocketHttpListener.Net
|
||||||
{
|
{
|
||||||
force_close |= !context.Request.KeepAlive;
|
force_close |= !context.Request.KeepAlive;
|
||||||
if (!force_close)
|
if (!force_close)
|
||||||
force_close = (context.Response.Headers["connection"] == "close");
|
force_close = (string.Equals(context.Response.Headers["connection"], "close", StringComparison.OrdinalIgnoreCase));
|
||||||
/*
|
/*
|
||||||
if (!force_close) {
|
if (!force_close) {
|
||||||
// bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 ||
|
// bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 ||
|
||||||
|
|
|
@ -386,7 +386,7 @@ namespace SocketHttpListener.Net
|
||||||
|
|
||||||
if (content_type != null)
|
if (content_type != null)
|
||||||
{
|
{
|
||||||
if (content_encoding != null && content_type.IndexOf("charset=", StringComparison.Ordinal) == -1)
|
if (content_encoding != null && content_type.IndexOf("charset=", StringComparison.OrdinalIgnoreCase) == -1)
|
||||||
{
|
{
|
||||||
string enc_name = content_encoding.WebName;
|
string enc_name = content_encoding.WebName;
|
||||||
headers.SetInternal("Content-Type", content_type + "; charset=" + enc_name);
|
headers.SetInternal("Content-Type", content_type + "; charset=" + enc_name);
|
||||||
|
@ -429,9 +429,10 @@ namespace SocketHttpListener.Net
|
||||||
* HttpStatusCode.InternalServerError 500
|
* HttpStatusCode.InternalServerError 500
|
||||||
* HttpStatusCode.ServiceUnavailable 503
|
* HttpStatusCode.ServiceUnavailable 503
|
||||||
*/
|
*/
|
||||||
bool conn_close = (status_code == 408 || status_code == 411 ||
|
bool conn_close = status_code == 400 || status_code == 408 || status_code == 411 ||
|
||||||
status_code == 413 || status_code == 414 ||
|
status_code == 413 || status_code == 414 ||
|
||||||
status_code == 503);
|
status_code == 500 ||
|
||||||
|
status_code == 503;
|
||||||
|
|
||||||
if (conn_close == false)
|
if (conn_close == false)
|
||||||
conn_close = !context.Request.KeepAlive;
|
conn_close = !context.Request.KeepAlive;
|
||||||
|
|
|
@ -136,6 +136,11 @@ namespace SocketHttpListener.Net
|
||||||
if (disposed)
|
if (disposed)
|
||||||
throw new ObjectDisposedException(GetType().ToString());
|
throw new ObjectDisposedException(GetType().ToString());
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
|
||||||
byte[] bytes = null;
|
byte[] bytes = null;
|
||||||
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
||||||
bool chunked = response.SendChunked;
|
bool chunked = response.SendChunked;
|
||||||
|
@ -176,6 +181,11 @@ namespace SocketHttpListener.Net
|
||||||
if (disposed)
|
if (disposed)
|
||||||
throw new ObjectDisposedException(GetType().ToString());
|
throw new ObjectDisposedException(GetType().ToString());
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
|
||||||
byte[] bytes = null;
|
byte[] bytes = null;
|
||||||
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
||||||
bool chunked = response.SendChunked;
|
bool chunked = response.SendChunked;
|
||||||
|
@ -206,7 +216,7 @@ namespace SocketHttpListener.Net
|
||||||
await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
|
await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.SendChunked)
|
if (chunked)
|
||||||
stream.Write(crlf, 0, 2);
|
stream.Write(crlf, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user