mirror of https://github.com/jellyfin/jellyfin.git
update .net core startup
This commit is contained in:
parent
3c55747cd6
commit
0e9cd51f9c
|
@ -326,7 +326,7 @@ namespace Emby.Common.Implementations
|
||||||
|
|
||||||
builder.AppendLine(string.Format("Processor count: {0}", Environment.ProcessorCount));
|
builder.AppendLine(string.Format("Processor count: {0}", Environment.ProcessorCount));
|
||||||
builder.AppendLine(string.Format("Program data path: {0}", appPaths.ProgramDataPath));
|
builder.AppendLine(string.Format("Program data path: {0}", appPaths.ProgramDataPath));
|
||||||
builder.AppendLine(string.Format("Application Path: {0}", appPaths.ApplicationPath));
|
builder.AppendLine(string.Format("Application directory: {0}", appPaths.ProgramSystemPath));
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,7 @@ return null;
|
||||||
TimerFactory = new TimerFactory();
|
TimerFactory = new TimerFactory();
|
||||||
RegisterSingleInstance(TimerFactory);
|
RegisterSingleInstance(TimerFactory);
|
||||||
|
|
||||||
SocketFactory = new SocketFactory(null);
|
SocketFactory = new SocketFactory(LogManager.GetLogger("SocketFactory"));
|
||||||
RegisterSingleInstance(SocketFactory);
|
RegisterSingleInstance(SocketFactory);
|
||||||
|
|
||||||
RegisterSingleInstance(CryptographyProvider);
|
RegisterSingleInstance(CryptographyProvider);
|
||||||
|
|
|
@ -12,22 +12,18 @@ namespace Emby.Common.Implementations
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
|
/// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected BaseApplicationPaths(string programDataPath, string applicationPath)
|
protected BaseApplicationPaths(string programDataPath, string appFolderPath)
|
||||||
{
|
{
|
||||||
ProgramDataPath = programDataPath;
|
ProgramDataPath = programDataPath;
|
||||||
ApplicationPath = applicationPath;
|
ProgramSystemPath = appFolderPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ApplicationPath { get; private set; }
|
|
||||||
public string ProgramDataPath { get; private set; }
|
public string ProgramDataPath { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path to the system folder
|
/// Gets the path to the system folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ProgramSystemPath
|
public string ProgramSystemPath { get; private set; }
|
||||||
{
|
|
||||||
get { return Path.GetDirectoryName(ApplicationPath); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _data directory
|
/// The _data directory
|
||||||
|
|
|
@ -95,5 +95,15 @@ namespace Emby.Common.Implementations.EnvironmentInfo
|
||||||
return MediaBrowser.Model.System.Architecture.X64;
|
return MediaBrowser.Model.System.Architecture.X64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetEnvironmentVariable(string name)
|
||||||
|
{
|
||||||
|
return Environment.GetEnvironmentVariable(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string GetUserId()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,14 @@ namespace Emby.Common.Implementations.IO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public char PathSeparator
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Path.DirectorySeparatorChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string GetFullPath(string path)
|
public string GetFullPath(string path)
|
||||||
{
|
{
|
||||||
return Path.GetFullPath(path);
|
return Path.GetFullPath(path);
|
||||||
|
|
|
@ -15,6 +15,15 @@ namespace Emby.Common.Implementations.Net
|
||||||
|
|
||||||
public NetSocket(Socket socket, ILogger logger)
|
public NetSocket(Socket socket, ILogger logger)
|
||||||
{
|
{
|
||||||
|
if (socket == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("socket");
|
||||||
|
}
|
||||||
|
if (logger == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("logger");
|
||||||
|
}
|
||||||
|
|
||||||
Socket = socket;
|
Socket = socket;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,23 @@ namespace Emby.Common.Implementations.Net
|
||||||
|
|
||||||
public SocketAcceptor(ILogger logger, Socket originalSocket, Action<ISocket> onAccept, Func<bool> isClosed)
|
public SocketAcceptor(ILogger logger, Socket originalSocket, Action<ISocket> onAccept, Func<bool> isClosed)
|
||||||
{
|
{
|
||||||
|
if (logger == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("logger");
|
||||||
|
}
|
||||||
|
if (originalSocket == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("originalSocket");
|
||||||
|
}
|
||||||
|
if (onAccept == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("onAccept");
|
||||||
|
}
|
||||||
|
if (isClosed == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("isClosed");
|
||||||
|
}
|
||||||
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_originalSocket = originalSocket;
|
_originalSocket = originalSocket;
|
||||||
_isClosed = isClosed;
|
_isClosed = isClosed;
|
||||||
|
@ -101,11 +118,8 @@ namespace Emby.Common.Implementations.Net
|
||||||
_onAccept(new NetSocket(acceptSocket, _logger));
|
_onAccept(new NetSocket(acceptSocket, _logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_originalSocket != null)
|
// Accept the next connection request
|
||||||
{
|
StartAccept(e, ref acceptSocket);
|
||||||
// Accept the next connection request
|
|
||||||
StartAccept(e, ref acceptSocket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,15 @@ namespace Emby.Common.Implementations.Net
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private IPAddress _LocalIP;
|
private IPAddress _LocalIP;
|
||||||
|
|
||||||
private ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public SocketFactory(ILogger logger)
|
public SocketFactory(ILogger logger)
|
||||||
{
|
{
|
||||||
|
if (logger == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("logger");
|
||||||
|
}
|
||||||
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_LocalIP = IPAddress.Any;
|
_LocalIP = IPAddress.Any;
|
||||||
}
|
}
|
||||||
|
|
|
@ -725,6 +725,11 @@ namespace Emby.Server.Core
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (!FileSystemManager.FileExists(certificateLocation))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
X509Certificate2 localCert = new X509Certificate2(certificateLocation);
|
X509Certificate2 localCert = new X509Certificate2(certificateLocation);
|
||||||
//localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA;
|
//localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA;
|
||||||
if (!localCert.HasPrivateKey)
|
if (!localCert.HasPrivateKey)
|
||||||
|
@ -1438,12 +1443,7 @@ namespace Emby.Server.Core
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AuthorizeServer(
|
AuthorizeServer();
|
||||||
UdpServerEntryPoint.PortNumber,
|
|
||||||
ServerConfigurationManager.Configuration.HttpServerPortNumber,
|
|
||||||
ServerConfigurationManager.Configuration.HttpsPortNumber,
|
|
||||||
ConfigurationManager.CommonApplicationPaths.ApplicationPath,
|
|
||||||
ConfigurationManager.CommonApplicationPaths.TempDirectory);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -1451,7 +1451,7 @@ namespace Emby.Server.Core
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory);
|
protected abstract void AuthorizeServer();
|
||||||
protected abstract IDbConnector GetDbConnector();
|
protected abstract IDbConnector GetDbConnector();
|
||||||
|
|
||||||
public event EventHandler HasUpdateAvailableChanged;
|
public event EventHandler HasUpdateAvailableChanged;
|
||||||
|
|
|
@ -173,7 +173,7 @@ namespace Emby.Server.Core.Data
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
builder.AppendLine("alter table " + table);
|
builder.AppendLine("alter table " + table);
|
||||||
builder.AppendLine("add column " + columnName + " " + type);
|
builder.AppendLine("add column " + columnName + " " + type + " NULL");
|
||||||
|
|
||||||
connection.RunQueries(new[] { builder.ToString() }, logger);
|
connection.RunQueries(new[] { builder.ToString() }, logger);
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace Emby.Server.Core.Data
|
||||||
|
|
||||||
string[] queries = {
|
string[] queries = {
|
||||||
|
|
||||||
"create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID, Path TEXT)",
|
"create table if not exists TypedBaseItems (guid GUID primary key NOT NULL, type TEXT NOT NULL, data BLOB NULL, ParentId GUID NULL, Path TEXT NULL)",
|
||||||
|
|
||||||
"create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
|
"create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
|
||||||
"create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
|
"create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
|
||||||
|
@ -286,6 +286,7 @@ namespace Emby.Server.Core.Data
|
||||||
_connection.AddColumn(Logger, "TypedBaseItems", "ExtraType", "Text");
|
_connection.AddColumn(Logger, "TypedBaseItems", "ExtraType", "Text");
|
||||||
_connection.AddColumn(Logger, "TypedBaseItems", "Artists", "Text");
|
_connection.AddColumn(Logger, "TypedBaseItems", "Artists", "Text");
|
||||||
_connection.AddColumn(Logger, "TypedBaseItems", "AlbumArtists", "Text");
|
_connection.AddColumn(Logger, "TypedBaseItems", "AlbumArtists", "Text");
|
||||||
|
_connection.AddColumn(Logger, "TypedBaseItems", "ExternalId", "Text");
|
||||||
|
|
||||||
_connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text");
|
_connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text");
|
||||||
|
|
||||||
|
@ -440,7 +441,8 @@ namespace Emby.Server.Core.Data
|
||||||
"TotalBitrate",
|
"TotalBitrate",
|
||||||
"ExtraType",
|
"ExtraType",
|
||||||
"Artists",
|
"Artists",
|
||||||
"AlbumArtists"
|
"AlbumArtists",
|
||||||
|
"ExternalId"
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly string[] _mediaStreamSaveColumns =
|
private readonly string[] _mediaStreamSaveColumns =
|
||||||
|
@ -575,7 +577,8 @@ namespace Emby.Server.Core.Data
|
||||||
"TotalBitrate",
|
"TotalBitrate",
|
||||||
"ExtraType",
|
"ExtraType",
|
||||||
"Artists",
|
"Artists",
|
||||||
"AlbumArtists"
|
"AlbumArtists",
|
||||||
|
"ExternalId"
|
||||||
};
|
};
|
||||||
_saveItemCommand = _connection.CreateCommand();
|
_saveItemCommand = _connection.CreateCommand();
|
||||||
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
|
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
|
||||||
|
@ -1084,6 +1087,10 @@ namespace Emby.Server.Core.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = item.ExternalId;
|
||||||
|
|
||||||
|
//Logger.Debug(_saveItemCommand.CommandText);
|
||||||
|
|
||||||
_saveItemCommand.Transaction = transaction;
|
_saveItemCommand.Transaction = transaction;
|
||||||
|
|
||||||
_saveItemCommand.ExecuteNonQuery();
|
_saveItemCommand.ExecuteNonQuery();
|
||||||
|
@ -1967,6 +1974,12 @@ namespace Emby.Server.Core.Data
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
|
if (!reader.IsDBNull(index))
|
||||||
|
{
|
||||||
|
item.ExternalId = reader.GetString(index);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(item.Tagline))
|
if (string.IsNullOrWhiteSpace(item.Tagline))
|
||||||
{
|
{
|
||||||
var movie = item as Movie;
|
var movie = item as Movie;
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace Emby.Server.Core.Notifications
|
||||||
{
|
{
|
||||||
string[] queries = {
|
string[] queries = {
|
||||||
|
|
||||||
"create table if not exists Notifications (Id GUID NOT NULL, UserId GUID NOT NULL, Date DATETIME NOT NULL, Name TEXT NOT NULL, Description TEXT, Url TEXT, Level TEXT NOT NULL, IsRead BOOLEAN NOT NULL, Category TEXT NOT NULL, RelatedId TEXT, PRIMARY KEY (Id, UserId))",
|
"create table if not exists Notifications (Id GUID NOT NULL, UserId GUID NOT NULL, Date DATETIME NOT NULL, Name TEXT NOT NULL, Description TEXT NULL, Url TEXT NULL, Level TEXT NOT NULL, IsRead BOOLEAN NOT NULL, Category TEXT NOT NULL, RelatedId TEXT NULL, PRIMARY KEY (Id, UserId))",
|
||||||
"create index if not exists idx_Notifications1 on Notifications(Id)",
|
"create index if not exists idx_Notifications1 on Notifications(Id)",
|
||||||
"create index if not exists idx_Notifications2 on Notifications(UserId)"
|
"create index if not exists idx_Notifications2 on Notifications(UserId)"
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,8 +12,8 @@ namespace Emby.Server.Core
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BaseApplicationPaths" /> class.
|
/// Initializes a new instance of the <see cref="BaseApplicationPaths" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ServerApplicationPaths(string programDataPath, string applicationPath, string applicationResourcesPath)
|
public ServerApplicationPaths(string programDataPath, string appFolderPath, string applicationResourcesPath)
|
||||||
: base(programDataPath, applicationPath)
|
: base(programDataPath, appFolderPath)
|
||||||
{
|
{
|
||||||
ApplicationResourcesPath = applicationResourcesPath;
|
ApplicationResourcesPath = applicationResourcesPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,7 +326,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
if (requiresCallback != null)
|
if (requiresCallback != null)
|
||||||
{
|
{
|
||||||
results = await GetChannelItemMediaSourcesInternal(requiresCallback, item.ExternalId, cancellationToken)
|
results = await GetChannelItemMediaSourcesInternal(requiresCallback, GetItemExternalId(item), cancellationToken)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1075,6 +1075,18 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetItemExternalId(BaseItem item)
|
||||||
|
{
|
||||||
|
var externalId = item.ExternalId;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(externalId))
|
||||||
|
{
|
||||||
|
externalId = item.GetProviderId("ProviderExternalId");
|
||||||
|
}
|
||||||
|
|
||||||
|
return externalId;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
|
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
|
||||||
private async Task<ChannelItemResult> GetChannelItems(IChannel channel,
|
private async Task<ChannelItemResult> GetChannelItems(IChannel channel,
|
||||||
User user,
|
User user,
|
||||||
|
@ -1145,7 +1157,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
var categoryItem = _libraryManager.GetItemById(new Guid(folderId));
|
var categoryItem = _libraryManager.GetItemById(new Guid(folderId));
|
||||||
|
|
||||||
query.FolderId = categoryItem.ExternalId;
|
query.FolderId = GetItemExternalId(categoryItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false);
|
var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
|
@ -396,6 +396,8 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
{
|
{
|
||||||
httpRes.StatusCode = 503;
|
httpRes.StatusCode = 503;
|
||||||
|
httpRes.ContentType = "text/plain";
|
||||||
|
Write(httpRes, "Server shutting down");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1551,13 +1551,28 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (timer.IsSports)
|
||||||
|
{
|
||||||
|
AddGenre(timer.Genres, "Sports");
|
||||||
|
}
|
||||||
|
if (timer.IsKids)
|
||||||
|
{
|
||||||
|
AddGenre(timer.Genres, "Kids");
|
||||||
|
AddGenre(timer.Genres, "Children");
|
||||||
|
}
|
||||||
|
if (timer.IsNews)
|
||||||
|
{
|
||||||
|
AddGenre(timer.Genres, "News");
|
||||||
|
}
|
||||||
|
|
||||||
if (timer.IsProgramSeries)
|
if (timer.IsProgramSeries)
|
||||||
{
|
{
|
||||||
SaveSeriesNfo(timer, recordingPath, seriesPath);
|
SaveSeriesNfo(timer, recordingPath, seriesPath);
|
||||||
|
SaveVideoNfo(timer, recordingPath, false);
|
||||||
}
|
}
|
||||||
else if (!timer.IsMovie || timer.IsSports || timer.IsNews)
|
else if (!timer.IsMovie || timer.IsSports || timer.IsNews)
|
||||||
{
|
{
|
||||||
SaveVideoNfo(timer, recordingPath);
|
SaveVideoNfo(timer, recordingPath, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -1594,6 +1609,16 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
writer.WriteElementString("title", timer.Name);
|
writer.WriteElementString("title", timer.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(timer.OfficialRating))
|
||||||
|
{
|
||||||
|
writer.WriteElementString("mpaa", timer.OfficialRating);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var genre in timer.Genres)
|
||||||
|
{
|
||||||
|
writer.WriteElementString("genre", genre);
|
||||||
|
}
|
||||||
|
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
writer.WriteEndDocument();
|
writer.WriteEndDocument();
|
||||||
}
|
}
|
||||||
|
@ -1601,7 +1626,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
}
|
}
|
||||||
|
|
||||||
public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss";
|
public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss";
|
||||||
private void SaveVideoNfo(TimerInfo timer, string recordingPath)
|
private void SaveVideoNfo(TimerInfo timer, string recordingPath, bool lockData)
|
||||||
{
|
{
|
||||||
var nfoPath = Path.ChangeExtension(recordingPath, ".nfo");
|
var nfoPath = Path.ChangeExtension(recordingPath, ".nfo");
|
||||||
|
|
||||||
|
@ -1622,11 +1647,41 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
using (XmlWriter writer = XmlWriter.Create(stream, settings))
|
using (XmlWriter writer = XmlWriter.Create(stream, settings))
|
||||||
{
|
{
|
||||||
writer.WriteStartDocument(true);
|
writer.WriteStartDocument(true);
|
||||||
writer.WriteStartElement("movie");
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(timer.Name))
|
if (timer.IsProgramSeries)
|
||||||
{
|
{
|
||||||
writer.WriteElementString("title", timer.Name);
|
writer.WriteStartElement("episodedetails");
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(timer.EpisodeTitle))
|
||||||
|
{
|
||||||
|
writer.WriteElementString("title", timer.EpisodeTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer.OriginalAirDate.HasValue)
|
||||||
|
{
|
||||||
|
var formatString = _config.GetNfoConfiguration().ReleaseDateFormat;
|
||||||
|
|
||||||
|
writer.WriteElementString("aired", timer.OriginalAirDate.Value.ToLocalTime().ToString(formatString));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer.EpisodeNumber.HasValue)
|
||||||
|
{
|
||||||
|
writer.WriteElementString("episode", timer.EpisodeNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer.SeasonNumber.HasValue)
|
||||||
|
{
|
||||||
|
writer.WriteElementString("season", timer.SeasonNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("movie");
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(timer.Name))
|
||||||
|
{
|
||||||
|
writer.WriteElementString("title", timer.Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteElementString("dateadded", DateTime.UtcNow.ToLocalTime().ToString(DateAddedFormat));
|
writer.WriteElementString("dateadded", DateTime.UtcNow.ToLocalTime().ToString(DateAddedFormat));
|
||||||
|
@ -1645,27 +1700,17 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
.Replace(""", "'");
|
.Replace(""", "'");
|
||||||
|
|
||||||
writer.WriteElementString("plot", overview);
|
writer.WriteElementString("plot", overview);
|
||||||
writer.WriteElementString("lockdata", true.ToString().ToLower());
|
|
||||||
|
if (lockData)
|
||||||
|
{
|
||||||
|
writer.WriteElementString("lockdata", true.ToString().ToLower());
|
||||||
|
}
|
||||||
|
|
||||||
if (timer.CommunityRating.HasValue)
|
if (timer.CommunityRating.HasValue)
|
||||||
{
|
{
|
||||||
writer.WriteElementString("rating", timer.CommunityRating.Value.ToString(CultureInfo.InvariantCulture));
|
writer.WriteElementString("rating", timer.CommunityRating.Value.ToString(CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer.IsSports)
|
|
||||||
{
|
|
||||||
AddGenre(timer.Genres, "Sports");
|
|
||||||
}
|
|
||||||
if (timer.IsKids)
|
|
||||||
{
|
|
||||||
AddGenre(timer.Genres, "Kids");
|
|
||||||
AddGenre(timer.Genres, "Children");
|
|
||||||
}
|
|
||||||
if (timer.IsNews)
|
|
||||||
{
|
|
||||||
AddGenre(timer.Genres, "News");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var genre in timer.Genres)
|
foreach (var genre in timer.Genres)
|
||||||
{
|
{
|
||||||
writer.WriteElementString("genre", genre);
|
writer.WriteElementString("genre", genre);
|
||||||
|
@ -1968,4 +2013,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
public CancellationTokenSource CancellationTokenSource { get; set; }
|
public CancellationTokenSource CancellationTokenSource { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static class ConfigurationExtension
|
||||||
|
{
|
||||||
|
public static XbmcMetadataOptions GetNfoConfiguration(this IConfigurationManager manager)
|
||||||
|
{
|
||||||
|
return manager.GetConfiguration<XbmcMetadataOptions>("xbmcmetadata");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -54,9 +54,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error deserializing {0}", ex, jsonFile);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -269,6 +269,18 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
return _libraryManager.GetNewItemId(name.ToLower(), typeof(ILiveTvRecording));
|
return _libraryManager.GetNewItemId(name.ToLower(), typeof(ILiveTvRecording));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetItemExternalId(BaseItem item)
|
||||||
|
{
|
||||||
|
var externalId = item.ExternalId;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(externalId))
|
||||||
|
{
|
||||||
|
externalId = item.GetProviderId("ProviderExternalId");
|
||||||
|
}
|
||||||
|
|
||||||
|
return externalId;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<TimerInfo> GetTimerInfo(TimerInfoDto dto, bool isNew, LiveTvManager liveTv, CancellationToken cancellationToken)
|
public async Task<TimerInfo> GetTimerInfo(TimerInfoDto dto, bool isNew, LiveTvManager liveTv, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var info = new TimerInfo
|
var info = new TimerInfo
|
||||||
|
@ -304,7 +316,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
{
|
{
|
||||||
info.ChannelId = channel.ExternalId;
|
info.ChannelId = GetItemExternalId(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +326,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
if (program != null)
|
if (program != null)
|
||||||
{
|
{
|
||||||
info.ProgramId = program.ExternalId;
|
info.ProgramId = GetItemExternalId(program);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,7 +382,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
{
|
{
|
||||||
info.ChannelId = channel.ExternalId;
|
info.ChannelId = GetItemExternalId(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +392,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
if (program != null)
|
if (program != null)
|
||||||
{
|
{
|
||||||
info.ProgramId = program.ExternalId;
|
info.ProgramId = GetItemExternalId(program);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,12 +251,24 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
return await GetLiveStream(id, mediaSourceId, true, cancellationToken).ConfigureAwait(false);
|
return await GetLiveStream(id, mediaSourceId, true, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetItemExternalId(BaseItem item)
|
||||||
|
{
|
||||||
|
var externalId = item.ExternalId;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(externalId))
|
||||||
|
{
|
||||||
|
externalId = item.GetProviderId("ProviderExternalId");
|
||||||
|
}
|
||||||
|
|
||||||
|
return externalId;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
|
public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var baseItem = (BaseItem)item;
|
var baseItem = (BaseItem)item;
|
||||||
var service = GetService(baseItem);
|
var service = GetService(baseItem);
|
||||||
|
|
||||||
return await service.GetRecordingStreamMediaSources(baseItem.ExternalId, cancellationToken).ConfigureAwait(false);
|
return await service.GetRecordingStreamMediaSources(GetItemExternalId(baseItem), cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
|
public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
|
||||||
|
@ -313,18 +325,18 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
var channel = GetInternalChannel(id);
|
var channel = GetInternalChannel(id);
|
||||||
isVideo = channel.ChannelType == ChannelType.TV;
|
isVideo = channel.ChannelType == ChannelType.TV;
|
||||||
service = GetService(channel);
|
service = GetService(channel);
|
||||||
_logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId);
|
_logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, GetItemExternalId(channel));
|
||||||
|
|
||||||
var supportsManagedStream = service as ISupportsDirectStreamProvider;
|
var supportsManagedStream = service as ISupportsDirectStreamProvider;
|
||||||
if (supportsManagedStream != null)
|
if (supportsManagedStream != null)
|
||||||
{
|
{
|
||||||
var streamInfo = await supportsManagedStream.GetChannelStreamWithDirectStreamProvider(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false);
|
var streamInfo = await supportsManagedStream.GetChannelStreamWithDirectStreamProvider(GetItemExternalId(channel), mediaSourceId, cancellationToken).ConfigureAwait(false);
|
||||||
info = streamInfo.Item1;
|
info = streamInfo.Item1;
|
||||||
directStreamProvider = streamInfo.Item2;
|
directStreamProvider = streamInfo.Item2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info = await service.GetChannelStream(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false);
|
info = await service.GetChannelStream(GetItemExternalId(channel), mediaSourceId, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
info.RequiresClosing = true;
|
info.RequiresClosing = true;
|
||||||
|
|
||||||
|
@ -341,8 +353,8 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase);
|
isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase);
|
||||||
service = GetService(recording);
|
service = GetService(recording);
|
||||||
|
|
||||||
_logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.ExternalId);
|
_logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, GetItemExternalId(recording));
|
||||||
info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false);
|
info = await service.GetRecordingStream(GetItemExternalId(recording), null, cancellationToken).ConfigureAwait(false);
|
||||||
info.RequiresClosing = true;
|
info.RequiresClosing = true;
|
||||||
|
|
||||||
if (info.RequiresClosing)
|
if (info.RequiresClosing)
|
||||||
|
@ -493,7 +505,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
isNew = true;
|
isNew = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.Equals(channelInfo.Id, item.ExternalId))
|
if (!string.Equals(channelInfo.Id, item.ExternalId, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
isNew = true;
|
isNew = true;
|
||||||
}
|
}
|
||||||
|
@ -601,7 +613,6 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
item.EpisodeTitle = info.EpisodeTitle;
|
item.EpisodeTitle = info.EpisodeTitle;
|
||||||
item.ExternalId = info.Id;
|
item.ExternalId = info.Id;
|
||||||
item.ExternalSeriesIdLegacy = seriesId;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(seriesId) && !string.Equals(item.ExternalSeriesId, seriesId, StringComparison.Ordinal))
|
if (!string.IsNullOrWhiteSpace(seriesId) && !string.Equals(item.ExternalSeriesId, seriesId, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
|
@ -841,6 +852,13 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
return item.Id;
|
return item.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private string GetExternalSeriesIdLegacy(BaseItem item)
|
||||||
|
{
|
||||||
|
return item.GetProviderId("ProviderExternalSeriesId");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<BaseItemDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
|
public async Task<BaseItemDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
|
||||||
{
|
{
|
||||||
var program = GetInternalProgram(id);
|
var program = GetInternalProgram(id);
|
||||||
|
@ -848,7 +866,15 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
|
var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
|
||||||
|
|
||||||
var list = new List<Tuple<BaseItemDto, string, string, string>>();
|
var list = new List<Tuple<BaseItemDto, string, string, string>>();
|
||||||
list.Add(new Tuple<BaseItemDto, string, string, string>(dto, program.ServiceName, program.ExternalId, program.ExternalSeriesIdLegacy));
|
|
||||||
|
var externalSeriesId = program.ExternalSeriesId;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(externalSeriesId))
|
||||||
|
{
|
||||||
|
externalSeriesId = GetExternalSeriesIdLegacy(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(new Tuple<BaseItemDto, string, string, string>(dto, program.ServiceName, GetItemExternalId(program), externalSeriesId));
|
||||||
|
|
||||||
await AddRecordingInfo(list, cancellationToken).ConfigureAwait(false);
|
await AddRecordingInfo(list, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
@ -1283,7 +1309,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
var isKids = false;
|
var isKids = false;
|
||||||
var iSSeries = false;
|
var iSSeries = false;
|
||||||
|
|
||||||
var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false);
|
var channelPrograms = await service.GetProgramsAsync(GetItemExternalId(currentChannel), start, end, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var existingPrograms = _libraryManager.GetItemList(new InternalItemsQuery
|
var existingPrograms = _libraryManager.GetItemList(new InternalItemsQuery
|
||||||
{
|
{
|
||||||
|
@ -1830,7 +1856,14 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
dto.ServiceName = serviceName;
|
dto.ServiceName = serviceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
programTuples.Add(new Tuple<BaseItemDto, string, string, string>(dto, serviceName, program.ExternalId, program.ExternalSeriesIdLegacy));
|
var externalSeriesId = program.ExternalSeriesId;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(externalSeriesId))
|
||||||
|
{
|
||||||
|
externalSeriesId = GetExternalSeriesIdLegacy(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
programTuples.Add(new Tuple<BaseItemDto, string, string, string>(dto, serviceName, GetItemExternalId(program), externalSeriesId));
|
||||||
}
|
}
|
||||||
|
|
||||||
await AddRecordingInfo(programTuples, CancellationToken.None).ConfigureAwait(false);
|
await AddRecordingInfo(programTuples, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
@ -2006,7 +2039,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
if (service is EmbyTV.EmbyTV)
|
if (service is EmbyTV.EmbyTV)
|
||||||
{
|
{
|
||||||
// We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says
|
// We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says
|
||||||
return service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None);
|
return service.DeleteRecordingAsync(GetItemExternalId(recording), CancellationToken.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
|
@ -2030,7 +2063,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None).ConfigureAwait(false);
|
await service.DeleteRecordingAsync(GetItemExternalId(recording), CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (ResourceNotFoundException)
|
catch (ResourceNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -2289,12 +2322,12 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
programInfo = new ProgramInfo
|
programInfo = new ProgramInfo
|
||||||
{
|
{
|
||||||
Audio = program.Audio,
|
Audio = program.Audio,
|
||||||
ChannelId = channel.ExternalId,
|
ChannelId = GetItemExternalId(channel),
|
||||||
CommunityRating = program.CommunityRating,
|
CommunityRating = program.CommunityRating,
|
||||||
EndDate = program.EndDate ?? DateTime.MinValue,
|
EndDate = program.EndDate ?? DateTime.MinValue,
|
||||||
EpisodeTitle = program.EpisodeTitle,
|
EpisodeTitle = program.EpisodeTitle,
|
||||||
Genres = program.Genres,
|
Genres = program.Genres,
|
||||||
Id = program.ExternalId,
|
Id = GetItemExternalId(program),
|
||||||
IsHD = program.IsHD,
|
IsHD = program.IsHD,
|
||||||
IsKids = program.IsKids,
|
IsKids = program.IsKids,
|
||||||
IsLive = program.IsLive,
|
IsLive = program.IsLive,
|
||||||
|
@ -2360,7 +2393,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
info.Name = program.Name;
|
info.Name = program.Name;
|
||||||
info.Overview = program.Overview;
|
info.Overview = program.Overview;
|
||||||
info.ProgramId = programDto.Id;
|
info.ProgramId = programDto.Id;
|
||||||
info.ExternalProgramId = program.ExternalId;
|
info.ExternalProgramId = GetItemExternalId(program);
|
||||||
|
|
||||||
if (program.EndDate.HasValue)
|
if (program.EndDate.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -2804,7 +2837,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
public async Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings)
|
public async Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings)
|
||||||
{
|
{
|
||||||
info = _jsonSerializer.DeserializeFromString< ListingsProviderInfo>(_jsonSerializer.SerializeToString(info));
|
info = _jsonSerializer.DeserializeFromString<ListingsProviderInfo>(_jsonSerializer.SerializeToString(info));
|
||||||
|
|
||||||
var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase));
|
var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,18 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
return new[] { ImageType.Primary };
|
return new[] { ImageType.Primary };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetItemExternalId(BaseItem item)
|
||||||
|
{
|
||||||
|
var externalId = item.ExternalId;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(externalId))
|
||||||
|
{
|
||||||
|
externalId = item.GetProviderId("ProviderExternalId");
|
||||||
|
}
|
||||||
|
|
||||||
|
return externalId;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken)
|
public async Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var liveTvItem = (LiveTvProgram)item;
|
var liveTvItem = (LiveTvProgram)item;
|
||||||
|
@ -38,7 +50,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
{
|
{
|
||||||
var channel = _liveTvManager.GetInternalChannel(liveTvItem.ChannelId);
|
var channel = _liveTvManager.GetInternalChannel(liveTvItem.ChannelId);
|
||||||
|
|
||||||
var response = await service.GetProgramImageAsync(liveTvItem.ExternalId, channel.ExternalId, cancellationToken).ConfigureAwait(false);
|
var response = await service.GetProgramImageAsync(GetItemExternalId(liveTvItem), GetItemExternalId(channel), cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
if (response != null)
|
if (response != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -128,7 +128,11 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
// Don't clutter the log
|
// Don't clutter the log
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException)
|
||||||
|
{
|
||||||
|
// Don't clutter the log
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error deleting encoded media cache", ex);
|
Logger.ErrorException("Error deleting encoded media cache", ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,6 @@ namespace MediaBrowser.Common.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IApplicationPaths
|
public interface IApplicationPaths
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets the application path.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The application path.</value>
|
|
||||||
string ApplicationPath { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path to the program data folder
|
/// Gets the path to the program data folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -296,28 +296,11 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// If this content came from an external service, the id of the content on that service
|
/// If this content came from an external service, the id of the content on that service
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public string ExternalId
|
public string ExternalId { get; set; }
|
||||||
{
|
|
||||||
get { return this.GetProviderId("ProviderExternalId"); }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
this.SetProviderId("ProviderExternalId", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public string ExternalSeriesId { get; set; }
|
public string ExternalSeriesId { get; set; }
|
||||||
|
|
||||||
[IgnoreDataMember]
|
|
||||||
public string ExternalSeriesIdLegacy
|
|
||||||
{
|
|
||||||
get { return this.GetProviderId("ProviderExternalSeriesId"); }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
this.SetProviderId("ProviderExternalSeriesId", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the etag.
|
/// Gets or sets the etag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -37,15 +37,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
{
|
{
|
||||||
output = GetProcessOutput(encoderAppPath, "-version");
|
output = GetProcessOutput(encoderAppPath, "-version");
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
}
|
if (logOutput)
|
||||||
|
{
|
||||||
output = output ?? string.Empty;
|
_logger.ErrorException("Error validating encoder", ex);
|
||||||
|
}
|
||||||
if (logOutput)
|
|
||||||
{
|
|
||||||
_logger.Info("ffmpeg info: {0}", output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(output))
|
if (string.IsNullOrWhiteSpace(output))
|
||||||
|
@ -53,6 +50,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (logOutput)
|
||||||
|
{
|
||||||
|
_logger.Info("ffmpeg info: {0}", output);
|
||||||
|
}
|
||||||
|
|
||||||
if (output.IndexOf("Libav developers", StringComparison.OrdinalIgnoreCase) != -1)
|
if (output.IndexOf("Libav developers", StringComparison.OrdinalIgnoreCase) != -1)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -308,6 +308,7 @@ namespace MediaBrowser.Model.IO
|
||||||
void SetReadOnly(string path, bool isHidden);
|
void SetReadOnly(string path, bool isHidden);
|
||||||
|
|
||||||
char DirectorySeparatorChar { get; }
|
char DirectorySeparatorChar { get; }
|
||||||
|
char PathSeparator { get; }
|
||||||
|
|
||||||
string GetFullPath(string path);
|
string GetFullPath(string path);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ namespace MediaBrowser.Model.System
|
||||||
string OperatingSystemName { get; }
|
string OperatingSystemName { get; }
|
||||||
string OperatingSystemVersion { get; }
|
string OperatingSystemVersion { get; }
|
||||||
Architecture SystemArchitecture { get; }
|
Architecture SystemArchitecture { get; }
|
||||||
|
string GetEnvironmentVariable(string name);
|
||||||
|
string GetUserId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum OperatingSystem
|
public enum OperatingSystem
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace MediaBrowser.Server.Mono
|
||||||
MainClass.Shutdown();
|
MainClass.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
|
protected override void AuthorizeServer()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using MediaBrowser.Server.Startup.Common;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
@ -74,7 +75,9 @@ namespace MediaBrowser.Server.Mono
|
||||||
programDataPath = ApplicationPathHelper.GetProgramDataPath(applicationPath);
|
programDataPath = ApplicationPathHelper.GetProgramDataPath(applicationPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ServerApplicationPaths(programDataPath, applicationPath, Path.GetDirectoryName(applicationPath));
|
var appFolderPath = Path.GetDirectoryName(applicationPath);
|
||||||
|
|
||||||
|
return new ServerApplicationPaths(programDataPath, appFolderPath, Path.GetDirectoryName(applicationPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly TaskCompletionSource<bool> ApplicationTaskCompletionSource = new TaskCompletionSource<bool>();
|
private static readonly TaskCompletionSource<bool> ApplicationTaskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
|
@ -305,5 +308,10 @@ namespace MediaBrowser.Server.Mono
|
||||||
public class MonoEnvironmentInfo : EnvironmentInfo
|
public class MonoEnvironmentInfo : EnvironmentInfo
|
||||||
{
|
{
|
||||||
public bool IsBsd { get; set; }
|
public bool IsBsd { get; set; }
|
||||||
|
|
||||||
|
public virtual string GetUserId()
|
||||||
|
{
|
||||||
|
return Syscall.getuid().ToString(CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,11 @@ namespace Emby.Server.Core.Data
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connects to db.
|
/// Connects to db.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static async Task<IDbConnection> ConnectToDb(string dbPath, bool isReadOnly, bool enablePooling, int? cacheSize, ILogger logger)
|
public static async Task<IDbConnection> ConnectToDb(string dbPath,
|
||||||
|
bool isReadOnly,
|
||||||
|
bool enablePooling,
|
||||||
|
int? cacheSize,
|
||||||
|
ILogger logger)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(dbPath))
|
if (string.IsNullOrEmpty(dbPath))
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,6 +44,8 @@ namespace MediaBrowser.ServerApplication
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
static extern bool SetDllDirectory(string lpPathName);
|
static extern bool SetDllDirectory(string lpPathName);
|
||||||
|
|
||||||
|
public static string ApplicationPath;
|
||||||
|
|
||||||
public static bool TryGetLocalFromUncDirectory(string local, out string unc)
|
public static bool TryGetLocalFromUncDirectory(string local, out string unc)
|
||||||
{
|
{
|
||||||
if ((local == null) || (local == ""))
|
if ((local == null) || (local == ""))
|
||||||
|
@ -81,14 +83,14 @@ namespace MediaBrowser.ServerApplication
|
||||||
|
|
||||||
var currentProcess = Process.GetCurrentProcess();
|
var currentProcess = Process.GetCurrentProcess();
|
||||||
|
|
||||||
var applicationPath = currentProcess.MainModule.FileName;
|
ApplicationPath = currentProcess.MainModule.FileName;
|
||||||
var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86");
|
var architecturePath = Path.Combine(Path.GetDirectoryName(ApplicationPath), Environment.Is64BitProcess ? "x64" : "x86");
|
||||||
|
|
||||||
Wand.SetMagickCoderModulePath(architecturePath);
|
Wand.SetMagickCoderModulePath(architecturePath);
|
||||||
|
|
||||||
var success = SetDllDirectory(architecturePath);
|
var success = SetDllDirectory(architecturePath);
|
||||||
|
|
||||||
var appPaths = CreateApplicationPaths(applicationPath, IsRunningAsService);
|
var appPaths = CreateApplicationPaths(ApplicationPath, IsRunningAsService);
|
||||||
|
|
||||||
var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
|
var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
|
||||||
logManager.ReloadLogger(LogSeverity.Debug);
|
logManager.ReloadLogger(LogSeverity.Debug);
|
||||||
|
@ -102,7 +104,7 @@ namespace MediaBrowser.ServerApplication
|
||||||
if (options.ContainsOption("-installservice"))
|
if (options.ContainsOption("-installservice"))
|
||||||
{
|
{
|
||||||
logger.Info("Performing service installation");
|
logger.Info("Performing service installation");
|
||||||
InstallService(applicationPath, logger);
|
InstallService(ApplicationPath, logger);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +112,7 @@ namespace MediaBrowser.ServerApplication
|
||||||
if (options.ContainsOption("-installserviceasadmin"))
|
if (options.ContainsOption("-installserviceasadmin"))
|
||||||
{
|
{
|
||||||
logger.Info("Performing service installation");
|
logger.Info("Performing service installation");
|
||||||
RunServiceInstallation(applicationPath);
|
RunServiceInstallation(ApplicationPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +120,7 @@ namespace MediaBrowser.ServerApplication
|
||||||
if (options.ContainsOption("-uninstallservice"))
|
if (options.ContainsOption("-uninstallservice"))
|
||||||
{
|
{
|
||||||
logger.Info("Performing service uninstallation");
|
logger.Info("Performing service uninstallation");
|
||||||
UninstallService(applicationPath, logger);
|
UninstallService(ApplicationPath, logger);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,15 +128,15 @@ namespace MediaBrowser.ServerApplication
|
||||||
if (options.ContainsOption("-uninstallserviceasadmin"))
|
if (options.ContainsOption("-uninstallserviceasadmin"))
|
||||||
{
|
{
|
||||||
logger.Info("Performing service uninstallation");
|
logger.Info("Performing service uninstallation");
|
||||||
RunServiceUninstallation(applicationPath);
|
RunServiceUninstallation(ApplicationPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||||
|
|
||||||
RunServiceInstallationIfNeeded(applicationPath);
|
RunServiceInstallationIfNeeded(ApplicationPath);
|
||||||
|
|
||||||
if (IsAlreadyRunning(applicationPath, currentProcess))
|
if (IsAlreadyRunning(ApplicationPath, currentProcess))
|
||||||
{
|
{
|
||||||
logger.Info("Shutting down because another instance of Emby Server is already running.");
|
logger.Info("Shutting down because another instance of Emby Server is already running.");
|
||||||
return;
|
return;
|
||||||
|
@ -250,6 +252,8 @@ namespace MediaBrowser.ServerApplication
|
||||||
/// <returns>ServerApplicationPaths.</returns>
|
/// <returns>ServerApplicationPaths.</returns>
|
||||||
private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, bool runAsService)
|
private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, bool runAsService)
|
||||||
{
|
{
|
||||||
|
var appFolderPath = Path.GetDirectoryName(applicationPath);
|
||||||
|
|
||||||
var resourcesPath = Path.GetDirectoryName(applicationPath);
|
var resourcesPath = Path.GetDirectoryName(applicationPath);
|
||||||
|
|
||||||
if (runAsService)
|
if (runAsService)
|
||||||
|
@ -258,10 +262,10 @@ namespace MediaBrowser.ServerApplication
|
||||||
|
|
||||||
var programDataPath = Path.GetDirectoryName(systemPath);
|
var programDataPath = Path.GetDirectoryName(systemPath);
|
||||||
|
|
||||||
return new ServerApplicationPaths(programDataPath, applicationPath, resourcesPath);
|
return new ServerApplicationPaths(programDataPath, appFolderPath, resourcesPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(applicationPath), applicationPath, resourcesPath);
|
return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(applicationPath), appFolderPath, resourcesPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -663,7 +667,7 @@ namespace MediaBrowser.ServerApplication
|
||||||
|
|
||||||
_logger.Info("Starting new instance");
|
_logger.Info("Starting new instance");
|
||||||
//Application.Restart();
|
//Application.Restart();
|
||||||
Process.Start(_appHost.ServerConfigurationManager.ApplicationPaths.ApplicationPath);
|
Process.Start(ApplicationPath);
|
||||||
|
|
||||||
ShutdownWindowsApplication();
|
ShutdownWindowsApplication();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace MediaBrowser.ServerApplication.Updates
|
||||||
// startpath = executable to launch
|
// startpath = executable to launch
|
||||||
// systempath = folder containing installation
|
// systempath = folder containing installation
|
||||||
var args = string.Format("product={0} archive=\"{1}\" caller={2} pismo=false version={3} service={4} installpath=\"{5}\" startpath=\"{6}\" systempath=\"{7}\"",
|
var args = string.Format("product={0} archive=\"{1}\" caller={2} pismo=false version={3} service={4} installpath=\"{5}\" startpath=\"{6}\" systempath=\"{7}\"",
|
||||||
product, archive, Process.GetCurrentProcess().Id, version, restartServiceName ?? string.Empty, appPaths.ProgramDataPath, appPaths.ApplicationPath, systemPath);
|
product, archive, Process.GetCurrentProcess().Id, version, restartServiceName ?? string.Empty, appPaths.ProgramDataPath, MainStartup.ApplicationPath, systemPath);
|
||||||
|
|
||||||
logger.Info("Args: {0}", args);
|
logger.Info("Args: {0}", args);
|
||||||
Process.Start(tempUpdater, args);
|
Process.Start(tempUpdater, args);
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Reflection;
|
||||||
using Emby.Server.Core;
|
using Emby.Server.Core;
|
||||||
using Emby.Server.Core.Data;
|
using Emby.Server.Core.Data;
|
||||||
using Emby.Server.Core.FFMpeg;
|
using Emby.Server.Core.FFMpeg;
|
||||||
|
using Emby.Server.Implementations.EntryPoints;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.System;
|
using MediaBrowser.Model.System;
|
||||||
|
@ -60,9 +61,13 @@ namespace MediaBrowser.ServerApplication
|
||||||
MainStartup.Shutdown();
|
MainStartup.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
|
protected override void AuthorizeServer()
|
||||||
{
|
{
|
||||||
ServerAuthorization.AuthorizeServer(udpPort, httpServerPort, httpsServerPort, applicationPath, tempDirectory);
|
ServerAuthorization.AuthorizeServer(UdpServerEntryPoint.PortNumber,
|
||||||
|
ServerConfigurationManager.Configuration.HttpServerPortNumber,
|
||||||
|
ServerConfigurationManager.Configuration.HttpsPortNumber,
|
||||||
|
MainStartup.ApplicationPath,
|
||||||
|
ConfigurationManager.CommonApplicationPaths.TempDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IDbConnector GetDbConnector()
|
protected override IDbConnector GetDbConnector()
|
||||||
|
|
|
@ -90,8 +90,6 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
|
||||||
|
|
||||||
protected override List<string> GetTagsUsed()
|
protected override List<string> GetTagsUsed()
|
||||||
{
|
{
|
||||||
var list = new List<string>
|
var list = new List<string>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Common</id>
|
<id>MediaBrowser.Common</id>
|
||||||
<version>3.0.689</version>
|
<version>3.0.691</version>
|
||||||
<title>Emby.Common</title>
|
<title>Emby.Common</title>
|
||||||
<authors>Emby Team</authors>
|
<authors>Emby Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Server.Core</id>
|
<id>MediaBrowser.Server.Core</id>
|
||||||
<version>3.0.689</version>
|
<version>3.0.691</version>
|
||||||
<title>Emby.Server.Core</title>
|
<title>Emby.Server.Core</title>
|
||||||
<authors>Emby Team</authors>
|
<authors>Emby Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<description>Contains core components required to build plugins for Emby Server.</description>
|
<description>Contains core components required to build plugins for Emby Server.</description>
|
||||||
<copyright>Copyright © Emby 2013</copyright>
|
<copyright>Copyright © Emby 2013</copyright>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="MediaBrowser.Common" version="3.0.689" />
|
<dependency id="MediaBrowser.Common" version="3.0.691" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Emby.Server
|
||||||
{
|
{
|
||||||
public class ApplicationPathHelper
|
public class ApplicationPathHelper
|
||||||
{
|
{
|
||||||
public static string GetProgramDataPath(string applicationPath)
|
public static string GetProgramDataPath(string appDirectory)
|
||||||
{
|
{
|
||||||
var useDebugPath = false;
|
var useDebugPath = false;
|
||||||
|
|
||||||
|
@ -27,14 +27,7 @@ namespace Emby.Server
|
||||||
// If it's a relative path, e.g. "..\"
|
// If it's a relative path, e.g. "..\"
|
||||||
if (!Path.IsPathRooted(programDataPath))
|
if (!Path.IsPathRooted(programDataPath))
|
||||||
{
|
{
|
||||||
var path = Path.GetDirectoryName(applicationPath);
|
programDataPath = Path.Combine(appDirectory, programDataPath);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(path))
|
|
||||||
{
|
|
||||||
throw new Exception("Unable to determine running assembly location");
|
|
||||||
}
|
|
||||||
|
|
||||||
programDataPath = Path.Combine(path, programDataPath);
|
|
||||||
|
|
||||||
programDataPath = Path.GetFullPath(programDataPath);
|
programDataPath = Path.GetFullPath(programDataPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Emby.Server
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
|
protected override void AuthorizeServer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,6 @@ namespace Emby.Server
|
||||||
|
|
||||||
private static ILogger _logger;
|
private static ILogger _logger;
|
||||||
|
|
||||||
private static bool _isRunningAsService = false;
|
|
||||||
private static bool _canRestartService = false;
|
|
||||||
private static bool _appHostDisposed;
|
private static bool _appHostDisposed;
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
@ -41,23 +39,17 @@ namespace Emby.Server
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var options = new StartupOptions();
|
var options = new StartupOptions();
|
||||||
_isRunningAsService = options.ContainsOption("-service");
|
|
||||||
|
|
||||||
if (_isRunningAsService)
|
|
||||||
{
|
|
||||||
//_canRestartService = CanRestartWindowsService();
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentProcess = Process.GetCurrentProcess();
|
var currentProcess = Process.GetCurrentProcess();
|
||||||
|
|
||||||
var applicationPath = currentProcess.MainModule.FileName;
|
var baseDirectory = System.AppContext.BaseDirectory;
|
||||||
//var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86");
|
//var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86");
|
||||||
|
|
||||||
//Wand.SetMagickCoderModulePath(architecturePath);
|
//Wand.SetMagickCoderModulePath(architecturePath);
|
||||||
|
|
||||||
//var success = SetDllDirectory(architecturePath);
|
//var success = SetDllDirectory(architecturePath);
|
||||||
|
|
||||||
var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService);
|
var appPaths = CreateApplicationPaths(baseDirectory);
|
||||||
|
|
||||||
var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
|
var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
|
||||||
logManager.ReloadLogger(LogSeverity.Debug);
|
logManager.ReloadLogger(LogSeverity.Debug);
|
||||||
|
@ -69,11 +61,11 @@ namespace Emby.Server
|
||||||
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||||
|
|
||||||
if (IsAlreadyRunning(applicationPath, currentProcess))
|
//if (IsAlreadyRunning(applicationPath, currentProcess))
|
||||||
{
|
//{
|
||||||
logger.Info("Shutting down because another instance of Emby Server is already running.");
|
// logger.Info("Shutting down because another instance of Emby Server is already running.");
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (PerformUpdateIfNeeded(appPaths, logger))
|
if (PerformUpdateIfNeeded(appPaths, logger))
|
||||||
{
|
{
|
||||||
|
@ -81,14 +73,7 @@ namespace Emby.Server
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
RunApplication(appPaths, logManager, options);
|
||||||
{
|
|
||||||
RunApplication(appPaths, logManager, _isRunningAsService, options);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
OnServiceShutdown();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -139,34 +124,17 @@ namespace Emby.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_isRunningAsService)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the application paths.
|
/// Creates the application paths.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="applicationPath">The application path.</param>
|
private static ServerApplicationPaths CreateApplicationPaths(string appDirectory)
|
||||||
/// <param name="runAsService">if set to <c>true</c> [run as service].</param>
|
|
||||||
/// <returns>ServerApplicationPaths.</returns>
|
|
||||||
private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, bool runAsService)
|
|
||||||
{
|
{
|
||||||
var resourcesPath = Path.GetDirectoryName(applicationPath);
|
var resourcesPath = appDirectory;
|
||||||
|
|
||||||
if (runAsService)
|
return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(appDirectory), appDirectory, resourcesPath);
|
||||||
{
|
|
||||||
var systemPath = Path.GetDirectoryName(applicationPath);
|
|
||||||
|
|
||||||
var programDataPath = Path.GetDirectoryName(systemPath);
|
|
||||||
|
|
||||||
return new ServerApplicationPaths(programDataPath, applicationPath, resourcesPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(applicationPath), applicationPath, resourcesPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -177,14 +145,7 @@ namespace Emby.Server
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_isRunningAsService)
|
return true;
|
||||||
{
|
|
||||||
return _canRestartService;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,14 +157,7 @@ namespace Emby.Server
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_isRunningAsService)
|
return false;
|
||||||
{
|
|
||||||
return _canRestartService;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,9 +168,8 @@ namespace Emby.Server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="appPaths">The app paths.</param>
|
/// <param name="appPaths">The app paths.</param>
|
||||||
/// <param name="logManager">The log manager.</param>
|
/// <param name="logManager">The log manager.</param>
|
||||||
/// <param name="runService">if set to <c>true</c> [run service].</param>
|
|
||||||
/// <param name="options">The options.</param>
|
/// <param name="options">The options.</param>
|
||||||
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService, StartupOptions options)
|
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, StartupOptions options)
|
||||||
{
|
{
|
||||||
var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true);
|
var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true);
|
||||||
|
|
||||||
|
@ -240,29 +193,19 @@ namespace Emby.Server
|
||||||
|
|
||||||
var initProgress = new Progress<double>();
|
var initProgress = new Progress<double>();
|
||||||
|
|
||||||
if (!runService)
|
// Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes
|
||||||
{
|
SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT |
|
||||||
// Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes
|
ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
|
||||||
SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT |
|
|
||||||
ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
|
|
||||||
}
|
|
||||||
|
|
||||||
var task = _appHost.Init(initProgress);
|
var task = _appHost.Init(initProgress);
|
||||||
Task.WaitAll(task);
|
Task.WaitAll(task);
|
||||||
|
|
||||||
task = task.ContinueWith(new Action<Task>(a => _appHost.RunStartupTasks()), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent);
|
task = task.ContinueWith(new Action<Task>(a => _appHost.RunStartupTasks()), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent);
|
||||||
|
|
||||||
if (runService)
|
Task.WaitAll(task);
|
||||||
{
|
|
||||||
StartService(logManager);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Task.WaitAll(task);
|
|
||||||
|
|
||||||
task = ApplicationTaskCompletionSource.Task;
|
task = ApplicationTaskCompletionSource.Task;
|
||||||
Task.WaitAll(task);
|
Task.WaitAll(task);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateCertificate(string certPath, string certHost)
|
private static void GenerateCertificate(string certPath, string certHost)
|
||||||
|
@ -270,31 +213,6 @@ namespace Emby.Server
|
||||||
//CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger);
|
//CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Starts the service.
|
|
||||||
/// </summary>
|
|
||||||
private static void StartService(ILogManager logManager)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles the Disposed event of the service control.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">The source of the event.</param>
|
|
||||||
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
|
||||||
static void service_Disposed(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
ApplicationTaskCompletionSource.SetResult(true);
|
|
||||||
OnServiceShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OnServiceShutdown()
|
|
||||||
{
|
|
||||||
_logger.Info("Shutting down");
|
|
||||||
|
|
||||||
DisposeAppHost();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the UnhandledException event of the CurrentDomain control.
|
/// Handles the UnhandledException event of the CurrentDomain control.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -306,10 +224,7 @@ namespace Emby.Server
|
||||||
|
|
||||||
new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager).Log(exception);
|
new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager).Log(exception);
|
||||||
|
|
||||||
if (!_isRunningAsService)
|
ShowMessageBox("Unhandled exception: " + exception.Message);
|
||||||
{
|
|
||||||
ShowMessageBox("Unhandled exception: " + exception.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Debugger.IsAttached)
|
if (!Debugger.IsAttached)
|
||||||
{
|
{
|
||||||
|
@ -325,29 +240,6 @@ namespace Emby.Server
|
||||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||||
private static bool PerformUpdateIfNeeded(ServerApplicationPaths appPaths, ILogger logger)
|
private static bool PerformUpdateIfNeeded(ServerApplicationPaths appPaths, ILogger logger)
|
||||||
{
|
{
|
||||||
// Look for the existence of an update archive
|
|
||||||
var updateArchive = Path.Combine(appPaths.TempUpdatePath, "MBServer" + ".zip");
|
|
||||||
if (File.Exists(updateArchive))
|
|
||||||
{
|
|
||||||
logger.Info("An update is available from {0}", updateArchive);
|
|
||||||
|
|
||||||
// Update is there - execute update
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//var serviceName = _isRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty;
|
|
||||||
//new ApplicationUpdater().UpdateApplication(appPaths, updateArchive, logger, serviceName);
|
|
||||||
|
|
||||||
// And just let the app exit so it can update
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.ErrorException("Error starting updater.", e);
|
|
||||||
|
|
||||||
ShowMessageBox(string.Format("Error attempting to update application.\n\n{0}\n\n{1}", e.GetType().Name, e.Message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,37 +250,25 @@ namespace Emby.Server
|
||||||
|
|
||||||
public static void Shutdown()
|
public static void Shutdown()
|
||||||
{
|
{
|
||||||
if (_isRunningAsService)
|
DisposeAppHost();
|
||||||
{
|
|
||||||
ShutdownWindowsService();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DisposeAppHost();
|
|
||||||
|
|
||||||
ShutdownWindowsApplication();
|
//_logger.Info("Calling Application.Exit");
|
||||||
}
|
//Application.Exit();
|
||||||
|
|
||||||
|
_logger.Info("Calling Environment.Exit");
|
||||||
|
Environment.Exit(0);
|
||||||
|
|
||||||
|
_logger.Info("Calling ApplicationTaskCompletionSource.SetResult");
|
||||||
|
ApplicationTaskCompletionSource.SetResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Restart()
|
public static void Restart()
|
||||||
{
|
{
|
||||||
DisposeAppHost();
|
DisposeAppHost();
|
||||||
|
|
||||||
if (_isRunningAsService)
|
// todo: start new instance
|
||||||
{
|
|
||||||
RestartWindowsService();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//_logger.Info("Hiding server notify icon");
|
|
||||||
//_serverNotifyIcon.Visible = false;
|
|
||||||
|
|
||||||
_logger.Info("Starting new instance");
|
Shutdown();
|
||||||
//Application.Restart();
|
|
||||||
Process.Start(_appHost.ServerConfigurationManager.ApplicationPaths.ApplicationPath);
|
|
||||||
|
|
||||||
ShutdownWindowsApplication();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DisposeAppHost()
|
private static void DisposeAppHost()
|
||||||
|
@ -402,31 +282,6 @@ namespace Emby.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShutdownWindowsApplication()
|
|
||||||
{
|
|
||||||
//_logger.Info("Calling Application.Exit");
|
|
||||||
//Application.Exit();
|
|
||||||
|
|
||||||
_logger.Info("Calling Environment.Exit");
|
|
||||||
Environment.Exit(0);
|
|
||||||
|
|
||||||
_logger.Info("Calling ApplicationTaskCompletionSource.SetResult");
|
|
||||||
ApplicationTaskCompletionSource.SetResult(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShutdownWindowsService()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RestartWindowsService()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool CanRestartWindowsService()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the error mode.
|
/// Sets the error mode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
"version": "1.0.1"
|
"version": "1.0.1"
|
||||||
},
|
},
|
||||||
"Mono.Nat": "1.0.0-*",
|
"Mono.Nat": "1.0.0-*",
|
||||||
"Microsoft.Win32.Registry": "4.0.0",
|
"Microsoft.Win32.Registry": "4.0.0",
|
||||||
"System.Runtime.Extensions": "4.1.0",
|
"System.Runtime.Extensions": "4.1.0",
|
||||||
"System.Diagnostics.Process": "4.1.0",
|
"System.Diagnostics.Process": "4.1.0",
|
||||||
"Microsoft.Data.SQLite": "1.0.0"
|
"Microsoft.Data.SQLite": "1.1.0-preview1-final"
|
||||||
},
|
},
|
||||||
|
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
|
|
Loading…
Reference in New Issue